스텐실 버퍼는 픽셀을 저장 또는 폐기하기 위한 용도의 픽셀 마스크로 사용할 수 있습니다.
스텐실 버퍼는 보통 한 픽셀당 8비트 정수입니다. 이 값은 쓰기, 증가, 감소가 가능합니다. 픽셀 셰이더를 실행하기 전 어떤 픽셀이 제거되어야 할지 여부를 결정하기 위해 드로우 콜로 이 값을 테스트할 수 있습니다.
Ref referenceValue
비교될 값(Comp가 always 가 아닌 경우) 그리고/또는 버퍼에 기록될 값(Pass, Fail, Zfail 중 하나가 대체할 예정일 경우)입니다. 0255 사이의 정수입니다.
ReadMask readMask
0255 사이의 정수인 8비트 마스크이며 레퍼런스 값을 버퍼의 콘텐츠와 비교할 때 사용합니다(referenceValue & readMask) comparisonFunction (stencilBufferValue & readMask). 디폴트는 255 입니다.
WriteMask writeMask
0255 사이의 정수인 8비트 마스크이며 버퍼에 작성할 때 사용합니다. 다른 작성 마스크와 마찬가지로 스텐실 마스크의 어느 비트가 작성의 영향을 받을지 지정한다는 점을 참조하십시오. 예를 들어, WriteMask 0은 아무 비트에도 영향을 주지 않으며 0은 작성되지 않습니다. 디폴트는 255 입니다.
Comp comparisonFunction
이 함수는 레퍼런스 값을 버퍼의 현재 콘텐츠와 비교할 때 사용합니다. 디폴트는 always 입니다.
Pass stencilOperation
스텐실 테스트(와 뎁스 테스트)를 통과한다면 버퍼의 콘텐츠를 어떻게 할 것인지 지정합니다. 디폴트는 keep 입니다.
Fail stencilOperation
스텐실 테스트가 실패한다면 버퍼의 콘텐츠를 어떻게 할 것인지 지정합니다. 디폴트는 keep 입니다.
ZFail stencilOperation
스텐실 테스트를 통과했으나 뎁스 테스트에 실패한다면 버퍼의 콘텐츠를 어떻게 할 것인지 지정합니다. 디폴트는 keep 입니다.
Comp, Pass, Fail, ZFail은 Cull Front 가 지정되어 있지 않으면 전면 지오메트리에 적용되며 지정된 경우엔 후면 지오메트리에 적용됩니다. 또한 CompFront, PassFront, FailFront, ZFailFront(전면 방향 지오메트리), CompBack, PassBack, FailBack, ZFailBack(후면 지오메트리)을 정의하여 명시적으로 양면 스텐실 스테이트를 명시할 수 있습니다.
비교 함수는 다음 중 하나입니다.
Greater | 레퍼런스 값이 버퍼 안의 값보다 큰 픽셀만 렌더링합니다. |
GEqual | 레퍼런스 값이 버퍼 안의 값보다 크거나 같은 픽셀만 렌더링합니다. |
Less | 레퍼런스 값이 버퍼 안의 값보다 작은 픽셀만 렌더링합니다. |
LEqual | 레퍼런스 값이 버퍼 안의 값보다 작거나 같은 픽셀만 렌더링합니다. |
Equal | 레퍼런스 값이 버퍼 안의 값과 같은 픽셀만 렌더링합니다. |
NotEqual | 레퍼런스 값이 버퍼 안의 값과 다른 픽셀만 렌더링합니다. |
Always | 스텐실 테스트를 항상 통과하도록 만듭니다. |
Never | 스텐실 테스트를 항상 실패하도록 만듭니다. |
스텐실 동작은 다음 중 하나입니다.
Keep | 버퍼의 현재 콘텐츠를 유지합니다. |
Zero | 버퍼에 0을 작성합니다. |
Replace | 버퍼에 레퍼런스 값을 작성합니다. |
IncrSat | 버퍼의 현재 값을 증가시킵니다. 만약 값이 이미 255라면 그대로 255를 유지합니다. |
DecrSat | 버퍼의 현재 값을 감소시킵니다. 만약 값이 이미 0이면 그대로 0을 유지합니다. |
Invert | 모든 비트의 값을 반전합니다. |
IncrWrap | 버퍼의 현재 값을 증가시킵니다. 만약 값이 이미 255라면 0이 됩니다. |
DecrWrap | 버퍼의 현재 값을 감소시킵니다. 만약 값이 이미 0이면 255가 됩니다. |
디퍼드 렌더링 경로에서 렌더링된 오브젝트에 대한 스텐실 기능은 다소 제한적인데, 이는 스텐실 버퍼가 G버퍼 패스 및 조명 패스 진행 중에 다른 목적으로 사용되기 때문입니다. 이 두 단계 동안 셰이더에서 정의된 스텐실 스테이트는 무시됩니다. 이로 인해 스텐실 테스트에 기반하여 오브젝트를 마스크하는 것은 불가능합니다. 그러나 여전히 버퍼 콘텐츠를 수정하여 프레임에서 나중에 렌더링될 오브젝트에서 사용하도록 할 수 있습니다. 디퍼드 경로에 이어 포워드 렌더링 경로에서 렌더링되는 오브젝트(예: 투명 오브젝트 또는 표면 셰이더가 없는 오브젝트)는 해당 스텐실 스테이트를 대게 다시 설정합니다.
다음의 비트들이 디퍼드 렌더링 경로에서 스텐실 버퍼에 사용됩니다.
스텐실 읽기 및 쓰기 마스크를 사용하여 사용되지 않는 비트 범위 내에서 작동하거나, Camera.clearStencilAfterLightingPass를 사용하여 조명 패스 이후에 강제로 카메라가 스텐실 버퍼를 정리하도록 만들 수 있습니다.
첫 번째 예제 셰이더는 뎁스 테스트가 통과한 곳에 ’2’값을 작성합니다. 스텐실 테스트는 언제나 통과하게 설정되어 있습니다.
Shader "Red" {
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry"}
Pass {
Stencil {
Ref 2
Comp always
Pass replace
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(1,0,0,1);
}
ENDCG
}
}
}
두 번째 셰이더는 ’2’라는 값과 같은지 체크하여 첫 번째 셰이더(빨간색)를 통과한 픽셀만을 통과시킵니다. Z 테스트에 실패하면 버퍼의 값을 감소시킵니다.
Shader "Green" {
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}
Pass {
Stencil {
Ref 2
Comp equal
Pass keep
ZFail decrWrap
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(0,1,0,1);
}
ENDCG
}
}
}
세 번째 셰이더는 스텐실 값이 ’1’일 경우에만 통과시키므로 빨간색과 초록색 구체가 교차하는 픽셀만이 해당됩니다. 여기에서 빨간 셰이더가 스텐실을 ’2’로 설정하고 초록 셰이더가 ’1’로 감소됩니다.
Shader "Blue" {
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}
Pass {
Stencil {
Ref 1
Comp equal
}
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(0,0,1,1);
}
ENDCG
}
}
}
결과:
더 직접적인 효과를 보여주는 다른 예제입니다. 스텐실 버퍼의 적절한 구역을 표시하기 위해 이 구체는 이 셰이더를 가지고 렌더링됩니다.
Shader "HolePrepare" {
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}
ColorMask 0
ZWrite off
Stencil {
Ref 1
Comp always
Pass replace
}
CGINCLUDE
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag(v2f i) : SV_Target {
return half4(1,1,0,1);
}
ENDCG
Pass {
Cull Front
ZTest Less
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
Pass {
Cull Back
ZTest Greater
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}
그 후 전면 컬링, 비활성화 뎁스 테스트 및 앞서 표시한 픽셀을 폐기하는 스텐실 테스트를 제외하고 상당히 표준적인 표면 셰이더로서 다시 한 번 렌더링합니다.
Shader "Hole" {
Properties {
_Color ("Main Color", Color) = (1,1,1,0)
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}
ColorMask RGB
Cull Front
ZTest Always
Stencil {
Ref 1
Comp notequal
}
CGPROGRAM
#pragma surface surf Lambert
float4 _Color;
struct Input {
float4 color : COLOR;
};
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = _Color.rgb;
o.Normal = half3(0,0,-1);
o.Alpha = 1;
}
ENDCG
}
}
결과:
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.