RasterizerState , SampleState, BlendState

나무늘보·2024년 1월 12일

DirectX

목록 보기
3/5

문서를 조금 찾아보면서 살짝 알아보면 좋다

RS단계가 비어있어 , RS 단계에서 코딩을 할순없지만 , 설정은 할수있다

중간에 굉장히 중요한단계

IA - VS - RS - PS - OM / VS가 넘겨준 삼각형을 대상으로 삼각형 내부에 있는 모든 픽셀들을 판별하는 영역

//header 
private:
	void CreateRasterizerState();
// RS
	ComPtr<ID3D11RasterizerState> _rasterizerState = nullptr;

//cpp
// init 에 CreateRasterizerState() 추가 

void Game::CreateRasterizerState()
{
	D3D11_RASTERIZER_DESC desc;
	ZeroMemory(&desc, sizeof(desc));

// 3개다 매우 중요하다 
	desc.FillMode = D3D11_FILL_SOLID;
	desc.CullMode = D3D11_CULL_BACK;
	desc.FrontCounterClockwise = false;

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

}

desc의 3가지 요소가 모두 중요한대 FillMode의 내부를 살펴보면

typedef 
enum D3D11_FILL_MODE
    {
        D3D11_FILL_WIREFRAME	= 2,
        D3D11_FILL_SOLID	= 3
    } 	D3D11_FILL_MODE;

이런식으로 되어있고 여기서 우리가 D3D11_FILL_WIREFRAME 으로 설정하면

이런식으로 와이어 프레임 모드로 삼각형 단위로 표시해주게 된다

그 다음 Cull mode 가있는데 cull mode back 이라고 back 이면 culling 을 하겠다 라고만 되어있는데 일단은 잘보인다 .

culling 이라는게 보통은 그리지않게끔 이걸 아예 스킵하는걸 culling 이라고 한다 . 예를 들면 카메라 영역에서 벗어나면 컬링을 한다던가 , ex) occlusion culling , 프러스텀 컬링 등등

RS가 해주는건 후면으로 인식으로하면 나는 더이상 그리지 않겠다 . 뒤라는걸 어떻게 인식하냐 , 바로 이 옵션으로

desc.FrontCounterClockwise = false;

Clockwise 뜻이 시계 방향인데 counter가 붙어있으니 반시계방향 , 우리가 시계방향으로 가는게 앞 방향이라는뜻 우리가 삼각형을 만들때 , 우리가 시계방향으로 돌면서 정점을 만들었다 ( 0 , 1 , 2 )

