그림자 구현방법에는 원형 그림자, 투영 그림자, 그리고 깊이 버퍼 그림자 방식이 있다.  이 중 가장 정교한 묘사가 가능한 깊이 버퍼 그림자(Depth Buffer Shadow)를 구현하여 그림자를 표현하였다. Two Pass Rendering 원리를 이용하여 깊이 버퍼 그림자를 계산하고 이를 활용한다. 

 

목차

     

     


     

     

    그림자 구현하기

     

     

    그림자 구현방법

    • 원형 그림자:  고전 방식
    • 투영 그림자:  그 다음 등장한  방식. 장면 그대로 렌더링
    • 깊이 버퍼 그림자 (Depth Buffer Shadow): 최근 대부분의 게임에서 사용하는 방식. 
      • 깊이 버퍼를 이용하여 그림자를 구현한다. 

     

     

    깊이 버퍼 그림자 (Depth Buffer Shadow)

    • Two Pass Rendering
      • 1 Pass: 깊이(DSV) - 조명의 방향을 가지고 Projection 렌더링 진행한다.
        • Light 공간(WVP)
      • 2 Pass: 깊이를 비교해가면서 실제 렌더링을 수행한다. 
        • Main Camera 공간(WVP)
        • Light 공간(WVP)에서 깊이를 비교한다.
          • depth >= z 이면 그림자가 생길 부분이 아니다. 
          • depth < z   이면  그림자가 지어질 영역이다.
      • 여기서 말하는 하나의 패스(Pass)는 IA → VS → RS → PS → OM을 지난다는 것을 의미한다.

     

     

    Shaders
      Render.fx
    Light.fx
    Shadow.fx 생성
    Framework
      Objects
      Shadow.h .cpp 생성
    UnitTest
      Objects
      ShadowDemo.h .cpp 생성

     

     


     

     

    Render.fx

     

    Render.fx

    더보기
    struct DepthOutput
    {
        float4 Position : SV_Position;
        float4 sPosition : Position1;
    };
    
    float4 PS_Depth(DepthOutput input) : SV_Target
    {
        float depth = input.Position.z / input.Position.w;
        
        return float4(depth, depth, depth, 1.0f);
    }
    
    #define VS_DEPTH_GENERATE \
    output.Position = WorldPosition(input.Position); \
    output.Position = mul(output.Position, ShadowView); \
    output.Position = mul(output.Position, ShadowProjection); \
    \
    output.sPosition = output.Position;
    
    
    DepthOutput VS_Depth_Mesh(VertexMesh input)
    {
        DepthOutput output;
        
        SetMeshWorld(World, input);
        VS_DEPTH_GENERATE
        
        return output;
    }
    
    
    DepthOutput VS_Depth_Model(VertexModel input)
    {
        DepthOutput output;
        
        SetModelWorld(World, input);
        VS_DEPTH_GENERATE
        
        return output;
    }
    
    
    DepthOutput VS_Depth_Animation(VertexModel input)
    {
        DepthOutput output;
        
        if (BlendFrames[input.InstanceID].Mode == 0)
            SetTweenWorld(World, input);
        else
            SetBlendWorld(World, input);
        
        VS_DEPTH_GENERATE
        
        return output;
    }

     

     


     

     

     

    Light.fx

     

    Light.fx

    더보기
    cbuffer CB_Shadow
    {
        matrix ShadowView;
        matrix ShadowProjection;
        
        float2 ShadowMapSize;
        float ShadowBias;
        
        uint ShadowQuality;
    };

     

     


     

     

    Shadow.fx

     

    Shadow.fx

    #include "00_Global.fx"
    #include "00_Light.fx"
    #include "00_Render.fx"
    
    float4 PS(MeshOutput input) : SV_Target
    {
        //float4 color = float4(1, 1, 1, 1);
        float4 color = PS_AllLight(input);
        
        float4 position = input.sPosition;
        
        position.xyz /= position.w;
        
        [flatten]
        if (position.x < -1.0f || position.x > +1.0f ||
            position.y < -1.0f || position.y > +1.0f ||
            position.z < +0.0f || position.z > +1.0f)
        {
            return color;
        }
        
        
        position.x = position.x * 0.5f + 0.5f;
        position.y = -position.y * 0.5f + 0.5f;
        
        float depth = 0;
        float z = position.z - ShadowBias;
        float factor = 0;
        
        if(ShadowQuality == 0)
        {
            depth = ShadowMap.Sample(LinearSampler, position.xy).r;
            factor = (float) (depth >= z);
        }
        else if (ShadowQuality == 1) //PCF
        {
            depth = position.z;
            factor = ShadowMap.SampleCmpLevelZero(ShadowSampler, position.xy, depth).r;
        }
        else if (ShadowQuality == 2) //PCF + Blur
        {
            depth = position.z;
            
            float2 size = 1.0f / ShadowMapSize;
            float2 offsets[] =
            {
                float2(-size.x, -size.y), float2(0.0f, -size.y), float2(+size.x, -size.y),
                float2(-size.x, 0.0f), float2(0.0f, 0.0f), float2(+size.x, 0.0f),
                float2(-size.x, +size.y), float2(0.0f, +size.y), float2(+size.x, +size.y),
            };
            
            
            float2 uv = 0;
            float sum = 0;
            
            [unroll(9)]
            for (int i = 0; i < 9; i++)
            {
                uv = position.xy + offsets[i];
                sum += ShadowMap.SampleCmpLevelZero(ShadowSampler, uv, depth).r;
            }
            
            factor = sum / 9.0f;
        }
        
        factor = saturate(factor + depth);
        return color * factor;
    }
    
    technique11 T0
    {
        //1Pass - Depth Rendering
        //P_VP(P0, VS_Depth_Mesh, PS_Depth)
        //P_VP(P1, VS_Depth_Model, PS_Depth)
        //P_VP(P2, VS_Depth_Animation, PS_Depth)
    
        //1Pass - Depth Rendering
        //z-fighting 문제가 발생하지 않도록 뒤집어(P_RS_VP)준다.
        P_RS_VP(P0, FrontCounterClockwise_True, VS_Depth_Mesh, PS_Depth)
        P_RS_VP(P1, FrontCounterClockwise_True, VS_Depth_Model, PS_Depth)
        P_RS_VP(P2, FrontCounterClockwise_True, VS_Depth_Animation, PS_Depth)
    
        P_VP(P3, VS_Mesh, PS)
        P_VP(P4, VS_Model, PS)
        P_VP(P5, VS_Animation, PS)
    }

     

    z-fighting 문제가 발생하지 않도록 뒤집어(P_RS_VP, FrontCounterClockwise)준다.

    • technique11 T0 {
          //1Pass - Depth Rendering
          P_RS_VP(P0, FrontCounterClockwise_True, VS_Depth_Mesh, PS_Depth)
          P_RS_VP(P1, FrontCounterClockwise_True, VS_Depth_Model, PS_Depth)
          P_RS_VP(P2, FrontCounterClockwise_True, VS_Depth_Animation, PS_Depth) }

     

     

    Shadow

     

    Shadow.h

    더보기
    #pragma once
    
    class Shadow
    {
    public:
    	Shadow(Shader* shader, Vector3& position, float radius, UINT width = 1024, UINT height = 1024);
    	~Shadow();
    
    	void PreRender();
    
    	ID3D11ShaderResourceView* SRV() { return renderTarget->SRV(); }
    
    private:
    	void CalcViewProjection();
    
    private:
    	struct Desc
    	{
    		Matrix View;//그림자를 그리기 위한 빛 방향에서의 View Projection
    		Matrix Projection;
    
    		Vector2 MapSize;
    		float Bias = -0.0006f;
    
    		UINT Quality = 0;
    	} desc;
    
    private:
    	Shader* shader;
    	UINT width, height;//그림자 맵의 해상도를 결정한 너비와 높이
    
    	Vector3 position;//조명이 빛을 비출 위치
    	float radius;//조명 구역. 그림자가 들어갈 구역. 
    
    	RenderTarget* renderTarget;
    	DepthStencil* depthStencil;
    	Viewport* viewport;
    
    	ConstantBuffer* buffer;
    	ID3DX11EffectConstantBuffer* sBuffer;//그림자 정보 넘길 변수
    	ID3DX11EffectShaderResourceVariable* sShadowMap;//깊이를 줄 변수
    
    	ID3D11SamplerState* pcfSampler;
    	ID3DX11EffectSamplerVariable* sPcfSampler;
    };

     

     

     

    Shadow.cpp

    더보기
    #include "Framework.h"
    #include "Shadow.h"
    
    Shadow::Shadow(Shader * shader, Vector3 & position, float radius, UINT width, UINT height)
    	: shader(shader), position(position), radius(radius), width(width), height(height)
    {
    	renderTarget = new RenderTarget(width, height);
    	depthStencil = new DepthStencil(width, height);
    	viewport = new Viewport((float)width, (float)height);
    
    	desc.MapSize = Vector2((float)width, (float)height);
    
    	buffer = new ConstantBuffer(&desc, sizeof(Desc));
    	sBuffer = shader->AsConstantBuffer("CB_Shadow");
    	sShadowMap = shader->AsSRV("ShadowMap");
    
    	
    	//Create Sampler State
    	{
    		D3D11_SAMPLER_DESC desc;
    		ZeroMemory(&desc, sizeof(D3D11_SAMPLER_DESC));
    		desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
    		desc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
    		desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
    		desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
    		desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
    		desc.MaxAnisotropy = 1;
    		desc.MaxLOD = FLT_MAX;
    
    		Check(D3D::GetDevice()->CreateSamplerState(&desc, &pcfSampler));
    		sPcfSampler = shader->AsSampler("ShadowSampler");
    	}
    }
    
    Shadow::~Shadow()
    {
    	SafeDelete(renderTarget);
    	SafeDelete(depthStencil);
    	SafeDelete(viewport);
    
    	SafeDelete(buffer);
    }
    
    void Shadow::PreRender()
    {
    	ImGui::InputInt("Quality", (int *)&desc.Quality);
    	desc.Quality %= 3;
    
    	//1Pass
    	ImGui::SliderFloat3("Light Direction", Context::Get()->Direction(), -1, +1);
    	ImGui::SliderFloat("Bias", &desc.Bias, -0.0001f, +0.01f, "%.4f");
    
    	renderTarget->PreRender(depthStencil);
    	viewport->RSSetViewport();
    
    
    	CalcViewProjection();
    
    	buffer->Render();
    	sBuffer->SetConstantBuffer(buffer->Buffer());
    
    	sShadowMap->SetResource(depthStencil->SRV());
    	sPcfSampler->SetSampler(0, pcfSampler);
    }
    
    void Shadow::CalcViewProjection()
    {
    	Vector3 up = Vector3(0, 1, 0);
    	Vector3 direction = Context::Get()->Direction();//주 빛의 방향(=조명 방향)
    	Vector3 position = direction * radius * -2.0f;//
    
    	D3DXMatrixLookAtLH(&desc.View, &position, &this->position, &up);
    
    	
    	Vector3 origin;
    	D3DXVec3TransformCoord(&origin, &this->position, &desc.View);//원점을 View공간 만큼 움직인다.
    
    	
    	float l = origin.x - radius;
    	float b = origin.y - radius;
    	float n = origin.z - radius;
    
    	float r = origin.x + radius;
    	float t = origin.y + radius;
    	float f = origin.z + radius;
    
    	D3DXMatrixOrthoLH(&desc.Projection, r - l, t - b, n, f);
    }

     

     


     

     

    ShadowDemo

     

    ShadowDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class ShadowDemo : 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 Mesh();
    	void Airplane();
    	void Kachujin();
    	void KachujinCollider();
    	void KachujinWeapon();
    	void PointLighting();
    	void SpotLighting();
    
    	void Pass(UINT mesh, UINT model, UINT anim);
    
    private:
    	Shader* shader;
    
    	Shadow* shadow;
    	Render2D* render2D;
    
    	CubeSky* sky;
    
    	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;
    };

     

     

     

    ShadowDemo.cpp

    더보기
    #include "stdafx.h"
    #include "ShadowDemo.h"
    
    void ShadowDemo::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"113_Shadow.fxo");
    
    	UINT size = 1024;// * 8; * 16;
    	shadow = new Shadow(shader, Vector3(0, 0, 0), 65, size, size);
    
    	render2D = new Render2D();
    	//render2D->GetTransform()->Position(D3D::Width() * 0.5f, D3D::Height() * 0.5f, 0);
    	//render2D->GetTransform()->Scale(D3D::Width(), D3D::Height(), 1);
    	render2D->GetTransform()->Position(150, D3D::Height() - 150, 0);
    	render2D->GetTransform()->Scale(300, 300, 1);
    	render2D->SRV(shadow->SRV());
    
    	
    
    	sky = new CubeSky(L"Environment/GrassCube1024.dds");
    	
    	Mesh();
    	Airplane();
    	
    	Kachujin();
    	KachujinCollider();
    	KachujinWeapon();
    
    	PointLighting();
    	SpotLighting();
    }
    
    void ShadowDemo::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();
    
    	render2D->Update();
    }
    
    void ShadowDemo::PreRender()
    {
    	shadow->PreRender();
    
    	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();
    }
    
    void ShadowDemo::Render()
    {
    	sky->Pass(0);
    	sky->Render();
    
    	Pass(3, 4, 5);
    
    	wall->Render();
    	sphere->Render();
    
    	brick->Render();
    	cylinder->Render();
    
    	stone->Render();
    	cube->Render();
    
    	floor->Render();
    	grid->Render();
    
    	airplane->Render();
    
    	kachujin->Render();
    	weapon->Render();
    }
    
    void ShadowDemo::PostRender()
    {
    	render2D->Render();
    }
    
    void ShadowDemo::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 ShadowDemo::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 ShadowDemo::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 ShadowDemo::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 ShadowDemo::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 ShadowDemo::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 ShadowDemo::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 ShadowDemo::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] 111-112 Projector  (0) 2023.05.10
    [DirectX11] 107-110 Dynamic Cube Map  (0) 2023.05.05
    [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