본문 바로가기
기본 쉐이더

스터디 - 스페큘러맵

by Raypop 2010. 11. 28.

오늘 부터 추가된 내용은 빨간색으로 구별하도록 하겠다...

스페큘러맵... 보통 알고 있는걸로는 빛이 없을때 빛이 있는것 처럼 하기 위해서 사용하는걸로 많이 알고 있다... 하지만 쉐이더에서의 스페큘러맵의 새로운 적용 방법에 대해서 엄청난 대발견이 있었다...

바로 아닌 알파채널에 등록된 스페큘러 맵으로 라이트마스크 같은 효과로 한개의 텍스쳐와 모델링에서 각기 다른 재질감을 표현할 수 있다는 것이다.


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

 

//------------------------------------
float4x4 matWVP : WorldViewProjection;
float4x4 matWorld : World;
float4x4 matWorldView : WorldView;
float4x4 matWorldInv : WorldInverseTranspose;
float4x4 matViewInv : 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
<
    string UIWidget = "Surface Color";
    string Space = "material";
 > = {1.0f, 1.0f, 1.0f, 0.0f};

 float LightPower : SpecularPower
<
    string UIWidget = "slider";
    float UIMin = 1.0;
    float UIMax = 128.0;
    float UIStep = 1.0;
    string UIName = "Light power";
> = 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>;
};

texture SpecularTexture // 스페큘러맵을 등록하였다
<
 string ResourceName = "default_bump_normal.dds";
>;
sampler SpecularSampler = sampler_state
{
 texture = <SpecularTexture>;
};

//------------------------------------
struct vertexInput {
    float3 Position : POSITION;
    float3 Normal  : NORMAL;
    float3 Tangent    : TANGENT;
    float3 Binormal    : BINORMAL;
    float2 UV      : TEXCOORD0;
   
};

struct vertexOutput {
    float4 HPosition : POSITION;
    float3 Normal : NORMAL;
    float3 Tangent    : TANGENT;
    float3 Binormal    : BINORMAL;
    float2 UV      : TEXCOORD0;
    float3 Eye      : TEXCOORD1;
};

//------------------------------------
vertexOutput VS_TransformDiffuse(vertexInput IN)
{
    vertexOutput OUT;
    OUT.HPosition = mul( float4(IN.Position.xyz , 1.0) , matWVP);
    OUT.Normal = mul(IN.Normal,matWorldInv);
    OUT.Tangent = mul(IN.Tangent,matWorldInv);
    OUT.Binormal = mul(IN.Binormal,matWorldInv);
    float3 viewPosition = mul( float4( IN.Position.xyz, 1.0 ), matWorldView);
    OUT.Eye = -viewPosition;
    OUT.UV = IN.UV;
    return OUT;
}

float4 PS_TransformDiffuse(vertexOutput IN) : COLOR
{
 float3 NormalColor = (tex2D(normalSampler, IN.UV) - 0.5) * 2;
 float3 Nn = normalize(IN.Tangent * NormalColor.x + IN.Binormal * NormalColor.y + IN.Normal * NormalColor.z);
 float3 E = normalize(IN.Eye);
 float3 L = normalize(-LightDir).xyz;
 float3 N = normalize(IN.Normal);
 //float3 R =reflect(-L,Nn);  // 함수 이용시 오브젝트 반대편에 반사광이 그대로 복사 되는 문제가 있어서
 float3 R = 2*max(0,dot(Nn,E))*Nn-E;  // 이와 같이 반사광 구하는 공식으로 재정의 하였다
 float3 diff = max(0,dot(Nn,L));
 float4 diffuseColor = tex2D(diffuseSampler, IN.UV);
     
 float4 specularColor = tex2D(SpecularSampler, IN.UV); // 기본 디퓨즈맵과 같은 방식으로 생성
 float spec = max(0,dot(L,R));


 spec = pow(spec, shininess*specularColor.a); // 제곱근에 스페큘러 맵의 "알파채널 부분"을 적용하여 한개의 맵 안에서 특정 부위의 재질감(스페큘러)을 표현이 가능하다 <<중요!!>>

놀고 있는 알파 채널을 이용하여 그래픽 퀄러티의 수준을 한층 업그레이드 가능하다.


 float3 Color =spec * LightColor * specularColor.rgb * LightPower; // 노 멀맵에은 사실 굴곡이 있는것 처럼 하는 눈속임으로 빛이 어느곳이든 일정하게 들어 오게 되는데 이것을 보완하기 위한 방법으로 스페큘러 맵을 마스크와 같은 방법으로 적용하여 특정 부위에 빛의 강도를 조절할수 있게 하여 노멀맵과 같이 사용시 좀 더 현실감 있는 느낌을 만들수가 있다. 
 
 return float4(Color.rgb+diff*diffuseColor, diffuseColor.a);
}

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

 

<스펙큘러 맵 적용전>


<스펙큘러 맵 적용후>

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

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