±×¸²ÀÚ ¸ÅÇÎ2

·»´õ¸µ Ãâ·ÂÀÌ Áö±Û±×¸®°í ±×¸²ÀÚ°¡ °ÝÀÚÀÌ´Ù. ÀÌ ¹®Á¦´Â ´ÙÀ½Àå¿¡¼­ ¼öÁ¤ÇÑ´Ù.

CreateShadow Æнº¿¡¼­ ¸¸µç °á°ú¹°À» ·»´õ·¯ÅؽºÃÄ·Î ¼³Á¤ÇÑ´Ù.

( CreateShadow Æнº ) tutorial05.html

·»´õ Ÿ°Ù ¼³Á¤

renderTexture¸¦ ShadowMapÀ¸·Î À̸§À» ¼öÁ¤ÇÑ´Ù.

ShadowMapÀ» ´õºíŬ¸¯Çؼ­ Æ÷¸ËÀ» º¯°æÇÑ´Ù.

A8R8G8B8¿¡¼­ R32FÀ¸·Î º¯°æ

"Auto-Generate Mip Map" üũ ¹Ú½º´Â ÇØÁ¦ ÇÑ´Ù.

Âü°í)
D3DFMT_R32F :
ÁöÁ¤ 32 ºñÆ® ºÓÀº ºÎµ¿ ¼Ò¼öÁ¡ Çȼ¿ Æ÷¸Ë

±íÀÌ°ªÀ» ÀúÀå ÇÒ·Á¸é ½Ç¼ö°ªÀ» ÀúÀå ÇÒ ¼ö ÀÖ´Â R32F Æ÷¸ËÀ¸·Î ÀúÀåÇÑ´Ù.
 

·»´õŸ°ÙÀ» ¸¸µç´Ù.

CreateShadow ÆнºÀ§¿¡¼­ ¿À¸¥ÂÊ ¸¶¿ì½º ¹öÆ°À» ´©¸¥´Ù.

CreateShadowÀÇ ·»´õŸ°ÙÀ» È­¸é¿¡¼­ ÅؽºÃÄ·Î ÁöÁ¤ÇÑ´Ù.

Add Render Target ¸Þ´º¼±ÅÃ

ShadowMap ¸Þ´º¼±ÅÃ

 

ShadowMapÀÌ Ãß°¡µÇ¸é Ãß°¡µÈ ShadowMapÀ» ´õºí Ŭ¸¯ÇÑ´Ù.

Ä®¶ó¸¦ °ËÀº»ö¿¡¼­ Èò»öÀ¸·Î ¹Ù²Û´Ù.

(·»´õ¸µÀ» ÇϱâÀü¿¡ ·»´õŸ°ÙÀ» Áö¿ï»öÀ» ÁöÁ¤ÇÑ´Ù.
¾Æ¹«°Íµµ ±×·ÁÁöÁö ¾Ê´Â ºÎºÐÀÇ °ªÀ» Èò»öÀ¸·Î ¼³Á¤ÇÑ´Ù.)

±×¸²ÀÚ Àû¿ë - »õ·Î¿î Pass Ãß°¡

±×¸²ÀÚ¸¦ ±×¸®±â À§ÇÑ »õ·Î¿î Pass¸¦ Ãß°¡ÇÑ´Ù.

ShadowMapÀ» ¸Þ½Ã¿¡ ÀÔÈ÷±â À§Çؼ­ Æнº¸¦ Ãß°¡ÇÑ´Ù.
ShadowMappingÀ» ¸¶¿ì½º ¿À¸¥ÂÊ ¹öÆ°À» Ŭ¸¯ ÈÄ AddPass ¼±ÅÃ

»ý¼ºµÈ Pass1ÀÇ À̸§À» ApplyShadowTorus·Î ¹Ù²Û´Ù.

ModelÀ» ÁöÁ¤ÇÑ´Ù.

ModelÀÇ Reference Node-Torus¸¦ ¼±ÅÃÇÑ´Ù.

±×¸²ÀÚ Àû¿ë - Á¤Á¡ ¼ÎÀÌ´õ

Á¤Á¡ ¼ÎÀÌ´õ ÀÔ·Â ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°´Ù.

struct VS_INPUT
{
   float4 pos : POSITION;
   float3 normal : NORMAL;   
};

ÀÔ·Â ±¸Á¶Ã¼¿¡ NORMALÀ» Ãß°¡ ÇßÀ¸¹Ç·Î Steam Mapping¿¡µµ Ãß°¡ ÇÑ´Ù.

ShadowMapping ÀÌÆåÆ® ¾Æ·¡ Steam MappingÀ» ´õºí Ŭ¸¯ÇÑ´Ù.
Index´Â 0, Data TypeÀº FLOAT3ÀÌ´Ù.

Á¤Á¡ ¼ÎÀÌ´õ Ãâ·Â ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°´Ù.

struct VS_OUTPUT
{
   float4 pos : POSITION0;
   float4 clipPos : TEXCOORD1;
   float diffuse : TEXCOORD2;
};

·¹½ºÅͶóÀÌÀú°¡ Çȼ¿À» ã±â À§ÇØ ±âº»ÀûÀ¸·Î À§Ä¡°ªÀº ³Ñ°ÜÁØ´Ù
±×¸²ÀÚ¸¦ ±×¸±¶§µµ ±×¸²ÀÚ ÅؽºÃĸ¦ ¸¸µé¶§Ã³·³ ±¤¿øÀ¸·ÎºÎÅÍ ±íÀ̸¦ ±¸ÇÑ´Ù.
--> ±×¸²ÀÚ¸Ê ±íÀÌ¿Í ºñ±³Çϱâ À§Çؼ­ÀÌ´Ù.

±×·¡¼­, ±×¸²ÀÚ¸¦ ¸¸µé¶§¿Í ¸¶Âù°¡Áö·Î clipPos ÇÊ¿ä
³­¹Ý»ç±¤ °á°ú ÇÊ¿ä
 

ÇÊ¿äÇÑ Àü¿ªº¯¼ö´Â ´ÙÀ½°ú °°´Ù.

float4x4 gWorldMat;
float4x4 gLightViewMat;
float4x4 gLightProjMat;

float4 gWorldLightPos;

±¤¿øÀ¸·ÎºÎÅÍ ±íÀ̸¦ ±¸ÇØ¾ß ÇϹǷΠ±×¸²ÀÚ¸¦ ¸¸µé¶§ »ç¿ëÇß´ø º¯¼öµéÀÌ ÀüºÎ ÇÊ¿äÇÏ´Ù.

¹°Ã¼¸¦ ±×¸±¶§ »ç¿ëÇÏ´Â Çà·ÄÀÌ ÇÊ¿äÇÏ´Ù

float4x4 gViewProjMat;

·»´õ¸ùÅ°ÀÇ ShadowMapping ÀÌÆåÆ®¿¡µµ ÀÌ Çà·ÄÀ» Ãß°¡ÇÑ´Ù. ½Ã¸àƽÀ» ViewProjectionÀ¸·Î ÇÑ´Ù.

±¤¿ø-ºäÇà·Ä ±¸Çϱâ

ÀÌÀü ±×¸²ÀÚ¿Í ºñ±³¸¦ À§ÇØ ÇöÀç ±¤¿øÀ¸·ÎºÎÅÍ ±íÀ̸¦ ±¸ÇÑ´Ù.

 VS_OUTPUT output;
 
 float4x4 lightViewMat = gLightViewMat;  
 
 float3 dirZ = -normalize( gWorldLightPos);
 float3 up = float3( 0, 1, 0);
 float3 dirX = cross( up, dirZ);
 float3 dirY = cross( dirZ, dirX);

 lightViewMat = float4x4(
    float4( dirX, -dot( gWorldLightPos.xyz, dirX)),
    float4( dirY, -dot( gWorldLightPos.xyz, dirY)),
    float4( dirZ, -dot( gWorldLightPos.xyz, dirZ)),
    float4( 0, 0, 0, 1));   
 
 lightViewMat = transpose( lightViewMat);   

