응애맘마조
230825 강의 본문
어제 안되었던 빌보드가 완성되었습니다. 카메라의 회전이나 이동을 해도 오브젝트가 카메라를 향하는 모습입니다.
#pragma once
class Billboard : public Actor
{
public:
Vector2 pivot;
static Billboard* Create(string name = "Billboard");
virtual void Update() override;
virtual void Render() override;
void RenderDetail();
};
#include "framework.h"
Billboard* Billboard::Create(string name)
{
Billboard* temp = new Billboard();
temp->name = name;
temp->type = ObType::Billboard;
temp->mesh = RESOURCE->meshes.Load("9.Billboard.mesh");
temp->shader = RESOURCE->shaders.Load("9.Cube.hlsl");
temp->shader->LoadGeometry();
return temp;
}
void Billboard::Update()
{
Actor::Update();
}
void Billboard::Render()
{
VertexPSP* vertex = (VertexPSP*)mesh->vertices;
vertex[0].size = Vector2(S._11, S._22);
vertex[0].pivot = pivot;
mesh->Update();
Actor::Render();
}
void Billboard::RenderDetail()
{
Actor::RenderDetail();
if (ImGui::BeginTabBar("MyTabBar3"))
{
if (ImGui::BeginTabItem("Billboard"))
{
ImGui::SliderFloat2("pivot", (float*)&pivot, -1.0f, 1.0f);
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
빌보드도 액터를 상속받아 ImGui를 사용해 구현하도록 했습니다.
#include "Common.hlsl"
struct VertexInput
{
float4 Position : POSITION0;
float2 Size : SIZE0;
float2 Pivot : PIVOT0;
};
struct PixelInput
{
float4 Position : SV_POSITION;
float2 Uv : UV0;
};
VertexInput VS(VertexInput input)
{
VertexInput output;
output.Size = input.Size;
output.Pivot = input.Pivot;
// o = i X W
output.Position = mul(input.Position, World);
output.Position = mul(output.Position, View);
return output;
}
static const float2 TEXCOORD[4] =
{
float2(0.0f, 1.0f),
float2(0.0f, 0.0f),
float2(1.0f, 1.0f),
float2(1.0f, 0.0f)
};
[maxvertexcount(4)]
void GS(point VertexInput input[1], inout TriangleStream<PixelInput> output)
{
//한개의 점을 네개로 나누기
// 월드변환후 뷰 프로젝션변환
float3 up = float3(0, 1, 0);
float3 forward = float3(0, 0, 1);
float3 right = float3(1, 0, 0);
float2 halfSize = input[0].Size * 0.5f;
float4 vertices[4]; //(기준좌표,중점)
float3 pivot = input[0].Position.xyz;
pivot.x -= input[0].Pivot.x * halfSize.x;
pivot.y -= input[0].Pivot.y * halfSize.y;
vertices[0] = float4(pivot - right * halfSize.x - up * halfSize.y, 1.0f);
vertices[1] = float4(pivot - right * halfSize.x + up * halfSize.y, 1.0f);
vertices[2] = float4(pivot + right * halfSize.x - up * halfSize.y, 1.0f);
vertices[3] = float4(pivot + right * halfSize.x + up * halfSize.y, 1.0f);
PixelInput pixelInput;
[unroll(4)]
for (int i = 0; i < 4; i++)
{
//월드에서 다시 ndc까지 변환
pixelInput.Position = mul(vertices[i], GSProj);
pixelInput.Uv = TEXCOORD[i];
output.Append(pixelInput);
}
}
float4 PS(PixelInput input) : SV_TARGET
{
float4 BaseColor = DiffuseMapping(input.Uv);
if (BaseColor.a == 0)
discard;
return BaseColor;
}
hlsl파일입니다. 빌보드를 구현하기 위해서는 Position, Size, Pivot 이렇게 3가지가 필요합니다.
이런 식으로 체력 게이지를 표시할 수도 있으며 텍스쳐도 입혀서 이미지도 표시할 수 있습니다.
읽어주셔서 감사합니다.