픽셀 셰이더(1) - 기본

WanJu Kim·2022년 12월 29일

Direct3D

목록 보기
19/29

정점 버퍼들이 정점 셰이더, 래스터화기 단계를 거치면, 정점 특성들이 삼각형의 픽셀들을 따라 보간한 결과를 픽셀 셰이더에 입력한다. 픽셀 셰이더도 정점 셰이더처럼 본질적으로 하나의 함수이다. 정점 셰이더랑 차이는, 각 정점이 아니라 각 픽셀 단편마다 실행된다는 것이다. 픽셀 단편이란 게 뭔 말인가? → 하나의 픽셀에 선정되기 위해서는 경쟁에서 이겨야 한다. 예를 들어 깊이 값이 더 작은 다른 픽셀 단편에 가려질 수도 있고, 픽셀 셰이더 자체에서 잘려 나갈 수도 있고, 스텐실 판정에서도 폐기될 수 있다. 예시 픽셀 셰이더를 보자.

cbuffer cbPerObject
{
	float4x4 gWorldViewProj;
};

void VS(float3 iPosL : POSITION,
	float4 iColor : COLOR,
    out float4 oPosH : SV_POSITION,
    out float4 oColor : COLOR)
{
	oPosH = mul(float4(iPosL, 1.0f), gWorldViewProj);
    oColor = iColor;
}

// 픽셀 
float4 PS(float4 posH : SV_POSITION, float4 color : COLOR) : SV_Target
{
    return pin.Color;
}

이 예에서 픽셀 셰이더 함수는 그냥 보간된 색상 값을 돌려준다. 픽셀 셰이더의 입력이 정점 셰이더의 출력과 정확히 일치한다. 이건 필수조건이다. 함수명 끝 부분의 SV_TARGET 의미소는, 이 함수의 반환값 형식이 렌더 대상 형식과 일치해야 함을 뜻한다. 다음 코드는 구조체를 사용하여 약간 다르게 표현하겠다.

cbuffer cbPerObject
{
	float4x4 gWorldViewProj; 
};

struct VertexIn
{
	float3 PosL  : POSITION;
    float4 Color : COLOR;
};

struct VertexOut
{
	float4 PosH  : SV_POSITION;
    float4 Color : COLOR;
};

VertexOut VS(VertexIn vin)
{
	VertexOut vout;
	
	vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
    vout.Color = vin.Color;
    
    return vout;
}

float4 PS(VertexOut pin) : SV_Target
{
    return pin.Color;
}

입력 받는 매개변수만 좀 달라졌다. 정점 셰이더랑 픽셀 셰이더는 이렇게 하나의 파일 안에 같이 넣어도 되고, 다르게 넣어도 된다.

profile
Question, Think, Select

0개의 댓글