본문 바로가기

DirectX11 3D/기본 문법

<DirectX11 3D> 30. SkySphere

 

 

 

 

 

 

TextureCube 좌표(이미지 출처 : MSDN)
TextureCube 좌표 (이미지 출처 : MSDN)

 

 

 

 

 

 

필요한 개념


- TextureCube : 한 텍스쳐로 여러 방향을 저장해 놓은 것이다.(박스 펼친모양)

 

- MS에서는 DxTex라는 프로그램을 제공한다.(큐브맵 텍스쳐를 .dds 확장자로 생성할 수 있다.)

 

- oPosition : 박스에 어느부분을 닿을때 픽셀을 렌더링한다.

 

- SkyCube Position이 카메라 Position에 따라다님(-> 카메라 위치에 따라 일정한 배경을 볼 수 있다.)

 

- SkyCube 안에 카메라가 있다면 SkyCube가 반시계 방향으로 정점이 렌더링되어야 볼 수 있다.(RasterizerState의 FrontCounterClockWise 활용)

 

- 그러나 문제 발생 !!? 정상적으로 SkyCube가 그려지나, 내부 Mesh들이 안그려진다?(다른 물체에 의해 가려졌다.)

그래서 DepthStencilState에서 DepthEnable을 false로 준다.(그러면 Render() 함수내의 순서대로 객체들이 렌더링 된다.)

 

 

 

 

 

 

.h


더보기
#pragma once

class CubeSky
{
public:
	CubeSky(wstring file); 
	~CubeSky();

	void Update();
	void Render();

private:
	Shader* shader;
	MeshSphere* sphere;

	ID3D11ShaderResourceView* srv;
	ID3DX11EffectShaderResourceVariable* sSrv;
};

 

 

 

 

 

 

 

.Cpp


더보기
#include "Framework.h"
#include "CubeSky.h"

CubeSky::CubeSky(wstring file)
{
	shader = new Shader(L"29_CubeSky.fx");

	sphere = new MeshSphere(shader, 0.5f);

	file = L"../../_Textures/" + file;
	Check(D3DX11CreateShaderResourceViewFromFile
	(
		D3D::GetDevice(), file.c_str(), nullptr, nullptr, &srv,
		nullptr
	));

	sSrv = shader->AsSRV("SkyCubeMap");
}

CubeSky::~CubeSky()
{
	SafeDelete(shader);
	SafeDelete(sphere);

	SafeRelease(srv);
}

void CubeSky::Update()
{
	// 카메라의 포지션으로 구의 중심점을 설정
	Vector3 position;
	Context::Get()->GetCamera()->Position(&position);

	sphere->Position(position);
}

void CubeSky::Render()
{
	sSrv->SetResource(srv);
	sphere->Render();
}

 

 

 

 

 

 

 

 

.fx


더보기

 

matrix World;
matrix View;
matrix Projection;

TextureCube SkyCubeMap;

struct VertexInput
{
    float4 Position : Position;
    float2 Uv : Uv;
    float3 Normal : Normal;
};

struct VertexOutput
{
    // SV_Position -> position0번으로 취급됨
    float4 Position : SV_Position;
    // 그래서 1번
    // 원점좌표(원래 가지고 있던)
    float3 oPosition : Position1;
    float2 Uv : Uv;
    float3 Normal : Normal;
};

VertexOutput VS(VertexInput input)
{
    VertexOutput output;
    output.oPosition = input.Position.xyz;
    output.Position = mul(input.Position, World);
    output.Position = mul(output.Position, View);
    output.Position = mul(output.Position, Projection);
    
    output.Normal = mul(input.Normal, (float3x3) World);
    output.Uv = input.Uv;
    
    return output;
}

SamplerState LinearSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

RasterizerState FrontCounterClockWise_True
{
    FrontCounterClockWise = True;
};

DepthStencilState DepthEnable_False
{
    DepthEnable = false;
};

float4 PS(VertexOutput input) : SV_Target
{
    // 위치벡터를 방향벡터로 쓴다.
    // 즉(-0.5, 0,0, 0,0)이라면 -x 큐브 텍스쳐 해당 부분에 픽셀이 발라진다.
    // (why? 큐브 텍스쳐 니까, 어느부분에 어느 픽셀이 발라질지를 정해야함)
    // 그래서 original position을 받아온다.(이유는 월드 전에 local 포지션을 받아서 처리해야 해서)
    return CubeMap.Sample(LinearSampler, input.oPosition);
    // 기존 Texture2D 인자는 float2(uv 비율인데)
    // TextureCube(큐브맵)은 두번째 인자가 flaot3이다.
}

technique11 T0
{
    pass P0
    {
        SetRasterizerState(FrontCounterClockWise_True);
        // DepthStencilState 사용
        SetDepthStencilState(DepthEnable_False, 0);

        SetVertexShader(CompileShader(vs_5_0, VS()));
        SetPixelShader(CompileShader(ps_5_0, PS()));
    }
}

 

 

 

 

 

 

 

 

 

 

 

결과