응애맘마조

230911 강의 본문

공부/3D강의

230911 강의

TH.Wert 2023. 9. 11. 18:11

그림자매핑을 이어서 마저 끝내고 루트 모션에 대해서 강의했습니다.

#pragma once
class Shadow : public RenderTarget
{
	struct ShadowDesc
	{
		int		ShadowQuality = 0;
		float	ShadowBias = 0.00325f;
		Vector2 Size = Vector2(0.1f, 0.1f);
	}desc;
	static ID3D11Buffer* shadowPSBuffer;
	static ID3D11Buffer* shadowVSBuffer;
	Camera*				cam;
	float				textureSize;
public:
	float				range;
	static void CreateStaticMember();
	static void DeleteStaticMember();

	Shadow();
	~Shadow();

	void SetTarget(Vector3 target);
	void SetRGBTexture(int slot);
	void ResizeScreen(float width, float height);
};
#include "framework.h"

ID3D11Buffer* Shadow::shadowPSBuffer = nullptr;
ID3D11Buffer* Shadow::shadowVSBuffer = nullptr;
void Shadow::CreateStaticMember()
{
    {
        D3D11_BUFFER_DESC desc = { 0 };
        desc.ByteWidth = sizeof(ShadowDesc);
        desc.Usage = D3D11_USAGE_DYNAMIC;
        desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;//상수버퍼
        desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        desc.MiscFlags = 0;
        desc.StructureByteStride = 0;
        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, NULL, &shadowPSBuffer);

        assert(SUCCEEDED(hr));
    }
    {
        D3D11_BUFFER_DESC desc = { 0 };
        desc.ByteWidth = sizeof(Matrix);
        desc.Usage = D3D11_USAGE_DYNAMIC;
        desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;//상수버퍼
        desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        desc.MiscFlags = 0;
        desc.StructureByteStride = 0;
        HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, NULL, &shadowVSBuffer);
        assert(SUCCEEDED(hr));
    }
}

void Shadow::DeleteStaticMember()
{
    SafeRelease(shadowVSBuffer);
    SafeRelease(shadowPSBuffer);
}

Shadow::Shadow()
    : textureSize(500.0f), range(200.0f), RenderTarget(500.0f, 500.0f)
{
    cam = Camera::Create();
    cam->viewport.width = textureSize;
    cam->viewport.height = textureSize;
    desc.Size.x = textureSize;
    desc.Size.y = textureSize;
}

Shadow::~Shadow()
{
    SafeRelease(cam);
}

void Shadow::SetTarget(Vector3 target)
{
    Vector3 up = Vector3(0, 1, 0);
    Vector3 direction(LIGHT->dirLight.direction.x, LIGHT->dirLight.direction.y, LIGHT->dirLight.direction.z);
    direction.Normalize();
    //               방향 * range
    Vector3 pos = target + (-direction * range);
    cam->view = Matrix::CreateLookAt(pos, target, up);
    Vector3 origin = Vector3::Transform(target, cam->view);
    float n = origin.z - range * 0.5f;
    float f = origin.z + range * 0.5f;

    cam->proj = Matrix::CreateOrthographic(range, range, n, f);
    cam->viewport.width = textureSize;
    cam->viewport.height = textureSize;

    RenderTarget::SetTarget(Color(1, 1, 1, 1));
}

void Shadow::SetRGBTexture(int slot)
{
}

void Shadow::ResizeScreen(float width, float height)
{
}

아직 다 완성되지 않은 그림자 클래스입니다. 이전에 선행으로 더 진도를 나갈 것들이 있어서 매핑을 하고 넘어갔습니다.


이번 팀 프로젝트를 만들면서 루트 모션이 필요한 경우가 있었습니다. 하지만 그리 권장되지는 않았습니다. 이미 가공된 데이터를 다시 가공해서 사용하기 때문입니다.

#include "Common.hlsl"

