Webgl Advanced Shader (based on Three.js) - the first simple Shader

    Three.js has simplified a lot of the work of writing shaders. The main work is that he has provided us with some commonly used matrices as a constant.

    First of all, let's look at the description of the Three.js official website . Some common parameters are already associated with geometric elements, cameras, etc., we only need to use them.

    Let's look at the first shader, changing the color of the geometry surface through the shader, the effect is still very cool.


<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Three框架</title>
    <script src="../library/three.js"></script>
    <script src="../library/stats.min.js"></script>    
    <style type="text/css">
        div#canvas-frame {
            border: none;
            cursor: pointer;
            width: 100%;
            height: 600px;
            background-color: #EEEEEE;
        }
    </style>
    <script id="fragment_shader" type="x-shader/x-fragment">
        uniform float time;

        varying vec2 vUv;

        void main( void ) {

        vec2 position = - 1.0 + 2.0 * vUv;

        float red = abs( sin( position.x * position.y + time / 5.0 ) );
        float green = abs( sin( position.x * position.y + time / 4.0 ) );
        float blue = abs( sin( position.x * position.y + time / 3.0 ) );
        gl_FragColor = vec4( red, green, blue, 1.0 );

        }

    </script>
    <script id="vertexShader" type="x-shader/x-vertex">
        varying vec2 vUv;

        void main()
        {
        vUv = uv;
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_Position = projectionMatrix * mvPosition;
        }

    </script>

    <script>      

        was renderer;
        var stats;
        var clock;
        var uniforms1;
        var camera;
        var scene;
        var light;
        var mesh;

        //Initialize webgl
        function initThree() {
            width = document.getElementById('canvas-frame').clientWidth;
            height = document.getElementById('canvas-frame').clientHeight;
            renderer = new THREE.WebGLRenderer();

            renderer.setSize(width, height);
            document.getElementById('canvas-frame').appendChild(renderer.domElement);
            renderer.setClearColor(0xFFFFFF, 1.0);

            clock = new THREE.Clock();

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';
            document.getElementById('canvas-frame').appendChild(stats.domElement);
        }

        //set the camera
        function initCamera() {
            camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);            
            camera.position.set(0,0,600);
            camera.up = new THREE.Vector3(0,1,0);
           
            camera.lookAt(0,0,0);
        }

        //initialize the scene
        function initScene() {
            scene = new THREE.Scene();
        }

        //set the lighting
        function initLight() {
            light = new THREE.AmbientLight(0xFF0000);
            light.position.set(100, 100, 200);
            scene.add(light);            
        }

        
        //geometric object
        function initObject() {
            uniforms1 = {
                time: { value: 1.0 }
            };

            var params = uniforms1;
            var geometry = new THREE.CylinderGeometry(100, 150, 400);
            var material = new THREE.ShaderMaterial({

                uniforms: params,
                vertexShader: document.getElementById('vertexShader').textContent,
                fragmentShader: document.getElementById('fragment_shader').textContent

            });
            mesh = new THREE.Mesh(geometry, material);
            mesh.position = new THREE.Vector3(0, 0, 0);
            scene.add(mesh);
        }
        // run webgl
        function threeStart() {
            initThree();
            initCamera();
            initScene();
            initLight();
            initObject();
            animation();    

        }
        //set dynamic scene
        function animation() {
            var delta = clock.getDelta ();
            uniforms1.time.value += delta * 5;
            renderer.render(scene, camera);
            requestAnimationFrame(animation);
            stats.update();           
        }

    </script>
</head>

<body onload="threeStart();">
    <div id="canvas-frame"></div>
</body>
</html>  

Then analyze the code to see how it is implemented.

1) Look at the vertexshader first, this is simple and clear, gl_Position=mvp, then pass the UV coordinates to the fragmentshader, define a time parameter in the fragmentshader, and then the color of the point changes with time and position.

2) Next, when creating a geometric object, get the time parameter, and the material in the geometry uses shaderMaterial();

3) Finally, change the time parameter in the animation with time.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325763278&siteId=291194637