GLSL顶点着色器查找表问题

4
我遇到了一些调试程序的困难。我试图使用数组作为查找表,在我的顶点着色器中偏移顶点位置,但是我甚至无法确定我是否正确地链接了我的数组。偏移因子总是结束为零(使我的向量变平,而不是给它们一个形状),所以要么我访问texture1D坐标有误,要么数组没有正确绑定到纹理上。
坦率地说,我不知道我应该使用哪些坐标来从1D纹理中获取值...但我已经尝试了所有组合。
在这里,我设置了数组并将其绑定到着色器:
//FISH
GLfloat fish_coords[100];
for (int i = 0; i < 50; i++){fish_coords[i] = 0;}
for (int i = 50; i < 100; i++){fish_coords[i] = 1;}
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glGenTextures(1, &fishtexture);  
glBindTexture(GL_TEXTURE_1D, fishtexture);
glTexImage1D(GL_TEXTURE_1D, 0, 1, 128,0,GL_RGBA, GL_UNSIGNED_BYTE, &fish_coords);

switch(shadow_selection){
case 0: 
    vertexShader = "fish.vert";
    fragmentShader = "fish.frag";
    setShaders();

    GLint loc1;
    loc1 = glGetUniformLocation(shaderProgram,"fish_coords");
    glUniform1i(loc1,0);    

我的顶点着色器:

uniform float spec_factor;
uniform sampler1D fish_coords;

varying vec3 lightDir,normal;

void main()
{

    vec4 v_pos;
    vec3 ldir;

    gl_TexCoord[0] = gl_MultiTexCoord0;

    v_pos = gl_ModelViewMatrix * gl_Vertex;
    ldir = vec3(gl_LightSource[0].position-v_pos);
    lightDir = normalize(ldir);
    normal = normalize(gl_NormalMatrix * gl_Normal);

    vec4 offset;
    offset = texture1D(fish_coords, gl_TexCoord[0].r);

    vec4 fish_shape;
    fish_shape.xz = gl_Vertex.xz;
    fish_shape.y = gl_Vertex.y * offset.x;
    fish_shape.w = 1;

    gl_Position = gl_ModelViewProjectionMatrix * fish_shape;
}

1
快速的答案是:那不是你加载纹理的方式。Bind通过id选择你要操作的纹理。你可以使用glGenTextures分配id,绑定它们,加载它们(例如使用glTexImage1D),然后再使用它们。 - Ben Jackson
啊,我以为查找表是一种通过纹理来进行的黑客技巧,所以我之前没有这样做。谢谢。 - jakev
好的,那么做了这些更改后......我并没有更接近解决问题。 - jakev
2个回答

3

您的纹理加载代码存在两个问题:

1.- 默认的MIN过滤器使用了mipmaps,因此该设置会使纹理不完整。请在将纹理绑定到GL_NEAREST后设置MIN/MAG过滤器。 2.- 您的纹理数据是浮点型的,但您告诉GL它们是无符号字节,请将其更改为GL_FLOAT。

进行这些更改后,您的纹理应该可以出现了。


1

有一个GLSL命令可以让你访问纹理的单个纹素,而不进行纹理过滤: texelFetch 它使用整数而不是归一化坐标(0-1),因此texelFetch(32,32)将获取向右32个纹素和向下32个纹素的纹素。

看起来你正在编写相当老派的GLSL,所以我不知道它是否适用。

警告:如果您在Nvidia卡上使用Nvidia驱动程序编译GLSL程序,它将像CG一样编译,这有一个有趣的附带条件。 有趣的是,如果您尝试使用硬编码值访问足够大的数组索引(您正在将纹理用作数组,因此这对您不应该成为问题),它将编译。 但是,如果您使用动态索引(变量)访问同一数组的字段,则不会编译。 原因是Nvidia的编译器优化了所有未使用的索引(由于您使用了硬编码值,编译器认为可以丢弃其他数组值)!

几年前这让我头疼不已。

顺便说一下,我看到你正在尝试渲染一群鱼或其他什么东西,看起来很有趣,你有演示的地方吗?

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