Я пытаюсь научиться отображать тени, чтобы интегрировать их в свою игру, и в настоящее время я использую этот учебник (пока без мягких шейдеров):
Я успешно внедрил большую часть кода в свою игру. Я могу сформировать матрицу, необходимую для создания буфера глубины для карты теней, и отрендерить ее, чтобы убедиться, что она выглядит правильно. Затем я ввожу это в последний цикл рендеринга, и именно здесь я столкнулся со своими проблемами. Кажется, я не могу правильно выполнить окончательный расчет матрицы, или я сделал что-то не так на этом пути. Я в основном нахожусь в одном шаге от этой работы, надеюсь, но мои матричные вычисления кажутся неправильными, я надеюсь, что это так, и это не то, что есть в другой части реализации.
Вот код инициализации (здесь нет известных проблем): (удален для упрощения)
Вот код инициализации для настройки рендеринга буфера глубины (здесь нет известных проблем): (удален для упрощения)
Весь этот код успешно создал карту глубины и поместил ее в g_pShadowMap
Вот код HLSL, используемый для визуализации карты глубины (здесь нет известных проблем): (удален для упрощения)
Я сохраняю изображение карты глубины в файл и смотрю на него, поскольку значения 0,5 и больше, изображение белое, однако, если я делю значение глубины на 100, я вижу изображение глубины более точно, и оно правильно отрисовывает нисходящий источник света от 20 единиц над персонажем, смотрящий в направлении + x, как и планировалось. Я не уверен, должны ли z-расстояния, хранящиеся на карте, иметь определенный масштаб, но, опять же, изображение будет белым, если я не разделю значения z на 100, чтобы увидеть мою «синюю» карту глубины. (Я не использую разделенные значения в качестве окончательного изображения).
Вот код для окончательного рендеринга моего ландшафта (здесь, скорее всего, есть проблема):
// Restore the render target and depth buffer
g_pd3dDevice->SetRenderTarget( 0, g_pOldColorRT );
g_pd3dDevice->SetDepthStencilSurface( g_pOldDepthRT );
SAFE_RELEASE( g_pOldColorRT );
SAFE_RELEASE( g_pOldDepthRT );
// Compute the texture matrix
float fTexOffs = 0.5 + (0.5 / (float)VGlobal::SHADOW_MAP_SIZE);
D3DXMATRIX matTexAdj( 0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
fTexOffs, fTexOffs, 0.0f, 1.0f );
D3DXMATRIX matTexture = matLightViewProj * matTexAdj;
g_pEffect->SetMatrix( "g_matTexture", &matTexture );
g_pEffect->SetTexture( "tShadowMap", g_pShadowMap );
// Begin the scene
// g_pd3dDevice->BeginScene();
// Setup the world, view, and projection matrices
SetupMatrices();
// Extract the 6 Viewing Frustrum planes for culling calculations
D3DXMATRIX tWorld, tView, tProj, tFinal;
g_pd3dDevice->GetTransform( D3DTS_PROJECTION, &tProj );
g_pd3dDevice->GetTransform( D3DTS_VIEW, &tView );
D3DXMatrixMultiply( &tFinal, &tView, &tProj);
gFrustrum.ExtractPlanesD3D( gFrustrum.frPlanes, tFinal, true );
D3DXMATRIX tempMat = matInfo.ReturnWorld() * matInfo.ReturnView() * matInfo.ReturnProj();
D3DXMatrixTranspose( &tempMat, &tempMat );
g_pEffect->SetMatrix( "worldViewProj", &tempMat );
g_pEffect->SetTechnique( "Technique0" );
//The main render code continues from here, and renders the non-shaded aspects correctly
Теперь, что касается окончательного кода рендеринга HLSL, я предполагаю, что неправильно работаю с матрицей карты теней ...
fragment TerrainVS( vertex IN )
{
fragment OUT;
OUT.hposition = mul( worldViewProj, float4(IN.position, 1) );
//Removed non-relevant code (textures/color calculation)
//...
//Shadow mapping
// Output the projective texture coordinates
OUT.vProjCoord = mul( g_matTexture, float4(IN.position, 1) );
return OUT;
}
pixel TerrainPS( fragment IN )
{
pixel OUT;
//Removed non-relevant code (normal/lighting/color calculations)
//...
// Grab the shadow term
float fShadowTerm = 0.0f;
fShadowTerm = tex2Dproj( ShadowSampler, IN.vProjCoord ) < (IN.vProjCoord.z - 0.001f) ? 0.1f : 1.0f;
OUT.color = max( normColor1, normColor2 ) * fShadowTerm;
OUT.color.a = 1.0f;
return OUT;
}
Любая помощь будет принята с благодарностью. Могу только предположить, что я неправильно вычисляю матрицу на карте теней. В примере используется проекция LH, а я - проекция RH. Кроме того, поскольку у меня уже были настроены матрицы моей игры, я не использовал вызов D3DXMatrixOrthoLH()
из примеров для вычисления моего окончательного matLightViewProj
, и я не уверен, нужно ли мне это. Я полагаю, что опубликовал весь соответствующий код для этой проблемы. Опять же, я был бы очень признателен за любую помощь, она ставит меня в тупик уже несколько дней.