GL_POINTS着色器中的样本纹理

3
我有一个绘制纯色粒子的着色器。我想让着色器采样FBO纹理,以便每个粒子可以对其“背后”的颜色产生影响。看起来应该很简单,但并非如此。
我已经简化了代码,以便期望我的FBO在每个粒子的表面上绘制,并缩小。虽然不美观,但至少可以证明我的粒子可以采样纹理。但是,每个粒子都只是一个纯色。我正在使用OpenFrameworks,因此有一些抽象。我已经验证tex.bind()绑定到第一个纹理位置,并且我能够在没有GL_POINTS的情况下将着色器应用于FBO。
这是我设置着色器、绘制FBO和渲染粒子的地方:
void Particles::draw(ofxFBOTexture &tex){
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        ofEnableSmoothing();
        glEnable(GL_POINT_SPRITE_ARB);
        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
        glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE, GL_TRUE);
                shader.begin();
                        shader.setUniform("winWidth", (float) width);
                        shader.setUniform("winHeight", (float) height);
                        tex.draw(0,0); // I've tried tex.bind() here too    

                        for(int i = 0; i < lastDead; i++){
                                allParticles[i]->draw(this->shader);
                        }

                shader.end();
        glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
        glDisable(GL_POINT_SPRITE_ARB);
        ofDisableSmoothing();
        glDisable(GL_BLEND);
}
// <snip>
void Particle::draw(ofxShader &shader){
        if(dead) return;

        // this must go outside glBegin
        shader.setAttribute("size", size);
        shader.setAttribute("velocity", xVel, yVel, 0.0);

        glBegin(GL_POINTS);
                glColor4f(r, g, b, multiplier * 0.8);
                glVertex3f(x, y, 0);
        glEnd();
}

以下是我的顶点着色器:

#version 120
attribute float size;
attribute vec3 velocity;
varying vec3 vel;
uniform float winWidth;
uniform float winHeight;

void main() {
        gl_PointSize = size;
        gl_FrontColor = gl_Color;

        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
        gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

        vel = velocity;
}

...以及我片段着色器中相关的摘录,为了调试而简化:

#version 120
#extension GL_ARB_texture_rectangle : enable
varying vec3 vel;
uniform sampler2DRect tex;
uniform float winWidth;
uniform float winHeight;

void main() {
        vec4 texColor = texture2DRect(tex, gl_TexCoord[0].st);
        gl_FragColor = texColor;
}
1个回答

3

谢谢,但似乎没有任何区别。有没有办法调试着色器以确保正确的纹理绑定到sampler2DRect tex?过去那部分一直都是正常工作的,但我从来不确定如何或为什么。texture2DRect是否采用vec2([0.0 - 1.0], [0.0 - 1.0])格式的第二个参数?我找不到任何文档。 - Ian
基于您的答案(我会接受它),texture2DRect 似乎需要窗口坐标。使用 gl_PointCoord.st * vec2(winWidth, winHeight) 在每个点上得到了整张纹理。从那里开始,很容易发现获得每个点后面的纹理像素只需要简单地使用 texture2DRect(tex, gl_FragCoord.st + (gl_PointCoord.st * vec2(2.0, 2.0) + vec2(-1.0, -1.0)))。谢谢! - Ian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接