【问题标题】:Triplanar texturing in glslglsl中的三平面纹理
【发布时间】:2019-09-28 15:22:07
【问题描述】:

我关注了一篇名为“基于 GPU 的地形纹理算法”的论文,其中内容如下:

应用三平面纹理的主要算法相当简单。 首先我们用同样的方法检查斜率是否比较大 我们用基于斜率的纹理来做。这些坡度高的地区 将是唯一受算法影响的区域。然后我们检查什么 法线的较大分量是 x 和 z 中的一个。如果 x 是 较大的分量,我们使用几何 z 坐标作为纹理 坐标 s,几何 y 坐标作为纹理坐标 吨。如果 z 是较大的分量,我们使用几何 x 坐标作为 纹理坐标 s,几何 y 坐标作为纹理 坐标t。

所以我尝试实现它。这是我的高度图:

请注意,我在边界中添加了白线只是为了进行实验,所以现在我的地图周围有最大高度的墙。

紧接着文章,下面是顶点着色器中的实现:

#version 430

uniform mat4 ProjectionMatrix;
uniform mat4 CameraMatrix;

uniform vec3 scale;

layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 normal;

out vec3 fsVertex;
out vec3 fsNormal;
out vec2 fsUvs;

void main()
{
    fsVertex = vertex;
    fsNormal = normalize(normal);

    if(fsNormal.y < 0.75) {
        if(fsNormal.x > fsNormal.z)
            fsUvs = vertex.zy * scale.zy;
        else
            fsUvs = vertex.xy * scale.xy;
    }
    else
        fsUvs = vertex.xz * scale.xz;

    gl_Position = ProjectionMatrix * CameraMatrix * vec4(vertex * scale, 1.0);
}

Here's片段着色器,如果有帮助的话。

这是我得到的:

Here's a further look,表示比例。 (高度图的)顶部和左侧墙壁渲染正常,底部和右侧墙壁仍然受到拉伸的影响。我还在墙的开始处发现了这些奇怪的延伸点。

这可能是什么原因?

【问题讨论】:

    标签: opengl graphics glsl shader hlsl


    【解决方案1】:

    如果你想检查法线的x或z坐标是否更长,你应该使用abs函数:

    if(abs(fsNormal.x) > abs(fsNormal.z))
    

    此外,y &gt; 0.75 似乎是一个粗略的近似值,在大多数情况下可能已经足够了。实际上,abs(x), abs(y), abs(z) 的最大值为您提供了正确的平面。

    【讨论】:

    • 为什么是粗略的近似?谢谢,这解决了大部分问题,但我仍然在某些地方得到这些奇怪的错误采样纹理(在我发布的图片中标记为“这是什么?”)。你有什么想法吗?
    • 粗近似意味着y可以是最大值而不满足y&gt;0.75。例如。对于法线向量(0.5, 0.71, 0.5)y 最大但小于0.75。对于红线,我不知道你的意思。问题“这是什么?”有答案“一条红线”,但我怀疑你的意思是这个。如果存在不连续性,如果两个或更多组件接近最大值,您可能需要混合纹理。
    • 我检查 vertex.y 是否高于 0.75,然后它将使用雪纹理。你还有什么别的目的?此外,如果您以完整尺寸查看图像,您会看到纹理在那里拧紧。我是地形渲染的新手,所以如果你能把我链接到一些学习资源,那就太好了
    【解决方案2】:

    这是我使用的 DX11/HLSL 实现。 GLSL 转换应该很容易。 使用指数值,您可以调整边界处的混合速度。我用了类似 3 的东西。

    float3 SampleTriplanarTexture(Texture2D<float4> tex1, Texture2D<float4> tex2, Texture2D<float4> tex3, float3 normal, float3 pos, float exponent)
    {
        //triplanar projection
        float mXY = pow(abs(normal.z), exponent);
        float mXZ = pow(abs(normal.y), exponent);
        float mYZ = pow(abs(normal.x), exponent);
        float total = 1.0f / (mXY + mXZ + mYZ);
        mXY *= total;
        mXZ *= total;
        mYZ *= total;
    
        return  tex1.SampleLevel(linearSampler2, pos.xz, 0) * mXZ +
                tex2.SampleLevel(linearSampler2, pos.xy, 0) * mXY +
                tex3.SampleLevel(linearSampler2, pos.yz, 0) * mYZ;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 1970-01-01
      • 2018-04-16
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 2017-04-18
      • 1970-01-01
      相关资源
      最近更新 更多