最终花了一些时间与着色器一起玩,但是一时陷入困境。我想将顶点传递到着色器并对其进行一些gpgpu。
我猜Gpgpu工作正常,因为当我输入代码进行测试时,看到很少的像素,中间的一个像素被推到一边。
现在我想通过球体顶点。这是我正在采取的步骤。请指出错误:-)
编辑:提琴添加-click here
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;
}
2)将其保存为数据纹理
posTexture[2] = new THREE.DataTexture(a, 16, 16, THREE.RGBAFormat, THREE.FloatType);
3)设置“设置场景”(应该将数据纹理传递给它一次)setUniforms = {posTexture:{类型:“ t”,值: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);
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>
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);
}
我不得不略微修改着色器代码,对我来说似乎有点混乱^^ http://jsfiddle.net/ec5zU/1/
[好,您正在尝试将球面顶点向下推到GPU。您想要这样做的事实表明您可能不太了解gpgpu的概念。它可以在GPU上计算内容(算法,数学)。不使用/显示3D相关内容的情况下使用GPU是一种概念。
将球面顶点传递到纹理中,然后对该纹理进行处理对我来说是没有意义的-但也许我只是不太了解您要做什么。因此,您可以使用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>