【问题标题】:GLSL normal mapping shader issuesGLSL法线贴图着色器问题
【发布时间】:2012-01-12 20:12:49
【问题描述】:

VC++ 2010、OpenGL、GLSL、SDL

所以我有两个主要问题。我希望主要解决第一个问题:我正在使用的法线贴图着色器不适用于指向正或负 x 方向的法线。 z 和 y 似乎工作得很好(测试立方体上的纹理和法线)。

edit :它似乎不是 x 方向的法线,因为当我旋转几何图形时,正面的四边形仍然可以工作。所以看起来最初面向 x 的任何东西都不起作用。

这是一些简单的测试几何:

glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, 0.0f, 1.0f);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(-1.0f, 0.0f, 0.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0f, 2.0f, -1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0f, 0.0f, -1.0f);
glEnd();

顶点着色器

#define MAX_LIGHTS 8
#define NUM_LIGHTS 1

varying vec3 lightVec[MAX_LIGHTS];
varying vec3 viewVec;

attribute vec4 glTangent4f;

void main(void)
{
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;

    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
    vec3 t = normalize(gl_NormalMatrix * glTangent4f.xyz);
    vec3 b = cross(n, t);

    vec3 v;
    vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
    int i;
    for (i=0; i<NUM_LIGHTS; ++i)
    {
        vec3 lVec = gl_LightSource[i].position.xyz - vVertex;
        v.x = dot(lVec, t);
        v.y = dot(lVec, b);
        v.z = dot(lVec, n);
        lightVec[i] = v;
    }

    vec3 vVec = -vVertex;
    v.x = dot(vVec, t);
    v.y = dot(vVec, b);
    v.z = dot(vVec, n);
    viewVec = v;
}

片段着色器

#define MAX_LIGHTS 8
#define NUM_LIGHTS 1

varying vec3 lightVec[MAX_LIGHTS];
varying vec3 viewVec;

uniform sampler2D colorMap;
uniform sampler2D normalMap;

void main (void)
{
    vec2 uv = gl_TexCoord[0].st * 4.0;
    vec4 base = texture2D(colorMap, uv);
    vec4 final_color = vec4(0.2, 0.2, 0.2, 1.0) * base;
    vec3 vVec = normalize(viewVec);
    vec3 bump = normalize(texture2D(normalMap, uv).xyz * 2.0 - 1.0);
    vec3 R = reflect(-vVec, bump);

    int i;
    for (i=0; i<NUM_LIGHTS; ++i)
    {
        vec3 lVec = normalize(lightVec[i]);
        float diffuse = max(dot(lVec, bump), 0.0);
        vec4 vDiffuse = gl_FrontLightProduct[i].diffuse * diffuse * base;
        final_color += vDiffuse;

        float specular = pow(clamp(dot(R, lVec), 0.0, 1.0), gl_FrontMaterial.shininess);
        vec4 vSpecular = gl_FrontLightProduct[i].specular * specular * diffuse;
        final_color += vSpecular;
    }

    gl_FragColor = final_color;
}

另一个问题(我现在不一定需要解决)是定向光的镜面反射似乎跟随相机

【问题讨论】:

  • 与您的预期相比,发生了什么/没有发生什么?
  • 您的着色器缺少#version 指令。它们是编译着色器所必需的。
  • 我期待看到法线贴图在面向 x 方向的第二组几何体上工作。
  • 好的。你能张贴一张你在运行时看到的截图吗?
  • 不幸的是,屏幕截图现在在我的应用程序中显示为黑色。

标签: c++ opengl glsl shader


【解决方案1】:
attribute vec4 glTangent4f;

您实际上在哪里提供这个值?这是一个顶点属性,但你的渲染代码似乎没有提供任何东西。

【讨论】:

  • 如何将这个曲面切线传递给程序?
【解决方案2】:

“我将如何将这个曲面切线传递给程序?”

您是否计算了对象的切线基础?我记得波前对象通常不包括顶点切线数据,在这种情况下,您需要在解析波前数据后计算切线基础。 从您的代码看起来,您似乎根本没有切线数据。

您也可以在顶点着色器中进行切线逼近,只需使用法线即可。

我实际上不知道您将如何将切线数据传递给程序,因为您没有使用 VBO。

编辑:

我现在看到我做了一个愚蠢的假设,即您正在从 3d 文件格式加载数据,但您仍然需要在某处计算切线。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    相关资源
    最近更新 更多