Glsl WebGL:使用FBO的粒子引擎,如何从纹理正确写入和采样粒子位置?
我怀疑我没有正确地将粒子位置渲染到FBO,或者在渲染时没有正确地对这些位置进行采样,尽管无可否认,这可能不是我的代码的实际问题 我这里有一个完整的jsfiddle: 代码的简要概述: 初始化:Glsl WebGL:使用FBO的粒子引擎,如何从纹理正确写入和采样粒子位置?,glsl,webgl,Glsl,Webgl,我怀疑我没有正确地将粒子位置渲染到FBO,或者在渲染时没有正确地对这些位置进行采样,尽管无可否认,这可能不是我的代码的实际问题 我这里有一个完整的jsfiddle: 代码的简要概述: 初始化: 在x、y、z方向创建一个随机粒子位置数组 创建纹理采样位置阵列(例如,对于2个粒子,第一个粒子位于0,0,下一个位于0.5,0) 创建一个帧缓冲区对象和两个粒子位置纹理(一个用于输入,一个用于输出) 创建一个全屏四元组(-1,-1到1,1) 粒子模拟: 使用粒子程序渲染全屏四边形(绑定帧缓冲区,将视口设置
// 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
}
粒子渲染顶点着色器:
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错误,并将我所能做的记录到控制台。您的四元菜单面朝远离视图,因此我尝试添加gl.disable(gl.CULL_FACE),但仍然没有结果 然后我注意到,当用画布调整窗口面板的大小时,它实际上显示了一个黑色的方形粒子。所以看起来渲染循环不是很好 如果您查看控制台日志,它无法加载粒子图像,并且它还表示FBO大小为512x1,这不好 某些函数声明不存在,如getTexSize。(?!) 代码需要整理和分组,如果您已经在使用console,请始终检查它 希望这有点帮助。发现了问题 gl_FragCoord是从[0,0]到[screenwidth,screenheight],我错误地认为它是从[0,0]到[1,1]
我必须传入宽度和高度的着色器变量,然后在从纹理采样之前规范化采样坐标。谢谢!我没意识到那辆四轮车走错了方向。渲染粒子为黑色的原因是粒子精灵图像未实际加载,因此这是意料之中的。FBO应该是512x1,因为有512个粒子,为什么这样不好?getTexSize在顶部声明,它选择一个纹理大小,使得像素数==粒子数(因此为512x1)。
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;
}