게임 개발 자료/DirectX 스터디

DirectX 11 스터디 - 래스터라이저 스테이트, 샘플 스테이트, 블렌드 스테이트

원생계 2023. 9. 11. 11:49

1. 래스터라이저 스테이트를 생성/설정하고 Render() 함수에서 전달해준다.

ID3D11RasterizerState 를 생성하고, ~_DESC 에 설정값을 담아 생성한다.

그리고 Render() 함수에서 Pixel Shader 에 적용되도록 전달함.

ComPtr<ID3D11RasterizerState> _rasterizerState;

void Game::CreateRasterizerState()
{
	D3D11_RASTERIZER_DESC desc;
	ZeroMemory(&desc, sizeof(desc));
	desc.FillMode = D3D11_FILL_SOLID;
	desc.CullMode = D3D11_CULL_BACK;
	desc.FrontCounterClockwise = false; // 시계방향/반시계방향 = Clockwise / CounterClockwise

	HRESULT hr = _device->CreateRasterizerState(&desc, _rasterizerState.GetAddressOf());
	CHECK(hr);
}

Render()
{
	// ...
    
	// Vertex Shader
    _deviceContext->VSSetShader(_vertexShader.Get(), nullptr, 0);
    _deviceContext->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());

    // Rasterizer Stage
    _deviceContext->RSSetState(_rasterizerState.Get());

    // Pixel Shader
    _deviceContext->PSSetShader(_pixelShader.Get(), nullptr, 0);
    _deviceContext->PSSetShaderResources(0, 1, _shaderResourceView0.GetAddressOf());
    _deviceContext->PSSetShaderResources(1, 1, _shaderResourceView1.GetAddressOf());
    
    // ...
}

위 CreateRasterizerState() 에서 FillMode 를 ~_WIREFRAME 으로 설정하면 아래와 같이 폴리손의 와이어프레임을 볼 수 있음.

 

2. SamplerState, BlendState

이번에는 샘플러 스테이트(SamplerState)와 블랜드 스테이트(BlendState) 를 생성해서 연결해준다.

모든 디바이스 오브젝트와 동일한 절차로 생성해준다. 아래처럼 껍데기를 먼저 만들어주고, _DESC 를 적절한 값들로 채우면 된다. 이쯤되면 Device::Create~ 시리즈들은 인터페이스일 뿐이고, 진짜 중요한 내용들은 모두 ~_DESC 구조체 안에 들어있다 보면 됨.

ComPtr<ID3D11BlendState> _blendState;
ComPtr<ID3D11SamplerState> _samplerState;

void Game::CreateSamplerState()
{
	D3D11_SAMPLER_DESC desc;
	HRESULT hr = _device->CreateSamplerState(&desc, _samplerState.GetAddressOf());
}

void Game::CreateBlendSTate()
{
	D3D11_BLEND_DESC desc;
	HRESULT hr = _device->CreateBlendState(&desc, _blendState.GetAddressOf());
}

먼저 SamplerState 는 PiexelShader 에 넘겨주는 샘플러스테이트 그것이 맞다. 기존에 만들었전 픽셀셰이더 코드를 다시 보면 이렇게 생김. 여기서 s0~ 레지스터로 넘어가는 SamplerState 가 그것. 텍스쳐를 어떻게 샘플링 할지에 대한 규칙이 담겨있음.

Texture2D texture0 : register(t0); // t0, s0 은 레지스터 이름.
Texture2D texture1 : register(t1); // t0, s0 은 레지스터 이름.
SamplerState sampler0 : register(s0);

float4 PS(VS_OUTPUT input) : SV_Target
{
	//return input.color;
	//float4 color = ceil(input.color * 5) / 5.0f;
	float4 color = texture0.Sample(sampler0, input.uv);
	color = color * texture1.Sample(sampler0, input.uv);
	return color;
}

D3D11_SAMPLER_DESC 내용을 적절히 채우고 변경해가면서 설정값을 이해하는 게 중요. 아래는 샘플 설정값. 텍스쳐 샘플링 필터 옵션과 UVW 주소 모드, BORDER 모드일 때의 Border 색상값 등의 설정을 담아준다. AddressU,V,W 모드를 ~_WRAP 으로 설정하면, 유니티엔진 등에서 볼 수 있는 Tiling 옵션으로 동작함.

void Game::CreateSamplerState()
{
	D3D11_SAMPLER_DESC desc;
	ZeroMemory(&desc, sizeof(desc));
	desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
	desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
	desc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
	desc.BorderColor[0] = 1;
	desc.BorderColor[1] = 0;
	desc.BorderColor[2] = 0;
	desc.BorderColor[3] = 1;
	desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	desc.MaxAnisotropy = 16;
	desc.MaxLOD = FLT_MAX;
	desc.MinLOD = FLT_MIN;
	desc.MipLODBias = 0.0f;

	HRESULT hr = _device->CreateSamplerState(&desc, _samplerState.GetAddressOf());
}

