헤더파일
셰이더 공부 - 환경매핑 본문
주위환경이 표면에 반사되는 걸 재현하는 기법입니다. 매끄러운 자동차표면에 주위 환경이 반사되는 것 같은 멋진 효과를 줄 수 있습니다. 사실 이건 표면이 입사광을 전혀 흡수하지 않고 그 모두를 정반사하는 원리입니다. 하지만 다른 물체에서 나온 정반사, 난반사광을 끝없이 따라가며 구하는 것은 실시간렌더링에서 많이 어려운 작업입니다. 따라서 여기에 약간의 트릭을 씁니다.
미리 반사될 주위 환경을 큐브형태의 텍스쳐를 만들어 놓습니다. 그 다음에 카메라벡터의 반사벡터를 구해 큐브형태의 텍스쳐에서 텍셀을 얻어옵니다.
정점 셰이더는 법선매핑 때와 다를게 없습니다.
픽셀 셰이더
struct PS_INPUT
{
float2 mUV : TEXCOORD0;
float3 mLightDir : TEXCOORD1;
float3 mViewDir: TEXCOORD2;
float3 T:TEXCOORD3;
float3 B:TEXCOORD4;
float3 N:TEXCOORD5;
};
sampler2D DiffuseSampler;
sampler2D SpecularSampler;
sampler2D NormalSampler;
samplerCUBE EnvironmentSampler;
float3 gLightColor;
float4 ps_main(PS_INPUT Input) : COLOR
{
float3 tangentNormal = tex2D(NormalSampler, Input.mUV).xyz;
tangentNormal = float3(0,0,1);
float3x3 TBN = float3x3(normalize(Input.T),normalize(Input.B),normalize(Input.N));
TBN = transpose(TBN);
float3 worldNormal = mul(TBN, tangentNormal);
float3 lightDir = normalize(Input.mLightDir);
float3 diffuse = saturate(dot(worldNormal, -lightDir));
float4 albedo = tex2D(DiffuseSampler, Input.mUV);
diffuse = gLightColor*albedo.rgb*diffuse;
float3 specular = 0;
float3 viewDir = normalize(Input.mViewDir);
if(diffuse.x>0)
{
float3 reflection = reflect(lightDir,worldNormal);
specular = saturate(dot(reflection,-viewDir));
specular = pow(specular,20.0f);
float4 specularIntensity = tex2D(SpecularSampler, Input.mUV);
specular *=specularIntensity.rgb * gLightColor;
}
float3 reflectView = reflect(viewDir, worldNormal);
float3 environment = texCUBE(EnvironmentSampler,reflectView).rgb;
float3 ambient = float3(0.1f,0.1f,0.1f)*albedo;
return float4(ambient + diffuse + specular + (environment*0.5f), 1);
}
float3 tangentNormal = tex2D(NormalSampler, Input.mUV).xyz;
tangentNormal = float3(0,0,1);
이 부분은 원래는 필요없지만 현재의 노멀맵이 환경매핑을 고려하지 않은 울퉁불퉁해서 반사를 잘 못 나타내기 때문에 넣은 것입니다. x,y 방향의 값은 없애고 표면의 바깥쪽만 향하게 합니다.
float3 reflectView = reflect(viewDir, worldNormal);
float3 environment = texCUBE(EnvironmentSampler,reflectView).rgb;
카메라 벡터인 viewDir의 반사벡터를 reflect 함수로 구해줍니다. texCUBE함수는 벡터값으로 텍셀을 찾게해주는 함수입니다.
return float4(ambient + diffuse + specular + (environment*0.5f), 1);
이렇게 얻은 텍셀을 조명결과와 합치는데 환경매핑의 결과가 너무 강해 0.5를 곱했습니다.
'DirectX' 카테고리의 다른 글
HLSL 프로그래밍 - 반구형 엠비언트 라이트 (0) | 2018.02.28 |
---|---|
HLSL 프로그래밍 - DXUT프레임워크 (0) | 2018.02.28 |
셰이더 공부 - 법선 매핑 (1) | 2018.02.26 |
셰이더 공부 - 스페큘러 맵핑 (0) | 2018.02.26 |
셰이더 공부 - 툰셰이더 (0) | 2018.02.25 |