GL_POINTS 着色器中的示例纹理

Posted

技术标签:

【中文标题】GL_POINTS 着色器中的示例纹理【英文标题】:Sample texture in GL_POINTS shaders 【发布时间】:2011-04-30 02:39:22 【问题描述】:

我有一个用纯色绘制粒子的着色器。我想让着色器对 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】:

你需要gl_PointCoord.st,而不是gl_TexCoord[0].st

【讨论】:

谢谢,但这似乎没有任何区别。有什么方法可以调试着色器以确保正确的纹理绑定到sampler2DRect tex?在过去,那部分只是工作,但我从来没有真正确定如何或为什么。 texture2DRect 是否采用 vec2([0.0 - 1.0], [0.0 - 1.0]) 格式的第二个参数?我找不到任何文档。 以您的答案为基础(所以我会继续接受它)。 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))) 一样简单。谢谢!

以上是关于GL_POINTS 着色器中的示例纹理的主要内容,如果未能解决你的问题,请参考以下文章

顶点纹理获取(在顶点着色器中读取纹理)

OpenGL 计算着色器中的样本深度缓冲区

从片段着色器中的地形高程数据计算法线

LWJGL 无法在着色器中采样帧缓冲纹理

在片段着色器中丢失纹理定义

在着色器中解释纹理数据