[DirectX11] 107-110 Dynamic Cube Map
큐브맵은 3D 그래픽스에서 환경 맵핑(environment mapping)에 주로 사용되며, 사실적인 조명 효과와 반사 효과를 구현하는 데 필수적이다. 큐브맵 UV는 큐브맵을 효율적으로 활용하는 기술로, 3D 공간에서의 객체와 환경 사이의 상호작용을 정교하게 표현하게 해준다.
목차
Dynamic Cube Map
Shaders | |
Global.fx DynamicCubMap.fx 생성 |
|
Framework | |
Objects | |
DynamicCubeMap.h .cpp 생성 | |
UnitTest | |
Objects | |
DynamicCubeMapDemo.h .cpp 생성 |
Dynamic Cube Map 매핑 원리


View[6] - GS에서 생성
Projection
큐브맵(CubeMap)
큐브맵은 하나의 텍스처가 아닌 6개의 면으로 구성된 직육면체 형태의 텍스처다.
- 각 면은 텍스처 큐브(TextureCube)로 구현되며, 이를 통해 360도 모든 방향에서의 시각적 정보를 제공한다.
- 하늘이나 주변 환경 등을 입체적으로 표현할 때 사용한다.
- 3D 세계에서 객체가 위치한 환경을 반영하는 데에 자주 쓰이며, 반사나 굴절 효과를 구현할 때도 유용하다.
큐브맵 UV
큐브맵을 사용할 때, 각 정점의 로컬 위치는 UV 좌표로 사용된다.
- 정점의 로컬 위치는 방향 벡터로 간주되며, 이 방향이 큐브맵 상의 어느 면과 충돌하는지를 계산하여 해당 면의 픽셀을 렌더링한다.
- 로컬 정점의 위치를 방향으로 해석하여, 그 방향에 해당하는 큐브맵의 면에서 샘플링을 진행한다.
- 큐브맵을 샘플링할 때는 TextureCube.Sample(샘플러, 로컬 정점의 위치)와 같은 함수를 사용하여, 정점의 위치에 따른 텍스처 데이터를 얻어낸다.
Global.fx
Global.fx - 추가된 부분
더보기
struct MeshOutput { float4 Position : SV_Position0; //Rasterizing Position float3 oPosition : Position1; //Original Position float3 wPosition : Position2; //World Position float4 wvpPosition : Position3; //WVP float4 wvpPosition_Sub : Position4; //WVP float4 sPosition : Position5; //Light WVP float3 Normal : Normal; float3 Tangent : Tangent; float2 Uv : Uv; float4 Color : Color; }; struct MeshGeometryOutput { float4 Position : SV_Position0; //Rasterizing Position float3 oPosition : Position1; //Original Position float3 wPosition : Position2; //World Position float3 Normal : Normal; float3 Tangent : Tangent; float2 Uv : Uv; float4 Color : Color; uint TargetIndex : SV_RenderTargetArrayIndex; //RenderTarget 인덱스 번호를 부여한다. }; MeshOutput ConvetMeshOutput(MeshGeometryOutput input) { MeshOutput output; output.Position = input.Position; output.oPosition = input.oPosition; output.wPosition = input.wPosition; output.Normal = input.Normal; output.Tangent = input.Tangent; output.Uv = input.Uv; output.Color = input.Color; return output; }
DynamicCubeMap.fx에 넘겨줄 데이터 추가
- struct MehsOutput
- struct MeshGeometryOutput
- MeshOutput ConvetMeshOutput
DynamicCubeMap.fx
DynamicCubeMap.fx
더보기
cbuffer CB_DynamicCube { uint CubeRenderType; float3 CB_DynamicCube_Padding; matrix CubeViews[6]; matrix CubeProjection; }; [maxvertexcount(18)] void GS_PreRender(triangle MeshOutput input[3], inout TriangleStream<MeshGeometryOutput> stream) { int vertex = 0; MeshGeometryOutput output; [unroll(6)] for (int i = 0; i < 6; i++) { output.TargetIndex = i; [unroll(3)] for (vertex = 0; vertex < 3; vertex++) { output.Position = mul(float4(input[vertex].wPosition, 1), CubeViews[i]); output.Position = mul(output.Position, CubeProjection); output.oPosition = input[vertex].oPosition; output.wPosition = input[vertex].wPosition; output.Normal = input[vertex].Normal; output.Tangent = input[vertex].Tangent; output.Uv = input[vertex].Uv; output.Color = input[vertex].Color; stream.Append(output); } stream.RestartStrip(); } } float4 PS_PreRender_Sky(MeshGeometryOutput input) : SV_Target { return PS_Sky(ConvetMeshOutput(input)); } float4 PS_PreRender(MeshGeometryOutput input) : SV_Target { return PS_AllLight(ConvetMeshOutput(input)); } TextureCube DynamicCubeMap; float RefractionAmount = 0.2f; float RefractionAlpha = 0.75f; float CubeMapAmount = 1.0f; float CubeMapBias = 1.0f; float CubeMapScale = 1.0f; float4 PS_CubeMap(MeshOutput input) : SV_Target { float4 color = 0; float3 view = normalize(input.wPosition - ViewPosition()); float3 normal = normalize(input.Normal); float3 reflection = reflect(view, normal); float3 refraction = refract(view, normal, RefractionAmount); float4 diffuse = 0; if(CubeRenderType == 0) { color = DynamicCubeMap.Sample(LinearSampler, input.oPosition); } else if (CubeRenderType == 1) { color = DynamicCubeMap.Sample(LinearSampler, reflection); } else if (CubeRenderType == 2) { color = DynamicCubeMap.Sample(LinearSampler, -refraction); color.a = RefractionAlpha; } else if (CubeRenderType == 3) { diffuse = PS_AllLight(input); color = DynamicCubeMap.Sample(LinearSampler, reflection); color.rgb *= (0.15f + diffuse * 0.95f); } else if (CubeRenderType == 4) { diffuse = PS_AllLight(input); color = DynamicCubeMap.Sample(LinearSampler, reflection); float4 fresnel = CubeMapBias + (1.0f - CubeMapScale) * pow(abs(1.0f - dot(view, normal)), CubeMapAmount); color = CubeMapAmount * diffuse + lerp(diffuse, color, fresnel); color.a = 1.0f; } return color; } technique11 T0 { //Sky P_RS_DSS_VP(P0, FrontCounterClockwise_True, DepthEnable_False, VS_Mesh, PS_Sky) //Render P_VP(P1, VS_Mesh, PS) P_VP(P2, VS_Model, PS) P_VP(P3, VS_Animation, PS) //Billboard P_BS_VGP(P4, AlphaBlend, VS, GS_Billboard, PS_Billboard) P_RS_BS_VGP(P5, CullMode_None, AlphaBlend_AlphaToCoverageEnable, VS, GS_Cross, PS_Billboard) //Dynamic Cube Map PreRender P_RS_DSS_VGP(P6, FrontCounterClockwise_True, DepthEnable_False, VS_Mesh, GS_PreRender, PS_PreRender_Sky) P_VGP(P7, VS_Mesh, GS_PreRender, PS_PreRender) P_VGP(P8, VS_Model, GS_PreRender, PS_PreRender) P_VGP(P9, VS_Animation, GS_PreRender, PS_PreRender) //Dynamic CubeMap Render P_BS_VP(P10, AlphaBlend, VS_Mesh, PS_CubeMap) P_BS_VP(P11, AlphaBlend, VS_Model, PS_CubeMap) P_BS_VP(P12, AlphaBlend, VS_Animation, PS_CubeMap) }
핵심 코드
DynamicCubeMap.h .cpp
DynamicCubeMap.h
더보기
#pragma once class DynamicCubeMap { public: DynamicCubeMap(Shader* shader, UINT width, UINT height); ~DynamicCubeMap(); void PreRender(Vector3& position, Vector3& scale, float zNear = 0.1f, float zFar = 500.0f, float fov = 0.5f); void Type(UINT val) { desc.Type = val; } ID3D11ShaderResourceView* SRV() { return srv; } Perspective* GetPerspective() { return perspective; } private: struct Desc { UINT Type; float Padding[3]; Matrix Views[6]; Matrix Projection; } desc; private: Shader* shader; Vector3 position; //CubeMap의 위치 UINT width, height;//CubeMap의 폭, 높이 ID3D11Texture2D* rtvTexture;//Render Target View ID3D11RenderTargetView* rtv; ID3D11ShaderResourceView* srv; ID3D11Texture2D* dsvTexture; ID3D11DepthStencilView* dsv; Perspective* perspective; Viewport* viewport; class ConstantBuffer* buffer; ID3DX11EffectConstantBuffer* sBuffer = NULL; };
DynamicCubeMap.cpp
더보기
#include "Framework.h" #include "DynamicCubeMap.h" DynamicCubeMap::DynamicCubeMap(Shader * shader, UINT width, UINT height) : shader(shader), position(0, 0, 0), width(width), height(height) { DXGI_FORMAT rtvFormat = DXGI_FORMAT_R8G8B8A8_UNORM; //Create Texture2D - RTV { D3D11_TEXTURE2D_DESC desc; ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC)); desc.Width = width; desc.Height = height; desc.ArraySize = 6; desc.Format = rtvFormat; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; //TextureCube형태로 렌더를 할 수 있게 해준다. desc.MipLevels = 1; desc.SampleDesc.Count = 1; Check(D3D::GetDevice()->CreateTexture2D(&desc, NULL, &rtvTexture)); } //Create RTV { //시스템에게 알려준다. DX 부분 D3D11_RENDER_TARGET_VIEW_DESC desc; ZeroMemory(&desc, sizeof(D3D11_RENDER_TARGET_VIEW_DESC)); desc.Format = rtvFormat; desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; desc.Texture2DArray.ArraySize = 6; //6개로 지정. Check(D3D::GetDevice()->CreateRenderTargetView(rtvTexture, &desc, &rtv)); } //Create SRV { //쉐이더에게 알려준다. Shader 부분 D3D11_SHADER_RESOURCE_VIEW_DESC desc; ZeroMemory(&desc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC)); desc.Format = rtvFormat; desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;//TextureCube형태로 알려준다. desc.TextureCube.MipLevels = 1; Check(D3D::GetDevice()->CreateShaderResourceView(rtvTexture, &desc, &srv)); } DXGI_FORMAT dsvFormat = DXGI_FORMAT_D32_FLOAT; //Create Texture - DSV { D3D11_TEXTURE2D_DESC desc; ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC)); desc.Width = width; desc.Height = height; desc.ArraySize = 6; desc.Format = dsvFormat; desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; desc.MipLevels = 1; desc.SampleDesc.Count = 1; Check(D3D::GetDevice()->CreateTexture2D(&desc, NULL, &dsvTexture)); } //CreateDSV { D3D11_DEPTH_STENCIL_VIEW_DESC desc; ZeroMemory(&desc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC)); desc.Format = dsvFormat; desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; desc.Texture2DArray.ArraySize = 6; Check(D3D::GetDevice()->CreateDepthStencilView(dsvTexture, &desc, &dsv)); } viewport = new Viewport((float)width, (float)height); buffer = new ConstantBuffer(&desc, sizeof(Desc)); sBuffer = shader->AsConstantBuffer("CB_DynamicCube"); } DynamicCubeMap::~DynamicCubeMap() { SafeRelease(rtvTexture); SafeRelease(srv); SafeRelease(rtv); SafeRelease(dsvTexture); SafeRelease(dsv); SafeDelete(viewport); SafeDelete(buffer); } void DynamicCubeMap::PreRender(Vector3 & position, Vector3 & scale, float zNear, float zFar, float fov) { this->position = position; //Create Views { float x = position.x; float y = position.y; float z = position.z; struct LookAt { Vector3 LookAt; Vector3 Up; } lookAt[6]; lookAt[0] = { Vector3(x + scale.x, y, z), Vector3(0, 1, 0) }; lookAt[1] = { Vector3(x - scale.x, y, z), Vector3(0, 1, 0) }; lookAt[2] = { Vector3(x, y + scale.y, z), Vector3(0, 0, -1) }; lookAt[3] = { Vector3(x, y - scale.y, z), Vector3(0, 0, +1) }; lookAt[4] = { Vector3(x, y, z + scale.z), Vector3(0, 1, 0) }; lookAt[5] = { Vector3(x, y, z - scale.z), Vector3(0, 1, 0) }; for (UINT i = 0; i < 6; i++) D3DXMatrixLookAtLH(&desc.Views[i], &position, &lookAt[i].LookAt, &lookAt[i].Up); } perspective = new Perspective(1, 1, zNear, zFar, Math::PI * fov);//절두체를 활용한 perspective 구하기. fov각이 작으면 왜곡이 심해진다. perspective->GetMatrix(&desc.Projection); buffer->Render(); sBuffer->SetConstantBuffer(buffer->Buffer()); D3D::Get()->SetRenderTarget(rtv, dsv); D3D::Get()->Clear(Color(0, 0, 0, 1), rtv, dsv); viewport->RSSetViewport(); }
DynamicCubeMapDemo
DynamicCubeMapDemo.h
더보기
#pragma once #include "Systems/IExecute.h" class DynamicCubeMapDemo : 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; DynamicCubeMap* cubeMap; Billboard* billboard; CubeSky* sky; Material* floor; Material* stone; Material* brick; Material* wall; MeshRender* cube; MeshRender* cylinder; MeshRender* sphere; MeshRender* sphere2; 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; };
DynamicCubeMapDemo.cpp
더보기
#include "stdafx.h" #include "DynamicCubeMapDemo.h" void DynamicCubeMapDemo::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"107_DynamicCubeMap.fxo"); cubeMap = new DynamicCubeMap(shader, 256, 256); sky = new CubeSky(L"Environment/GrassCube1024.dds", shader); Billboards(); Mesh(); Airplane(); Kachujin(); KachujinCollider(); KachujinWeapon(); PointLighting(); SpotLighting(); } void DynamicCubeMapDemo::Update() { Vector3 position; sphere2->GetTransform(0)->Position(&position); if (Keyboard::Get()->Press('L')) position.x += 20 * Time::Delta(); else if (Keyboard::Get()->Press('J')) position.x -= 20 * Time::Delta(); if (Keyboard::Get()->Press('I')) position.z += 20 * Time::Delta(); else if (Keyboard::Get()->Press('K')) position.z -= 20 * Time::Delta(); if (Keyboard::Get()->Press('O')) position.y += 20 * Time::Delta(); else if (Keyboard::Get()->Press('U')) position.y -= 20 * Time::Delta(); sphere2->GetTransform(0)->Position(position); sphere2->UpdateTransforms(); sky->Update(); cube->Update(); grid->Update(); cylinder->Update(); sphere->Update(); sphere2->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(); } void DynamicCubeMapDemo::PreRender() { //Dynamic CubeMap { Vector3 p, s; sphere2->GetTransform(0)->Position(&p); sphere2->GetTransform(0)->Scale(&s); cubeMap->PreRender(p, s); sky->Pass(6); sky->Render(); Pass(7, 8, 9); wall->Render(); sphere->Render(); brick->Render(); cylinder->Render(); stone->Render(); cube->Render(); floor->Render(); grid->Render(); airplane->Render(); kachujin->Render(); weapon->Render(); } } void DynamicCubeMapDemo::Render() { sky->Pass(0); sky->Render(); Pass(1, 2, 3); wall->Render(); sphere->Render(); shader->AsSRV("DynamicCubeMap")->SetResource(cubeMap->SRV()); sphere2->Pass(10); sphere2->Render(); brick->Render(); cylinder->Render(); stone->Render(); cube->Render(); floor->Render(); grid->Render(); airplane->Render(); kachujin->Render(); weapon->Render(); billboard->Render(); } void DynamicCubeMapDemo::PostRender() { } void DynamicCubeMapDemo::Billboards() { billboard = new Billboard(shader); //billboard->Pass(3); billboard->Pass(4); billboard->AddTexture(L"Terrain/grass_14.tga"); billboard->AddTexture(L"Terrain/grass_07.tga"); billboard->AddTexture(L"Terrain/grass_11.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, 0); } for (UINT i = 0; i < 300; 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, 1); } for (UINT i = 0; i < 700; 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, 2); } } void DynamicCubeMapDemo::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); } sphere2 = new MeshRender(shader, new MeshSphere(0.5f, 20, 20)); transform = sphere2->AddTransform(); transform->Position(10, 10, 0); transform->Scale(5, 5, 5); } sphere->UpdateTransforms(); cylinder->UpdateTransforms(); cube->UpdateTransforms(); grid->UpdateTransforms(); sphere2->UpdateTransforms(); meshes.push_back(sphere); meshes.push_back(sphere2); meshes.push_back(cylinder); meshes.push_back(cube); meshes.push_back(grid); } void DynamicCubeMapDemo::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 DynamicCubeMapDemo::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 DynamicCubeMapDemo::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 DynamicCubeMapDemo::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 DynamicCubeMapDemo::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 DynamicCubeMapDemo::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 DynamicCubeMapDemo::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] 113-117 Shadow 그림자, PCF (Percentage Closer Filtering) (0) | 2023.05.17 |
---|---|
[DirectX11] 111-112 Projector (0) | 2023.05.10 |
[DirectX11] 106 Bloom (0) | 2023.05.03 |
[DirectX11] 104-105 Blur, Gaussian Blur (0) | 2023.04.28 |
[DirectX11] 103 MRT(Multiple Render Targets) (0) | 2023.04.27 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 113-117 Shadow 그림자, PCF (Percentage Closer Filtering)
[DirectX11] 113-117 Shadow 그림자, PCF (Percentage Closer Filtering)
2023.05.17그림자 구현방법에는 원형 그림자, 투영 그림자, 그리고 깊이 버퍼 그림자 방식이 있다. 이 중 가장 정교한 묘사가 가능한 깊이 버퍼 그림자(Depth Buffer Shadow)를 구현하여 그림자를 표현하였다. Two Pass Rendering 원리를 이용하여 깊이 버퍼 그림자를 계산하고 이를 활용한다. 목차 그림자 구현하기 그림자 구현방법 원형 그림자: 고전 방식 투영 그림자: 그 다음 등장한 방식. 장면 그대로 렌더링 깊이 버퍼 그림자 (Depth Buffer Shadow): 최근 대부분의 게임에서 사용하는 방식. 깊이 버퍼를 이용하여 그림자를 구현한다. 깊이 버퍼 그림자 (Depth Buffer Shadow) Two Pass Rendering 1 Pass: 깊이(DSV) - 조명의 방향을 가지고 Pr… -
[DirectX11] 111-112 Projector
[DirectX11] 111-112 Projector
2023.05.10투영은 3D 공간에서의 객체를 2D 화면에 어떻게 표현할 것인지를 결정하는 과정이다. 이 과정에서 VS 단계에서 WVP(World, View, Projection) 변환된 결과가 SV_Position을 기준으로 2D 좌표로 레스터라이징되어 화면에 표현된다. 하지만, 이렇게 레스터라이징된 2D 좌표는 쉐이더로부터 바로 리턴받을 수 없기 때문에, CPU를 통해 VS, RS에서 사용된 같은 수식을 통해 2D 변환된 위치를 계산하고, 그 위치에 UI 요소를 배치하기 위해 사용된다. 목차 Projector Shaders Light.fxProjector.fx 생성Framework Objects Projector.h .cpp 생성 Viewer Fixity.h .cpp 생성UnitTest Objects Pro… -
[DirectX11] 106 Bloom
[DirectX11] 106 Bloom
2023.05.03Bloom은 카메라 렌즈에서 빛이 작동하는 방식을 시뮬레이션하기 위해 그래픽 및 게임에서 사용되는 시각 효과다. 밝은 물체 주위에 빛나는 효과를 만든다. 목차 Bloom 다음의 과정을 거쳐 Bloom을 구현한다. 장면을 텍스처로 렌더링: 첫 번째 단계는 장면을 BackBuffer 대신 텍스처로 렌더링하는 것이다. 이를 통해 원래 렌더링된 이미지에 영향을 주지 않고 장면에 후처리 효과를 적용할 수 있다.임계값 적용: 다음으로 텍스처에 임계값을 적용하여 장면에서 밝은 픽셀을 식별한다. 이는 각 픽셀의 색상 값을 임계값과 비교하여 수행된다. 픽셀의 색상 값이 임계값보다 크면 밝은 픽셀로 간주되어 추가 처리된다.밝은 픽셀 추출: 픽셀 셰이더를 사용하여 다른 텍스처로 렌더링하여 장면에서 밝은 픽셀을 추출한… -
[DirectX11] 104-105 Blur, Gaussian Blur
[DirectX11] 104-105 Blur, Gaussian Blur
2023.04.28DirectX 11에서 Blur는 이미지를 초점이 맞지 않거나 흐릿하게 보이게 하는 시각적 효과를 말한다. 이 효과는 종종 그래픽과 게임에서 필드 깊이를 시뮬레이션하거나 이미지의 가장자리를 부드럽게 하는 데 사용된다. Blur 효과를 생성하기 위한 다양한 기법이 있으며, 가장 일반적으로 사용되는 기법 중 하나는 Gaussian Blur다. 목차 Blur Gaussian blur는 가우스 함수로 이미지를 합성하여 작동하는 블러의 일종이다. 이 기능은 각 픽셀에 적용되는 흐림의 양을 결정하는 종 모양의 곡선을 가지고 있다. 픽셀이 주변 영역에 더 많은 픽셀을 가질수록 픽셀은 더 흐려진다. 가우스 블러 효과는 부드럽고 자연스럽게 보이는 흐림을 생성하기 때문에 종종 사용되며, 다양한 수준의 흐림을 달성하기 위해…
댓글을 사용할 수 없습니다.