Проблема отображения теней с DirectX9 и HLSL

Я пытаюсь научиться отображать тени, чтобы интегрировать их в свою игру, и в настоящее время я использую этот учебник (пока без мягких шейдеров):

http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/soft-edged-shadows-r2193.

Я успешно внедрил большую часть кода в свою игру. Я могу сформировать матрицу, необходимую для создания буфера глубины для карты теней, и отрендерить ее, чтобы убедиться, что она выглядит правильно. Затем я ввожу это в последний цикл рендеринга, и именно здесь я столкнулся со своими проблемами. Кажется, я не могу правильно выполнить окончательный расчет матрицы, или я сделал что-то не так на этом пути. Я в основном нахожусь в одном шаге от этой работы, надеюсь, но мои матричные вычисления кажутся неправильными, я надеюсь, что это так, и это не то, что есть в другой части реализации.

Вот код инициализации (здесь нет известных проблем): (удален для упрощения)

Вот код инициализации для настройки рендеринга буфера глубины (здесь нет известных проблем): (удален для упрощения)

Весь этот код успешно создал карту глубины и поместил ее в 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, и я не уверен, нужно ли мне это. Я полагаю, что опубликовал весь соответствующий код для этой проблемы. Опять же, я был бы очень признателен за любую помощь, она ставит меня в тупик уже несколько дней.


person Carradine    schedule 06.09.2014    source источник
comment
Можно ли немного урезать этот гигантский образец кода, чтобы только та часть, которая вызывает ошибку, которую вы описываете, является в вопросе?   -  person APerson    schedule 06.09.2014
comment
@APerson Конечно, я просто хотел убедиться, что опубликовал какой-либо соответствующий код на случай, если что-то я пропустил, но я удалю его, если мне кажется, что я поместил здесь слишком много информации.   -  person Carradine    schedule 06.09.2014


Ответы (1)


Я нашел ответ, по-видимому, мне нужно было отменить умножение положения и модифицированной световой матрицы, используя код OUT.vProjCoord = mul( float4(IN.position, 1), g_matTexture );

Это сбило меня с толку, так как я умножаю его в обратном порядке для нормального рендеринга сцены.

person Carradine    schedule 08.09.2014