기능들이 많으니깐 찾아보면 좋다 -

  • D3D11_RASTERIZER_DESC , direct x 11 레스터라이저 description 인자 정리 'D3D11_RASTERIZER_DESC'는 래스터라이저 상태를 설명하는 데 사용됩니다. 이 상태는 렌더링 프로세스 중에 기하학이 어떻게 래스터화되거나 픽셀로 변환되는지를 제어합니다. 이 구조체의 구성원을 하나씩 살펴보겠습니다.
    1. FillMode:

      • 타입: D3D11_FILL_MODE
      • 목적: 기하학적 도형의 내부를 어떻게 채울지 지정합니다. D3D11_FILL_SOLID는 단색으로, D3D11_FILL_WIREFRAME은 와이어프레임 표현으로 사용될 수 있습니다.
    2. CullMode:

      • 타입: D3D11_CULL_MODE
      • 목적: 기하학적 도형의 어떤 면을 제거하거나 렌더링하지 않을지를 결정합니다. D3D11_CULL_NONE (제거 없음), D3D11_CULL_FRONT (앞면 제거), D3D11_CULL_BACK (뒷면 제거)과 같은 값들을 가질 수 있습니다.
    3. FrontCounterClockwise:

      • 타입: BOOL (부울)
      • 목적: 앞면이 반시계 방향으로 정의되었는지를 지정합니다. TRUE로 설정하면 앞면이 반시계 방향이고, FALSE로 설정하면 시계 방향입니다.
    4. DepthBias:

      • 타입: INT (정수)
      • 목적: 깊이 테스트 중에 픽셀의 깊이 값에 추가되는 상수 깊이 오프셋입니다. Z-피팅과 관련된 어떤 아티팩트를 완화하는 데 도움이 됩니다.
    5. DepthBiasClamp:

      • 타입: FLOAT (부동소수점)
      • 목적: 깊이 테스트 중에 적용되는 최대 깊이 오프셋입니다. 시각적 아티팩트를 방지하기 위해 과도한 깊이 오프셋을 방지합니다.
    6. SlopeScaledDepthBias:

      • 타입: FLOAT (부동소수점)
      • 목적: 삼각형의 깊이 그라데이션의 기울기에 따라 깊이 오프셋을 조절합니다. Z-피팅과 관련된 아티팩트를 줄이는 데 다른 요소입니다.
    7. DepthClipEnable:

      • 타입: BOOL (부울)
      • 목적: 기하학적 도형을 가까운 및 먼 클리핑 평면에 대한 클리핑을 활성화할지 여부를 결정합니다. TRUE로 설정하면 클리핑이 활성화되고, FALSE로 설정하면 비활성화됩니다.
    8. ScissorEnable:

      • 타입: BOOL (부울)
      • 목적: 시저-사각형 클리핑을 활성화할지 여부를 지정합니다. TRUE로 설정하면 시저 사각형이 지정된 영역 외의 픽셀을 클리핑하는 데 사용되고, FALSE로 설정하면 시저 클리핑이 비활성화됩니다.
    9. MultisampleEnable:

      • 타입: BOOL (부울)
      • 목적: 래스터화 중에 멀티샘플링을 적용할지 여부를 결정합니다. TRUE로 설정하면 멀티샘플링이 활성화되고, FALSE로 설정하면 비활성화됩니다.
    10. AntialiasedLineEnable:
      - 타입: BOOL (부울)
      - 목적: 선 안티앨리어싱을 활성화할지 여부를 지정합니다. TRUE로 설정하면 안티앨리어싱된 선이 활성화되고, FALSE로 설정하면 비활성화됩니다.

      이러한 설정은 Direct3D 11 응용 프로그램에서 렌더링된 장면의 시각적 모양을 제어합니다. 이러한 매개변수를 구성함으로써 다양한 유형의 그래픽을 렌더링할 수 있게 해주며 다각형 채우기 스타일, 면 컬링, 깊이 바이어스, 시저 클리핑 등의 측면을 제어할 수 있습니다.

나머지 기능들도 이런식으로 사용하면된다 , 렌더링단계에서 어느단계에 들어가는지 문서를 확인해서 알맞는 단계에 넣어주면된다 . RS state 뿐만 아니라 SampleState 그리고 Blend State 이렇게 좀 덜 중요한 당장 중요하진않은 3총사가 있다

Sampler State

//header 
private:
	void CreateSamplerState();
// cpp
void Game::CreateSamplerState()
{
	D3D11_SAMPLER_DESC desc;
	ZeroMemory(&desc, sizeof(desc));
	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;
	//border color는 RGBA 라고보면된다 
	desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	//어떻게 비교하면될지 
	desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	desc.MaxAnisotropy = 16;
	desc.MaxLOD = FLT_MAX;
	desc.MinLOD = FLT_MIN;
	desc.MipLODBias = 0.0f;

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

}

SamplerState → 애는 샘플링을 한다 , 언제 설정하냐면 쉐이더에서

//HLSL 
Texture2D texture0 : register(t0);
SamplerState sampler0 : register(s0);

float4 PS(VS_OUTPUT input) : SV_Target 
{

	float4 color = texture1.Sample(sampler0, input.uv);
	//Sample이라는 함수를이용해서 sampler0번이랑 input의uv를 각각건네준다 
	// texture0번의 uv 좌표를 가져와서 거기해당하는 색상을 뺴온다라는 느낌 

	return color;

}

이 샘플링이라는 애랑 UV좌표랑 어떤 텍스쳐를 건네주면 그거에 따라서 샘플을 꺼내 준다 즉 어떠한 색상인지를 꺼내줘가지고 우리가 색상을 결정한다 , 그거와 관련된 옵션

