简体   繁体   中英

Interpolated Colous with Fragment-and VertexShader in GLSL

i want to draw a cube an a square in a scene, both with interpolated colours. I want to use just the fragment-and vertexshader! i can draw it with just simple one colour.

The code for that is the following

<!DOCTYPE html>
[enter image description here][1]<html>
<head>
    <meta charset="utf-8">
    <title>GLSL - Texturen</title>  
</head>

<body>
    <h1>Texturen</h1>
    <!-- three.js einbinden -->
    <script src="js/three.min.js"></script>
    <!-- Einbinden der OrbitControls, um die Darstellung mit der Maus rotieren zu können. -->
    <script src="js/OrbitControls.js"></script>

    <script type="x-shader/x-vertex" id="vertexshader">

        // switch on high precision floats
        #ifdef GL_ES
        precision highp float;
        #endif

        // transmit uv coordinates to fragment shader

        void main()
        {
            /* set fragment position */
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);             
            // transmit uv coordinates to fragment shader
        }

    </script>

    <script type="x-shader/x-fragment" id="fragmentshader">

        #ifdef GL_ES
        precision highp float;
        #endif
        // transmit uv coordinates to fragment shader

        void main()
        {
            // set color based on uv coordinates
            // gl_FragColor = 
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }

    </script>

    <!-- TODO: separate Shader für spätere getrennte Behandlung von Kugel und Würfel -->

    <script>
        /* Copyright world image: By NASA/Goddard Space Flight Center [Public domain], via Wikimedia Commons */

        /* Scene */
        var scene = new THREE.Scene();

        /* Camera */
        var camera = new THREE.PerspectiveCamera(45,window.innerWidth/(window.innerHeight-150),1,1000);
        camera.position.x = 0;
        camera.position.y = 0;
        camera.position.z = 20;
        camera.lookAt(new THREE.Vector3(0,0,-10));
        scene.add(camera);

        /* Renderer */
        var renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setSize(window.innerWidth, (window.innerHeight-150));
        renderer.setClearColor( 0xeeeeee);
        renderer.clear();

        /* Append document to HTML */
        document.body.appendChild(renderer.domElement);

        // load vertex shader by using the inner content of the element
        // 'vertexshader' 
        var vShader = document.getElementById('vertexshader').textContent;
        // load fragement shader by using the inner content of the element
        // 'fragmentshader' 
        var fShader = document.getElementById('fragmentshader').textContent;


        // create the shader material to use the custom vertex and fragment shaders
        var shaderMaterial =
          new THREE.ShaderMaterial({
            vertexShader:   vShader,
            fragmentShader: fShader,
            vertexColors: THREE.FaceColors,
        });

        /* definition of a sphere */
        var sphereGeometry = new THREE.SphereGeometry(5, 60, 60);
        // create the mesh
        sphereMesh = new THREE.Mesh(sphereGeometry, shaderMaterial);
        // location
        sphereMesh.position.set(-8, 0, -5);
        // ... and add it to the scene
        scene.add(sphereMesh);

        // TODO (1d): Add your code so that only the right part of the texture is shown 
        // for each face


        // END TODO

        /* definition of a cube */
        var cubeGeometry = new THREE.BoxGeometry(8, 8, 8);
        // create the mesh
        cubeMesh = new THREE.Mesh(cubeGeometry, shaderMaterial);
        // location
        cubeMesh.position.set(8, 0, -5);
        // ... and add it to the scene
        scene.add(cubeMesh);

        // OrbitControls erzeugen, um mit der Maus beliebig rotieren zu können
        var controls = new THREE.OrbitControls(camera, renderer.domElement);

        // initialize the system
        init();


        function render() {
            requestAnimationFrame( render );
            controls.update();

            renderer.render( scene, camera );
        }

        function init() {
            render();
        }

    </script>

and the result looks like that:

那

It is the cube and the square just in red! But i want it to be interpolated colours. Can anyone tell me how that works with the just adding something in the fragment-and vertex-shader?

The result i want to get should look like that:

IMG

You can pass the UV coordinates from your vertex shader to your fragment shader, using a varying, and then use its x and y values to make gl_FragColor , like so:

var vShader = `
varying vec2 vUv;
void main()
{
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);             
}`;

var fShader = `
varying vec2 vUv;
void main()
{
    gl_FragColor = vec4(vUv.x, vUv.y, 0., 1.0);
}
`;

jsfiddle example r86.

PS Bonus: if you want to know more about fragment shaders, then you can visit https://www.shadertoy.com/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM