³ë¸Ö ¸ÊÇÎÀº ¹ý¼± ¸ÊÇÎÀ̶ó°íµµ ÇÑ´Ù. ³ë¸Ö¸ÊÀº ÅؽºÃÄÀÇ RGB Á¤º¸¿¡ Normal Vector XYZ¸¦ ÀÎÄÚµùÇÑ ¸ÊÀÌ´Ù. Çȼ¿´ç Á¶¸í(Per-Pixel Lighting)À» ±¸ÇöÇϱâ À§ÇؼÀÌ´Ù.
³ë¸Ö ¸ÊÇÎ ÇÏ´Â ¹æ¹ýÀº µÎ°¡Áö°¡ ÀÖ´Ù.
¿ÀºêÁ§Æ® °ø°£ ³ë¸Ö ¸Ê°ú źÁ¨Æ® °ø°£ ³ë¸Ö ¸ÊÀÌ ÀÖ´Ù.
< ¿ÀºêÁ§Æ® °ø°£ ³ë¸Ö ¸Ê >
- ³ë¸Ö º¤ÅÍ°¡ ¿ÀºêÁ§Æ® °ø°£À» ±âÁØÀ¸·Î µÇ¾î ÀÖÀ½.
- ±¸ÇöÀÌ ½±°í ¿Ü°û ½Ç·ç¿§À» Á¦¿ÜÇϸé ÇÏÀÌ Æú¸®°ï°ú µ¿ÀÏÇÑ È¿°ú
- ½ºÅ°´×(Á¤Á¡ º¯È¯) µÇÁö ¾Ê´Â °Ç¹°, ÀÚµ¿Â÷¿¡ È¿°úÀû
- ³ë¸Ö¸ÊÀÌ ¹«Áö°³ »ö±ò·Î º¸ÀδÙ.
< źÁ¨Æ® °ø°£ ³ë¸Ö ¸Ê >
- źÁ¨Æ® °ø°£À» ÅؽºÃÄ ÁÂÇ¥°è ±âÁØÀ¸·Î ±¸ÇÑ ´ÙÀ½ ³ë¸Ö °è»ê
- ¿ÀºêÁ§Æ® °ø°£ ³ë¸Ö ¸Êº¸´Ù Ä÷¸®Æ¼´Â ¶³¾îÁü
- ½ºÅ°´× µÇ¾îµµ Àû¿ë °¡´ÉÇϱ⠶§¹®¿¡ ij¸¯ÅÍ¿¡ È¿°úÀû
- ³ë¸Ö¸ÊÀÌ Çª¸£°Ô º¸ÀδÙ. ( źÁ¨Æ® °ø°£À» »ç¿ëÇÏ°í Àֱ⠶§¹®¿¡ ³ë¸Ö¸ÊÀÌ À§·Î ÇâÇÑ´Ù )
- Z°ªÀÌ 0º¸´Ù Å©±â ¶§¹®¿¡ ÅؽºÃÄ¿¡ ÀúÀåÇϸé 0.5~1ÀÇ °ªÀ» °¡Áø´Ù.
1. ³ë¸Ö ¸Ê( ÅؽºÃÄ ) ¸¸µé±â
¹ý¼±¸Ê(ÅؽºÃÄÀº 0°ú 1»çÀÌÀÇ °ªÀ» °¡Áø´Ù. ( 0 ~ 1 ) ¹ý¼±º¤ÅÍ´Â -1°ú 1»çÀÌÀÇ °ªÀ» °¡Áø´Ù. ( -1 ~ 1 )
¹ý¼±º¤ÅÍ¿¡¼ ÅؽºÃÄ·Î ¹Ù²Ü·Á¸é »çÀÌÁ ¹ÝÀ¸·Î ÁÙ¿©¾ß ÇÑ´Ù. ( 0.5 °öÇϱâ) ±×·¯¸é ¹ý¼±º¤ÅÍÀÇ °ªÀº -0.5 ~ 0.5ÀÇ °ªÀ» °¡Áø´Ù. ( 0.5 ´õÇϱâ)
0.5¸¦ ´õÇϸé 0 ~ 1 »çÀÌÀÇ °ªÀ» °¡Áø´Ù.
¹ý¼±¸Ê RGB = ¹ý¼±º¤ÅÍ XYZ * 0.5 + 0.5 ( ÅؽºÃÄ ÀúÀå ÇÒ ¶§ )
¹ý¼±º¤ÅÍ XYZ = ¹ý¼±¸Ê RGB * 2 - 1 ( ÅؽºÃÄ¿¡¼ º¤ÅÍ·Î º¯È¯ ÇÒ ¶§ )
2. Á¢¼±(źÁ¨Æ®) °ø°£
Tangent (Á¢¼±) : Á¤Á¡ Ç¥¸éÀ§ÀÇ Á¤º¸ Bi-normal(Á¾¹ý¼±): Á¢¼±, Á¤Á¡ÀÇ ¿ÜÀû¿¡ ÀÇÇØ ¿¬»ê Normal(¹ý¼±): Á¤Á¡ÀÇ ¹ý¼±°ú µ¿ÀÏ
¸Æ½º¿¡¼ ÀͽºÆ÷Æ®½Ã Tangent, Bi-normal Á¤º¸´Â Á¤Á¡ Á¤º¸¿Í ÇÔ²² ÀͽºÆ÷Æ® µÈ´Ù. Normal °ªÀº Á¤Á¡ÀÇ ³ë¸ÖÀ» ÀÌ¿ëÇÑ´Ù.
Çà·Ä·Î Ç¥½ÃÇÏ¸é ´ÙÀ½°ú °°´Ù
Çà±âÁØ Çà·Ä( Row major matrix ) - d3d | Tx Ty Tz | | Bx By Bz | | Nx Ny Nz |
¿±âÁØ Çà·Ä ( Column major matrix ) - open gl | Tx Bx Nx | | Ty By Ny | | Tz Bz Nz |
3. ¼ÎÀÌ´õ ÄÚµå
³ë¸Ö¸Ê ¶óÀÌÆ®ÀÇ °è»êÀº Å©°Ô ´ÙÀ½ÀÇ °úÁ¤À¸·Î ÁøÇàÇÑ´Ù.
< Á¤Á¡ ¼ÎÀÌ´õ >
Á¤Á¡À» ¿ùµå °ø°£À¸·Î º¯È¯ ¶óÀÌÆ® º¤ÅÍ ±¸Çϱ⠺交ÅÍ ±¸Çϱ⠰¢°¢ÀÇ TBNÀ» ¿ùµå°ø°£À¸·Î º¯È¯
< Çȼ¿ ¼ÎÀÌ´õ >
TBN ¿ùµå Çà·Ä ±¸Çϱ⠳ë¸Ö°ª ±¸Çϱ⠳¹Ý±¤ °è»ê Á¤¹Ý»ç±¤ °è»ê ¿¥ºñ¾îÆ® ¶óÀÌÆ® °è»ê ¸ðµç ¶óÀÌÆ® ´õÇϱâ
|
SpecularMapping2.rfx¿¡ Äڵ带 ¼öÁ¤Çؼ »ç¿ë ÇÒ °ÍÀÌ´Ù.
·»´õ¸ùÅ°¿¡ ÀÖ´Â »ùÇà À̹ÌÁö FieldstoneBumpDOT3.tga¸¦ ³ë¸Ö ¸ÊÀ¸·Î Ãß°¡ÇÑ´Ù. ÅؽºÃÄ ¿ÀºêÁ§Æ® À̸§Àº NormalSampler·Î ÇÑ´Ù.
½ºÆ®¸² ¸ÊÇÎÀ» ´õºíŬ¸¯Çؼ Tangent, Bi-normalÀ» Float3, À妽º 0À¸·Î Ãß°¡ÇÑ´Ù.
NormalMapping
float4x4 gWorldMat;
float4x4 gWorldViewProjMat;
float4 gLightPos;
float4 gViewPos;
struct VS_INPUT
{
float4 pos : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
float3 tangent : TANGENT;
float3 binoraml : BINORMAL;
};
struct VS_OUTPUT
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
float3 lightDir : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float3 T : TEXCOORD3;
float3 B : TEXCOORD4;
float3 N : TEXCOORD5;
};
VS_OUTPUT vs_main( VS_INPUT input )
{
VS_OUTPUT output;
output.pos = mul( input.pos, gWorldViewProjMat);
output.uv = input.uv;
float4 worldPos = mul( input.pos, gWorldMat);
float3 lightDir = worldPos - gLightPos.xyz;
output.lightDir = normalize( lightDir);
float3 viewDir = worldPos - gViewPos.xyz;
output.viewDir = normalize( viewDir);
float3 worldNormal = mul( input.normal, (float3x3)gWorldMat);
output.N = normalize( worldNormal);
float3 worldTangent = mul( input.tangent, (float3x3)gWorldMat);
output.T = normalize( worldTangent);
float3 worldBinormal = mul( input.binoraml, (float3x3)gWorldMat);
output.B = normalize( worldBinormal);
return output;
}
//----------------------------------------------------------------
sampler2D DiffuseSampler;
sampler2D SpecularSampler;
sampler2D NormalSampler;
struct PS_INPUT
{
float2 uv : TEXCOORD0;
float3 lightDir : TEXCOORD1;
float3 viewDir : TEXCOORD2;
float3 T : TEXCOORD3;
float3 B : TEXCOORD4;
float3 N : TEXCOORD5;
};
float3 gLightColor;
float4 ps_main( PS_INPUT input) : COLOR
{
float3 tangentNormal = tex2D( NormalSampler, input.uv).xyz;
tangentNormal = normalize( tangentNormal * 2 - 1);
//Á¢¼±°ø°£ --> ¿ùµå°ø°£À¸·Î º¯È¯
float3x3 TBN = float3x3( normalize( input.T),
normalize( input.B),
normalize( input.N)); //¿ùµå --> Á¢¼±Çà·Ä·Î º¯È¯ÇÏ´Â Çà·Ä
TBN = transpose( TBN); //Á¢¼± --> ¿ùµå
float3 worldNormal = mul( TBN, tangentNormal);
float4 albedo = tex2D(DiffuseSampler, input.uv);
float3 lightDir = normalize( input.lightDir);
float3 diffuse = saturate( dot( worldNormal, -lightDir));
diffuse = gLightColor * albedo.rgb * diffuse;
float3 specular = 0;
if( diffuse.x > 0)
{
float3 reflection = reflect( lightDir, worldNormal);
float3 viewDir = normalize( input.viewDir);
specular = dot( reflection, -viewDir);
specular = saturate( specular);
specular = pow( specular, 20);
float4 specularIntensity = tex2D(SpecularSampler, input.uv);
specular = gLightColor * specularIntensity.rgb * specular;
}
float3 ambient = float3( 0.1f, 0.1f, 0.1f) * albedo;
return( float4( ambient + specular + diffuse, 1.0f) );
}
< Á¤Á¡ ¼ÎÀÌ´õ >
struct VS_INPUT { float4 pos : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; float3 tangent : TANGENT; float3 binoraml : BINORMAL; };
TANGENT, BINORMALÀÌ Ãß°¡ µÇ¾ú´Ù. NORMALÀº ±âÁ¸¿¡ ÀÖ´ø NORMAL °ªÀ» »ç¿ëÇÏ¸é µÈ´Ù.
struct VS_OUTPUT { float4 pos : POSITION; float2 uv : TEXCOORD0; float3 lightDir : TEXCOORD1; float3 viewDir : TEXCOORD2; float3 T : TEXCOORD3; float3 B : TEXCOORD4; float3 N : TEXCOORD5; };
TBN Çà·ÄÀ» ÀÌ¿ëÇØ Çȼ¿ ¼ÎÀÌ´õ¿¡¼ ³ë¸Ö°ªÀ» °è»êÇϱ⠶§¹®¿¡ ÀÌÀü¿¡ VS_OUTPUT¿¡ Æ÷ÇÔ µÇ¾ú´ø diffuse, reflectionÀÇ °è»êÀº Çȼ¿ ¼ÎÀÌ´õ¿¡¼ °è»êÀÌ µÈ´Ù. Çȼ¿¼ÎÀÌ´õ¿¡¼ °è»êÇϱâ À§ÇØ lightDirÀ» Ãß°¡ÇÑ´Ù.
T, B, NÀÇ °ªÀº ¿ùµåÇà·Ä·Î º¯È¯Çؼ ³Ñ±ä´Ù.
< ÇȼР¼ÎÀÌ´õ >
½ºÆåŧ·¯ ¼ÎÀÌ´õ¿¡³ë¸Ö¸Ê »ùÇ÷¯°¡ Ãß°¡ µÇ¾ú´Ù. TBNÀ» ÀÌ¿ëÇØ ³ë¸Ö°ª ±¸ÇÏ´Â ÄÚµå ºÎºÐÀÌ Ãß°¡ µÇ¾ú´Ù.
tangentNormal = normalize( tangentNormal * 2 - 1)
ÅؽºÃÄ °ªÀ» ÀÌ¿ëÇØ ¹ý¼± º¤ÅÍ·Î º¯È¯ÇÑ´Ù. ( -1 ~ 1 ----> 0 ~ 1 )
float3x3 TBN = float3x3( normalize( input.T), normalize( input.B), normalize( input.N))
ÀÌ TBNÀº Á÷±³ÀÌ°í ¿ùµå°ø°£À» Á¢¼± °ø°£À¸·Î º¯È¯ÇÏ´Â Çà·ÄÀÌ´Ù.
TBN = transpose( TBN)
TBNÀÇ ¿ªÇà·Ä·Î Á¢¼± °ø°£¿¡¼ ¿ùµå°ø°£À¸·Î º¯È¯ÇÏ´Â Çà·ÄÀÌ´Ù.
À§Å° ¹é°ú - Á÷±³Çà·ÄÀ» ÂüÁ¶ÇÏ¸é ´ÙÀ½ÀÇ ¼öÇнÄÀÌ ÀÖ´Ù.
Á÷±³Çà·ÄÀÇ ÀüÄ¡Çà·ÄÀº ¿ø·¡ Çà·ÄÀÇ ¿ªÇà·Ä°ú °°´Ù. Áï, ÀÓÀÇÀÇ Á÷±³Çà·Ä Q¿¡ ´ëÇؼ
float3 worldNormal = mul( TBN, tangentNormal)
¹Ý»ç±¤ °è»êÀ» À§ÇØ, worldNormalÀ» ±¸ÇÑ´Ù. Çà·ÄÀÇ °ö ¼ø¼°¡ mul( º¤ÅÍ, Çà·Ä)ÀÌ ¾Æ´Ï´Ù. float3x3 »ý¼ºÀÚ´Â Çà±âÁØ Çà·ÄÀÌÁö¸¸ SetMatrix( ) ÇÔ¼ö¸¦ ÅëÇØ ³Ñ¾î¿À´Â Çà·ÄÀº ¿±âÁØÀÌ´Ù. Çà±âÁØ°ú ¿±âÁØÀÌ ´Ù¸¦ ¶§´Â mul ½ÇÇà½Ã º¤ÅÍ¿Í Çà·ÄÀÇ ¼ø¼¸¦ ¹Ù²ãÁØ´Ù.
float3 diffuse = saturate( dot( worldNormal, -lightDir))
worldNormalÀ» ÀÌ¿ëÇØ diffuse °ªÀ» ±¸ÇÏ°í ÀÖ´Ù.
³ª¸ÓÁö ¼ÎÀÌ´õ ÄÚµå´Â ½ºÆåŧ·¯ ¸Ê¿¡¼ º» ÄÚµå¿Í ºñ½ÁÇÏ´Ù.
´Ù¿î·Îµå : NormalMapping.rfx
Âü°í:
ÇѺû¹Ìµð¾î "¼ÎÀÌ´õ ÇÁ·Î±×·¡¹Ö ÀÔ¹®"
http://zho.pe.kr/view.html?file_name=doc/normalmap.txt
http://www.surlybird.com/tutorials/TangentSpace/
http://marupeke296.com/DXPS_S_No5_NormalMap.html
À§ÀÇ ÀϺ»½ÎÀÌÆ® Çؼ®ÇÑ ½ÎÀÌÆ®ÀÓ
http://blog.naver.com/sorkelf/40157218010
|