¶óÀÌÆ® Ÿ°ÙÀÌ (0, 0, 0)À̹ǷΠgWorldLightPos¸¸ ³Ö´Â´Ù.

float3 dirZ = -normalize( gWorldLightPos);

2¹øÀÇ °ø°£ º¯È¯

1) ½ÇÁ¦·Î ¹°Ã¼¸¦ ±×¸®±â À§ÇÑ °ø°£ º¯È¯

¹°Ã¼°ø°£  --->  ¿ùµå°ø°£  --->  ºä°ø°£  --->  Åõ¿µ°ø°£   
//render world-view-projection position
float4 worldPos = mul( input.pos, gWorldMat);
output.pos = mul( worldPos, gViewProjMat);

2) ¹°Ã¼ÀÇ ±íÀÌ(±¤¿øÀ¸·ÎºÎÅÍ ±íÀÌ)¸¦ ±¸Çϱâ À§ÇÑ º¯È¯

¹°Ã¼°ø°£  --->  ¿ùµå°ø°£  -->  ±¤¿ø-ºä°ø°£  -->  ±¤¿ø-Åõ¿µ°ø°£
//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);

 

±×¸²ÀÚ Àû¿ë - Çȼ¿ ¼ÎÀÌ´õ

Çȼ¿¼ÎÀÌ´õ¿¡¼­ ÇöÀç ±íÀÌ¿Í ±×¸²ÀÚ ¸ÊÀÇ ±íÀ̸¦ ºñ±³ÇØ ±×¸²ÀÚ¸¦ º¸¿©ÁØ´Ù.

ÅؽºÃÄ »ùÇ÷¯ ¼±¾ð

±×¸²ÀÚ¸Ê »ç¿ëÀ» À§ÇØ ÅؽºÃÄ »ùÇ÷¯¸¦ ¼±¾ðÇÑ´Ù.
·»´õ¸ùÅ°ÀÇ ApplyShadowTorus Æнº¿¡¼­ ShadowMapÀ» Ãß°¡ÇÑ´Ù.

"Add Texture Object" ->

ShadowMap Ãß°¡

À̸§À» Texture0¿¡¼­

ShadowSampler·Î ¹Ù²Û´Ù.

* CreateShadow Æнº¿¡¼­ »ý¼ºÇÑ ÅؽºÃĸ¦ ApplyShadowTorus Æнº¿¡¼­ ÀÌ¿ë ÇÒ·Á¸é CreateShadow Æнº°¡ ApplyShadowTorus Æнº À§¿¡ ÀÖ¾î¾ß ÇÑ´Ù.

sampler2D ShadowSampler

Çȼ¿ ¼ÎÀÌ´õ Àü¿ª º¯¼ö 

¹°Ã¼ÀÇ »öÀ» À§ÇÑ Àü¿ªº¯¼ö¸¦ ÁöÁ¤ÇÑ´Ù.

float4 gObjectColor;

ApplyShadowTorus Æнº¿¡
Color º¯¼ö¸¦ Ãß°¡ÇÑ´Ù.

Ãß°¡ÇÑ º¯¼ö À̸§À»
gObjectColor·Î ¹Ù²Û´Ù.

Çȼ¿ ¼ÎÀÌ´õ ÀÔ·Â ±¸Á¶Ã¼

Á¤Á¡ ¼ÎÀÌ´õÀÇ Ãâ·Â ±¸Á¶Ã¼¿Í ÀÏÄ¡ ½ÃŲ´Ù.

struct PS_INPUT
{
   float4 clipPos: TEXCOORD1;
   float diffuse: TEXCOORD2;
};

³­¹Ý»ç±¤¿¡ ¹°Ã¼ÀÇ »ö»óÀ» °öÇÑ´Ù.

±×¸²ÀÚ°¡ ¾øÀ¸¸é ÀÌ »ö»óÀÌ µé¾î¿Ã °ÍÀÌ°í ±×¸²ÀÚ°¡ ÇÊ¿äÇÏ´Ù¸é ÀÌ °ªÀ» Àû´çÈ÷ ÁÙ¿©ÁØ´Ù.

