큐브맵은 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);
    }

     

     


     

     

    실행화면