D3D11_SAMPLER_DESC 를 살펴보면 UV 좌표랑 밀접하게 관계되어있는것을 확인할수있다.

  • Sampler Description 인자 정리
    typedef struct D3D11_SAMPLER_DESC
        {
        D3D11_FILTER Filter;
        D3D11_TEXTURE_ADDRESS_MODE AddressU;
        D3D11_TEXTURE_ADDRESS_MODE AddressV;
        D3D11_TEXTURE_ADDRESS_MODE AddressW;
        FLOAT MipLODBias;
        UINT MaxAnisotropy;
        D3D11_COMPARISON_FUNC ComparisonFunc;
        FLOAT BorderColor[ 4 ];
        FLOAT MinLOD;
        FLOAT MaxLOD;
        } 	D3D11_SAMPLER_DESC
    'D3D11_SAMPLER_DESC' 구조체는 Direct3D 11 (D3D11) API의 일부로 텍스처 샘플링 상태를 설명하는 데 사용됩니다. 이 구조체의 각 구성원에 대한 설명은 다음과 같습니다.
    1. Filter:

      • 타입: D3D11_FILTER
      • 목적: 텍스처를 샘플링할 때 사용되는 필터링 방법을 지정합니다. 포인트 샘플링, 바이선형 보간, 트라이선형 보간 또는 아니소트로픽 필터링과 같은 값들을 가질 수 있습니다.
    2. AddressU:

      • 타입: D3D11_TEXTURE_ADDRESS_MODE
      • 목적: U (가로) 방향에서 텍스처 좌표가 [0.0, 1.0] 범위를 벗어날 때 처리되는 방법을 결정합니다. wrap, mirror, clamp, 또는 border와 같은 값들을 가질 수 있습니다.
    3. AddressV:

      • 타입: D3D11_TEXTURE_ADDRESS_MODE
      • 목적: AddressU와 유사하지만 V (세로) 방향에 적용됩니다.
    4. AddressW:

      • 타입: D3D11_TEXTURE_ADDRESS_MODE
      • 목적: AddressU 및 AddressV와 유사하지만 W (깊이) 방향에 적용됩니다.
    5. MipLODBias:

      • 타입: FLOAT (부동소수점)
      • 목적: 텍스처를 샘플링할 때 레벨 오브 디테일 (LOD) 계산에 추가되는 보정값입니다. 샘플링에 사용되는 Mip 레벨을 조절하는 데 사용됩니다.
    6. MaxAnisotropy:

      • 타입: UINT (부호 없는 정수)
      • 목적: 아니소트로픽 필터링의 수준을 제어합니다. 텍스처 필터링 시 적용할 최대 아니소트로픽 레벨을 지정합니다.
    7. ComparisonFunc:

      • 타입: D3D11_COMPARISON_FUNC
      • 목적: 샘플링을 비교 모드로 사용하는 경우(예: 섀도우 매핑), 사용할 비교 함수를 지정합니다.
    8. BorderColor[4]:

      • 타입: 4 개의 FLOAT 값으로 구성된 배열 (부동소수점)
      • 목적: 주소 모드가 border로 설정된 경우 사용할 테두리 색상을 지정합니다. 배열은 RGBA 값을 나타냅니다.
    9. MinLOD:

      • 타입: FLOAT (부동소수점)
      • 목적: 텍스처를 샘플링할 때 사용할 최소 레벨 오브 디테일 (LOD)을 지정합니다. 낮은 디테일 Mip 레벨의 사용을 제한하는 데 도움이 됩니다.
    10. MaxLOD:
      - 타입: FLOAT (부동소수점)
      - 목적: 텍스처를 샘플링할 때 사용할 최대 레벨 오브 디테일 (LOD)을 지정합니다. 높은 디테일 Mip 레벨의 사용을 제한하는 데 도움이 됩니다.

      이러한 설정은 렌더링 중에 텍스처를 샘플링하고 필터링하는 방법을 정의하며, Direct3D 11 응용 프로그램에서 텍스처의 품질과 외관에 영향을 미칩니다. 개발자는 이러한 매개변수를 사용하여 필터링 품질, 텍스처 주소 지정, 아니소트로픽 필터링 및 LOD 보정과 같은 측면을 제어할 수 있습니다

UV좌표에서 내가 1을 초과해서 2 혹은 3으로 값을 설정했을때 그 빈 부분들을 어떻게 채워야 되는지 이런 관련된 부분을 SamplerState가 해준다고 보면된다 , 한마디로 샘플링 규칙을 정해준다고 보면된다 애네들을 어떻게 꺼내가지고

텍스쳐에 이용할지 에 대한 관련 규칙이라고 보면된다 , 현재 BorderColor를 빨간색으로 설정함 → 결과에서 어떻게 달라지나 확인

결국이 Sampler는 쉐이더에서도 볼수있듯 PS 단계에서 설정하기떄문에 PS단계에서 deviceContext로 연결을 시켜줘야한다

void Render()
{
	// IA - VS - RS 
	_deviceContext->PSSetSamplers(0, 1, _samplerState.GetAddressOf());
	//OM	
}

그러면 이제 우리가 설정한대로 된다 , 처음에 Geometry값중 UV 값을 큰값으로 바꿔봐야 티가 날것이다 UV값을 1 에서 5로 전부 바꾸면


