将顶点保存到纹理并传递到着色器

mja*_*sz1 -5 javascript shader textures three.js

终于有时间玩着色器,但一时间卡住了.我想将顶点传递给着色器并在其上制作一些gpgpu.

Gpgpu工作正常,我猜是因为我看到几个像素,中间的一个被推到一边,因为我放入代码只是为了测试.

现在我想传递球体顶点.以下是我要采取的步骤.请指出错误:-)

编辑:小提琴添加 - 点击这里

1)创建几何体,并将其传递给数据数组.

geometry = new THREE.SphereGeometry( 0.2, 15, 15 );
console.log(geometry.vertices.length);
var a = new Float32Array(geometry.vertices.length * 4);
for(var k=0; k<geometry.vertices.length; k++) {
                a[ k*4 + 0 ] = geometry.vertices[k].x;
                a[ k*4 + 1 ] = geometry.vertices[k].y;
                a[ k*4 + 2 ] = geometry.vertices[k].z;
                a[ k*4 + 3 ] = 1;   
}
Run Code Online (Sandbox Code Playgroud)

2)将其保存在数据纹理中

posTexture[2] = new THREE.DataTexture(a, 16, 16, THREE.RGBAFormat, THREE.FloatType);
Run Code Online (Sandbox Code Playgroud)

3)设置'Set scene'(它应该将datatexture传递给它一次)setUniforms = {posTexture:{type:"t",value:posTexture [2]}};

var setMaterial = new THREE.ShaderMaterial({
    uniforms: setUniforms,
    vertexShader:   document.getElementById('setVert').textContent,
    fragmentShader: document.getElementById('setFrag').textContent,
    wireframe: true
});

var setPlane = new THREE.Mesh(new THREE.PlaneGeometry(16,16), setMaterial);
setScene.add(setPlane);
Run Code Online (Sandbox Code Playgroud)

4)设置着色器.

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

    // switch on high precision floats
    #ifdef GL_ES
    precision highp float;
    #endif
    varying vec2 vUv;
    uniform sampler2D posTexture;

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

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

    #ifdef GL_ES
    precision highp float;
    #endif
    uniform sampler2D posTexture;
    varying vec2 vUv;

    void main(){
        vec3 color = texture2D( posTexture, vUv ).xyz;

        gl_FragColor = vec4(col, 1.0);
    }
</script>
Run Code Online (Sandbox Code Playgroud)

5)动画!!! start设置SetShader以保存数据并将WebGLRenderTarget输出到下一个着色器:一个负责进行计算并返回带坐标的纹理,下一个用于显示

function animate() {

    requestAnimationFrame(animate);
    renderer.setViewport(0,0,16, 16);
    if(buffer == 0) {
        buffer = 1;
        a = 0;
        b = 1;
    } else {
        buffer = 0;
        a = 1;
        b = 0;
    }

    if(start) {
        renderer.render(setScene, processCamera, posTexture[a]);
        start = false;
    }

    posUniforms.posTexture.value = posTexture[a];
    renderer.render(posScene, processCamera, posTexture[b])
    dispUniforms.posTexture.value = posTexture[b];
    renderer.setViewport(0,0,dispSize.x, dispSize.y);
    renderer.render(scene, camera);

}
Run Code Online (Sandbox Code Playgroud)

编辑:我不明白所有的downvoting.只是问我的代码有什么问题,为什么它不起作用.我不是要求为我写的.显然,试图解释它的人写了不同的东西,这与问题无关,这就是我不接受答案的原因.

Doi*_*del 93

我不得不稍微抛光着色器代码,这对我来说似乎有点凌乱^^ http://jsfiddle.net/ec5zU/1/

好吧,你正试图将球体顶点向下推到gpu.您想要这样做的事实表明您可能不太了解gpgpu的概念.它可以在GPU上计算内容(算法,数学).这是一个与GPU协同工作而不进行/显示3D相关内容的概念.

将球体顶点传递到纹理然后使用该纹理做一些事情对我来说没有任何意义 - 但也许我只是不太明白你想要做什么.那么你可以用gpgpu方法详细说明你的最终目标吗?

在演示纹理中使用的原因如下:您可以轻松地将数据从CPU(JavaScript)移动到GPU(与制服,属性一样),但反过来却更难.一种可能性是为GPU设置一个单独的渲染目标,这将导致您在渲染周期完成后保存为纹理.然后你可以"存储你的数据".

包括对这个答案的评论我想说的是:我建议学习更多关于着色器和three.js的知识,因为大部分时间都可以更轻松,更好地完成.如果那个演示案例很重要,那么尝试实现修复我和Andon M. Coleman给你的,并考虑你的领域逻辑以及你想如何实现它'因为你现在的方式也没有做到很有意义......

如果你确定没有比在每一帧上创建和重新分配纹理位置更好的方法,那就这样吧:)我玩了一个小时,添加评论,更改了一些东西,修复了最糟糕的部分,现在你看到了一个红点在屏幕上移动:http://jsfiddle.net/ec5zU/2/我不会再投入时间了,因为我认为stackoverflow不是要让你的项目编码^^我希望我能提供一些帮助尽管如此,你还有一个起点,因为现在某些东西实际上是"工作和移动".祝好运并玩得开心点!

(Stackoverflow告诉我要包含一些代码.所以底部有一些抛光的着色器代码.)

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

        precision highp float;

        varying vec2 vUv;
        uniform sampler2D posTexture;

        void main()
        {
            vec3 color = texture2D(posTexture, vUv).rgb;
            color.x += 0.01;
            gl_FragColor = vec4(color, 1.0);

        }

    </script>
Run Code Online (Sandbox Code Playgroud)