DirectX11에서 Post Effect를 적용하여 장면을 새로운 텍스처로 렌더링하고, 새로운 셰이더 세트를 사용하여 효과를 적용한다. Post Effect는 Diffuse, Inverse, Greyscale, Saturation, Sharpness, Sephia, Lens Distortion, Interace, Blur, Vignette, Wiggle 등 적용하려는 효과에 따라 달라질 수 있다.

 

목차

     

     


     

     

     

     

    Color Tone

     

    DirectX

    • IA → VS → GS →SO   RS → PS → OM (RTV를 구하여 Texture에 사용)
    • IA → VS → GS →SO   RS → PS (Post Effect 적용) OM

     

     

    Shaders
       ColorTone.fx 생성
    Framework
      Viewer
      DepthStencil.h .cpp 생성
    RenderTarget.h .cpp 생성
      Object
      PostEffect .cpp 생성
    UnitTest
      PostEffects
      ColorToneDemo.h .cpp 생성
       

     

     

     


     

     

    ColorTone.fx

     

    ColorTone.fx

    더보기
    #include "00_Global.fx"
    #include "00_Light.fx"
    
    float2 PixelSize;
    
    struct VertexOutput
    {
        float4 Position : SV_Position;
        float2 Uv : Uv;
    };
    
    VertexOutput VS(float4 Position : Position)
    {
        VertexOutput output;
        
        output.Position = Position;
        output.Uv.x = Position.x * 0.5f + 0.5f;
        output.Uv.y = -Position.y * 0.5f + 0.5f;
        
        return output;
    }
    
    float4 PS_Diffuse(VertexOutput input) : SV_Target
    {
        return DiffuseMap.Sample(LinearSampler, input.Uv);
    }
    
    //색상 반전
    float4 PS_Inverse(VertexOutput input) : SV_Target
    {
        return float4(1.0f - DiffuseMap.Sample(LinearSampler, input.Uv).rgb, 1.0f);
    }
    
    //이론상 흑백 효과
    float4 PS_Grayscale(VertexOutput input) : SV_Target
    {
        float4 color = float4(DiffuseMap.Sample(LinearSampler, input.Uv));
        float average = (color.r + color.g + color.b) / 3.0f;
        
        return float4(average, average, average, 1.0f);
    }
    
    //실제 주로 쓰이는 흑백 효과
    float4 PS_Grayscale2(VertexOutput input) : SV_Target
    {
        float4 color = float4(DiffuseMap.Sample(LinearSampler, input.Uv));
        float3 grayscale = float3(0.2627f, 0.6780f, 0.0593f); //사람들이 느끼는 흑백
        
        float average = dot(color.rgb, grayscale);
        
        return float4(average, average, average, 1.0f);
    }
    
    
    float Saturation = 0;
    //Saturation = 0 : grayscale
    //0 < Saturation < 1 : desaturation
    //Saturation = 1 : original
    //Saturation > 1 : satuaration
    
    float4 PS_Saturation(VertexOutput input) : SV_Target
    {
        float4 color = float4(DiffuseMap.Sample(LinearSampler, input.Uv));
        float3 grayscale = float3(0.2627f, 0.6780f, 0.0593f);
        
        float temp = dot(color.rgb, grayscale);
        
        color.rgb = lerp(temp, color.rgb, Saturation);
        color.a = 1.0f;
        
        return color;
    }
    
    //외곽선 효과
    float Sharpness = 0;
    float4 PS_Sharpness(VertexOutput input) : SV_Target
    {
        float4 center = DiffuseMap.Sample(LinearSampler, input.Uv);//PixelShader가 처리하고 있는 현재 픽셀
        float4 top = DiffuseMap.Sample(LinearSampler, input.Uv + float2(0, -PixelSize.y));//-PixelSize.y는 바로 위 픽셀
        float4 bottom = DiffuseMap.Sample(LinearSampler, input.Uv + float2(0, +PixelSize.y));//-PixelSize.y는 바로 아래 픽셀
        float4 left = DiffuseMap.Sample(LinearSampler, input.Uv + float2(-PixelSize.x, 0));//-PixelSize.y는 바로 왼쪽 픽셀
        float4 right = DiffuseMap.Sample(LinearSampler, input.Uv + float2(+PixelSize.x, 0)); //-PixelSize.y는 바로 오른쪽 픽셀
        
        float edge = center * 4 - top - bottom - left - right;
        
        return (center + Sharpness) * edge;
    }
    
    
    float4x4 ColorToSepiaMatrix = float4x4
    (
        0.393, 0.769, 0.189, 0,
        0.349, 0.686, 0.168, 0,
        0.272, 0.534, 0.131, 0,
        0, 0, 0, 1
    );
    
    float4 PS_Sepia(VertexOutput input) : SV_Target
    {
        float4 color = DiffuseMap.Sample(LinearSampler, input.Uv);
        
        return mul(ColorToSepiaMatrix, color);
    }
    
    
    float Power = 2; //1 - Linear, 1 > Non-Linear
    float2 Scale = float2(2, 2);
    
    float4 PS_Vignette(VertexOutput input) : SV_Target
    {
        float4 color = DiffuseMap.Sample(LinearSampler, input.Uv);
        
        float radius = length((input.Uv - 0.5f) * 2 / Scale);
        float vignette = pow(abs(radius + 0.0001f), Power);
        
        return saturate(1 - vignette) * color;
    }
    
    
    float LensPower = 1;
    float3 Distortion = -0.02f;
    
    float4 PS_LensDistortion(VertexOutput input) : SV_Target
    {
        float2 uv = input.Uv * 2 - 1;
        
        float2 vpSize = float2(1.0f / PixelSize.x, 1.0f / PixelSize.y);
        float aspect = vpSize.x / vpSize.y;
        float radiusSquared = aspect * aspect + uv.x * uv.x + uv.y * uv.y;
        float radius = sqrt(radiusSquared);
    
        float3 f = Distortion * pow(abs(radius + 1e-6f), LensPower) + 1;
        
        float2 r = (f.r * uv + 1) * 0.5f;
        float2 g = (f.g * uv + 1) * 0.5f;
        float2 b = (f.b * uv + 1) * 0.5f;
        
        float4 color = 0;
        color.r = DiffuseMap.Sample(LinearSampler, r).r;
        color.ga = DiffuseMap.Sample(LinearSampler, g).ga;
        color.b = DiffuseMap.Sample(LinearSampler, b).b;
        
        return color;
    }
    
    float Strength = 1.0f;
    int interaceValue = 2;
    
    float4 PS_Interace(VertexOutput input) : SV_Target
    {
        float4 color = DiffuseMap.Sample(LinearSampler, input.Uv);
        float height = 1.0f / PixelSize.y;
        
        int value = (int) ((floor(input.Uv.y * height) % interaceValue) / (interaceValue / 2));
        
        [flatten]
        if (value)
        {
            float3 grayScale = float3(0.2126f, 0.7152f, 0.0722f);
            float luminance = dot(color.rgb, grayScale);
            
            luminance = min(0.999f, luminance);
            
            color.rgb = lerp(color.rgb, color.rgb * luminance, Strength);
        }
        return color;
    }
    
    float2 ScaleSourceSize;
    float4 PS_Blur(VertexOutput input) : SV_Target
    {
        float2 size = 1.0f / ScaleSourceSize;
        
        float4 s0 = DiffuseMap.Sample(LinearSampler, input.Uv + float2(-size.x, -size.y));
        float4 s1 = DiffuseMap.Sample(LinearSampler, input.Uv + float2(+size.x, -size.y));
        float4 s2 = DiffuseMap.Sample(LinearSampler, input.Uv + float2(-size.x, +size.y));
        float4 s3 = DiffuseMap.Sample(LinearSampler, input.Uv + float2(+size.x, +size.y));
        
        return (s0 + s1 + s2 + s3) / 4;
    }
    
    float2 WiggleOffset = float2(10, 10);
    float2 WiggleAmount = float2(0.01f, 0.01f);
    float4 PS_Wiggle(VertexOutput input) : SV_Target
    {
        float2 uv = input.Uv;
        uv.x += sin(Time + uv.x * WiggleOffset.x) * WiggleAmount.x;
        uv.y += cos(Time + uv.y * WiggleOffset.y) * WiggleAmount.y;
        
        return DiffuseMap.Sample(LinearSampler, uv);
    }
    
    technique11 T0
    {
        P_VP(P0, VS, PS_Diffuse)
        P_VP(P1, VS, PS_Inverse)
        P_VP(P2, VS, PS_Grayscale)
        P_VP(P3, VS, PS_Grayscale2)
        P_VP(P4, VS, PS_Saturation)
        P_VP(P5, VS, PS_Sharpness)
        P_VP(P6, VS, PS_Sepia)
        P_VP(P7, VS, PS_Vignette)
        P_VP(P8, VS, PS_LensDistortion)
        P_VP(P9, VS, PS_Interace)
        P_VP(P10, VS, PS_Blur)
        P_VP(P11, VS, PS_Wiggle)
    }

     

    Post Effect 효과 넣기

    • 0: Diffuse
    • 1: Inverse 색상 반전
    • 2: Greyscale 흑백 효과
    • 3: Greyscale 2 실제 많이 쓰이는 흑백 효과
    • 4: Saturation
    • 5: Sharpness 외곽선 효과
    • 6: Sephia
    • 7: Vignetting
    • 8: LensDistortion 렌즈 왜곡 효과
    • 9: Interace
    • 10: Blur
    • 11: Wiggle

     


     

     

    RenderTarget

     

    RenderTarget.h

    더보기
    #pragma once
    
    class RenderTarget
    {
    public:
    	RenderTarget(UINT width = 0, UINT height = 0, DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM);
    	~RenderTarget();
    
    	ID3D11RenderTargetView* RTV() { return rtv; }
    	ID3D11ShaderResourceView* SRV() { return srv; }
    
    	void SaveTexture(wstring file);
    
    	void PreRender(class DepthStencil* depthStencil);
    
    private:
    	UINT width, height;
    	DXGI_FORMAT format;
    
    	ID3D11Texture2D* texture;
    	ID3D11RenderTargetView* rtv;
    	ID3D11ShaderResourceView* srv;
    };

     

     

     

    RenderTarget.cpp

    더보기
    #include "Framework.h"
    #include "RenderTarget.h"
    
    RenderTarget::RenderTarget(UINT width, UINT height, DXGI_FORMAT format)
    	: format(format)
    {
    	this->width = (width < 1) ? (UINT)D3D::Width() : width;
    	this->height = (height < 1) ? (UINT)D3D::Height() : height;
    
    
    	D3D11_TEXTURE2D_DESC textureDesc;
    	ZeroMemory(&textureDesc, sizeof(D3D11_TEXTURE2D_DESC));
    	textureDesc.Width = this->width;
    	textureDesc.Height = this->height;
    	textureDesc.ArraySize = 1;
    	textureDesc.Format = format;
    	textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
    	textureDesc.MipLevels = 1;
    	textureDesc.SampleDesc.Count = 1;
    	Check(D3D::GetDevice()->CreateTexture2D(&textureDesc, NULL, &texture));
    
    	D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
    	ZeroMemory(&rtvDesc, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
    	rtvDesc.Format = format;
    	rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
    	Check(D3D::GetDevice()->CreateRenderTargetView(texture, &rtvDesc, &rtv));
    
    	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    	ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
    	srvDesc.Format = format;
    	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    	srvDesc.Texture2D.MipLevels = 1;
    	Check(D3D::GetDevice()->CreateShaderResourceView(texture, &srvDesc, &srv));
    
    }
    
    RenderTarget::~RenderTarget()
    {
    	SafeRelease(texture);
    	SafeRelease(rtv);
    	SafeRelease(srv);
    }
    
    void RenderTarget::SaveTexture(wstring file)
    {
    	Check(D3DX11SaveTextureToFile(D3D::GetDC(), texture, D3DX11_IFF_PNG, file.c_str()));
    }
    
    void RenderTarget::PreRender(DepthStencil * depthStencil)
    {
    	D3D::GetDC()->OMSetRenderTargets(1, &rtv, depthStencil->DSV());
    	D3D::Get()->Clear(Color(0, 0, 0, 1), rtv, depthStencil->DSV());
    }

     

     

     


     

     

    DepthStiencil

     

    DepthStiencil.h

    더보기
    #pragma once
    
    class DepthStencil
    {
    public:
    	DepthStencil(UINT width = 0, UINT height = 0, bool bUseStencil = false);
    	~DepthStencil();
    
    	ID3D11ShaderResourceView* SRV() { return srv; }
    	void SaveTexture(wstring saveFile);
    
    	ID3D11DepthStencilView* DSV() { return dsv; }
    
    private:
    	bool bUseStencil;
    	UINT width, height;
    
    	ID3D11Texture2D* texture;
    	ID3D11DepthStencilView* dsv;
    	ID3D11ShaderResourceView* srv;
    };

     

     

     

    DepthStiencil.cpp

    더보기
    #include "Framework.h"
    #include "DepthStencil.h"
    
    DepthStencil::DepthStencil(UINT width, UINT height, bool bUseStencil)
    {
    	this->width = (width < 1) ? (UINT)D3D::Width() : width;
    	this->height = (height < 1) ? (UINT)D3D::Height() : height;
    
    	//Create Texture
    	{
    		D3D11_TEXTURE2D_DESC desc;
    		ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
    		desc.Width = this->width;
    		desc.Height = this->height;
    		desc.MipLevels = 1;
    		desc.ArraySize = 1;
    		desc.Format = bUseStencil ? DXGI_FORMAT_R24G8_TYPELESS : DXGI_FORMAT_R32_TYPELESS;
    		desc.SampleDesc.Count = 1;
    		desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
    		Check(D3D::GetDevice()->CreateTexture2D(&desc, NULL, &texture));
    	}
    
    	//Create DSV
    	{
    		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
    		ZeroMemory(&desc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));
    		desc.Format = bUseStencil ? DXGI_FORMAT_D24_UNORM_S8_UINT : DXGI_FORMAT_D32_FLOAT;
    		desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    		Check(D3D::GetDevice()->CreateDepthStencilView(texture, &desc, &dsv));
    	}
    
    	//Create SRV
    	{
    		D3D11_SHADER_RESOURCE_VIEW_DESC desc;
    		ZeroMemory(&desc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
    		desc.Format = bUseStencil ? DXGI_FORMAT_R24_UNORM_X8_TYPELESS : DXGI_FORMAT_R32_FLOAT;
    		desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    		desc.Texture2D.MipLevels = 1;
    		Check(D3D::GetDevice()->CreateShaderResourceView(texture, &desc, &srv));
    	}
    }
    
    DepthStencil::~DepthStencil()
    {
    	SafeRelease(texture);
    	SafeRelease(dsv);
    	SafeRelease(srv);
    }
    
    void DepthStencil::SaveTexture(wstring saveFile)
    {
    	Check(D3DX11SaveTextureToFile
    	(
    		D3D::GetDC(), texture, D3DX11_IFF_PNG, saveFile.c_str()
    	));
    }

     

     

     


     

     

    PostEffect

     

    PostEffect.h

    더보기
    #pragma once
    
    class PostEffect : public Renderer
    {
    public:
    	PostEffect(wstring shaderFile);
    	~PostEffect();
    
    	void Update();
    	void Render();
    
    	void SRV(ID3D11ShaderResourceView* srv);
    
    private:
    	//struct Desc
    	//{
    	//	Matrix View;
    	//	Matrix Projection;
    	//} desc;
    
    private:
    	//ConstantBuffer* buffer;
    	ID3DX11EffectShaderResourceVariable* sDiffuseMap;
    };

     

     

     

    PostEffect.cpp

    더보기
    #include "Framework.h"
    #include "PostEffect.h"
    
    PostEffect::PostEffect(wstring shaderFile)
    	: Renderer(shaderFile)
    {
    	//buffer = new ConstantBuffer(&desc, sizeof(Desc));
    	//shader->AsConstantBuffer("CB_PostEffect")->SetConstantBuffer(buffer->Buffer());
    
    	Vertex vertices[6];
    	vertices[0].Position = Vector3(-1.0f, -1.0f, 0.0f);
    	vertices[1].Position = Vector3(-1.0f, +1.0f, 0.0f);
    	vertices[2].Position = Vector3(+1.0f, -1.0f, 0.0f);
    	vertices[3].Position = Vector3(+1.0f, -1.0f, 0.0f);
    	vertices[4].Position = Vector3(-1.0f, +1.0f, 0.0f);
    	vertices[5].Position = Vector3(+1.0f, +1.0f, 0.0f);
    
    	vertexBuffer = new VertexBuffer(vertices, 6, sizeof(Vertex));
    	sDiffuseMap = shader->AsSRV("DiffuseMap");
    
    	transform->Scale(D3D::Width(), D3D::Height(), 1);
    	transform->Position(D3D::Width() * 0.5f, D3D::Height() * 0.5f, 0);
    }
    
    PostEffect::~PostEffect()
    {
    	
    }
    
    void PostEffect::Update()
    {
    	Super::Update();
    }
    
    void PostEffect::Render()
    {
    	Super::Render();
    
    	//buffer->Render();
    	shader->Draw(0, Pass(), 6);
    }
    
    void PostEffect::SRV(ID3D11ShaderResourceView * srv)
    {
    	sDiffuseMap->SetResource(srv);
    }

     

     


     

    ColorToneDemo

     

    ColorToneDemo.h

    더보기
    #pragma once
    #include "Systems/IExecute.h"
    
    class ColorToneDemo : 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;
    
    	RenderTarget* renderTarget;
    	DepthStencil* depthStencil;
    	Viewport* viewport;
    	Render2D* render2D;
    	PostEffect* postEffect;
    
    	Billboard* billboard;
    
    	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;
    };

     

     

     

    ColorToneDemo.cpp

    더보기
    #include "stdafx.h"
    #include "ColorToneDemo.h"
    
    void ColorToneDemo::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"96_Billboard.fxo");
    
    
    	float width = D3D::Width(), height = D3D::Height();
    	width = height = 4096;
    
    	renderTarget = new RenderTarget((UINT)width, (UINT)height);
    	depthStencil = new DepthStencil((UINT)width, (UINT)height);
    	viewport = new Viewport(width, height);
    
    	
    	render2D = new Render2D();
    	render2D->GetTransform()->Scale(355, 200, 1);
    	render2D->GetTransform()->Position(200, 120, 0);
    	render2D->SRV(renderTarget->SRV());
    
    	postEffect = new PostEffect(L"100_ColorTone.fxo");
    	postEffect->SRV(renderTarget->SRV());
    
    
    	sky = new CubeSky(L"Environment/GrassCube1024.dds");
    	
    	Billboards();
    
    	Mesh();
    	Airplane();
    	
    	Kachujin();
    	KachujinCollider();
    	KachujinWeapon();
    
    	PointLighting();
    	SpotLighting();
    }
    
    void ColorToneDemo::Update()
    {
    	static UINT Pass = postEffect->GetShader()->PassCount() - 1;
    	ImGui::InputInt("ColorTone Pass", (int *)&Pass);
    	Pass %= postEffect->GetShader()->PassCount();
    	postEffect->Pass(Pass);
    
    
    	Vector2 PixelSize = Vector2(1.0f / D3D::Width(), 1.0f / D3D::Height());
    	postEffect->GetShader()->AsVector("PixelSize")->SetFloatVector(PixelSize);
    
    
    	//Saturation
    	{
    		ImGui::Separator();
    
    		static float Saturation = 0.0f;
    		ImGui::InputFloat("Saturation", &Saturation, 0.1f);
    		postEffect->GetShader()->AsScalar("Saturation")->SetFloat(Saturation);
    	}
    
    	//Sharpness
    	{
    		ImGui::Separator();
    
    		static float Sharpness = 0.0f;
    		ImGui::InputFloat("Sharpness", &Sharpness, 0.1f);
    		postEffect->GetShader()->AsScalar("Sharpness")->SetFloat(Sharpness);
    	}
    
    	//Vignette
    	{
    		ImGui::Separator();
    
    		static float Power = 1.0f;
    		ImGui::InputFloat("Power", &Power, 0.1f);
    		postEffect->GetShader()->AsScalar("Power")->SetFloat(Power);
    
    		static float ScaleX = 1.0f;
    		ImGui::InputFloat("ScaleX", &ScaleX, 0.1f);
    
    		static float ScaleY = 1.0f;
    		ImGui::InputFloat("ScaleY", &ScaleY, 0.1f);
    		postEffect->GetShader()->AsVector("Scale")->SetFloatVector(Vector2(ScaleX, ScaleY));
    	}
    
    	//LensDistortion
    	{
    		ImGui::Separator();
    
    		static float LensPower = 1.0f;
    		ImGui::InputFloat("LensPower", &LensPower, 0.01f);
    		postEffect->GetShader()->AsScalar("LensPower")->SetFloat(LensPower);
    
    		static Vector3 Distortion = Vector3(-0.02f, -0.02f, -0.02f);
    		ImGui::InputFloat("DistortionX", &Distortion.x, 0.001f);
    		ImGui::InputFloat("DistortionY", &Distortion.y, 0.001f);
    		ImGui::InputFloat("DistortionZ", &Distortion.z, 0.001f);
    		postEffect->GetShader()->AsVector("Distortion")->SetFloatVector(Distortion);
    	}
    
    	//Interace
    	{
    		ImGui::Separator();
    
    		static float Strength = 1.0f;
    		ImGui::InputFloat("Strength", &Strength, 0.01f);
    		postEffect->GetShader()->AsScalar("Strength")->SetFloat(Strength);
    
    		static int InteraceValue = 2;
    		ImGui::InputInt("InteraceValue", &InteraceValue);
    		postEffect->GetShader()->AsScalar("interaceValue")->SetInt(InteraceValue);
    	}
    
    	//Down Scale
    	{
    		ImGui::Separator();
    
    		static float ScaleX = D3D::Width();
    		ImGui::InputFloat("DownScaleX", &ScaleX, 1.0f);
    
    		static float ScaleY = D3D::Height();
    		ImGui::InputFloat("DownScaleY", &ScaleY, 1.0f);
    		postEffect->GetShader()->AsVector("ScaleSourceSize")->SetFloatVector(Vector2(ScaleX, ScaleY));
    	}
    
    	//Wiggle
    	{
    		ImGui::Separator();
    
    		static float OffsetX = 10;
    		ImGui::InputFloat("OffsetX", &OffsetX, 0.1f);
    
    		static float OffsetY = 10;
    		ImGui::InputFloat("OffsetY", &OffsetY, 0.1f);
    		postEffect->GetShader()->AsVector("WiggleOffset")->SetFloatVector(Vector2(OffsetX, OffsetY));
    
    		static float AmountX = 0.01f;
    		ImGui::InputFloat("AmountX", &AmountX, 0.001f);
    
    		static float AmountY = 0.01f;
    		ImGui::InputFloat("AmountY", &AmountY, 0.001f);
    		postEffect->GetShader()->AsVector("WiggleAmount")->SetFloatVector(Vector2(AmountX, AmountY));
    	}
    
    
    	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();
    
    	render2D->Update();
    	postEffect->Update();
    }
    
    void ColorToneDemo::PreRender()
    {
    	renderTarget->PreRender(depthStencil);
    	viewport->RSSetViewport();
    
    
    	//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();
    	}
    }
    
    void ColorToneDemo::Render()
    {
    	
    }
    
    void ColorToneDemo::PostRender()
    {
    	postEffect->Render();
    
    	render2D->Render();
    }
    
    void ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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 ColorToneDemo::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);
    }

     

     

     


     

     

    실행화면