Featured image of post 셰이더 프로그래밍 기본공부 6

셰이더 프로그래밍 기본공부 6

드디어 제대로 뷰 벡터를 구해서 블린-퐁 (Blinn-Phong) 반영 반사를 구하다.
앗싸.

덤으로 Gloss 맵도 추가.
점점 할 수 있는게 늘어나서 기쁘다.

float4x4 World                : WORLD ;
float4x4 View                 : VIEW ;
float4x4 Projection          : PROJECTION ;
float4x4 WorldViewProj    : WORLDVIEWPROJ ;
float4x4 WorldView          : WORLDVIEW ;
float4x4 ViewInv              : ViewI;
//ViewI 에 대한 정의는 확실하지 않으나, 지금으로 짐작할 수 있는 것은
//월드 좌표계에서의 카메라 메트릭스라고 짐작된다. 걍 외우자. 
 

float4 I_a = {1.0f, 1.0f, 1.0f, 1.0f};//엠비언트
float4 I_d = {1.0f, 1.0f, 1.0f, 1.0f};//디퓨즈
float4 I_s = {1.0f, 1.0f, 1.0f, 1.0f};//스페큘러

//라이트의 단순한 가중치 값이다.

float3 lightDir : Direction
<
 string UIName = “라이트 디렉션”;
 string Object = “DirectionalLight”;
 string Space = “WORLD”;
 int refID = 0;

;

// 재질 반사색
float4 k_a
<
 string UIName = “엠비언트”;

;

float4 k_d
<
 string UIName = “디퓨즈”;

;

float4 k_s
<
 string UIName = “스페큘러”;

;

float n
<
 string UIName = “스페큘러 파워”;
 string UItype = “IntSpinner”;
 float UIMin = 0.0f;
 float UIMax = 100.0f;

;

texture Glossmap : GLOSSMAP
<
 string UIName = “글로스맵”;
 int Texcoord = 0;

;

sampler2D GlossSampler = sampler_state
{
 texture = ;
 MinFilter = Linear;
 MagFilter = Linear;
 MipFilter = Linear;
};

void VS
(
 in float4 iPos : POSITION ,
 in float3 iNormal : NORMAL,
 in float2 itex : TEXCOORD0,
 out float4 oPos : POSITION,
 out float3 oDiffuse : COLOR0,
 out float3 oSpecular : COLOR1,
 out float2 otex : TEXCOORD0
)

//본래 TEXCOORD 는 필요 없으나, 글로스맵을 퍼픽셀 단위에서 계산해 주기위해 추가했습니다.
{
 oPos = mul( iPos, WorldViewProj );
//이건 이제 보기만 해도 뭔지 알겠고.
 
 float3 EyeDirection = normalize( ViewInv[3].xyz - mul( iPos, World ).xyz );
/*
뷰 쪽으로 향하는 벡터를 구하기 위한 가장 중요한 부분. 
원리를 보자. 뷰 메트릭스에서 3열의 XYZ 부분의 데이터는, 카메라의 위치 벡터를 의미한다.

여기서의 카메라 벡터는, 월드 좌표계라고 외우도록 하자. 확실하진 않지만.
거기서 포지션을 월드 좌표계로 변환시켰다.

그렇게 해서, 카메라 월드 위치벡터 - 버텍스의 월드 위치벡터 공식이 되었는데,
여기서 외워둬야 할 것은 벡터A - 벡터B는 Head-Tail 이라는 것이다. 즉, A가 머리이고, B가 꼬리가 되는 화살표가 나온다.
이렇게 해서, 버텍스에서 카메라에 달하는 뷰 벡터를 구할 수 있었다.
이것을 노말라이즈 해서, 단위 벡터로 구했다.
*/

 float3 LightDirection = lightDir;
 float3 HalfVector = normalize( EyeDirection + LightDirection );
//블린 공식에서 가장 중요한 하프벡터 구하기,
//이것은 아까 구한 뷰 벡터와 라이트 벡터를 더해서 나온 값을 노말라이즈 시켜주면 간단하다. 
 float3 SurfaceNormal = normalize( mul( iNormal, (float3x3)World ) );
 
 oDiffuse = I_a * k_a + I_d * k_d * max( 0, dot( SurfaceNormal, LightDirection ) );
 oSpecular = I_s * k_s * pow( max( 0, dot( SurfaceNormal, HalfVector ) ), n );
//블린 스페큘러 공식의 핵심이다. 당연하게도, 하프벡터와 서페이스 노말의 내적연산을 하면 간단하다.
//곱하기 n으로 크기를 조절할 수 있게 되었다. 
otex = itex;
};

void PS
(
 in float4 iDiffuse : COLOR0,
 in float4 iSpecular : COLOR1,
 in float2 iTex : TEXCOORD0,
    out float4 oColor : COLOR
)
{
 oColor = iDiffuse + iSpecular * tex2D( GlossSampler, iTex );
//스페큘러에다가 글로스 맵을 단순하게 곱해만 주는 것으로 글로스 맵 완성.
};

technique jp10
{
 pass p0
 {
  CullMode = None;
  VertexShader = compile vs_2_0 VS();
  PixelShader = compile ps_2_0 PS();
 }
}

Hugo로 만듦
JimmyStack 테마 사용 중