glsl

时间:2015-05-31 15:33:07

标签: opengl graphics glsl shader hlsl

我跟着一篇名为"基于GPU的地形纹理算法"并说它如下:

  

应用三平面纹理的主要算法非常简单。   首先,我们以相同的方式检查斜率是否相对较大   我们用基于斜率的纹理来做。这些地区坡度较高   将是该算法所影响的唯一区域。然后我们检查一下   正常的较大分量是x和z。如果x是   更大的组件,我们使用几何z坐标作为纹理   坐标s,几何y坐标作为纹理坐标   吨。如果z是较大的组件,我们使用几何x坐标作为   纹理坐标s和几何y坐标作为纹理   协调t。

所以我试着实现它。这是我的身高图: heightmap

请注意,我在边框中添加了仅用于实验的白线,所以现在我的地图周围有最大高度的墙。

现在关注文章,这里是顶点着色器中的实现:

#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片段着色器,如果有帮助的话。

这就是我得到的: outcome

Here's a further look,比例。 顶部和左侧墙壁(高度贴图)呈现正常,底部和右侧墙壁仍然受到拉伸。我还在墙的开头旁边看到了这些奇怪的延伸点。

这可能是什么原因?

2 个答案:

答案 0 :(得分:2)

如果您想检查普通的x或z坐标是否更长,则应使用abs函数:

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

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

答案 1 :(得分:-1)

这是我使用的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;
}
相关问题