이런식으로 비어있는곳에 우리가설정한 RGBA 값인 빨간색이 들어가게된고 , SamplerState 규칙에 따라 AddressBorder로 된다

Mirror 로 바꾸면 어떻게 될까 ?


이런식으로 미러 형식으로 대칭되서 나오게된다 , 남은곳들을 어떻게 채워줄지에 대한 옵션이라고 생각하면된다 .

경우에 따라서 UI 하나 만들꺼면 그냥 빈공간에 다 채우는게 낫지않을까 싶지만 → 경우에따라 이게 하나의 타일이여서 반복적으로 그리는게 더 나을때도 있고 이럴때 이런 규칙을 사용한다고 볼수있다

이게 Sampler 의 역할

BlendState

가볍게 알아보는게 목표

  • BlendState Description struct Variable
    typedef struct D3D11_BLEND_DESC
        {
        BOOL AlphaToCoverageEnable;
        BOOL IndependentBlendEnable;
        D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[ 8 ];
        } 	D3D11_BLEND_DESC;
    D3D11_BLEND_DESC는 Direct3D 11 (D3D11) API의 일부입니다. 이 구조체는 블렌드 상태를 설명하는 데 사용되며, 픽셀의 출력 색상이 렌더 타겟의 기존 내용과 어떻게 결합되는지를 제어합니다. 각 멤버의 설명은 다음과 같습니다:
    1. AlphaToCoverageEnable:
      • 타입: BOOL (부울)
      • 목적: 알파-투-커버리지 멀티샘플링을 활성화할지 여부를 지정합니다. 활성화되면 픽셀의 알파 구성 요소가 멀티샘플 안티에일리어싱 중에 커버리지 마스크를 제어할 수 있습니다.
    2. IndependentBlendEnable:
      • 타입: BOOL (부울)
      • 목적: 여러 렌더 타겟에 대해 독립적인 블렌딩을 활성화할지 여부를 결정합니다. TRUE로 설정하면 각 렌더 타겟마다 자체 블렌드 상태를 가질 수 있고, FALSE로 설정하면 모든 렌더 타겟이 동일한 블렌드 상태를 사용합니다.
    3. RenderTarget[8]:
      • 타입: D3D11_RENDER_TARGET_BLEND_DESC의 배열
      • 목적: 각 렌더 타겟에 대한 블렌드 상태를 설명하는 구조체의 배열입니다. 일반적인 사용에서 이 배열은 최대 8개의 렌더 타겟에 대한 블렌딩 설정을 나타냅니다.
    • RenderTarget 관련 vairable
      typedef struct D3D11_RENDER_TARGET_BLEND_DESC
          {
          BOOL BlendEnable;
          D3D11_BLEND SrcBlend;
          D3D11_BLEND DestBlend;
          D3D11_BLEND_OP BlendOp;
          D3D11_BLEND SrcBlendAlpha;
          D3D11_BLEND DestBlendAlpha;
          D3D11_BLEND_OP BlendOpAlpha;
          UINT8 RenderTargetWriteMask;
          } 	D3D11_RENDER_TARGET_BLEND_DESC;
      'D3D11_RENDER_TARGET_BLEND_DESC'라는 구조체를 정의합니다. 이 구조체의 구성원을 살펴보겠습니다.
      1. BlendEnable:

        • 타입: BOOL (부울)
        • 목적: 해당 렌더 타겟에 대해 블렌딩이 활성화되었는지 여부를 지정합니다. TRUE로 설정하면 블렌딩이 활성화되며, FALSE로 설정하면 블렌딩이 비활성화되어 픽셀 색상이 직접 렌더 타겟에 기록됩니다.
      2. SrcBlend:

        • 타입: D3D11_BLEND
        • 목적: 소스 색상에 대한 블렌딩 팩터를 지정합니다. 소스 색상이 블렌딩 작업에 기여하는 방식을 결정합니다.
      3. DestBlend:

        • 타입: D3D11_BLEND
        • 목적: 대상 색상에 대한 블렌딩 팩터를 지정합니다. 대상 색상이 블렌딩 작업에 기여하는 방식을 결정합니다.
      4. BlendOp:

        • 타입: D3D11_BLEND_OP
        • 목적: 소스 및 대상 색상 간에 수행할 블렌딩 작업을 지정합니다.
      5. SrcBlendAlpha:

        • 타입: D3D11_BLEND
        • 목적: 소스 알파에 대한 블렌딩 팩터를 지정합니다. 소스 알파가 블렌딩 작업에 기여하는 방식을 결정합니다.
      6. DestBlendAlpha:

        • 타입: D3D11_BLEND
        • 목적: 대상 알파에 대한 블렌딩 팩터를 지정합니다. 대상 알파가 블렌딩 작업에 기여하는 방식을 결정합니다.
      7. BlendOpAlpha:

        • 타입: D3D11_BLEND_OP
        • 목적: 소스 및 대상 알파 값 간에 수행할 블렌딩 작업을 지정합니다.
      8. RenderTargetWriteMask:
        - 타입: UINT8 (부호 없는 8비트 정수)
        - 목적: 렌더 타겟의 개별 색상 채널(Red, Green, Blue 및 Alpha)에 대한 쓰기 마스크를 지정합니다. 각 채널은 비트로 나타내며, 이 마스크는 어떤 채널이 쓰기 가능한지를 결정합니다.

        이 구조체는 일반적으로 Direct3D 11에서 사용되며 특정 렌더 타겟에 대한 블렌딩 상태를 설명합니다. 이는 특정 타겟에 렌더링되는 픽셀의 색상 및 알파 구성 요소에 대한 블렌딩 작업이 어떻게 적용되는지에 대한 세밀한 제어를 제공합니다.

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);

}

