Я рендеринг большой динамической c местности с использованием карты высот. В вершинном шейдере я пытаюсь сгенерировать нормали, но в итоге они выглядят довольно странно, с шаблоном алмазной проверки - см. Скриншот ниже.
![enter image description here](https://i.stack.imgur.com/3bj2S.png)
Вот каркас местности для справки
![enter image description here](https://i.stack.imgur.com/6Llre.png)
Полный вершинный шейдер - соответствующие части являются нормалями в конце на основе 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;
}
Что я могу сделать, чтобы это исправить?