float3 rgb = saturate( input.diffuse) * gObjectColor;

ÇöÀç Çȼ¿ÀÇ ±íÀÌ°ª

//current pixel depth
float currentDepth = input.clipPos.z / input.clipPos.w;

±×¸²ÀÚ¸Ê Çȼ¿ÀÇ ±íÀÌ°ª

ÅؽºÃÄ UV ÁÂÇ¥¿Í Åõ¿µ°ø°£ÀÇ ÁÂÇ¥´Â À§Ä¡³ª Å©±â°¡ ´Ù¸£´Ù.
Åõ¿µ°ø°£ÀÇ ÁÂÇ¥°è ÅؽºÃÄ ÁÂÇ¥°è
Åõ¿µ °ø°£¿¡¼­ ÅؽºÃÄ ÁÂÇ¥°è·Î Çȼ¿ÀÇ Å©±â´Â 2¿¡¼­ 1 ºñÀ²·Î ÁÙ¾î µç´Ù.

1) Åõ¿µ ÁÂÇ¥°è ---> UV ÁÂÇ¥°è·Î º¯È¯

,u = x / 2 + 0.5     (Å©±â°¡ 1/2À̹ǷΠ0.5¸¦ ´õÇØÁØ´Ù.)
v = -y / 2 + 0.5

2) UV ÁÂÇ¥°è ---> Åõ¿µ ÁÂÇ¥°è

x = u * 2 - 1
y = -v * 2 - 1

Åõ¿µ ÁÂÇ¥°èÀÇ xy ÁÂÇ¥·Î UV ÁÂÇ¥¸¦ ±¸ÇÑ´Ù.

//shadowmap pixel depth
float2 uv = input.clipPos.xy / input.clipPos.w;
uv.y = -uv.y;
uv = uv * 0.5 + 0.5;

float shadowDepth = tex2D( ShadowSampler, uv).r;

CreateShadow ÆнºÀÇ Çȼ¿ ¼ÎÀÌ´õ¿¡¼­ ´ÙÀ½°ú °°ÀÌ ±íÀÌ °ªÀ» ÀúÀå Çß¾ú´Ù.

float depth = input.clipPos.z / input.clipPos.w;
R32F Æ÷¸ËÀ¸·Î ÅؽºÃĸ¦ ÀúÀå Ç߱⠶§¹®¿¡ r ä³Î·Î ±íÀÌ°ªÀ» ÀÐ¾î ¿Â´Ù.

ÇöÀç ±íÀÌ°¡ ±×¸²Àڸʠº¸´Ù ´õ ±íÀ¸¸é ±×¸²ÀÚ¸¦ Ç¥½ÃÇÑ´Ù.
±×¸²ÀÚ°¡ ÀÖÀ¸¸é Á¶¸íÀ» 50% ÁÙ¿´´Ù.

if( currentDepth > shadowDepth + 0.0000125f)
{
   rgb *= 0.5f;
}

return float4( rgb, 1.0f);

±íÀ̸¦ °è»êÇÒ ¶§ 0.0000125¸¦ ´õÇÏ¿© Áö±Û°Å¸®´Â ¹®Á¦¸¦ ÇØ°áÇÏ°í ÀÖ´Ù.

currentDepth¿Í shadowDepth°¡ ¸ðµÎ µ¿ÀÏÇÑ ±íÀÌ °á°ú°¡ ³ª¿Í¾ß ÇÏÁö¸¸ ºÎµ¿¼Ò¼öÁ¡ ¿¡·¯¹®Á¦µµ ÀÖ°í ÅؽºÃÄ ÀúÀåÇÒ ¶§ »ý±â´Â ¿ÀÂ÷µµ À־ ÀÌ·± ¹®Á¦°¡ ¹ß»ýÇÑ´Ù.

ºÎµ¿¼Ò¼öÁ¡ ¿ÀÂ÷¸¦ ÇØ°áÇϱâ À§ÇØ 0.000125¸¦ ´õÇß´Ù.

