Skybox

ㅋㅋ·2022년 7월 25일
0

DirectX12강의

목록 보기
25/39

플레이어를 둘러싸는 큐브 또는 구를 만들고 물체 표면에 하늘 텍스쳐를 입힘

=>

밖에서는 어디든 하늘을 볼 수 있음


  1. skybox에 의해 skybox 뒤에 있는 다른 물체들이 안보일 수 있음

  2. 카메라가 이동해도 항상 멀어보이도록 해야 함

1 => view space에서 항상 depth가 1이 되도록 함

2 =>

카메라가 view space에서 원점이기 때문에 skybox 또한 원점에 두고 움직이지 않도록 함

카메라의 방향에 따라 하늘의 각도가 바뀌긴 해야함

SRT에서 S와 T 사용하지 않음 => (x,y,z,0)


skybox로 큐브를 사용 시 보통 텍스쳐 타입을 바꿔주어야 함

void Texture::CreateView()
{
	...

	D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
	srvDesc.Format = _image.GetMetadata().format;
	srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
	
    ...
}

D3D12_SRV_DIMENSION_TEXTURE2D 타입이 아닌 D3D12_SRV_DIMENSION_TEXTURECUBE 사용


void Shader::Init(const wstring& path)
{
	...

	_pipelineDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
	_pipelineDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
	_pipelineDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
	
    ...
}

skybox를 만들기 위해 RasterizerState와 DepthStencilState 수정 필요

explicit CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT)
    {
        FillMode = D3D12_FILL_MODE_SOLID;
        CullMode = D3D12_CULL_MODE_BACK;
        FrontCounterClockwise = FALSE;
        DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
        DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
        SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
        DepthClipEnable = TRUE;
        MultisampleEnable = FALSE;
        AntialiasedLineEnable = FALSE;
        ForcedSampleCount = 0;
        ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
    }
    
typedef 
enum D3D12_CULL_MODE
    {
        D3D12_CULL_MODE_NONE	= 1,
        D3D12_CULL_MODE_FRONT	= 2,
        D3D12_CULL_MODE_BACK	= 3
    } 	D3D12_CULL_MODE;

RasterizerState의 cull mode

cull mode => 스킵 모드

default는 back으로 메시의 뒷부분은 스킵한다는 뜻

FrontCounterClockwise는 메시의 정점 순서가 반시계 방향이냐 시계 방향이냐를 의미

카메라는 skybox 안에 존재하기 때문에 skybox 내부를 텍스쳐로 감싸야 함


shaer 클래스 수정

enum class RASTERIZER_TYPE
{
	CULL_NONE,
	CULL_FRONT,
	CULL_BACK,
	WIREFRAME,
};

enum class DEPTH_STENCIL_TYPE
{
	LESS,
	LESS_EQUAL,
	GREATER,
	GREATER_EQUAL,
};

struct ShaderInfo
{
	RASTERIZER_TYPE rasterizerType = RASTERIZER_TYPE::CULL_BACK;
	DEPTH_STENCIL_TYPE depthStencilType = DEPTH_STENCIL_TYPE::LESS;
};

기존 Depth Stencil Buffer를 구현할 때 버퍼의 초기 값을 1로 하도록 함

skybox의 depth가 1일 때 1은 1보다 작지 않아 그려지지 않기 때문에

1보다 더 작거나 같은 물체를 그리도록 해야함

=> 연산 방법을 less equal로 수정


void Shader::Init(const wstring& path, ShaderInfo info)
{
	...

	switch (info.rasterizerType)
	{
	case RASTERIZER_TYPE::CULL_BACK:
		_pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
		_pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
		break;
	case RASTERIZER_TYPE::CULL_FRONT:
		_pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
		_pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_FRONT;
		break;
        
		...
	}

	switch (info.depthStencilType)
	{
	case DEPTH_STENCIL_TYPE::LESS:
		_pipelineDesc.DepthStencilState.DepthEnable = TRUE;
		_pipelineDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
		break;
	case DEPTH_STENCIL_TYPE::LESS_EQUAL:
		_pipelineDesc.DepthStencilState.DepthEnable = TRUE;
		_pipelineDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
		break;
		
        ...
	}

	...
}

ShaderInfo에 따라 RasterizerState와 DepthStencilState를 덮어쓰도록 함


VS_OUT VS_Main(VS_IN input)
{
    ...

    float4 viewPos = mul(float4(input.localPos, 0), g_matView);
    float4 clipSpacePos = mul(viewPos, g_matProjection);

    output.pos = clipSpacePos.xyww;
    output.uv = input.uv;

    return output;
}

float4 PS_Main(VS_OUT input) : SV_Target
{
    float4 color = g_tex_0.Sample(g_sam_0, input.uv);

    return color;
}

skybox를 위한 쉐이더 파일을 구현

output.pos를 (x,y,w,w) 벡터를 사용하여 screen space로 투영 될 때,

w로 나눠지며 z값이 항상 1이 됨

0개의 댓글