GLSL 顶点着色器查找表问题

发布于 2024-10-01 05:46:33 字数 1579 浏览 12 评论 0原文

我在调试我的程序时遇到了一些困难。我正在尝试使用数组作为查找表来偏移顶点着色器中的顶点位置,但我什至无法判断我是否正确链接了数组。偏移因子总是以零结束(压平我的向量,而不是给它们一个形状),所以要么我错误地访问了texture1D坐标,要么数组没有正确绑定到纹理。

坦率地说,我不知道应该使用哪个坐标来从一维纹理获取值......但我已经尝试了所有组合。

在这里,我设置了数组并将其绑定到着色器:

//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;
}

I've got some difficulty debugging my program. I'm trying use an array as a lookup table to offset the vertex location in my vertex shader, but I can't even tell if I'm linking my array correctly. The offset factor always ends up zero (flattening my vectors, rather than giving them a shape), so either I'm accessing the texture1D coordinates wrong or the array isn't binding right to the texture.

Frankly, I don't know which coordinates I should be using to get the values from a 1D texture... but I've tried all the combinations.

Here I setup the array and bind it to the shader:

//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);    

And my vertex shader:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

习惯成性 2024-10-08 05:46:33

您的纹理加载代码中有两个问题:

1.- 默认的 MIN 过滤器使用 mipmap,因此设置后纹理不完整。将纹理绑定到 GL_NEAREST 后设置 MIN/MAG 过滤器。
2.- 你的纹理数据是浮点数,但你对 GL 说它们是无符号字节,将其更改为 GL_FLOAT。

进行此更改后,您的纹理应该会出现。

There are two problems in your texture loading code:

1.- The default MIN filter uses mipmaps, so with that setup the texture incomplete. Set the MIN/MAG filters after binding the texture to GL_NEAREST.
2.- Your texture data is floats, but you say to GL they are unsigned bytes, change that to GL_FLOAT.

After this changes your texture should appear.

明天过后 2024-10-08 05:46:33

有一个 GLSL 命令允许您访问纹理的单个纹素,而无需纹理过滤:
纹素提取
它不使用标准化坐标 (0-1),而是使用整数,因此 texelFetch(32, 32) 将获取右侧 32 个纹理像素和下方 32 个纹理像素。

看起来你正在写相当老式的 GLSL,所以我不知道它有多适用。

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

几年前,这让我很头疼。

顺便说一句,我看到你正在尝试渲染一群鱼什么的,看起来很有趣,哪里有演示?

There is a GLSL command that allows you to access single texels of a texture, without no texture filtering:
texelFetch
Instead of using normalized coordinates (0-1), it uses integers, so texelFetch(32, 32) would fetch the the texel 32 texel to the right and 32 texels down.

It looks like you are writing pretty old school GLSL though, so I don't know how applicable it is.

Warning: If you are compiling your GLSL programs on an Nvidia card, with the Nvidia drivers, it will compile like it was CG, which has a funny caveat.
Interestingly enough, if you try to access an index of an sufficiently large array (you are using an texture as an array, so that should not be a problem for you) using an hardcoded value for the index, it will compile.
However, if you use an dynamic index (variable) to access an field of the same array, it will not compile.
The reason is that Nvidias compiler optimizes out all the indexes not being used (since you are using a hardcoded value, the compiler thinks that it can throw away the other array values)!

This gave me quite an headache some years ago.

Incidentally, I see that you're trying to render a school of fishes or something, it looks interesting, any place where you have a demo?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文