Áö±Û °Å¸®´Â ¹®Á¦´Â ÇØ°á ÇßÁö¸¸ ¿©ÀüÈ÷ ÅؽºÃÄ´Â °¢Á® º¸ÀδÙ.

°¢Á® º¸ÀÌ´Â ¹®Á¦¸¦ ÇØ°áÇÏ·Á¸é ±×¸²ÀÚ¸ÊÀÇ ÅؽºÃÄ Å©±â¸¦ Å°¿î´Ù.

ShadowMapping ÀÌÆåÆ®¿¡ ÀÖ´Â ShadowMapÀÇ Å©±â¸¦ 2048·Î ¸¸µé¸é ±×¸²°ú °°ÀÌ °¢Á® º¸ÀÌ´Â ¹®Á¦°¡ ÇØ°áµÈ´Ù.

 

 

ApplyShadowTorus ÆнºÀÇ HLSL ÄÚµåÀÌ´Ù.

//Vertex Shader
struct VS_INPUT
{
   float4 pos : POSITION;
   float3 normal : NORMAL;   
};

struct VS_OUTPUT
{
   float4 pos : POSITION0;
   float4 clipPos : TEXCOORD1;
   float diffuse : TEXCOORD2;
};

float4x4 gWorldMat;
float4x4 gLightViewMat;
float4x4 gLightProjMat;

float4 gWorldLightPos;

float4x4 gViewProjMat;

VS_OUTPUT vs_main( VS_INPUT input)
{
   VS_OUTPUT output;
   
   float4x4 lightViewMat = gLightViewMat;  
   
   float3 dirZ = -normalize( gWorldLightPos);
   float3 up = float3( 0, 1, 0);
   float3 dirX = cross( up, dirZ);
   float3 dirY = cross( dirZ, dirX);
  
   lightViewMat = float4x4(
      float4( dirX, -dot( gWorldLightPos.xyz, dirX)),
      float4( dirY, -dot( gWorldLightPos.xyz, dirY)),
      float4( dirZ, -dot( gWorldLightPos.xyz, dirZ)),
      float4( 0, 0, 0, 1));   
   
   lightViewMat = transpose( lightViewMat);   
   
   output.pos = mul( input.pos, gWorldMat);
   output.pos = mul( output.pos, lightViewMat);
   output.pos = mul( output.pos, gLightProjMat);
   
   //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;
   
}

//Pixel Shader
sampler2D ShadowSampler;

struct PS_INPUT
{
   float4 clipPos: TEXCOORD1;
   float diffuse: TEXCOORD2;
};

float4 gObjectColor;

float4 ps_main( PS_INPUT input) : COLOR
{   
   float3 rgb = saturate( input.diffuse) * gObjectColor;
   
   //current pixel depth
   float currentDepth = input.clipPos.z / input.clipPos.w;
   
   //shadowmap pixel depth
   float2 uv = input.clipPos.xy / input.clipPos.w;
   uv.y = -uv.y;
   uv = uv * 0.5 + 0.5;
   
   float shadowDepth = tex2D( ShadowSampler, uv).r;
   
   if( currentDepth > shadowDepth + 0.0000125f)
   {
      rgb *= 0.5f;
   }
   
   return float4( rgb, 1.0f);
}

´Ù¿î·Îµå : ShadowMapping2.rfx

´Ù¿î·Îµå : ShadowMapping3.rfx ( ShadowMap Å©±â°¡ 2048ÀÓ )

( CreateShadow Æнº ) tutorial05.html

Âü°í ) ¼ÎÀÌ´õ ÇÁ·Î±×·¡¹Ö ÀÔ¹® (ÇѺû¹Ìµð¾î)

Depth¸¦ ±â·ÏÇÏÀÚ
http://ttmayrin.tistory.com/35

Introduction to 3D Game Programming with DirectX 9.0c ±×¸²ÀÚ¸ÅÇÎ
http://coreafive.tistory.com/?page=4

http://cybershin.tistory.com/89