// 디퓨즈맵 vs 스페큘러맵
난반사광에 적용하는 텍스쳐 디퓨즈맵
정반사광에 적용하는 텍스쳐 스페큘러맵
디퓨즈맵은 색상 표현에 사용한다.
각 픽셀이 반사하는 정도를 조절하는 용도로 스페큘러맵을 사용한다.
따라서 두 텍스쳐의 생김새가 많이 다르다. (스페큘러맵은 흑백으로 표현 가능)
// 물체의 색에 영향을 미치는 또 다른 요소
조명의 색이다.
조명의 색은 전역변수로 쉽게 지정 가능하다.
// 정리
난반사광 = 빛의 색상 X 난반사광의 양 X 디퓨즈맵의 값
정반사광 = 빛의 색상 X 정반사광의 양 X 스페큘러맵의 값
// 스페큘러맵에 대하여
스페큘러맵을 보라.
텍스쳐는 언제나 색상정보만을 가지지는 않는다.
각 픽셀이 반사하는 정반사광의 양을 담고 있다.
픽셀 수준에서 제어하고 싶은 변수가 있다면 텍스쳐 사용하는 것이 일반적이다.
정점셰이더
float4x4 gWorldMatrix;
float4x4 gViewMatrix;
float4x4 gProjectionMatrix;
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
struct VS_INPUT
{
float4 mPosition : POSITION;
float3 mNormal : NORMAL;
float2 mUV : TEXCOORD0;
float3 mDiffuse : TEXCOORD1;
float3 mViewDir : TEXCOORD2;
float3 mReflection : TEXCOORD3;
};
struct VS_OUTPUT
{
float4 mPosition : POSITION;
float2 mUV : TEXCOORD0;
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 = normalize(Output.mPosition.xyz-gWorldLightPosition.xyz);
// viewDir
float3 viewDir = normalize(Output.mPosition.xyz-gWorldCameraPosition.xyz);
Output.mViewDir = viewDir;
// Position
Output.mPosition = mul(Output.mPosition, gViewMatrix);
Output.mPosition = mul(Output.mPosition, gProjectionMatrix);
// Diffuse & Reflection
float3 worldNormal = mul(Input.mNormal, gWorldMatrix);
Output.mDiffuse = dot(-lightDir, worldNormal);
float3 reflection = reflect(lightDir, worldNormal);
Output.mReflection = reflection;
Output.mUV = Input.mUV;
return Output;
}
텍스쳐 샘플러는 픽셀셰이더에서 사용한다.
여기서 선언하지 않는다.
빛의 색상도 픽셀셰이더에서 곱한다.
픽셀셰이더
float3 gLightColor;
sampler2D DiffuseSampler;
sampler2D SpecularSampler;
struct PS_INPUT
{
float2 mUV : TEXCOORD0;
float3 mDiffuse : TEXCOORD1;
float3 mViewDir : TEXCOORD2;
float3 mReflection : TEXCOORD3;
};
float4 ps_main(PS_INPUT Input) : COLOR
{
float4 albedo = tex2D(DiffuseSampler, Input.mUV);
float3 diffuse = gLightColor * albedo.rgb * saturate(Input.mDiffuse);
float3 viewDir = normalize(Input.mViewDir);
float3 reflection = normalize(Input.mReflection);
float3 specular = 0;
if(diffuse.x > 0)
{
specular = saturate(dot(reflection, -viewDir));
specular = pow(specular, 20.0);
float4 specularIntensity = tex2D(SpecularSampler, Input.mUV);
specular *= specularIntensity.rgb * gLightColor;
}
float3 ambient = float3(0.1, 0.1, 0.1) * albedo.rgb;
return float4(diffuse + specular + ambient, 1.0);
}
// 디퓨즈맵을 샘플링
여기에 난반사광의 양과 빛의 색상을 곱한다.
// 스페큘러맵을 샘플링
정반사광의 양과 빛의 색상을 곱한다.
// ambient에도 디퓨즈맵 적용
난반사광이 없는 곳에도 환경광으로 인해 물체가 보인다.
그런데 0.1만 주었기 때문에 디테일이 표현되지 않는다.
그래서 디퓨즈맵을 곱해준다.
'셰이더 (Shader) > 셰이더 프로그래밍 입문 - Pope Kim (완)' 카테고리의 다른 글
[HLSL] 챕터7 - 법선매핑 (1) | 2023.03.19 |
---|---|
[HLSL] 챕터6 - 툰셰이더 (0) | 2023.03.19 |
[HLSL] 챕터4 - 조명셰이더 기초 (0) | 2023.03.18 |
[HLSL] 챕터3 - 텍스쳐매핑 (0) | 2023.03.18 |
[HLSL] 챕터2 - 진짜 쉬운 빨강셰이더 (0) | 2023.03.18 |
댓글