03
17

이전 포스팅에서는 렌더몽키 환경에서

난반사광, 정반사광 적용을 했었다.

복습할겸, 다이렉트X11 환경에서 적용해보았다.

 

VS_0.hlsl

cbuffer CBuf
{
	matrix g_matWorld : packoffset(c0);
	matrix g_matView : packoffset(c4);
	matrix g_matProj : packoffset(c8);
	matrix g_matNormal : packoffset(c12);
	float4 g_lightPos : packoffset(c16); //라이트 방향
	float4 g_lightColor : packoffset(c17); //라이트 방향
	float4 g_camPos : packoffset(c18); //카메라 방향
	float4 g_value : packoffset(c19); //기타 시간 값등
};
struct VS_INPUT 
{
   float3 mPosition : POSITION;
   float3 mNormal    : NORMAL;
   float4 mColor	: COLOR;
   float2 mUV		: TEXTURE;
};
struct VS_OUTPUT
{
	float4 mPosition : SV_POSITION;
	float3 mNormal : NORMAL;
	float4 mColor : COLOR0;
	float2 mUV : TEXCOORD0;		//uv
	float3 mDiffuse : TEXCOORD1; //디퓨즈
	float3 mViewDir : TEXCOORD2; //방향
	float3 mReflection : TEXCOORD3; //반사
};

VS_OUTPUT VS(VS_INPUT Input) 
{
	//난반사광의 계산 동일한 계산을 PS VS 둘다 할 수 있음. 
   //하지만 픽셀단위 계산보다 정점단위 계산이 더 연산량이 적음
	VS_OUTPUT Output = (VS_OUTPUT)0;
	Output.mPosition = float4(Input.mPosition, 1.0f);
	Output.mPosition = mul(Output.mPosition, g_matWorld);

	//월드 행렬 곱함, 월드 공간에서의 위치여서 여기서 광원의 위치를 뺀다.
	float3 lightDir = Output.mPosition.xyz - g_lightPos.xyz;
	lightDir = normalize(lightDir);
	//
	float3 viewDir = Output.mPosition.xyz - g_camPos.xyz;
	Output.mViewDir = viewDir;
	//

	Output.mPosition = mul(Output.mPosition, g_matView);
	Output.mPosition = mul(Output.mPosition, g_matProj);

	float3 worldNormal = mul(Input.mNormal, (float3x3)g_matWorld);
	worldNormal = normalize(worldNormal);
	//내적함수 dot()사용
	Output.mDiffuse = dot(-lightDir, worldNormal);
	Output.mReflection = reflect(lightDir, worldNormal);

	Output.mNormal = Input.mNormal;
	Output.mColor = Input.mColor;
	Output.mUV = Input.mUV;
	return  Output;
}

 

PS_0.hlsl

Texture2D		g_txDiffuse : register(t0);
Texture2D		g_txSpecular : register(t1);
Texture2D		g_txNormal : register(t2);
SamplerState	g_Sample : register(s0);

struct VS_OUTPUT
{
	float4 mPosition : SV_POSITION;
	float3 mNormal : NORMAL;
	float4 mColor : COLOR0;
	float2 mUV : TEXCOORD0;		//uv
	float3 mDiffuse : TEXCOORD1; //디퓨즈
	float3 mViewDir : TEXCOORD2; //방향
	float3 mReflection : TEXCOORD3; //반사
};

float4 PS(VS_OUTPUT Input) : SV_TARGET
{	
	float3 diffuse = saturate(Input.mDiffuse);
	//보간기를 거치는 동안 값이 흐트러질수도 있음 다시 정규화
	float3 reflection = normalize(Input.mReflection);
	float3 viewDir = normalize(Input.mViewDir);
	float3 specular = 0;
	//난사빛(빛이 닿아야)이 있어야 정반사광이 존재함
	if (diffuse.x > 0.0f)
	{
	   specular = saturate(dot(reflection, -viewDir));
	   //20번 거듭제곱
	   specular = pow(specular,20.0f);
	}

	float3 ambient = float3(0.1f, 0.1f, 0.1f);

	return float4(ambient + diffuse + specular,1);
}

 

퐁모델 : 반사광과 카메라벡터 각도의 코사인 값을 구하고, 그 결과를 여러번 거듭제곱함.

다만 코사인 연산은 내적 연산보다 무거워서 내적연산으로 대체한다. -1 다른방향 , 0 직각 , 1 같은 방향


내적공식으로 코사인 값은 둘의 내적값에 두 벡터의 길이를 곱한 결과를 나누면 코사인 값이 나온다.

 

 

COMMENT