OpenGL 3D地形照明文物

时间:2016-02-24 14:31:54

标签: opengl lighting terrain

我在我的地形上进行逐像素照明(phong着色)。我使用高度图生成地形高度,然后计算每个顶点的法线。法线在片段着色器中进行插值并进行标准化。

我在三角形边缘附近有一些奇怪的暗线,那里不应该有。 http://imgur.com/L2kj4ca

我使用几何着色器在地形上绘制法线来检查法线是否正确,它们似乎是正确的。 http://imgur.com/FrJpdXI

对于地形使用法线贴图是没有意义的,它只能给出几乎相同的法线。问题在于法线在三角形内插的方式。

我不知道如何解决这个问题。我无法在线找到任何可行的解决方案。

地形顶点着色器:

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 textureCoords;

out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
out float visibility;

uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

uniform vec3 lightPosition;

const float density = 0.0035;
const float gradient = 5.0;

void main()
{
    vec4 worldPosition = transformationMatrix * vec4(position, 1.0f);
    vec4 positionRelativeToCam = viewMatrix * worldPosition;

    gl_Position = projectionMatrix * positionRelativeToCam;
    pass_textureCoords = textureCoords;

    surfaceNormal = (transformationMatrix * vec4(normal, 0.0f)).xyz;
    toLightVector = lightPosition - worldPosition.xyz;

    float distance = length(positionRelativeToCam.xyz);
    visibility = exp(-pow((distance * density), gradient));
    visibility = clamp(visibility, 0.0, 1.0);
}

Terrain Fragment Shader:

#version 330 core

in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in float visibility;

out vec4 colour;

uniform vec3 lightColour;
uniform vec3 fogColour;

uniform sampler2DArray blendMap;
uniform sampler2DArray diffuseMap;

void main()
{
    vec4 blendMapColour = texture(blendMap, vec3(pass_textureCoords, 0));

    float backTextureAmount = 1 - (blendMapColour.r + blendMapColour.g + blendMapColour.b);
    vec2 tiledCoords = pass_textureCoords * 255.0;
    vec4 backgroundTextureColour = texture(diffuseMap, vec3(tiledCoords, 0)) * backTextureAmount;
    vec4 rTextureColour = texture(diffuseMap, vec3(tiledCoords, 1)) * blendMapColour.r;
    vec4 gTextureColour = texture(diffuseMap, vec3(tiledCoords, 2)) * blendMapColour.g;
    vec4 bTextureColour = texture(diffuseMap, vec3(tiledCoords, 3)) * blendMapColour.b;

    vec4 diffuseColour = backgroundTextureColour + rTextureColour + gTextureColour + bTextureColour;

    vec3 unitSurfaceNormal = normalize(surfaceNormal);
    vec3 unitToLightVector = normalize(toLightVector);

    float brightness = dot(unitSurfaceNormal, unitToLightVector);
    float ambient = 0.2;
    brightness = max(brightness, ambient);
    vec3 diffuse = brightness * lightColour;

    colour = vec4(diffuse, 1.0) * diffuseColour;
    colour = mix(vec4(fogColour, 1.0), colour, visibility);
}

2 个答案:

答案 0 :(得分:0)

这可以是两个问题:

<强> 1。法线不正确: 有不同类型的着色:平面着色,Gouraud着色和Phong着色(不同的Phong镜面反射)example

你通常想做一个Phong阴影。要做到这一点,OpenGL会让你的生活变得更轻松,并为你插入每个三角形的每个顶点之间的法线,所以在每个像素处你都有正确的法线这个点:但是你仍然需要给它正确的正常值,即平均值连接到此顶点的每个三角形的法线。因此,在创建顶点,法线和UV的函数中,您需要通过平均附加到此顶点的每个三角形法线来计算每个顶点处的法线。 illustration

<强> 2。细分问题: 另一个可能的问题是你的地形没有被细分,或者你的高度图分辨率太低,导致这种故障,因为一个三角形中两个顶点之间的高度差异(因此高度图中的两个像素之间)。 / p>

也许你可以提供一些代码和着色器,甚至可以提供高度图,这样我们就可以确切地说明你的情况。

答案 1 :(得分:0)

这是旧的,但我怀疑你并没有使用模型视图矩阵的上3x3部分的转置反转来改变你的法线。见this。不确定&#34; transformationMatrix&#34;中的内容,但是如果您正在使用它来转换顶点并且正常情况可能会出现问题......