【问题标题】:Heightmap to Normalmap GLSL shader issue高度贴图到法线贴图 GLSL 着色器问题
【发布时间】:2014-07-13 12:14:13
【问题描述】:

我正在编写一个用于 GPU 生成景观的模块。我正在使用 OpenGL 和 GLSL 进行生成和可视化。在我编写了一个高度图生成着色器之后,我开始考虑光照的法线。我为法线贴图生成编写了一个简单的着色器,它有点工作,但结果很奇怪。法线贴图中有一些意想不到的四边形分割。 请参阅screen capture

以下是片段着色器:

#version 330

uniform sampler2D heightmap;
uniform float res_x;
uniform float res_y;

in vec4 fragmentColor;
in vec2 tc;
in vec4 pos;
in vec3 normal;

out vec4 color;

void main(void)
{
    float x_d = 1.0/res_x; //size of texel
    float y_d = 1.0/res_y;

    //1024 = resolution of hm
    vec3 top = vec3(tc.x*1024.0, texture2D(heightmap, tc + vec2(0.0, y_d)).r, (tc.y + y_d)*1024.0);
    vec3 bottom = vec3(tc.x*1024.0, texture2D(heightmap, tc + vec2(0.0, -y_d)).r, (tc.y - y_d)*1024.0);
    vec3 left = vec3((tc.x - x_d)*1024.0, texture2D(heightmap, tc + vec2(-x_d, 0.0)).r, tc.y*1024.0);
    vec3 right = vec3((tc.x + x_d)*1024.0, texture2D(heightmap, tc + vec2(x_d, 0.0)).r, tc.y*1024.0);
    vec3 center = vec3(tc.x*1024.0, texture2D(heightmap, tc + vec2(0.0, 0.0)).r, tc.y*1024.0);

    //this 4 vectors are forming 4 triangles
    vec3 top_minus_center = normalize(top - center);
    vec3 bot_minus_center = normalize(bottom - center); 
    vec3 left_minus_center = normalize(left - center);
    vec3 right_minus_center = normalize(right - center);

    //calc 4 normals to 4 triangls
    vec3 _normal[4];
    _normal[0] = normalize(cross(left_minus_center, top_minus_center));
    _normal[1] = normalize(cross(right_minus_center, top_minus_center));
    _normal[2] = normalize(cross(right_minus_center, bot_minus_center));
    _normal[3] = normalize(cross(left_minus_center, bot_minus_center));

    //right direction of normal
    for (int i = 0; i < 4; i++)
        if (_normal[i].y < 0.0)
            _normal[i] = -_normal[i];

    color = vec4(((_normal[0] + _normal[1] + _normal[2] + _normal[3]).xzy/4.0)/2.0 + 0.5, 1.0);//packing normal
}

这个缺陷的原因是什么?

【问题讨论】:

  • 不要将texture2D 与 GLSL 3.30 着色器一起使用。它已被弃用。
  • texture2D 不是问题的原因。

标签: opengl graphics 3d rendering glsl


【解决方案1】:

纹理坐标从 0 到 1

我会建议一些类似的东西:

// get the heights
float top = texture2D(heightmap, tc + vec2(0.0, y_d)).r;
float bottom = texture2D(heightmap, tc + vec2(0.0, -y_d)).r;
float left = texture2D(heightmap, tc + vec2(-v_x, 0.0)).r;
float right = texture2D(heightmap, tc + vec2(v_x, 0.0)).r;
// The center one is not really important

vec3 n = normalize(vec3(bottom - top, left - right, 2.0));
// viola, pack it and go

【讨论】:

  • 你可以只使用三个样本而不是四个。
  • @Tara 为什么?哪三个样本?怎么样?
  • @zwcloud 为什么?表现。哪些样品?例如,中心、顶部、右侧。
猜你喜欢
  • 2012-01-12
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 2014-04-30
  • 1970-01-01
  • 2013-08-14
相关资源
最近更新 更多