struct VertexInput
{
	float4 Position : POSITION0;
	float2 Uv : UV0;
	float3 Normal : NORMAL0;
	float3 Tangent : TANGENT0;
	//정점변환때만 쓰이는 멤버
	float4 Indices : INDICES0;
	float4 Weights : WEIGHTS0;
};

struct GeometryInput
{
	float4 Position : SV_POSITION;
	float3 wPosition : POSITION0;
	float2 Uv : UV0;
	float3 Normal : NORMAL;
	float3 Tangent : TANGENT;
	float3 Binormal : BINORMAL;
};

struct PixelInput
{
	uint TargetIndex : SV_RenderTargetArrayIndex;
	float4 Position : SV_POSITION;
	float3 wPosition : POSITION0;
	float2 Uv : UV0;
	float3 Normal : NORMAL;
	float3 Tangent : TANGENT;
	float3 Binormal : BINORMAL;
};

GeometryInput VS(VertexInput input)
{
	GeometryInput output;
	output.Uv = input.Uv;
	
	Matrix world;
    [flatten]
	if (input.Weights.x)
		world = SkinWorld(input.Indices, input.Weights);
	else
		world = World;
		
	output.Position = mul(input.Position, world);
	output.wPosition = output.Position.xyz;
	output.Normal = mul(input.Normal, (float3x3) world);
	output.Tangent = mul(input.Tangent, (float3x3) world);
	output.Binormal = cross(output.Normal.xyz, output.Tangent.xyz);
    
	return output;
}

[maxvertexcount(18)]
void GS(triangle GeometryInput input[3], inout TriangleStream<PixelInput> stream)
{
	int vertex = 0;
	PixelInput output;
    
    [unroll(6)]
	for (int i = 0; i < 6; i++)
	{
		output.TargetIndex = i;
        
        [unroll(3)]
		for (vertex = 0; vertex < 3; vertex++)
		{
			output.Position = input[vertex].Position;
			output.Position = mul(output.Position, (CubeViews[i]));
			output.Position = mul(output.Position, CubeProjection);
			output.Uv = input[vertex].Uv;
			output.Normal = input[vertex].Normal;
			output.Binormal = input[vertex].Binormal;
			output.Tangent = input[vertex].Tangent;
			output.wPosition = input[vertex].wPosition;
			stream.Append(output);
		}
		stream.RestartStrip();
	}
}

float4 PS(PixelInput input) : SV_TARGET
{
	float4 BaseColor = DiffuseMapping(input.Uv);
	float3 Normal = NormalMapping(input.Tangent, input.Binormal, input.Normal, input.Uv);
	BaseColor = Lighting(BaseColor, input.Uv, Normal, input.wPosition);
	return BaseColor;
}

hlsl 파일을 하나 만들었습니다. 실행하면 캐릭터의 이동값은 WorldPos를 사용해 보게 되면 이동하는 값이 나타나게 됩니다.

if (skelRoot and boneIndex != -1)
	{
		if (skelRoot->anim)
		{
			if (rootMotion)
			{
				Matrix temp = skelRoot->anim->GetFrameBone(boneIndex);
				temp._41 = 0.0f;
				temp._42 = 0.0f;
				temp._43 = 0.0f;
				Transform::UpdateAnim(std::move(temp));
			}
			else
			{
				Transform::UpdateAnim(skelRoot->anim->GetFrameBone(boneIndex));
			}
		}
		else
		{
			Transform::Update();
		}
		Matrix temp = skelRoot->skeleton->bonesOffset[boneIndex] * W;

		skelRoot->skeleton->bones[boneIndex] = temp.Transpose();
	}

이 루트 모션을 기본 값을 false로 했는데 있을 경우 이동 행렬을 0으로 만들어 가만히 있는 위치에서 움직이도록 했습니다.

 

읽어주셔서 감사합니다.

'공부 > 3D강의' 카테고리의 다른 글

230913 강의  (0) 2023.09.13
230912 강의  (0) 2023.09.12
230908 강의  (0) 2023.09.08
230907 강의  (0) 2023.09.07
230906 강의  (0) 2023.09.06
Comments