【问题标题】:OpenGL 3D terrain lighting artefactsOpenGL 3D 地形光照伪影
【发布时间】:2016-02-24 14:31:53
【问题描述】:

我正在我的地形上进行逐像素光照(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);
}

地形片段着色器:

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

【问题讨论】:

  • 我的地形图块的三角剖分方式如下:imgur.com/t8DOkTJ 我尝试了另一种三角剖分方法,但在三角形边缘附近出现了不同的暗线。我在我的地形上寻找的效果是这样的:imgur.com/9Jx2g24 This is from vanilla wow.
  • 请再提供两个图像:几何线框 + 法线从像素着色器中编码为颜色。这应该让我们更接近解决方案。
  • 我很抱歉 mrVoid 你是什么意思?绘制法线向量的几何着色器和片段着色器代码?
  • 他的意思是用surfaceNormal作为color的值,将顶点的法线转化为颜色分量。
  • 我用这段代码来可视化法线向量:learnopengl.com/#!Advanced-OpenGL/Geometry-Shader 向下滚动到“可视化法线向量”

标签: opengl lighting terrain


【解决方案1】:

这可能是两个问题:

1.不正确的法线: 有不同类型的着色:平面着色、Gouraud 着色和 Phong 着色(不同于 Phong 高光)example

您通常想要进行 Phong 着色。为此,OpenGL 让您的生活更轻松,并为您插入每个三角形的每个顶点之间的法线,因此在每个像素处,您都有该点的正确法线:但您仍然需要为其提供正确的法线值,即平均值连接到该顶点的每个三角形的法线。因此,在创建顶点、法线和 UV 的函数中,您需要通过平均附加到该顶点的每个三角形法线来计算每个顶点的法线。 illustration

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

也许您可以提供一些代码和着色器,甚至可以提供高度图,以便我们准确确定您的情况。

【讨论】:

  • 是的,我正在做 Phong 着色,但是我还没有使用任何镜面光照,我稍后会这样做,这并不难。要计算法线向量,我使用这种方法:stackoverflow.com/questions/13983189/…
  • 我使用的是 256x256 高度图:imgur.com/GHm9GbD 高度图上的一个像素代表地形上的一个顶点,因此我的地形有 256x256 个顶点。我的瓦片大小为 3.0,因此地形宽度和高度将为 256 x 3
  • 我定义了最大高度值为 50,因此最高点(全白)为 50,最低点(全黑)为 -50。这意味着一个像素颜色的高度差是0.39。所以颜色为(128, 128, 128)的像素的高度为0,(129,129,129)为0.39
  • 顺便说一下,这种计算法线的方法:stackoverflow.com/questions/13983189/… 他们用 z 轴切换了 y 轴,所以你知道......一开始可能会让人困惑,所以基本上我正在使用:vertices[ i].normal = glm::normalize(glm::vec3(heightL - heightR, 2.0f, heightB - heightF));
  • 好的,也许试试另一个更高维度(1024x1024)的高度图,看看你是否还有同样的问题。
【解决方案2】:

这是旧的,但我怀疑您没有使用模型视图矩阵上部 3x3 部分的转置逆来转换法线。见this。不确定“transformationMatrix”中的内容,但如果您使用它来转换顶点和法线,则可能有些可疑...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-04
    • 2011-08-11
    • 2011-08-17
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多