[DirectX11] 085~88 Weather (Rain, Snow)
전반적으로 DirectX11에서 기상 시스템을 생성하려면 예술적 비전과 기술의 조합이 필요하며 시뮬레이션하려는 기상 시스템의 물리 및 역학에 대한 깊은 이해가 필요하다. 올바른 도구와 전문 지식을 사용하면 멀티미디어 응용 프로그램의 전반적인 경험을 향상시킬 수 있는 매우 사실적이고 몰입감 있는 날씨 효과를 만들 수 있다.
목차
Weather
DirectX11에서 날씨 시스템을 생성하기 위한 첫 번째 단계는 시스템의 물리를 정의하는 것이다. 예를 들어 비를 시뮬레이트하려면 파티클의 속도와 방향, 떨어지는 속도, 환경과 상호 작용하는 방식(예: 표면에 튀거나 바람에 날리는 것)을 정의해야 한다.
날씨 시스템의 물리학을 정의한 후에는 DirectX11을 사용하여 시각 효과를 만들 수 있다. 여기에는 일반적으로 비, 눈 또는 기타 대기 효과에 대한 입자 시스템 생성과 텍스처를 사용하여 구름 덮개 또는 기타 대규모 날씨 패턴을 생성하는 작업이 포함된다.
DirectX11은 입자 크기, 모양 및 색상을 제어하는 기능은 물론 입자가 서로 및 환경과 상호 작용하는 방식을 포함하여 입자 시스템을 만들고 애니메이션화하기 위한 다양한 도구를 제공한다. 또한 텍스처 해상도, 압축 및 필터링을 제어하는 기능을 포함하여 텍스처를 만들고 조작하기 위한 다양한 도구를 제공한다.
Shaders | |
Global.fx Rain.fx 생성 Snow.fx 생성 |
|
Framework | |
Environment | |
Rain.h .cpp 생성 Snow.h .cpp 생성 |
|
UnitTest | |
Terrain | |
WeatherDemo.h. cpp 생성 |
Global.fx
Global.fx - 코드 추가
BlendState OpaqueBlend { BlendEnable[0] = true; SrcBlend[0] = One; DestBlend[0] = Zero; BlendOp[0] = ADD; SrcBlendAlpha[0] = One; DestBlendAlpha[0] = Zero; BlendOpAlpha[0] = Add; RenderTargetWriteMask[0] = 15; //Ox0F }; BlendState AlphaBlend { AlphaToCoverageEnable = false; BlendEnable[0] = true; SrcBlend[0] = SRC_ALPHA; DestBlend[0] = INV_SRC_ALPHA; BlendOp[0] = ADD; SrcBlendAlpha[0] = One; DestBlendAlpha[0] = Zero; BlendOpAlpha[0] = Add; RenderTargetWriteMask[0] = 15; //Ox0F }; BlendState AlphaBlend_AlphaToCoverageEnable { AlphaToCoverageEnable = true; BlendEnable[0] = true; SrcBlend[0] = SRC_ALPHA; DestBlend[0] = INV_SRC_ALPHA; BlendOp[0] = ADD; SrcBlendAlpha[0] = One; DestBlendAlpha[0] = Zero; BlendOpAlpha[0] = Add; RenderTargetWriteMask[0] = 15; //Ox0F }; BlendState AdditiveBlend { AlphaToCoverageEnable = false; BlendEnable[0] = true; SrcBlend[0] = One; DestBlend[0] = One; BlendOp[0] = ADD; SrcBlendAlpha[0] = One; DestBlendAlpha[0] = Zero; BlendOpAlpha[0] = Add; RenderTargetWriteMask[0] = 15; //Ox0F }; BlendState AdditiveBlend_Particle { AlphaToCoverageEnable = false; BlendEnable[0] = true; SrcBlend[0] = SRC_ALPHA; DestBlend[0] = One; BlendOp[0] = ADD; SrcBlendAlpha[0] = One; DestBlendAlpha[0] = Zero; BlendOpAlpha[0] = Add; RenderTargetWriteMask[0] = 15; //Ox0F }; BlendState AdditiveBlend_AlphaToCoverageEnable { AlphaToCoverageEnable = true; BlendEnable[0] = true; SrcBlend[0] = One; DestBlend[0] = One; BlendOp[0] = ADD; SrcBlendAlpha[0] = One; DestBlendAlpha[0] = Zero; BlendOpAlpha[0] = Add; RenderTargetWriteMask[0] = 15; //Ox0F }; DepthStencilState DepthRead_Particle { DepthEnable = true; DepthFunc = Less_Equal; DepthWriteMask = 0; };
코드 추가
- BlendState AlphaBlend
- BlendState AlphaBlend_AlphaToCoverageEnable
- BlendState AdditiveBlend
- 색을 더 진하게 만드는 효과
- BlendState AdditiveBlend_AlphaToCoverageEnable
SRC = SRC-Alpha
Dest = Inv SRC-Alpha
(SrcColor * SRC) + (DestColor * Dest) = 뒷색과 자신의 색이 섞인다.
Alpha Blending을 그릴 때는 불투명을 먼저 그린다. 그 후에 반투명을 그린다.
Rain.fx
Rain.fx
#include "00_Global.fx" #include "00_Light.fx" cbuffer CB_Rain { float4 Color; float3 Velocity; float DrawDistance; float3 Origin; float CB_Rain_Padding; float3 Extent; }; struct VertexInput { float4 Position : Position; float2 Uv : Uv; float2 Scale : Scale; }; struct VertexOutput { float4 Position : SV_Position; float2 Uv : Uv; float Alpha : Alpha; }; VertexOutput VS(VertexInput input) { VertexOutput output; float3 displace = Velocity; displace.xz /= input.Scale.y * 0.1f; //xz은 시간에 따라 증가. input.Scale.y로 나누어서 비 크기만큼 비례해서 속도를 늦추어 준다. displace *= Time; //Origin(=공간의 이동)에서 Extent 범위 내에서의 순환값 input.Position.xyz = Origin + (Extent + (input.Position.xyz + displace) % Extent) % Extent - (Extent * 0.5f); float4 position = WorldPosition(input.Position); float3 up = normalize(-Velocity); float3 forward = position.xyz - ViewPosition(); float3 right = normalize(cross(up, forward)); position.xyz += (input.Uv.x - 0.5f) * right * input.Scale.x; position.xyz += (1.0f - input.Uv.y - 0.5f) * up * input.Scale.y; position.w = 1.0f; output.Position = ViewProjection(position); output.Uv = input.Uv; float4 view = mul(position, View); output.Alpha = saturate(1 - view.z / DrawDistance) * 0.5f; return output; } //float4 PS_Discard(VertexOutput input) : SV_Target //{ // float4 diffuse = DiffuseMap.Sample(LinearSampler, input.Uv); // if (diffuse.a < 0.3) // discard; // return diffuse; //} float4 PS(VertexOutput input) : SV_Target { float4 diffuse = DiffuseMap.Sample(LinearSampler, input.Uv); diffuse.rgb = Color.rgb * input.Alpha * 2.0f; //rgb값 반영 diffuse.a = diffuse.a * input.Alpha * 1.5f; //alpha값 반영 return diffuse; } technique11 T0 { P_BS_VP(P0, AlphaBlend, VS, PS) //Global.fx 사용 P_BS_VP(P1, AlphaBlend_AlphaToCoverageEnable, VS, PS) P_BS_VP(P2, AdditiveBlend, VS, PS) P_BS_VP(P3, AdditiveBlend_AlphaToCoverageEnable, VS, PS) //P_VP(P0, VS, PS_Discard) }
핵심코
VertexOutput VS(VertexInput input) { VertexOutput output; float3 displace = Velocity; displace.xz /= input.Scale.y * 0.1f; //xz은 시간에 따라 증가. input.Scale.y로 나누어서 비 크기만큼 비례해서 속도를 늦추어 준다. displace *= Time; //Origin(=공간의 이동)에서 Extent 범위 내에서의 순환값 input.Position.xyz = Origin + (Extent + (input.Position.xyz + displace) % Extent) % Extent - (Extent * 0.5f); float4 position = WorldPosition(input.Position); float3 up = normalize(-Velocity); float3 forward = position.xyz - ViewPosition(); float3 right = normalize(cross(up, forward)); position.xyz += (input.Uv.x - 0.5f) * right * input.Scale.x; position.xyz += (1.0f - input.Uv.y - 0.5f) * up * input.Scale.y; position.w = 1.0f; output.Position = ViewProjection(position); output.Uv = input.Uv; float4 view = mul(position, View); output.Alpha = saturate(1 - view.z / DrawDistance) * 0.5f; return output; }
Snow.fx
Snow.fx
#include "00_Global.fx" #include "00_Light.fx" cbuffer CB_Snow { float4 Color; float3 Velocity; float DrawDistance; float3 Origin; float Turblence; //눈이 바람에 의해서 흔들리는 정도 float3 Extent; }; struct VertexInput { float4 Position : Position; float2 Uv : Uv; float Scale : Scale; float2 Random : Random; //눈이 바람에 흔들리는 값 랜덤으로 처리하기 위한 변수 }; struct VertexOutput { float4 Position : SV_Position; float2 Uv : Uv; float Alpha : Alpha; }; VertexOutput VS(VertexInput input) { VertexOutput output; float3 displace = Velocity * Time; //시간에 따라 속도가 증가되게 설정 input.Position.y = Origin.y + Extent.y - (input.Position.y - displace.y) % Extent.y; input.Position.x += cos(Time - input.Random.x) * Turblence; input.Position.z += cos(Time - input.Random.y) * Turblence; input.Position.xyz = Origin + (Extent + (input.Position.xyz + displace) % Extent) % Extent - (Extent * 0.5f); float4 position = WorldPosition(input.Position); float3 up = normalize(-Velocity); float3 forward = position.xyz - ViewPosition(); float3 right = normalize(cross(up, forward)); position.xyz += (input.Uv.x - 0.5f) * right * input.Scale; position.xyz += (1.0f - input.Uv.y - 0.5f) * up * input.Scale; position.w = 1.0f; output.Position = ViewProjection(position); output.Uv = input.Uv; float4 view = mul(position, View); output.Alpha = saturate(1 - view.z / DrawDistance) * 0.5f; return output; } float4 PS(VertexOutput input) : SV_Target { float4 diffuse = DiffuseMap.Sample(LinearSampler, input.Uv); diffuse.rgb = Color.rgb * input.Alpha * 2.0f; diffuse.a = diffuse.a * input.Alpha * 1.5f; return diffuse; } technique11 T0 { P_BS_VP(P0, AlphaBlend, VS, PS) P_BS_VP(P1, AlphaBlend_AlphaToCoverageEnable, VS, PS) P_BS_VP(P2, AdditiveBlend, VS, PS) P_BS_VP(P3, AdditiveBlend_AlphaToCoverageEnable, VS, PS) }
Rain
Rain.h
#pragma once class Rain : public Renderer { public: Rain(Vector3& extent, UINT count, wstring file);//비가 내릴 구역의 부피, 정점이 그려질 개수, 비의 texture 파일 ~Rain(); void Update(); void Render(); private: struct Desc { D3DXCOLOR Color = D3DXCOLOR(1, 1, 1, 1); //비 색깔 Vector3 Velocity = Vector3(-10, -100, 0); //비 방향 float DrawDistance = 0; //비의 그려질 거리 Vector3 Origin = Vector3(0, 0, 0); //비의 중심점 float Padding; Vector3 Extent = Vector3(0, 0, 0); //비가 내릴 구역의 부피 float Padding2; } desc; private: struct VertexRain { Vector3 Position; Vector2 Uv; Vector2 Scale; }; private: ConstantBuffer* buffer; ID3DX11EffectConstantBuffer* sBuffer; VertexRain* vertices; UINT* indices; Texture* texture; UINT drawCount = 100; };
Rain.cpp
#include "Framework.h" #include "Rain.h" Rain::Rain(Vector3 & extent, UINT count, wstring file) : Renderer(L"85_Rain.fxo"), drawCount(count) { desc.Extent = extent; desc.DrawDistance = desc.Extent.z * 2.0f; texture = new Texture(file); shader->AsSRV("DiffuseMap")->SetResource(texture->SRV()); buffer = new ConstantBuffer(&desc, sizeof(Desc)); sBuffer = shader->AsConstantBuffer("CB_Rain"); vertices = new VertexRain[drawCount * 4]; //정점 개수 for (UINT i = 0; i < drawCount * 4; i += 4) //i += 4로 만들어 i를 4씩 증가 { Vector2 scale; scale.x = Math::Random(0.1f, 0.4f); scale.y = Math::Random(2.0f, 6.0f); Vector3 position; position.x = Math::Random(-desc.Extent.x, desc.Extent.x); position.y = Math::Random(-desc.Extent.y, desc.Extent.y); position.z = Math::Random(-desc.Extent.z, desc.Extent.z); vertices[i + 0].Position = position; vertices[i + 1].Position = position; vertices[i + 2].Position = position; vertices[i + 3].Position = position; vertices[i + 0].Uv = Vector2(0, 1); vertices[i + 1].Uv = Vector2(0, 0); vertices[i + 2].Uv = Vector2(1, 1); vertices[i + 3].Uv = Vector2(1, 0); vertices[i + 0].Scale = scale; vertices[i + 1].Scale = scale; vertices[i + 2].Scale = scale; vertices[i + 3].Scale = scale; } indices = new UINT[drawCount * 6]; for (UINT i = 0; i < drawCount; i++) { indices[i * 6 + 0] = i * 4 + 0; indices[i * 6 + 1] = i * 4 + 1; indices[i * 6 + 2] = i * 4 + 2; indices[i * 6 + 3] = i * 4 + 2; indices[i * 6 + 4] = i * 4 + 1; indices[i * 6 + 5] = i * 4 + 3; } vertexBuffer = new VertexBuffer(vertices, drawCount * 4, sizeof(VertexRain)); indexBuffer = new IndexBuffer(indices, drawCount * 6); //ID3D11BlendState //D3D11_BLEND_DESC; } Rain::~Rain() { SafeDelete(buffer); SafeDeleteArray(vertices); SafeDeleteArray(indices); SafeDelete(texture); } void Rain::Update() { Super::Update(); Context::Get()->GetCamera()->Position(&desc.Origin); //ImGui::SliderFloat3("Origin", desc.Origin, 0, 200); //원점 ImGui::SliderFloat3("Velocity", desc.Velocity, -200, 200); //속도 ImGui::ColorEdit3("Color", desc.Color); //색상 ImGui::SliderFloat("Distance", &desc.DrawDistance, 0, desc.Extent.z * 2.0f); //거리 } void Rain::Render() { Super::Render(); buffer->Render(); sBuffer->SetConstantBuffer(buffer->Buffer()); static UINT pass = 0; ImGui::InputInt("Rain Pass", (int *)&pass); pass %= 4; shader->DrawIndexed(0, pass, drawCount * 6); //부모 pass 사용 }
Snow
Snow.h
#pragma once class Snow : public Renderer { public: Snow(Vector3& extent, UINT count, wstring file); ~Snow(); void Update(); void Render(); private: struct Desc { D3DXCOLOR Color = D3DXCOLOR(1, 1, 1, 1); Vector3 Velocity = Vector3(0, -5, 0); float DrawDistance = 0; Vector3 Origin = Vector3(0, 0, 0); float Turbulence = 5; //눈이 바람에 의해서 흔들리는 정도 Vector3 Extent = Vector3(0, 0, 0); float Padding2; } desc; private: struct VertexSnow { Vector3 Position; Vector2 Uv; float Scale; Vector2 Random; }; private: ConstantBuffer* buffer; ID3DX11EffectConstantBuffer* sBuffer; VertexSnow* vertices; UINT* indices; Texture* texture; UINT drawCount = 100; };
Snow.cpp
#include "Framework.h" #include "Snow.h" Snow::Snow(Vector3 & extent, UINT count, wstring file) : Renderer(L"85_Snow.fxo"), drawCount(count) { desc.Extent = extent; desc.DrawDistance = desc.Extent.z * 2.0f; texture = new Texture(file); shader->AsSRV("DiffuseMap")->SetResource(texture->SRV()); buffer = new ConstantBuffer(&desc, sizeof(Desc)); sBuffer = shader->AsConstantBuffer("CB_Snow"); vertices = new VertexSnow[drawCount * 4]; for (UINT i = 0; i < drawCount * 4; i += 4) { float scale; scale = Math::Random(0.1f, 0.4f); Vector3 position; position.x = Math::Random(-desc.Extent.x, desc.Extent.x); position.y = Math::Random(-desc.Extent.y, desc.Extent.y); position.z = Math::Random(-desc.Extent.z, desc.Extent.z); Vector2 random = Math::RandomVec2(0.0f, 1.0f); vertices[i + 0].Position = position; vertices[i + 1].Position = position; vertices[i + 2].Position = position; vertices[i + 3].Position = position; vertices[i + 0].Uv = Vector2(0, 1); vertices[i + 1].Uv = Vector2(0, 0); vertices[i + 2].Uv = Vector2(1, 1); vertices[i + 3].Uv = Vector2(1, 0); vertices[i + 0].Scale = scale; vertices[i + 1].Scale = scale; vertices[i + 2].Scale = scale; vertices[i + 3].Scale = scale; vertices[i + 0].Random = random; vertices[i + 1].Random = random; vertices[i + 2].Random = random; vertices[i + 3].Random = random; } indices = new UINT[drawCount * 6]; for (UINT i = 0; i < drawCount; i++) { indices[i * 6 + 0] = i * 4 + 0; indices[i * 6 + 1] = i * 4 + 1; indices[i * 6 + 2] = i * 4 + 2; indices[i * 6 + 3] = i * 4 + 2; indices[i * 6 + 4] = i * 4 + 1; indices[i * 6 + 5] = i * 4 + 3; } vertexBuffer = new VertexBuffer(vertices, drawCount * 4, sizeof(VertexSnow)); indexBuffer = new IndexBuffer(indices, drawCount * 6); //ID3D11BlendState //D3D11_BLEND_DESC; } Snow::~Snow() { SafeDelete(buffer); SafeDeleteArray(vertices); SafeDeleteArray(indices); SafeDelete(texture); } void Snow::Update() { Super::Update(); Context::Get()->GetCamera()->Position(&desc.Origin); //ImGui::SliderFloat3("Origin", desc.Origin, 0, 200); ImGui::SliderFloat3("Velocity", desc.Velocity, -200, 200); ImGui::ColorEdit3("Color", desc.Color); ImGui::SliderFloat("Distance", &desc.DrawDistance, 0, desc.Extent.z * 2.0f); ImGui::InputFloat("Turbulence", &desc.Turbulence, 0.1f); } void Snow::Render() { Super::Render(); buffer->Render(); sBuffer->SetConstantBuffer(buffer->Buffer()); static UINT pass = 0; ImGui::InputInt("Snow Pass", (int *)&pass); pass %= 4; shader->DrawIndexed(0, pass, drawCount * 6); }
WeatherDemo
WeatherDemo.h
#pragma once #include "Systems/IExecute.h" class WeatherDemo : public IExecute { public: virtual void Initialize() override; virtual void Ready() override {} virtual void Destroy() override {} virtual void Update() override; virtual void PreRender() override {} virtual void Render() override; virtual void PostRender() override {} virtual void ResizeScreen() override {} private: void Billboards(); void Mesh(); void Airplane(); void Kachujin(); void KachujinCollider(); void KachujinWeapon(); void PointLighting(); void SpotLighting(); void Pass(UINT mesh, UINT model, UINT anim); private: Shader* shader; Billboard* billboard; CubeSky* sky; enum class WeatherType { None = 0, Rain, Snow, Count, } weatherType; Rain* rain; Snow* snow; Material* floor; Material* stone; Material* brick; Material* wall; MeshRender* cube; MeshRender* cylinder; MeshRender* sphere; MeshRender* grid; ModelRender* airplane = NULL; ModelAnimator* kachujin = NULL; Transform* colliderInitTransforms; ColliderObject** colliders; ModelRender* weapon = NULL; Transform* weaponInitTransform; vector<MeshRender *> meshes; vector<ModelRender *> models; vector<ModelAnimator *> animators; };
WeatherDemo.cpp
#include "stdafx.h" #include "WeatherDemo.h" void WeatherDemo::Initialize() { Context::Get()->GetCamera()->RotationDegree(20, 0, 0); Context::Get()->GetCamera()->Position(1, 36, -85); ((Freedom *)Context::Get()->GetCamera())->Speed(50, 2); shader = new Shader(L"82_NormalMapping.fxo"); sky = new CubeSky(L"Environment/GrassCube1024.dds"); rain = new Rain(Vector3(300, 100, 500), (UINT)1e+4f, L"Environment/Rain.png"); snow = new Snow(Vector3(300, 100, 500), (UINT)1e+5f, L"Environment/Snow.png"); Billboards(); Mesh(); Airplane(); Kachujin(); KachujinCollider(); KachujinWeapon(); PointLighting(); SpotLighting(); } void WeatherDemo::Update() { sky->Update(); cube->Update(); grid->Update(); cylinder->Update(); sphere->Update(); airplane->Update(); kachujin->Update(); Matrix worlds[MAX_MODEL_TRANSFORMS]; for (UINT i = 0; i < kachujin->GetTransformCount(); i++) { kachujin->GetAttachTransform(i, worlds); weapon->GetTransform(i)->World(weaponInitTransform->World() * worlds[40]); } weapon->UpdateTransforms(); weapon->Update(); billboard->Update(); UINT WeatherSelected = (UINT)weatherType; ImGui::Separator(); ImGui::InputInt("Weather Type", (int *)&WeatherSelected); WeatherSelected %= (UINT)WeatherType::Count; weatherType = (WeatherType)WeatherSelected; switch (weatherType) { case WeatherType::Rain: rain->Update(); break; case WeatherType::Snow: snow->Update(); break; } } void WeatherDemo::Render() { sky->Render(); Pass(0, 1, 2); wall->Render(); sphere->Render(); brick->Render(); cylinder->Render(); stone->Render(); cube->Render(); floor->Render(); grid->Render(); airplane->Render(); kachujin->Render(); weapon->Render(); billboard->Render(); switch (weatherType) { case WeatherType::Rain: rain->Render(); break; case WeatherType::Snow: snow->Render(); break; } } void WeatherDemo::Billboards() { billboard = new Billboard(L"Terrain/grass_14.tga"); for (UINT i = 0; i < 1200; i++) { Vector2 scale = Math::RandomVec2(1, 3); Vector2 position = Math::RandomVec2(-60, 60); billboard->Add(Vector3(position.x, scale.y * 0.5f, position.y), scale); } } void WeatherDemo::Mesh() { //Create Material { floor = new Material(shader); floor->DiffuseMap("Floor.png"); floor->Specular(1, 1, 1, 20); floor->SpecularMap("Floor_Specular.png"); floor->NormalMap("Floor_Normal.png"); stone = new Material(shader); stone->DiffuseMap("Stones.png"); stone->Specular(1, 1, 1, 20); stone->SpecularMap("Stones_Specular.png"); stone->Emissive(0.15f, 0.15f, 0.15f, 0.3f); stone->NormalMap("Stones_Normal.png"); brick = new Material(shader); brick->DiffuseMap("Bricks.png"); brick->Specular(1, 0.3f, 0.3f, 20); brick->SpecularMap("Bricks_Specular.png"); brick->Emissive(0.15f, 0.15f, 0.15f, 0.3f); brick->NormalMap("Bricks_Normal.png"); wall = new Material(shader); wall->DiffuseMap("Wall.png"); wall->Specular(1, 1, 1, 20); wall->SpecularMap("Wall_Specular.png"); wall->Emissive(0.15f, 0.15f, 0.15f, 0.3f); wall->NormalMap("Wall_Normal.png"); } //Create Mesh { Transform* transform = NULL; cube = new MeshRender(shader, new MeshCube()); transform = cube->AddTransform(); transform->Position(0, 5, 0); transform->Scale(20, 10, 20); grid = new MeshRender(shader, new MeshGrid(5, 5)); transform = grid->AddTransform(); transform->Position(0, 0, 0); transform->Scale(12, 1, 12); cylinder = new MeshRender(shader, new MeshCylinder(0.5f, 3.0f, 20, 20)); sphere = new MeshRender(shader, new MeshSphere(0.5f, 20, 20)); for (UINT i = 0; i < 5; i++) { transform = cylinder->AddTransform(); transform->Position(-30, 6, -15.0f + (float)i * 15.0f); transform->Scale(5, 5, 5); transform = cylinder->AddTransform(); transform->Position(30, 6, -15.0f + (float)i * 15.0f); transform->Scale(5, 5, 5); transform = sphere->AddTransform(); transform->Position(-30, 15.5f, -15.0f + (float)i * 15.0f); transform->Scale(5, 5, 5); transform = sphere->AddTransform(); transform->Position(30, 15.5f, -15.0f + (float)i * 15.0f); transform->Scale(5, 5, 5); } } sphere->UpdateTransforms(); cylinder->UpdateTransforms(); cube->UpdateTransforms(); grid->UpdateTransforms(); meshes.push_back(sphere); meshes.push_back(cylinder); meshes.push_back(cube); meshes.push_back(grid); } void WeatherDemo::Airplane() { airplane = new ModelRender(shader); airplane->ReadMesh(L"B787/Airplane"); airplane->ReadMaterial(L"B787/Airplane"); Transform* transform = airplane->AddTransform(); transform->Position(2.0f, 9.91f, 2.0f); transform->Scale(0.004f, 0.004f, 0.004f); airplane->UpdateTransforms(); models.push_back(airplane); } void WeatherDemo::Kachujin() { kachujin = new ModelAnimator(shader); kachujin->ReadMesh(L"Kachujin/Mesh"); kachujin->ReadMaterial(L"Kachujin/Mesh"); kachujin->ReadClip(L"Kachujin/Sword And Shield Idle"); kachujin->ReadClip(L"Kachujin/Sword And Shield Walk"); kachujin->ReadClip(L"Kachujin/Sword And Shield Run"); kachujin->ReadClip(L"Kachujin/Sword And Shield Slash"); kachujin->ReadClip(L"Kachujin/Salsa Dancing"); Transform* transform = NULL; transform = kachujin->AddTransform(); transform->Position(0, 0, -30); transform->Scale(0.075f, 0.075f, 0.075f); kachujin->PlayTweenMode(0, 0, 1.0f); transform = kachujin->AddTransform(); transform->Position(-15, 0, -30); transform->Scale(0.075f, 0.075f, 0.075f); kachujin->PlayTweenMode(1, 1, 1.0f); transform = kachujin->AddTransform(); transform->Position(-30, 0, -30); transform->Scale(0.075f, 0.075f, 0.075f); kachujin->PlayTweenMode(2, 2, 0.75f); transform = kachujin->AddTransform(); transform->Position(15, 0, -30); transform->Scale(0.075f, 0.075f, 0.075f); kachujin->PlayBlendMode(3, 0, 1, 2); kachujin->SetBlendAlpha(3, 1.5f); transform = kachujin->AddTransform(); transform->Position(30, 0, -32.5f); transform->Scale(0.075f, 0.075f, 0.075f); kachujin->PlayTweenMode(4, 4, 0.75f); kachujin->UpdateTransforms(); animators.push_back(kachujin); } void WeatherDemo::KachujinCollider() { UINT count = kachujin->GetTransformCount(); colliders = new ColliderObject*[count]; colliderInitTransforms = new Transform(); colliderInitTransforms->Position(-2.9f, 1.45f, -50.0f); colliderInitTransforms->Scale(5, 5, 75); for (UINT i = 0; i < count; i++) { colliders[i] = new ColliderObject(); //colliders[i]->Init = new Transform(); //colliders[i]->Init->Position(0, 0, 0); //colliders[i]->Init->Scale(10, 30, 10); colliders[i]->Transform = new Transform(); //colliders[i]->Collider = new Collider(colliders[i]->Transform, colliders[i]->Init); colliders[i]->Collider = new Collider(colliders[i]->Transform, colliderInitTransforms); } } void WeatherDemo::KachujinWeapon() { weapon = new ModelRender(shader); weapon->ReadMesh(L"Weapon/Sword"); weapon->ReadMaterial(L"Weapon/Sword"); UINT count = kachujin->GetTransformCount(); for (UINT i = 0; i < count; i++) weapon->AddTransform(); weapon->UpdateTransforms(); models.push_back(weapon); weaponInitTransform = new Transform(); weaponInitTransform->Position(-2.9f, 1.45f, -6.45f); weaponInitTransform->Scale(0.5f, 0.5f, 0.75f); weaponInitTransform->Rotation(0, 0, 1); } void WeatherDemo::PointLighting() { PointLight light; light = { Color(0.0f, 0.0f, 0.0f, 1.0f), //Ambient Color(0.0f, 0.0f, 1.0f, 1.0f), //Diffuse Color(0.0f, 0.0f, 0.7f, 1.0f), //Specular Color(0.0f, 0.0f, 0.7f, 1.0f), //Emissive Vector3(-30, 10, -30), 5.0f, 0.9f }; Lighting::Get()->AddPointLight(light); light = { Color(0.0f, 0.0f, 0.0f, 1.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), Color(0.6f, 0.2f, 0.0f, 1.0f), Color(0.6f, 0.3f, 0.0f, 1.0f), Vector3(15, 10, -30), 10.0f, 0.3f }; Lighting::Get()->AddPointLight(light); light = { Color(0.0f, 0.0f, 0.0f, 1.0f), //Ambient Color(0.0f, 1.0f, 0.0f, 1.0f), //Diffuse Color(0.0f, 0.7f, 0.0f, 1.0f), //Specular Color(0.0f, 0.7f, 0.0f, 1.0f), //Emissive Vector3(-5, 1, -17.5f), 5.0f, 0.9f }; Lighting::Get()->AddPointLight(light); light = { Color(0.0f, 0.0f, 0.0f, 1.0f), Color(0.0f, 0.0f, 1.0f, 1.0f), Color(0.0f, 0.0f, 0.7f, 1.0f), Color(0.0f, 0.0f, 0.7f, 1.0f), Vector3(-10, 1, -17.5f), 5.0f, 0.9f }; Lighting::Get()->AddPointLight(light); } void WeatherDemo::SpotLighting() { SpotLight light; light = { Color(0.3f, 1.0f, 0.0f, 1.0f), Color(0.7f, 1.0f, 0.0f, 1.0f), Color(0.3f, 1.0f, 0.0f, 1.0f), Color(0.3f, 1.0f, 0.0f, 1.0f), Vector3(-15, 20, -30), 25.0f, Vector3(0, -1, 0), 30.0f, 0.4f }; Lighting::Get()->AddSpotLight(light); light = { Color(1.0f, 0.2f, 0.9f, 1.0f), Color(1.0f, 0.2f, 0.9f, 1.0f), Color(1.0f, 0.2f, 0.9f, 1.0f), Color(1.0f, 0.2f, 0.9f, 1.0f), Vector3(0, 20, -30), 30.0f, Vector3(0, -1, 0), 40.0f, 0.55f }; Lighting::Get()->AddSpotLight(light); } void WeatherDemo::Pass(UINT mesh, UINT model, UINT anim) { for (MeshRender* temp : meshes) temp->Pass(mesh); for (ModelRender* temp : models) temp->Pass(model); for (ModelAnimator* temp : animators) temp->Pass(anim); }
실행화면


'⭐ DirectX > DirectX11 3D' 카테고리의 다른 글
[DirectX11] 095 Particle Editor (0) | 2023.04.12 |
---|---|
[DirectX11] 089~94 Particle System (0) | 2023.04.04 |
[DirectX11] 083~84 Billboard (0) | 2023.03.28 |
[DirectX11] 081~82 Normal Mapping (0) | 2023.03.27 |
[DirectX11] 080 Spot Lighting (0) | 2023.03.26 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 095 Particle Editor
[DirectX11] 095 Particle Editor
2023.04.12DirectX11의 Particle Editor는 DirectX11 응용 프로그램에서 사용할 입자 효과를 만들고 관리하는 데 사용되는 소프트웨어 도구이다. 그것은 개발자들이 개별 입자의 행동과 모양을 제어함으로써 연기, 화재, 물, 폭발과 같은 복잡하고 역동적인 효과를 만들 수 있게 한다. 목차 Particle Editor 파티클 편집기에는 일반적으로 개발자가 파티클 시스템을 시각적으로 만들고 수정할 수 있는 시각적 편집기가 포함되어 있다. 일반적으로 크기, 색상, 불투명도 및 수명과 같은 입자 속성에 대한 제어를 제공하며 개발자가 입자 시스템의 동작 및 모양을 실시간으로 조정할 수 있다. 또한 DirectX11의 Particle Editor는 개발자가 입자에 이미지를 적용할 수 있는 텍스처 매핑 및 고… -
[DirectX11] 089~94 Particle System
[DirectX11] 089~94 Particle System
2023.04.04Particle System은 입자라고 하는 작고 개별적인 시각적 요소를 시뮬레이션하고 렌더링하는 데 사용되는 그래픽 기술로, 서로 움직이고 환경과 상호 작용한다. 화재, 연기, 물, 폭발 등과 같은 현상의 사실적이고 역동적인 애니메이션을 만들기 위해 컴퓨터 게임 및 시각 효과에 일반적으로 사용된다. 목차 Particle System DirectX11에서는 GPU를 사용하여 계산 및 렌더링을 수행하는 파티클 시스템을 구현할 수 있다. DirectX11에서 파티클 시스템을 만드는 기본 단계는 다음과 같다. 입자 데이터를 저장할 Vertex Buffer를 생성한다. 여기에는 각 입자의 위치, 속도, 색상, 크기 및 기타 속성이 포함된다. 입자 시뮬레이션 및 렌더링을 처리하도록 셰이더 프로그램을 설정한다. 여… -
[DirectX11] 083~84 Billboard
[DirectX11] 083~84 Billboard
2023.03.28DirectX 11에서 빌보드는 항상 카메라를 향하고 있는 2D 이미지로, 3D 개체의 환영을 만든다. 빌보드는 폭발, 연기 또는 화재와 같은 입자 효과 등에 사용된다. 빌보드를 만들려면 이미지를 3D 공간에 배치하고 법선이 카메라의 보기 방향과 수직이 되도록 정렬한다. 이렇게 하면 위치나 방향에 관계없이 이미지가 항상 카메라를 향하게 된다. 그러면 빌보드가 적절한 크기로 조정되고 텍스처 쿼드로 렌더링된다. 목차 Billboard DirectX 11에서 빌보드는 항상 카메라를 향하고 있는 2D 이미지로, 3D 개체의 환영을 만든다. 빌보드는 폭발, 연기 또는 화재와 같은 입자 효과 등에 사용된다. 빌보드를 만들려면 이미지를 3D 공간에 배치하고 법선이 카메라의 보기 방향과 수직이 되도록 정렬한다. 이렇게… -
[DirectX11] 081~82 Normal Mapping
[DirectX11] 081~82 Normal Mapping
2023.03.27글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자입니다 목차 Normal Mapping Shader Light.fx Lighting.fx Render.fx PointLighting.fx SpotLighting.fx NormalMapping.fx Framework Meshes Mesh.h - VertexTextureNormalTangent 추가 MeshCylinder.cpp - vertex.tangent, MeshVertex 추가 MeshGrid.cpp - vertex.tangent, MeshV…
댓글을 사용할 수 없습니다.