我怀疑我没有正确地将粒子位置渲染到我的FBO,或者在渲染时正确地对这些位置进行采样,尽管这可能不是我的代码的实际问题,不可否认。
我在这里有一个完整的jsfiddle :http://jsfiddle.net/p5mdv/53/
代码的简要概述:
初始化:
在x,y,z
创建纹理采样位置数组(例如,对于2个粒子,第一个粒子为0,0,下一个为0.5,0)
创建一个帧缓冲对象和两个粒子位置纹理(一个用于输入,一个用于输出)
创建全屏四(-1,-1到1,1)
粒子模拟:
使用粒子程序渲染全屏四边形(绑定帧缓冲区,将视口设置为我的粒子位置纹理的尺寸,绑定输入纹理,并从-1,-1到1,1绘制四边形) )。输入和输出纹理每帧交换。
粒子片段着色器在当前片段位置(gl_FragCoord.xy)对粒子纹理进行采样,进行一些修改,并写出修改后的位置
粒子渲染:
使用纹理采样位置的顶点缓冲区进行绘制
顶点着色器使用采样位置对粒子位置纹理进行采样,然后使用视图投影矩阵对其进行变换
使用精灵纹理(gl.POINTS)
问题:
我是否在粒子模拟步骤中正确设置了FBO的视口?即我正确渲染全屏四核吗?
// 6 2D corners = 12 vertices
var vertexBuffer = new Float32Array(12);
// -1,-1 to 1,1 screen quad
vertexBuffer[0] = -1;
vertexBuffer[1] = -1;
vertexBuffer[2] = -1;
vertexBuffer[3] = 1;
vertexBuffer[4] = 1;
vertexBuffer[5] = 1;
vertexBuffer[6] = -1;
vertexBuffer[7] = -1;
vertexBuffer[8] = 1;
vertexBuffer[9] = 1;
vertexBuffer[10] = 1;
vertexBuffer[11] = -1;
// Create GL buffers with this data
g.particleSystem.vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, g.particleSystem.vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, vertexBuffer, gl.STATIC_DRAW);
...
gl.viewport(0, 0,
g.particleSystem.particleFBO.width,
g.particleSystem.particleFBO.height);
...
// Set the quad as vertex buffer
gl.bindBuffer(gl.ARRAY_BUFFER, g.screenQuad.vertexObject);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
// Draw!
gl.drawArrays(gl.TRIANGLES, 0, 6);
我是否正确设置纹理坐标以对粒子位置进行采样?
for(var i=0; i<numParticles; i++)
{
// Coordinates of particle within texture (normalized)
var texCoordX = Math.floor(i % texSize.width) / texSize.width;
var texCoordY = Math.floor(i / texSize.width) / texSize.height;
particleIndices[ pclIdx ] = texCoordX;
particleIndices[ pclIdx + 1 ] = texCoordY;
particleIndices[ pclIdx + 2 ] = 1; // not used in shader
}
相关着色器:
粒子模拟片段着色器:
precision mediump float;
uniform sampler2D mParticleTex;
void main()
{
// Current pixel is the particle's position on the texture
vec2 particleSampleCoords = gl_FragCoord.xy;
vec4 particlePos = texture2D(mParticleTex, particleSampleCoords);
// Move the particle up
particlePos.y += 0.1;
if(particlePos.y > 2.0)
{
// Reset
particlePos.y = -2.0;
}
// Write particle out to texture
gl_FragColor = particlePos;
}
粒子渲染顶点着色器:
attribute vec4 vPosition;
uniform mat4 u_modelViewProjMatrix;
uniform sampler2D mParticleTex;
void main()
{
vec2 particleSampleCoords = vPosition.xy;
vec4 particlePos = texture2D(mParticleTex, particleSampleCoords);
gl_Position = u_modelViewProjMatrix * particlePos;
gl_PointSize = 10.0;
}
让我知道是否有更好的方法来调试这个,如果没有别的。我正在使用webgl-debug查找gl错误并将我可以记录到控制台。
答案 0 :(得分:1)
你的四边形背离视图所以我尝试添加gl.disable(gl.CULL_FACE),仍然没有结果。
然后我注意到,在使用画布调整窗口面板的大小时,它实际上显示了一个黑色的方形粒子。所以渲染循环似乎并不好。
如果查看控制台日志,它无法加载粒子图像,并且它还说FBO大小为512x1,这是不好的。
某些函数声明不存在,如getTexSize。 (?!)
代码需要整理和分组,如果您已经在使用它,请务必检查控制台。
希望这有点帮助。
答案 1 :(得分:0)
发现问题。
gl_FragCoord是从[0,0]到[screenwidth,screenheight],我错误地认为它是从[0,0]到[1,1]。
我必须传递着色器变量的宽度和高度,然后在从纹理采样之前对样本坐标进行标准化。