본문 바로가기
기본 쉐이더

스터디 - 기본 노멀맵

by Raypop 2010. 11. 16.

공부를 하면서 포스팅 하는 내용입니다. 참고해주세요

fxcomposer 사용


============================================================================================================


string description = "Basic Vertex Lighting without a Texture"; // 없어도 됨 ;

//------------------------------------
float4x4 worldViewProj     : WorldViewProjection;
float4x4 worldView      : WorldView;
float4x4 worldInverseTranspose  : WorldInverseTranspose;
float4x4 worldIViewnverseTranspose  : WorldViewInverseTranspose;
float4x4 world   : World;
float4x4 viewInverse : ViewInverse; // 여기까지는 기본적인 공간을 정의한 내용이다 항상 사용하니 꼭 외우도록

 

float4 lightDir : Direction // 라이트의 위치에 관한 설정이다
<
    string Object = "DirectionalLight";
    string Space = "World";
> = {1.0f, -1.0f, 1.0f, 0.0f};

 

float4 lightColor       : Diffuse // 라이트의 색깔
<
    string UIName = "Diffuse Light Color";
    string Object = "DirectionalLight";
> = {1.0f, 1.0f, 1.0f, 1.0f};

 

float4 materialDiffuse : Diffuse // 재질의 기본 색깔
<
    string UIWidget = "Surface Color";
    string Space = "material";
> = {1.0, 1.0, 1.0, 1.0};

 

float shininess : SpecularPower // 반사부분에 빛의 강도를 조절할 조절바생성
<
    string UIWidget = "slider";
    float UIMin = 1.0;
    float UIMax = 128.0;
    float UIStep = 1.0;
    string UIName = "specular power";
> = 30.0;

 

texture diffuseTexture // 기본 텍스쳐 설정
<
 string ResourceName = "default_color.dds";
>;


sampler diffuseSampler = sampler_state // 기본 텍스쳐를 샘플러로 등록하는 과정
{
 texture = <diffuseTexture>;
};


texture normalTexture // 노멀 텍스쳐 설정
<
 string ResourceName = "default_bump_normal.dds";
>;


sampler normalSampler = sampler_state
{
 texture = <normalTexture>;
};


//------------------------------------
struct vertexInput { //버텍스 쉐이더에서 가져와서 사용할 변수를 선언한다
    float3 position    : POSITION;
    float3 normal     : NORMAL; // 노멀의 Z방향 저장한다
    float3 tangent    : TANGENT; // 노멀의 X방향 저장한다
    float3 binormal    : BINORMAL; // 노멀의 Y방향을 저장한다
    float2 UV      : TEXCOORD0;
};

 

struct vertexOutput { // 버텍스 쉐이더에서 픽쉘 쉐이더로 넘길 변수를 선언한다.
    float4 hPosition    : POSITION;
    float3 Normal     : COLOR0;
    float3 tangent      : TANGENT;
    float3 binormal      : BINORMAL;
    float2 UV      : TEXCOORD0;
    float3 EyeVector    : TEXCOORD1;
};


//------------------------------------
vertexOutput VS_Transform(vertexInput IN)
{
 vertexOutput OUT;
 OUT.hPosition = mul( float4( IN.position.xyz , 1.0 ) , worldViewProj ); // 월드 포지션 생성

 OUT.Normal = mul(IN.normal, world).xyz; // 노멀을 월드 값으로 저장한다
 OUT.tangent = mul(IN.tangent, world).xyz; // 노멀의 위치가 월드에 있으므로 월드로 통일한다
 OUT.binormal = mul(IN.binormal, world).xyz; // 이하 동문

 float3 viewPosition = mul( float4( IN.position.xyz , 1.0 ) , worldView ); // 시선벡터를 구하기 위한 공식

 OUT.EyeVector = normalize(-viewPosition);

 OUT.UV = IN.UV; // uv는 걍 토스~*
  return OUT;
}

//-----------------------------------
float4 PS_Color( vertexOutput IN): COLOR
{
 float3 L = normalize( -lightDir.xyz); // 라이트벡터

 float3 normalCOLOR = (tex2D(normalSampler, IN.UV) - 0.5) * 2; // 노멀맵의 포인트 공식 첫번째, 0에서 1까지의 숫자로 음의 수를 표현하기 위해 사용된 공식이다
 float3 N = IN.Normal;
 float3 T = IN.tangent;
 float3 B = IN.binormal;
 
 float3 Nn = normalize(T * normalCOLOR.x + B * normalCOLOR.y + N * normalCOLOR.z); // 노멀맵의 포인트 공식 두번째 구해진 텍스쳐값과 노멀,탄젠트,바이노멀과 함께 대입 최종 노멀값을 산출한다
 
 float diff = max( 0, dot( Nn, L ) ); // 기본반사광 공식

 float3 R =reflect(-L,Nn); // reflect 는 반사광을 구하는 함수

 float3 E = normalize(IN.EyeVector); // 시선벡터를 노멀라이즈 했다
 
 float spec = max(0,dot(R,E)); // 여기와
 spec = pow( spec  , shininess ); // 여기는 퐁쉐이더를 구하는 공식이다

 float4 diffuseColor = tex2D(diffuseSampler, IN.UV); // 기본 텍스쳐를 구한다
 
 float3 Color = diffuseColor.rgb * lightColor * diff + spec * lightColor; // 최종값을 구한다.
 return float4(Color.rgb, diffuseColor.a); // 알파 부분에 주목!! 4x1행렬로 변환!

}


//-----------------------------------
technique textured
{
    pass p0
    {  
  VertexShader = compile vs_3_0 VS_Transform();
  PixelShader  = compile ps_3_0 PS_Color();
    }
}

 



 

최종 결과물


 

여기서 잠깐!!!

왜 노멀맵은 푸른색일까?

노멀이 푸른색인 이유.... rgb 채널중에서 b 채널은 노멀의 방향으로 90도 이상 넘어 가게 되면 음의 값으로 가게 되서 플립이 되는 현상을 보이게 된다 이를 막기 위해서 B채널의 색은 언제나 0.5 이상의 값을 가지기 때문에 전반적으로 푸른색을 띄게 되는것이다...

'기본 쉐이더' 카테고리의 다른 글

Half Lambert 의 원리와 공식  (0) 2010.12.09
스터디 - Fx(UV맵을 활용한 효과)  (0) 2010.12.04
스터디 - 스페큘러맵  (0) 2010.11.28
빛에 관한 공식  (0) 2010.09.16
쉐이더에 사용되는 기본 계산식  (0) 2010.09.13