응애맘마조

230825 강의 본문

공부/3D강의

230825 강의

TH.Wert 2023. 8. 25. 17:20

어제 안되었던 빌보드가 완성되었습니다. 카메라의 회전이나 이동을 해도 오브젝트가 카메라를 향하는 모습입니다.

#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가지가 필요합니다.

빌보드 구현 영상

이런 식으로 체력 게이지를 표시할 수도 있으며 텍스쳐도 입혀서 이미지도 표시할 수 있습니다.

 

읽어주셔서 감사합니다.

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

230829 강의  (0) 2023.08.29
230828 강의  (0) 2023.08.29
230824 강의  (0) 2023.08.24
230823 강의  (0) 2023.08.23
230822 강의  (0) 2023.08.22