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

[셰이더 프로그래밍 입문] 4.조명셰이더 본문

컴퓨터 그래픽스/쉐이더

[셰이더 프로그래밍 입문] 4.조명셰이더

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

4.조명셰이더

  • NORMAL : 정점의 법선정보를 불러오는 시맨틱

  • normalize() : 벡터 정규화 함수

  • dot() : 내적 함수

  • saturate() : 0~1 을 넘어서는 값의 범위를 짤라 냄

  • reflect() : 벡터 반사 함수

  • pow() : 거듭제곱 함수

난반사광

  • 입사광으로부터 여러방향으로 고르게 반사되는 빛

  • 어느 방향에서 바라봐도 물체의 명암이나 색조가 크게 변하지 않는 원인

  • 물체의 표면이 거칠수록 난반사가 심해진다.


정반사광

  • 한 방향으로만 반사되는 빛

  • 입사각=출사각

  • 정반사광의 효과를 보려면 빛이 반사되는 방향에서 물체를 바라봐야 함.

  • 퐁모델 : 반사광과 카메라벡터가 이루는 각도의 코사인 값을 구하고, 그 결과를 거듭제곱

  • 매끄러운 표면일수록 정반사광이 타이트 -> 거듭제곱많이


  • 블린 퐁(Blinn-Phong) : 퐁과 거의 비슷한 기법.

  • 오렌 네이어(Oren-Nayar) : 표면의 거친 정도를 고려한 난반사광 조명기법

  • 쿡 토런스(Cook-Torrance) : 표면의 거친 정도를 고려한 정반사광 조명기법

  • 구면조화 조명기법(spherical harmonics lighting) : 오프라인에서 간접광을 사전 처리한 뒤, 실시간으로 이를 주변광으로 적용할 때 사용할 수 있음



▶렌더몽키 코드 

- 버텍스 셰이더
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
float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;
 
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
 
struct VS_INPUT
{
   float4 mPosition:POSITION;
   float3 mNormal:NORMAL;
};
 
struct VS_OUTPUT
{
   float4 mPosition:POSITION;
   float3 mDiffuse:TEXCOORD1;
   float3 mViewDir:TEXCOORD2;
   float3 mReflection:TEXCOORD3;
};
 
 
VS_OUTPUT vs_main(VS_INPUT Input)
{
   VS_OUTPUT Output;
   
   Output.mPosition=mul(Input.mPosition,gWorldMatrix);
   
   float3 lightDir=Output.mPosition.xyz-gWorldLightPosition.xyz;
   lightDir=normalize(lightDir);
   
   float3 viewDir=normalize(Output.mPosition.xyz-gWorldCameraPosition.xyz);
   Output.mViewDir=viewDir;
   
   Output.mPosition=mul(Output.mPosition,gViewMatrix);
   Output.mPosition=mul(Output.mPosition,gProjectionMatrix);
   
   float3 worldNormal=mul(Input.mNormal,(float3x3)gWorldMatrix);
   worldNormal=normalize(worldNormal);
   
   Output.mDiffuse=dot(-lightDir,worldNormal);
   Output.mReflection=reflect(lightDir,worldNormal);
   
   
   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
struct PS_INPUT
{
   float3 mDiffuse:TEXCOORD1;
   float3 mViewDir:TEXCOORD2;
   float3 mReflection:TEXCOORD3;
};
 
float4 ps_main(PS_INPUT Input):COLOR
{
   float3 diffuse=saturate(Input.mDiffuse);
   
   float3 reflection=normalize(Input.mReflection);
   float3 viewdir=normalize(Input.mViewDir);
   float3 specular=0;
   
   if(diffuse.x>0)
   {
      specular=saturate(dot(reflection,-viewdir));
      specular=pow(specular,10.0f);
   }
   float3 ambient=float3(0.1f,0.1f,0.1f);
   
   return float4(diffuse+ambient+specular,1);
}
cs

- 결과

광원을 추가하여 정반사광과 난반사광을 표현한 셰이더입니다.

img