프로그래밍 공부
작성일
2023. 11. 1. 15:25
작성자
WDmil
728x90

 

빛의 연산과정은 포워드 렌더디퍼드 렌더가 존재한다.

 

DirectX의 게임연산시 효율적인 연산이 거의 무조건 옳음으로 디퍼드 렌더 방식으로 hlsl을 조율한다.


LightBuffer에 빛 연산의 개수를 적용하여 사용한다.

cbuffer LightBuffer : register(b0)
{
	Light lights[MAX_LIGHT];
	// 빛연산 계산수
	int lightCount;
	// 간접광
	float3 ambientLight;
    // 천장간접광. 천장부분의 반사정도를 따로준다.
	float3 ambientCeil;
}
cbuffer MaterialBuffer : register(b2)
{
	// 재질
	float4 mDiffuse;
	float4 mSpecular;
	float4 mAmbient;
	float4 mEmissive;
	
	float shininess;
	int hasNormalMap;
}

MaterialBuffer을 따로주어, 재질값과 NormalMap을 사용하는지 여부를 가져온다.

 

float4 PS(LightPixelInput input) : SV_TARGET
{
	// 광원 데이터를 가져옵니다.
	Material material = GetMaterial(input);
	
	// 주변광을 계산합니다.
	float4 ambient = CalcAmbient(material);
	float4 result = 0;
	
	for (int i = 0; i < lightCount; i++)
	{
		if (!lights[i].isActive)
			continue;

		if (lights[i].type == 0)
			result += CalcDirectional(material, lights[i]);
		else if (lights[i].type == 1)
			result += CalcPoint(material, lights[i]);
		else if (lights[i].type == 2)
			result += CalcSpot(material, lights[i]);
	}
	
	return ambient + result + mEmissive;
}

객체값을 사용할 때, 광원 연산시, lightcount에 따라 연산횟수가 달라진다.

현재 빛의 개수만큼 더 연산해야하는격.

class LightBuffer : public ConstBuffer
{
public:
	struct Light
	{
		Float4 color = { 1, 1, 1, 1 };

		Float3 direction = { 0, -1, 1 };
		int type;

		Float3 position = { 0, 0, 0 };
		float range = 100.0f;

		float inner = 55.0f;
		float outer = 70.0f;
		int isActive;
		float attentionIntensity = 1.5f;
	};
private:
	struct Data
	{
		Light lights[MAX_LIGHT];

		int lightCount = 1;
		Float3 ambientLight = { 0.1f, 0.1f, 0.1f };

		Float3 ambientCeil = { 0.1f, 0.1f, 0.1f };
		float padding;
	};

public:
	LightBuffer() : ConstBuffer(&data, sizeof(Data))
	{
	}

	Data* GetData() { return &data; }

private:
	Data data;
};

LightBuffer를 수정하여 현재 데이터값을 받아올 수 있도록 한다.

 

라이트 쉐이더를 여러개 사용 가능하다!

 

728x90