오다기리 박의 알고리즘 노트

[셰이더 프로그래밍 입문] 8. 환경매핑(반사매핑) 본문

컴퓨터 그래픽스/쉐이더

[셰이더 프로그래밍 입문] 8. 환경매핑(반사매핑)

오다기리 박 2018. 7. 1. 23:38

8. 환경매핑(반사매핑)

  • texCUBE() : 입방체 텍스처를 샘플링하는 함수


환경매핑

  • 주위에 있는 물체가 반사한 빛이 거울 같은 표면에 정반사되는 것




▶렌더몽키 코드 

- 버텍스 셰이더
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
float4x4 gWorldViewProjectionMatrix;
float4x4 gWorldMatrix;
 
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
 
struct VS_INPUT
{
   float4 mPosition:POSITION;
   float3 mNormal:NORMAL;
   float3 mBinormal:BINORMAL;
   float3 mTangent:TANGENT;
   float2 mUV:TEXCOORD0;
};
 
struct VS_OUTPUT
{
   float4 mPosition:POSITION;
   float2 mUV:TEXCOORD0;
   float3 mLightDir:TEXCOORD1;
   float3 mViewDir:TEXCOORD2;
   float3 T:TEXCOORD3;
   float3 B:TEXCOORD4;
   float3 N:TEXCOORD5;
};
 
 
VS_OUTPUT vs_main(VS_INPUT Input)
{
   VS_OUTPUT Output;
   
   Output.mPosition=mul(Input.mPosition,gWorldViewProjectionMatrix);
   Output.mUV=Input.mUV;
   
   float4 worldPosition=mul(Input.mPosition,gWorldMatrix);
   float3 lightDir=worldPosition.xyz-gWorldLightPosition.xyz;
   Output.mLightDir=normalize(lightDir);
   
   float3 viewDir=normalize(worldPosition.xyz-gWorldCameraPosition.xyz);
   Output.mViewDir=viewDir;
   
   float3 worldNormal=mul(Input.mNormal,(float3x3)gWorldMatrix);
   Output.N=normalize(worldNormal);
   
   float3 worldTangent=mul(Input.mTangent,(float3x3)gWorldMatrix);
   Output.T=normalize(worldTangent);
   
   float3 worldBinormal=mul(Input.mBinormal,(float3x3)gWorldMatrix);
   Output.B=normalize(worldBinormal);
   
   return Output;
}
cs

- 픽셀 셰이더
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
sampler2D DiffuseSampler;
sampler2D SpecularSampler;
sampler2D NormalSampler;
samplerCUBE EnvironmentSampler;
 
float3 gLightColor;
 
struct PS_INPUT
{
   float2 mUV:TEXCOORD0;
   float3 mLightDir:TEXCOORD1;
   float3 mViewDir:TEXCOORD2;
   float3 T:TEXCOORD3;
   float3 B:TEXCOORD4;
   float3 N:TEXCOORD5;
};
 
float4 ps_main(PS_INPUT Input):COLOR
{
   float3 tangentNormal=tex2D(NormalSampler,Input.mUV).xyz;
   tangentNormal=normalize(tangentNormal*2-1);
   tangentNormal=float3(0,0,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.mUV);
   float3 lightDir=normalize(Input.mLightDir);
   float3 diffuse=saturate(dot(-lightDir,worldNormal));
   diffuse=gLightColor*albedo.rgb*diffuse;
   
   float3 viewDir=normalize(Input.mViewDir);
   float3 specular=0;
   if(diffuse.x>0)
   {
      float3 reflection=reflect(lightDir,worldNormal);
      
      specular=saturate(dot(reflection,-viewDir));
      specular=pow(specular,20.0f);
      
      float4 specularIntensity=tex2D(SpecularSampler,Input.mUV);
      specular*=specularIntensity.rgb*gLightColor;
   }
   
   float3 viewReflect=reflect(viewDir,worldNormal);
   float3 environment=texCUBE(EnvironmentSampler,viewReflect).rgb;
   
   float3 ambient=float3(0.1f,0.1f,0.1f)*albedo;
   
   return float4(ambient+diffuse+specular+environment*0.5,1);
   
}
cs

- 결과

입방체 텍스처를 추가하여 환경매핑을 한 결과입니다. 즉 거울처럼 주위환경이 표면에 반사되는 걸 재현한 것입니다. 주위환경을 미리 텍스처 안에 저장해 놓은 뒤, 실행도중 실시간으로 그 텍스처를 입히는 원리입니다. 환경매핑은 주위에 있는 물체가 반사한 빛이 거울 같은 표면에 정반사되는 것입니다.

img