여러 옵션들이있는데 특히 BlendEnable 을 false 로 한다면 아무의미없겠지만 true로 켜주면 Blending이 되는거다 내가 들고있는 텍스쳐의 Alpha 값에 따라서 어떻게 섞어 줄지를 우리가 이제 여기에 규칙을 정해줄수 있다는 뜻 ,

예를 들면 내가 이미 배경이 이러이러한 색상인데 내가 뭐 어느색을 적당히 섞어 가지고 약간 반투명으로 보이게하 하거나 , 벽앞으로 가면 해당 벽이 투명하게 보여서 그벽을 뚫어서 내 캐릭터를 보이게 해야된다거나 하는

그럴 때 우리가 사용하는게 BlendState를 잘 조정해서 이런 옵션들을 조정하면 실질 적으로 내 캐릭터가 벽을 뚫려서도 보이게끔 우리가 유도를 해줄수 있다는 얘기가 된다 ← 마비노기 or 기타 RPG 특징 3인칭 게임에서 거의 필수

이 BlendState 는 OM ( Output Merge ) 단게에서 적용을 해주는 아이라서 Render 부분에서 또 DeviceContext로 연결을 시켜줘야한다

void Render()
{
	//IA - VS - RS - PS 
	//OM
		_deviceContext->OMSetBlendState(_blendState.Get(),nullptr , 0xFFFFFFFF);
}

요약

나머지 기능은 우리가 2d를 할때 더 해볼꺼여서 나머지 기능은 일단 패스 , 일단 이런식으로 흐름이 된다는게 중요하다

렌더링 파이프라인에 따라서 함수들이 반복해서 등장하고 필요따라서 값을 채워주고 넣어주고 하는게 dx11 이다 라고보면되고

수학식 공부해서 VS , PS 에서 기능들을 더 넣긴할테지만 , 기본적으로 함수를 여러개를만들어서 인자들을 실시간을 꽂아서 넣어줄수있게 만들어 주는것이다 라고 보면된다

나중에 이 인자들로 중간에 꽂아 넣는 애들은 일종의 함수의 변수처럼 물체마다 고유한 값을 가지고 있어가지고 그것만 우리가 이렇게 찔러주게 되면 그거에 따라가지고 요 물체의 변환이라거나 색상의 변화 등등을 우리가 충분히 얻어줄수가 있다는 얘기가 된다

텍스쳐도 마찬가지로 몬스터가 텍스쳐가 달라지만 요 텍스쳐만 바꿔주면되니깐

Constant Buffer 전까지가 제일 중요하다 ** 그 부분을 잘 익혀야하고 좀 익혀지면 세부적인 함수 인자들을 구글링하고 검색해보는것 , 나머지는 굳이 안해도되고 필요하면 그때 하면된다

샘플러 State 도 우리가 만들어서 연동하긴했지만 하기전에도 쉐이더가 잘동작한다 , 이건 필요에따라서 연결해서 알아보고 하는식으로 작업을해도 무방하다

가장 중요한 부분 , 렌더링 파이프라인을 이해하고 어떤식으로 DX11 에게 명령을 내리는지 이해하는것 가장 중요하다

profile
Unreal Programmer , C++

0개의 댓글