응애맘마조

230829 강의 본문

공부/3D강의

230829 강의

TH.Wert 2023. 8. 29. 19:24

효과 이펙트에 대해 강의했습니다.

#pragma once
class Particle
{
protected:

    //현재 재생중인 시간
    float playTime = 0.0f;
    //재생중인가?
    bool isPlaying = false;
public:
    //총 재생시간
    float duration = 1.0f;
    virtual void    Play()
    {
        playTime = 0.0f;
        isPlaying = true;
    };
    virtual void    Stop()
    {
        isPlaying = false;
    };
    void            UpdateParticle();
    void            Gui();
    float           PlayTime() { return playTime / duration; }
    bool            IsPlaying() { return isPlaying; }
};

//상수버퍼
struct RAIN_DESC
{
    Vector3 velocity;
    float padding;

    Vector3 range;
    float time;
    RAIN_DESC()
    {
        velocity = Vector3(0, -1, 0);
        range = Vector3(500, 500, 500);
        time = 0.0f;
    }
};

class Rain : public Actor, public Particle
{
    static ID3D11Buffer* RainBuffer;
public:
    RAIN_DESC desc;
    Vector2             particleScale = Vector2(0, 0);
    int                 particleCount = 10;

    static void         CreateStaticMember();
    static void         DeleteStaticMember();
    static Rain* Create(string name = "Rain");
    virtual void        Render();
    virtual void        Update();
    void                RenderDetail();
    void                Reset();
    virtual void        Play();
    virtual void        Stop();
};
#include "framework.h"

void Particle::UpdateParticle()
{
	if (isPlaying)
	{
		playTime += DELTA;
		if (playTime > duration)
		{
			Stop();
		}
	}
}

void Particle::Gui()
{
	if (ImGui::Button("Play"))
	{
		Play();
	}
	ImGui::SameLine();
	if (ImGui::Button("Stop"))
	{
		Stop();
	}
	//현재 재생 시간
	ImGui::Text("Playtime : %f", PlayTime());
	//총 재생할 시간
	ImGui::SliderFloat("duration", &duration, 0.0f, 100.0f);
}
ID3D11Buffer* Rain::RainBuffer = nullptr;
void Rain::CreateStaticMember()
{
	{
		D3D11_BUFFER_DESC desc = { 0 };
		desc.ByteWidth = sizeof(RAIN_DESC);
		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, &RainBuffer);
		assert(SUCCEEDED(hr));
	}
}

void Rain::DeleteStaticMember()
{
	SafeRelease(RainBuffer);
}

Rain* Rain::Create(string name)
{
	Rain* temp = new Rain();
	temp->name = name;

	temp->mesh = make_shared<Mesh>();
	temp->mesh->LoadFile("7.Billboard.mesh");
	temp->shader = RESOURCE->shaders.Load("7.Rain.hlsl");
	temp->shader->LoadGeometry();
	temp->type = ObType::Rain;

	return temp;
}

void Rain::Render()
{
	desc.time = TIMER->GetWorldTime();
	{
		D3D11_MAPPED_SUBRESOURCE mappedResource;
		D3D->GetDC()->Map(RainBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
		memcpy_s(mappedResource.pData, sizeof(RAIN_DESC), &desc,
			sizeof(RAIN_DESC));
		D3D->GetDC()->Unmap(RainBuffer, 0);
		D3D->GetDC()->VSSetConstantBuffers(10, 1, &RainBuffer);
	}
	if (isPlaying)
		Actor::Render();
}

void Rain::Update()
{
	Particle::UpdateParticle();
	Actor::Update();
}

void Rain::Reset()
{
	delete[](VertexPS*)mesh->vertices;
	delete[] mesh->indices;
	mesh->vertices = new VertexPS[particleCount];
	mesh->indices = new UINT[particleCount];
	mesh->vertexCount = particleCount;
	mesh->indexCount = particleCount;

	Vector2 scale;

	for (UINT i = 0; i < particleCount; i++)
	{
		//이미지 크기 가로세로를 랜덤값
		//4~8 사이값

		//오차값
		scale.x = RANDOM->Float(-particleScale.x, particleScale.x);
		scale.y = RANDOM->Float(-particleScale.y, particleScale.y);
		scale.x = S._11 + scale.x;
		scale.y = S._22 + scale.y;
		if (scale.x < 1.0f)scale.x = 1.0f;
		if (scale.y < 1.0f)scale.y = 1.0f;

		Vector3 position;
		//생성될위치   //-4~8   ~ 4~ 8
		position.x = RANDOM->Float(-desc.range.x, desc.range.x);
		position.y = RANDOM->Float(-desc.range.y, desc.range.y);
		position.z = RANDOM->Float(-desc.range.z, desc.range.z);

		((VertexPS*)mesh->vertices)[i].position = position;
		((VertexPS*)mesh->vertices)[i].size = scale;
		mesh->indices[i] = i;
	}
	SafeRelease(mesh->vertexBuffer);
	SafeRelease(mesh->indexBuffer);

	//CreateVertexBuffer
	{
		D3D11_BUFFER_DESC desc;
		desc = { 0 };
		desc.Usage = D3D11_USAGE_DEFAULT;
		desc.ByteWidth = sizeof(VertexPS) * particleCount;
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

		D3D11_SUBRESOURCE_DATA data = { 0 };
		data.pSysMem = mesh->vertices;

		HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &mesh->vertexBuffer);
		assert(SUCCEEDED(hr));
	}

	//Create Index Buffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
		desc.ByteWidth = sizeof(UINT) * particleCount;
		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

		D3D11_SUBRESOURCE_DATA data = { 0 };
		data.pSysMem = mesh->indices;

		HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, &data, &mesh->indexBuffer);
		assert(SUCCEEDED(hr));
	}
}

void Rain::Play()
{
	Reset();
	Particle::Play();
}

void Rain::Stop()
{
	Particle::Stop();
}


void Rain::RenderDetail()
{
	Actor::RenderDetail();
	if (ImGui::BeginTabBar("MyTabBar3"))
	{
		if (ImGui::BeginTabItem("Rain"))
		{
			Particle::Gui();
			ImGui::SliderFloat3("Velocity", (float*)&desc.velocity, -1000, 1000);
			ImGui::SliderFloat3("particleRange", (float*)&desc.range, 0, 1000);
			ImGui::SliderFloat2("particleScale", (float*)&particleScale, 0, 100);
			ImGui::SliderInt("particleCount", &particleCount, 1, 100);

			if (ImGui::Button("Reset"))
			{
				Reset();
			}
			ImGui::EndTabItem();
		}
		ImGui::EndTabBar();
	}
}

비를 내리게 하는 이펙트를 만들었습니다. 이것도 전에 만들었던 빌보드를 가지고 구현했습니다. 또한 텍스쳐도 입힐 수 있어 더 현실적인 효과를 나타낼 수 있습니다.

이펙트를 넣은 효과

읽어주셔서 감사합니다.

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

230831 강의  (0) 2023.08.31
230830 강의  (0) 2023.08.30
230828 강의  (0) 2023.08.29
230825 강의  (0) 2023.08.25
230824 강의  (0) 2023.08.24
Comments