응애맘마조
230911 강의 본문
그림자매핑을 이어서 마저 끝내고 루트 모션에 대해서 강의했습니다.
#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으로 만들어 가만히 있는 위치에서 움직이도록 했습니다.
읽어주셔서 감사합니다.
Comments