³ë¸Ö ¸ÊÇÎ

³ë¸Ö ¸ÊÇÎÀº ¹ý¼± ¸ÊÇÎÀ̶ó°íµµ ÇÑ´Ù.
³ë¸Ö¸ÊÀº ÅؽºÃÄÀÇ 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