Сгенерированные на местности нормали заканчиваются ромбовидными - PullRequest
0 голосов
/ 29 марта 2020

Я рендеринг большой динамической c местности с использованием карты высот. В вершинном шейдере я пытаюсь сгенерировать нормали, но в итоге они выглядят довольно странно, с шаблоном алмазной проверки - см. Скриншот ниже.

enter image description here

Вот каркас местности для справки

enter image description here

Полный вершинный шейдер - соответствующие части являются нормалями в конце на основе http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.161.8979&rep=rep1&type=pdf

VertexOut vs_main(VertexIn input)
{
    const uint transformIndex = gTransformOffset + input.mInstanceID;
    // silly that we have to transpose this...
    const float4x4 worldTransform = transpose( gTerrainWorldTransforms.Load( transformIndex ) );
    const uint LODlevel = gTerrainLODLevels.Load( transformIndex );
    const float4 worldPos = mul( worldTransform, float4( input.mPosition, 1 ) );
    bool doMorphing = LODlevel > 0;

    float morphLerpK = 0.0f;
    float2 texcoord;
    float4 outWorldPos = worldPos;
    if ( doMorphing )
    {
        float4 preMorphPos = worldPos;
        float2 preMorphTexcoord = GetTextureCoordinates( preMorphPos.xyz );
        preMorphPos.y += SampleHeightmap( preMorphTexcoord ) * gHeightModifier;

        float scaleX = worldTransform[ 0 ][ 0 ];
        float scaleZ = worldTransform[ 2 ][ 2 ];

        float cameraDistanceToVertex = distance( preMorphPos.xyz, gWorldEyePos );
        float2 morphConstants = gLODMorphConstants.Load( LODlevel );

        morphLerpK  = 1.0f - clamp( morphConstants.x - cameraDistanceToVertex * morphConstants.y, 0.0f, 1.0f );

        float meshSize = ( float) gTerrainMeshSize;
        float gridDimHalf = meshSize / 2.0f;
        float oneOverGridDim = 2.0f / meshSize;

        float2 fracPart = ( frac( input.mPosition.xz * float2( gridDimHalf, gridDimHalf ) ) * float2( oneOverGridDim, oneOverGridDim ) ) * float2( scaleX, scaleZ );
        preMorphPos.xz = preMorphPos.xz - ( fracPart * morphLerpK );

        float2 postMorphTexcoord = GetTextureCoordinates( preMorphPos.xyz );

        texcoord = postMorphTexcoord;
        outWorldPos.xz = preMorphPos.xz;
        outWorldPos.y += SampleHeightmap( postMorphTexcoord ) * gHeightModifier;
    }
    else
    {
        texcoord = GetTextureCoordinates( outWorldPos.xyz );
        outWorldPos.y += SampleHeightmap( texcoord ) * gHeightModifier;
    }

    float4 h;
    int mipmap = 0;
    h[0] = gHeightmap.SampleLevel(gAnisotropicSampler, texcoord, mipmap, float2( 0, -1) ).r * gHeightModifier;
    h[1] = gHeightmap.SampleLevel(gAnisotropicSampler, texcoord, mipmap, float2( -1, 0 ) ).r * gHeightModifier;
    h[2] = gHeightmap.SampleLevel(gAnisotropicSampler, texcoord, mipmap, float2( 1, 0) ).r * gHeightModifier;
    h[3] = gHeightmap.SampleLevel(gAnisotropicSampler, texcoord, mipmap, float2( 0, 1) ).r * gHeightModifier;

    normal.z = h[0] - h[3];
    normal.x = h[1] - h[2];
    normal.y = 1;
    normal = normalize( normal ); 

    VertexOut ret;
    ret.mPosition = mul( gFrameViewProj, outWorldPos );
#ifdef TERRAIN_DEBUG_NORMAL
    ret.mWorldNormal = normal;
#endif
    ret.mNormal = mul( ( float3x3 )gFrameView, normal );
    ret.mNormal = normalize( ret.mNormal );
    ret.mLOD = LODlevel;
    ret.mMorph = morphLerpK;

    return ret;
}

Что я могу сделать, чтобы это исправить?

...