Render()
{
	...
	// Pixel Shader
    ...
    _deviceContext->PSSetSamplers(0, 1, _samplerState.GetAddressOf()); //< 여기 추가
    ...
}

~_MIRROR 는 좌우 대칭이 반복되고, CLAMP 는 자르기, BORDER 는 경계 바깥을 BorderColor 로 채우는 모드 등.

 

아래는 D3D11_SAMPLER_DESC 구조체 API 문서.

https://learn.microsoft.com/ko-kr/windows/win32/api/d3d11/ns-d3d11-d3d11_sampler_desc

 

D3D11_SAMPLER_DESC(d3d11.h) - Win32 apps

샘플러 상태를 설명합니다. (D3D11_SAMPLER_DESC)

learn.microsoft.com

 

마지막으로 BlendState 생성.

말 그대로 텍스쳐를 블랜딩하는 옵션을 설정해줄 수 있는 상태. BlendState 를 생성하고 Output Merger 단계에서 사용할 수 있도록 Render() 함수에서 전달을 해주면 됨. 다른 오브젝트들과 마찬가지로 D3D11_BLEND_DESC 를 생성해서 적절히 설정해주면 되는데, 자세한 설명은 스킵하고 아래 샘플처럼 적당히 설정하고 진행하도록 함.

void Game::CreateBlendSTate()
{
	D3D11_BLEND_DESC desc;
	ZeroMemory(&desc, sizeof(desc));
	desc.AlphaToCoverageEnable = false;
	desc.IndependentBlendEnable = false;
	
	desc.RenderTarget[0].BlendEnable = true;
	desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	HRESULT hr = _device->CreateBlendState(&desc, _blendState.GetAddressOf());
	CHECK(hr);
}

Render()
{
	...
	// Output Merger
    _deviceContext->OMSetBlendState(_blendState.Get(), nullptr, 0xFFFFFF);
    ...
}

블랜드 스테이트로 알파블랜딩 설정을 하고 다시 실행해보면, 아래 이미지와 같이 검은색 영역이 투명하게 뚫려서 보이는 걸 확인할 수 있음.

아래는 D3D11_BLEND_DESC 구조체 API 문서

https://learn.microsoft.com/ko-kr/windows/win32/api/d3d11/ns-d3d11-d3d11_blend_desc

 

D3D11_BLEND_DESC(d3d11.h) - Win32 apps

ID3D11Device::CreateBlendState를 호출하여 혼합 상태 개체를 만드는 데 사용하는 혼합 상태를 설명합니다.

learn.microsoft.com

그리고 BLEND_DESC 의 핵심인 D3D11_RENDER_TARGET_BLEND_DESC 구조체

https://learn.microsoft.com/ko-kr/windows/win32/api/d3d11/ns-d3d11-d3d11_render_target_blend_desc

 

D3D11_RENDER_TARGET_BLEND_DESC(d3d11.h) - Win32 apps

렌더링 대상의 혼합 상태를 설명합니다. (D3D11_RENDER_TARGET_BLEND_DESC)

learn.microsoft.com

.

참조

OutputMerger(출력 병합기) State

https://learn.microsoft.com/ko-kr/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage

 

출력 병합기 단계 - Win32 apps

OM(출력 병합기) 단계는 파이프라인 상태, 픽셀 셰이더에서 생성된 픽셀 데이터, 렌더링 대상의 내용 및 깊이/스텐실 버퍼의 내용을 조합하여 최종 렌더링된 픽셀 색을 생성합니다.

learn.microsoft.com

 

정리

RS, SS, BS 즉, RasterizerState, SamplerState, BlendState 는 옵셔널한 성격이 있기 때문에 디폴트로 동작하는 셋팅이 있어서 설정하지 않아도 기본 렌더 파이프라인은 동작함. 세부 설정 변경이 필요한 경우에 추가해서 사용하면 되는 것들이기 때문에 기억하고 있을 필요는 있음.

 

기본적인 렌더링 파이프라인 객체들을 먼저 완전히 익힌 뒤에 RS, SS, BS 를 익히는 것이 정석적인 순서.


<리얼-타임 렌더링(REAL-TIME RENDERING) 4/e> 구입 링크
https://link.coupang.com/a/8VWas

 

리얼-타임 렌더링 4/e

COUPANG

www.coupang.com

<DirectX 12를 이용한 3D 게임 프로그래밍 입문> 구입 링크
https://link.coupang.com/a/8V4Wq

 

DirectX 12를 이용한 3D 게임 프로그래밍 입문:게임 개발 중심으로 익히는 대화식 컴퓨터 그래픽 프

COUPANG

www.coupang.com

유니티 에셋 스토어 링크

https://assetstore.unity.com?aid=1011lvz7h 

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

(링크를 통해 도서/에셋 구입시 일정액의 수수료를 지급받습니다.)


728x90
반응형