Three.JS - 移植自定义顶点着色器

时间:2014-03-07 18:38:14

标签: three.js glsl webgl

我想将this着色器与three.js一起使用。此示例中的顶点着色器使用属性surfacePosAttrib,该属性通过我认为的以下调用在托管javascript中设置:

surface.positionAttribute = gl.getAttribLocation(currentProgram, "surfacePosAttrib");
gl.enableVertexAttribArray(surface.positionAttribute);

webglrenderer搜索three.js来源时,我找不到这些来电,因此我认为这些缓冲区未在three.js中设置。

是否支持在three.js中为自定义着色器设置这些缓冲区的方法?

1 个答案:

答案 0 :(得分:1)

我在源代码中看到了这个顶点着色器:

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

    attribute vec3 position;
    attribute vec2 surfacePosAttrib;
    varying vec2 surfacePosition;

    void main() {

        surfacePosition = surfacePosAttrib;
        gl_Position = vec4( position, 1.0 );

    }

</script>

您提供的第一行代码会在surfacePosAttrib内的顶点着色器中找到索引绑定属性current program,并在javascript中将其分配给positionAttribute surface 。第二行就是启用它。 Javascript缓冲区名称是任意的。它们在不同的程序中有不同的名称,所以可以预测你在three.js中找不到这样的缓冲区。

我猜测(不确定)几乎所有的工作都是在片段着色器中完成的(就像IñigoQuílez完成的大部分类似作品都可以在his shadertoy page中找到)和顶点着色器仅为片段着色器提供绘制的表面。

下面的简单示例使用three.js中的自定义着色器。它定义了一个具有相机可见的2D平面几何体的网格,并定义了一个自定义着色器,其顶点着色器和片段着色器由用户提供。请注意,projectionMatrixmodelViewMatrixthree.js在顶点着色器中自动提供,因此您无需手动传递它们。

<!DOCTYPE html>
<html>
<head>
    <title>Shading #1</title>
    <style>canvas { width: 100%; height: 100% ;}</style>
    <style>
        body {
            margin: 0px;
        }
    </style>
</head>
<body>      
    <script src="https://rawgithub.com/mrdoob/three.js/master/build/three.min.js"></script>

    <script id="vs" type="x-shader/x-vertex">       
        void main()
        {
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
        }           
    </script>

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

        uniform float time;
        uniform vec2 resolution;

        void main()
        {               

            gl_FragColor = vec4(0.3, 0.0, 0.0 , 1.0);
        }

    </script>

    <script type="text/javascript">

        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
        var renderer = new THREE.WebGLRenderer({ antialias: true});

        var startTime = Date.now();

        //assignings happen here
        //more info on https://github.com/mrdoob/three.js/wiki/Uniforms-types
        var uniforms = {
            time: {
                type: 'f',
                value: 0
            },
            resolution: {
                type: "v2",
                value: new THREE.Vector2( window.innerWidth, window.innerHeight )
            }
        };          
        var myMaterial = new THREE.ShaderMaterial({
            uniforms: uniforms,
            vertexShader: document.getElementById( 'vs' ).textContent,
            fragmentShader: document.getElementById( 'fs' ).textContent
        });

        camera.position.z = 0.40;
        var itemGeometry = new THREE.PlaneGeometry( window.innerWidth / (window.innerWidth+window.innerHeight), window.innerHeight / (window.innerWidth+window.innerHeight), 0);
        var itemCube = new THREE.Mesh( itemGeometry, myMaterial );
        scene.add( itemCube );

        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );


        function render() {

            requestAnimationFrame(render);
            uniforms.time.value = (Date.now() - startTime)/1000;        
            renderer.render(scene, camera);

        }
        render();
    </script>
</body>
</html>
相关问题