´ÙÀÌ·ºÆ®X ÇÁ·Î±×·¥¿¡¼ ½ÇÇàµÈ ȸéÀÌ´Ù. ·»´õ¸ùÅ°¿¡¼ ÇÒÀÏ´ÙÀÌ·ºÆ®¿¡¼ ÄÚµùÇϱâ Àü¿¡ ·»´õ¸ùÅ°¿¡¼ ÇÒ ÀÛ¾÷ÀÌ ÀÖ´Ù. ¸ðµ¨ ÀúÀå
2°³ÀÇ fx ÆÄÀÏ ÀúÀåShadowMapping.rfx ÆÄÀÏÀ» CreateShadow.rfx¿Í ApplyShadowDisc.rfx·Î µÎ ¹ø ÀúÀåÇÑ´Ù. CreateShadow ¼öÁ¤ApplyShadowTorus, ApplyShadowDisc µÎ °³ÀÇ Æнº¸¦ »èÁ¦ÇÑ´Ù. CreateShadowÀÇ Á¤Á¡ ¼ÎÀÌ´õ¸¦ ¿ÀÇÂÇÑ´Ù. Á¤Á¡ ¼ÎÀÌ´õÀÇ ±¤¿ø-ºäÇà·ÄÀ» »èÁ¦ÇÑ´Ù. gWorldLightPos, gViewProjMat Àü¿ª º¯¼ö´Â CreateShadow Æнº¿¡¼ »ç¿ëµÇÁö ¾Ê´Â´Ù. //»èÁ¦ µÇ´Â ±¤¿ø-ºäÇà·Ä
»èÁ¦µÈ ÈÄÀÇ Á¤Á¡ ¼ÎÀÌ´õ ÄÚµåÀÌ´Ù. VS_OUTPUT vs_main( VS_INPUT input)
{ VS_OUTPUT output; float4x4 lightViewMat = gLightViewMat; output.pos = mul( input.pos, gWorldMat); output.pos = mul( output.pos, lightViewMat); output.pos = mul( output.pos, gLightProjMat); output.clipPos = output.pos; return output; } ApplyShadow ¼öÁ¤CreateShadow, ApplyShadowDisc µÎ °³ÀÇ Æнº¸¦ »èÁ¦ÇÑ´Ù. ¿©±â¿¡¼µµ Á¤Á¡ ¼ÎÀÌ´õÀÇ ±¤¿ø-ºäÇà·ÄÀ» »èÁ¦ÇÑ´Ù. VS_OUTPUT vs_main( VS_INPUT input)
{ VS_OUTPUT output; float4x4 lightViewMat = gLightViewMat; //render world-view-projection position float4 worldPos = mul( input.pos, gWorldMat); output.pos = mul( worldPos, gViewProjMat); //light world-view-projection position output.clipPos = mul( worldPos, lightViewMat); output.clipPos = mul( output.clipPos, gLightProjMat); float3 lightDir = normalize( worldPos.xyz - gWorldLightPos.xyz); float3 worldNormal = normalize( mul( input.normal, (float3x3)gWorldMat)); output.diffuse = dot(-lightDir, worldNormal); return output; } ÇÁ·¹ÀÓ¿öÅ©·»´õ¸µÀ» Å©°Ô ±×¸²ÀÚ ¸¸µé±â¿Í ±×¸²ÀÚ ÀÔÈ÷±â·Î ³ª´¶´Ù. Àü¿ªº¯¼ö¿øÇü Æò¸é ¸Þ½Ã gBackgroundMesh¿Í ±×¸²ÀÚ ¸¸µé±â ¼ÎÀÌ´õ gCreateShadowShader¸¦ º¯¼ö¸¦ Ãß°¡ÇÑ´Ù. LPD3DXMESH gBackgroundMesh = NULL;
LPD3DXEFFECT gCreateShadowShader = NULL; ¼ÎÀÌ´õÀÇ ¸Þ½Ã¿ë »ö»óÀ» À§ÇÑ º¯¼öµµ Ãß°¡ÇÑ´Ù. //¸Þ½Ã »ö»ó
D3DXVECTOR4 gMeshColor(1, 1, 0, 1); D3DXVECTOR4 gBackgroundColor(1, 1, 0, 1); ±×¸²ÀÚ ¸¸µé±â¿ë ·»´õ Ÿ°ÙÀ» Ãß°¡ÇÑ´Ù. //±×¸²ÀÚ ·»´õŸ°Ù
LPDIRECT3DTEXTURE9 gShadowRenderTarget = NULL; LPDIRECT3DSURFACE9 gShadowDepthStencil = NULL; LPDIRECT3DSURFACE9´Â ±×¸²ÀÚ ¸ÊÀ» ±×¸±¶§ »ç¿ëÇÒ ±íÀÌ ¹öÆÛÀÌ´Ù. DestroyDirectX( ) ÇÔ¼öÃß°¡Çß´ø º¯¼öµéÀ» ÇØÁ¦ÇÑ´Ù. _RELEASE_(gBackgroundMesh);
_RELEASE_(gCreateShadowShader); _RELEASE_(gShadowRenderTarget); _RELEASE_(gShadowDepthStencil); LoadAsset( ) ÇÔ¼ö¼ÎÀÌ´õ¿Í ¸ðµ¨À» ·ÎµùÇÑ´Ù. // ¼ÎÀÌ´õ ·Îµù
gShader = LoadShader("ApplyShadow.fx"); if(gShader == NULL) return false; // ¸ðµ¨ ·Îµù gMesh = LoadModel("torus.x"); if(gMesh == NULL) return false; //CreateShadow ¼ÎÀÌ´õ ·Îµù gCreateShadowShader = LoadShader("CreateShadow.fx"); if(gCreateShadowShader == NULL) return false; //¿øÇü Æò¸é ¸Þ½Ã ·Îµù gBackgroundMesh = LoadModel("disc.x"); if(gBackgroundMesh == NULL) return false; InitShadowRenderTarget( ) ÇÔ¼ö±×¸²ÀÚ¸ÊÀÇ Å©±â¸¦ 2048·Î ÇÑ´Ù. CreateTexture( )¿¡¼ D3DUSAGE_RENDERTARGET, D3DFMT_R32F Æ÷¸ËÀ¸·Î ·»´õŸ°Ù ÅؽºÃĸ¦ ¸¸µç´Ù. CreateDepthStencilSurface( )¿¡¼ ±×¸²Àڸʰú µ¿ÀÏÇÑ Å©±â·Î ±íÀÌ ¹öÆÛ¸¦ ¸¸µç´Ù. //·»´õŸ°Ù »ý¼º
const int shadowMapSize = 2048; if( FAILED(gD3DDevice->CreateTexture( shadowMapSize, shadowMapSize, 1, //¹Ó¸ÊÀÇ ¼ö, ·»´õŸ°ÙÀº Çϳª¸¸ ¸¸µç´Ù. D3DUSAGE_RENDERTARGET, //·»´õŸ°Ù¿ë ÅؽºÃÄ D3DFMT_R32F, //ÅؽºÃ³ Æ÷¸Ë, ·»´õ¸ùÅ°ÀÇ R32F Æ÷¸Ë D3DPOOL_DEFAULT, &gShadowRenderTarget, NULL))) { return false; } //±×¸²Àڸʰú µ¿ÀÏÇÑ Å©±âÀÇ ±íÀ̹öÆÛ »ý¼º if (FAILED(gD3DDevice->CreateDepthStencilSurface( shadowMapSize, shadowMapSize, D3DFMT_D24X8, //ÅؽºÃ³ Æ÷¸Ë, ±íÀÌ ¹öÆÛ·Î 24ºñÆ® D3DMULTISAMPLE_NONE, 0, //¸ÖƼ»ùÇÃÀ» »ç¿ëÇÏÁö ¾ÊÀ¸´Ï 0ÀÌ´Ù TRUE, //±íÀ̹öÆÛ¸¦ ¹Ù²Ü ¶§, ±× ¾È¿¡ ÀÖ´ø ³»¿ëÀ» º¸Á¸ÇÏÁö ¾Ê´Â´Ù. &gShadowDepthStencil, NULL))) { return false; } RenderScene( ) ÇÔ¼ö·»´õ¸µ¿¡¼ »ç¿ëÇÒ º¯¼öµéÀ» ¾Ë¾Æº¸ÀÚ. CreateShadow Æнº¿¡¼ ÇÊ¿äÇÑ º¯¼ö´Â gWorldMat, gLightViewMat, gLightProjMatÀÌ´Ù. ApplyShadowTorus Æнº¿¡¼ ÇÊ¿äÇÑ º¯¼ö´Â gWorldLightPos, gWorldMat, gLightViewMat, gLightProjMat, gViewProjMat, gObjectColorÀÌ´Ù. µÎ Æнº¿¡¼ ÇÊ¿äÇÑ º¯¼öµéÀ» ¹Ì¸® ±¸ÇÑ´Ù. gLightViewMat, gLightProjMat¸¦ ¼³Á¤Çϱâ À§ÇØ ±¤¿ø-ºä Çà·Ä, ±¤¿ø-Åõ¿µ Çà·ÄÀ» ±¸ÇÑ´Ù. // ±¤¿ø-ºä Çà·Ä
D3DXMATRIXA16 matLightView; { D3DXVECTOR3 vEyePt(gWorldLightPos.x, gWorldLightPos.y, gWorldLightPos.z); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matLightView, &vEyePt, &vLookatPt, &vUpVec); } // ±¤¿ø-Åõ¿µ Çà·Ä D3DXMATRIXA16 matLightProjection; D3DXMatrixPerspectiveFovLH(&matLightProjection, D3DX_PI / 4.0f, 1, 1, 3000); gViewProjMat¸¦ ¼³Á¤Çϱâ À§ÇØ ºä-Åõ¿µÇà·ÄÀ» ±¸ÇÑ´Ù. // ºä-Åõ¿µÇà·Ä
D3DXMATRIXA16 matViewProjection; { //ºäÇà·Ä D3DXMATRIXA16 matView; D3DXVECTOR3 vEyePt(gWorldCameraPos.x, gWorldCameraPos.y, gWorldCameraPos.z); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); //Åõ¿µÇà·Ä D3DXMATRIXA16 matProjection; D3DXMatrixPerspectiveFovLH(&matProjection, FOV, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE); D3DXMatrixMultiply(&matViewProjection, &matView, &matProjection); } Åä·¯½º¿Í ¿øÇüÆÇÀÇ ¿ùµåÇà·Ä matTrousWorld, matDiscWorld¸¦ ±¸ÇÑ´Ù. // Åä·¯½º ¿ùµåÇà·ÄÀ» ¸¸µç´Ù.
D3DXMATRIXA16 matTorusWorld; { // ÇÁ·¹ÀÓ¸¶´Ù 0.4µµ¾¿ ȸÀüÀ» ½ÃŲ´Ù. gRotationY += 0.004f * PI / 180.0f; if (gRotationY > 2 * PI) { gRotationY -= 2 * PI; } D3DXMatrixRotationY(&matTorusWorld, gRotationY); } //¿øÇüÆÇÀÇ ¿ùµåÇà·ÄÀ» ¸¸µç´Ù. D3DXMATRIXA16 matDiscWorld; { D3DXMATRIXA16 matScale; D3DXMatrixScaling(&matScale, 2, 2, 2); D3DXMATRIXA16 matTrans; D3DXMatrixTranslation(&matTrans, 0, -40, 0); D3DXMatrixMultiply(&matDiscWorld, &matScale, &matTrans); } ±×¸²ÀÚ¸ÊÀ» ¸¸µé¶§ ·»´õŸ°ÙÀ» ¼³Á¤Çϱâ Àü¿¡ ´Ù½Ã Çϵå¿þ¾î ¹é¹öÆÛ¿¡ ±×¸®±â À§ÇØ ÇöÀç ·»´õŸ°ÙÀ» ´Ù¸¥ º¯¼ö¿¡ º¸°üÇØ µÐ´Ù. // ÇöÀç Çϵå¿þ¾î ¹é¹öÆÛ¿Í ±íÀ̹öÆÛ¸¦ º¸°üÇÑ´Ù.
LPDIRECT3DSURFACE9 pHWBackBuffer = NULL; LPDIRECT3DSURFACE9 pHWDepthStencilBuffer = NULL; gD3DDevice->GetRenderTarget(0, &pHWBackBuffer); gD3DDevice->GetDepthStencilSurface(&pHWDepthStencilBuffer); 1. ±×¸²ÀÚ ¸¸µé±â±×¸²ÀÚ¸Ê¿ë ·»´õŸ°ÙÀ» ¼³Á¤ÇÑ´Ù. SetRenderTarget( )¿¡ Ç¥¸éÀ» ÀÎÀÚ·Î ³Ö¾îÁØ´Ù. // ±×¸²ÀÚ ¸ÊÀÇ ·»´õŸ±ê°ú ±íÀ̹öÆÛ¸¦ »ç¿ëÇÑ´Ù.
LPDIRECT3DSURFACE9 pShadowSurface = NULL; if (SUCCEEDED(gShadowRenderTarget->GetSurfaceLevel(0, &pShadowSurface))) { gD3DDevice->SetRenderTarget(0, pShadowSurface); pShadowSurface->Release(); pShadowSurface = NULL; } gD3DDevice->SetDepthStencilSurface(gShadowDepthStencil); ÀÌÀü ÇÁ·¹ÀÓ¿¡ ±×·È´ø ±×¸²ÀÚ¸ÊÀ» ÇϾá»öÀ¸·Î Áö¿î´Ù. ÇѾá»öÀÌ¸é ±×¸²ÀÚ¸¦ Àû¿ëÇÏÁö ¾Ê´Â´Ù. //ÀÌÀü ÇÁ·¹ÀÓ¿¡ ±×·È´ø ±×¸²ÀÚ Á¤º¸¸¦ Áö¿ò
gD3DDevice->Clear(0, NULL, (D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER), 0xFFFFFFFF, 1.0f, 0); ±×¸²ÀÚ ¸¸µé±â ¼ÎÀÌ´õ gCreateShadowShader¸¦ À§ÇØ ¿ùµåÇà·Ä, ±¤¿ø-ºäÇà·Ä, ±¤¿ø-Åõ¿µÇà·ÄÀ» ¼³Á¤ÇÑ´Ù. // ±×¸²ÀÚ ¸¸µé±â ½¦ÀÌ´õ Àü¿ªº¯¼öµéÀ» ¼³Á¤
gCreateShadowShader->SetMatrix("gWorldMat", &matTorusWorld); gCreateShadowShader->SetMatrix("gLightViewMat", &matLightView); gCreateShadowShader->SetMatrix("gLightProjMat", &matLightProjection); ±×¸²ÀڸʿëÀ¸·Î »ç¿ëµÉ ¸Þ½Ã¸¦ ±×¸°´Ù. // ±×¸²ÀÚ ¸¸µé±â ½¦ÀÌ´õ¸¦ ½ÃÀÛ
{ UINT numPasses = 0; gCreateShadowShader->Begin(&numPasses, NULL); { for (UINT i = 0; i < numPasses; ++i) { gCreateShadowShader->BeginPass(i); gMesh->DrawSubset(0); //torus ±×¸®±â gCreateShadowShader->EndPass(); } } gCreateShadowShader->End(); } 2. ±×¸²ÀÚ ±×¸®±âÅä·¯½º¿Í ¿øÇüÆÇ¿¡ ¾Õ¿¡¼ ¸¸µç ±×¸²ÀÚ¸ÊÀ» ±×¸°´Ù. ·»´õŸ°ÙÀ» Çϵå¿þ¾î ¹é¹öÆÛ, ±íÀ̹öÆÛ·Î ¿ø»óº¹±¸ ½ÃŲ´Ù. pHWBackBuffer, pHWDepthStencilBuffer¸¦ ÇØÁ¦ÇÏ´Â °ÍÀº GetRenderTarget( ), GetDepthStencilSurface( ) ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ D3D ³»ºÎÀûÀ¸·Î ¹öÆÛµéÀÇ ÂüÁ¶Ä«¿îÅ͸¦ Áõ°¡½ÃÄÑ Áֱ⠶§¹®ÀÌ´Ù. //Çϵå¿þ¾î ¹é¹öÆÛ, ±íÀ̹öÆÛ »ç¿ë
gD3DDevice->SetRenderTarget(0, pHWBackBuffer); gD3DDevice->SetDepthStencilSurface(pHWDepthStencilBuffer); pHWBackBuffer->Release(); pHWBackBuffer = NULL; pHWDepthStencilBuffer->Release(); pHWDepthStencilBuffer = NULL; ¹°Ã¼¸¦ ±×¸®±â À§ÇÑ º¯¼öµéÀ» ¼³Á¤ÇÑ´Ù. ³¹Ý»ç¸¦ °è»êÇϱâ À§ÇÑ ±¤¿øÀÇ À§Ä¡( gWorldLightPos )°¡ ÇÊ¿äÇÏ´Ù. // ±×¸²ÀÚ ÀÔÈ÷±â ½¦ÀÌ´õ Àü¿ªº¯¼öµéÀ» ¼³Á¤
gShader->SetVector("gWorldLightPos", &gWorldLightPos); gShader->SetMatrix("gWorldMat", &matTorusWorld); //¿øȯü gShader->SetMatrix("gLightViewMat", &matLightView); gShader->SetMatrix("gLightProjMat", &matLightProjection); gShader->SetMatrix("gViewProjMat", &matViewProjection); gShader->SetVector("gObjectColor", &gMeshColor); ·»´õ¸ùÅ°ÀÇ ¼ÎÀÌ´õ¸¦ fx·Î ÀͽºÆ÷Æ®Çϸé texture À̸§¿¡ Á¢¹Ì»ç "_Tex"¸¦ Ãß°¡ÇÑ´Ù. CreateShadown.fx³ª ApplyShadow.fx¸¦ ¿¾îº¸¸é "_Tex"°¡ ÀÚµ¿À¸·Î Ãß°¡µÈ´Ù. texture ShadowMap_Tex gShader->SetTexture("ShadowMap_Tex", gShadowRenderTarget);
Åä·¯½º¸¦ ±×¸°´Ù. UINT numPasses = 0;
gShader->Begin(&numPasses, NULL); { for (UINT i = 0; i < numPasses; ++i) { gShader->BeginPass(i); { //torus ±×¸®±â gMesh->DrawSubset(0); ¿øÇüÆÇÀ» ±×¸°´Ù. BeginPass( )¿Í EndPass( ) »çÀÌ¿¡ º¯¼ö°ªÀ» ¼öÁ¤ ÇÒ ¶§´Â CommitChanges( ) ÇÔ¼ö¸¦ È£ÃâÇÑ´ÙÀ½¿¡ ¿øÇüÆÇÀ» ±×¸°´Ù. //¿øÇüÆÇ ±×¸®±â
gShader->SetMatrix("gWorldMat", &matDiscWorld); gShader->SetVector("gObjectColor", &gBackgroundColor); gShader->CommitChanges(); gBackgroundMesh->DrawSubset(0); } gShader->EndPass(); } } gShader->End(); ´Ù¿î·Îµå : ApplyShadow.rfx , CreateShadow.rfx , ShadowMapping5.rfx , DxDemo_ShadowMapping.zip Âü°í : ÇѺû¹Ìµð¾î ¼ÎÀÌ´õ ÇÁ·Î±×·¡¹Ö ÀÔ¹®
|