입방체 텍스쳐면 있다면
코드 2줄만으로도 만들 수 있는 환경맵핑
정점 셰이더
float4x4 gWorldMatrix;
float4x4 gWorldViewProjectionMatrix;
float4 gWorldLightPosition;
float4 gWorldCameraPosition;
struct VS_INPUT
{
float4 mPosition : POSITION;
float3 mNormal: NORMAL;
float3 mTangent: TANGENT;
float3 mBinormal: BINORMAL;
float2 mUV: TEXCOORD0;
};
struct VS_OUTPUT
{
float4 mPosition : POSITION;
float2 mUV: TEXCOORD0;
float3 mLightDir : TEXCOORD1;
float3 mViewDir: TEXCOORD2;
float3 T : TEXCOORD3;
float3 B : TEXCOORD4;
float3 N : TEXCOORD5;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.mPosition = mul( Input.mPosition, gWorldViewProjectionMatrix );
Output.mUV = Input.mUV;
float4 worldPosition = mul( Input.mPosition, gWorldMatrix );
float3 lightDir = worldPosition.xyz - gWorldLightPosition.xyz;
Output.mLightDir = normalize(lightDir);
float3 viewDir = normalize(worldPosition.xyz - gWorldCameraPosition.xyz);
Output.mViewDir = viewDir;
float3 worldNormal = mul( Input.mNormal, (float3x3)gWorldMatrix );
Output.N = normalize(worldNormal);
float3 worldTangent = mul(Input.mTangent, (float3x3)gWorldMatrix );
Output.T = normalize(worldTangent);
float3 worldBinormal = mul(Input.mBinormal, (float3x3)gWorldMatrix );
Output.B = normalize(worldBinormal);
return Output;
}
픽셸 셰이더
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 = normalize(tangentNormal * 2 - 1)*float3(0,0,1);
//노멀값이 너무 쎄서 float3 값을 곱해줘서 환경맵핑이 잘보이게만들어 준다.
float3x3 TBN = float3x3(normalize(Input.T), normalize(Input.B), normalize(Input.N));
TBN = transpose(TBN);
float3 worldNormal = mul(TBN, tangentNormal);
float4 albedo = tex2D(DiffuseSampler, Input.mUV);
float3 lightDir = normalize(Input.mLightDir);
float3 diffuse = saturate(dot(worldNormal, -lightDir));
diffuse = gLightColor * albedo.rgb * diffuse;
float3 viewDir = normalize(Input.mViewDir);
//환경맵에도 카메라벡터를 사용하기위해 if문 밖으로 빼주었다.
float3 specular = 0;
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 viewReflect = reflect(viewDir, worldNormal);
//reflect()함수를 사용해 반사벡터를 구한다.
float3 environment = texCUBE(EnvironmentSampler, viewReflect).rgb;
// texCUBE()함수를 이용해 환경맵을 구현한다.
float3 ambient = float3(0.1f, 0.1f, 0.1f) * albedo;
return float4(ambient + diffuse + specular+environment * 0.5f, 1);
//return에 환경맵을 더해주고 강도를 조절을 위해 *0.5f를 해준다.
}
#HLSL#
texCUBE() : 입방체 텍스쳐를 샘플링하는 함수
reflect() : 카메라의 반사 벡터를 구하는 함수
'Unity공부 > HLSL Shader 공부' 카테고리의 다른 글
셰이더 프로그래밍 입문-9 (0) | 2012.12.04 |
---|---|
셰이더 프로그래밍 입문-8 (0) | 2012.12.03 |
셰이더 프로그래밍 입문-6 (0) | 2012.11.21 |
셰이더 프로그래밍 입문-5 (0) | 2012.11.19 |
셰이더 프로그래밍 입문-4 (0) | 2012.11.16 |