스텐실 버퍼
Stencil buffer![]() | 이 글에는 여러 가지 문제가 있다.이 문제를 개선하거나 대화 페이지에서 토의하십시오.(이러한 템플릿 메시지를 제거하는 방법 및 시기 알아보기)
|
스텐실 버퍼는 현대 그래픽 하드웨어에서 발견된 컬러 버퍼와 Z-버퍼 외에 추가 데이터 버퍼다.버퍼는 픽셀당이며 보통 픽셀당 1바이트의 깊이로 정수 값에 대해 작동한다.Z-버퍼와 스텐실 버퍼는 종종 그래픽 하드웨어의 RAM에서 동일한 영역을 공유한다.
가장 간단한 경우, 스텐실 버퍼를 사용하여 렌더링(스텐실링) 영역을 제한한다.스텐실 버퍼를 좀 더 고급스럽게 사용하면 렌더링 파이프라인에서 Z-버퍼와 스텐실 버퍼 사이의 강력한 연결을 활용할 수 있다.예를 들어, 스텐실 값은 깊이 테스트를 통과하거나 실패하는 모든 픽셀에 대해 자동으로 증가/감소될 수 있다.
비록 그들은 종종 여러 렌더링 패스가 필요한 깊이 시험 및 원판자 지정 한정자의 단순한 조합과,톤 효과 가능한(스텐실 그림자권 같은, Two-Sided Stencil,[1]채널, decaling,이 식는 동안이 사라지면 swipes, 실루엣, 그림 그리기, 또는 highlighting의 교차로 사이의 복잡한 기본 요소)의 방대한 숫자를 만든다그녀.따라서 그래픽 하드웨어에 무거운 부하를 가할 수 있다.
가장 일반적인 애플리케이션은 여전히 3D 애플리케이션에 그림자를 추가하는 것이다.평면반사에도 사용된다.
예를 들어, 포털 렌더링과 같은 다른 렌더링 기법은 스텐실 버퍼를 사용하여 포털에 의해 가려진 화면 영역을 찾아 해당 픽셀을 올바르게 렌더링할 수 있다.
스텐실 버퍼와 그 수식어는 OpenGL, Direct3D 또는 Vulkan과 같은 API를 사용하여 컴퓨터 그래픽으로 접근할 수 있다.
건축
스텐실 버퍼는 일반적으로 Z-버퍼와 동일한 메모리 공간을 공유하며, 일반적으로 스텐실 버퍼의 경우 Z-버퍼의 경우 24비트 + 8비트, 과거에는 스텐실 버퍼의 경우 15비트 + 1비트가 된다.또 다른 변종은 4 + 24로, 32비트 중 28비트가 사용되고 4는 무시된다.스텐실 및 Z-버퍼는 프레임 버퍼의 일부로서 색상 버퍼와 결합된다.더 넓은 시장에서 사용할 수 있는 첫 번째 칩은 1비트 스텐실 버퍼를 지원하는 3Dlabs의 Permedia II였다.
스텐실 버퍼에 할당된 비트는 [0, 2-1n] 범위의 숫자 값을 나타내기 위해 사용될 수 있으며, 또한 부울 행렬(n은 할당된 비트 수)로도 사용할 수 있으며, 각 비트는 씬(scene)의 특정 부분을 제어하기 위해 사용될 수 있다.사용 가능한 메모리를 사용하는 이 두 가지 방법의 어떤 조합도 가능하다.
스텐실 검정
스텐실 시험 또는 스텐실은 픽셀/마그네처(픽셀 단위 작업)에 대한 작업 중 하나이며 알파 시험 후 및 깊이 시험 전에 위치한다.스텐실 테스트는 원하지 않는 픽셀이 깊이 테스트에 도달하지 않도록 한다.이렇게 하면 씬(scene)의 처리 시간이 절약된다.마찬가지로 알파 테스트는 해당 픽셀이 스텐실 테스트에 도달하는 것을 방지할 수 있다.
시험 자체는 스텐실 완충기를 통해 그 안에 어느 정도 값을 갖도록 하거나 변형 또는 사용하며, 이른바 스텐실 기능과 스텐실 연산을 통해 실시된다.스텐실 함수는 특정 픽셀의 스텐실 값을 주어진 기준값과 비교하는 함수다.만약 이 비교가 논리적으로 사실이라면, 스텐실 시험은 통과한다.그렇지 않으면 그렇지 않다.
이렇게 함으로써 세 가지 서로 다른 상태 깊이와 스텐실 버퍼를 비교한 결과 발생하는 가능한 반응은 다음과 같다.
- 스텐실 테스트가 통과되지 않음
- 스텐실 테스트는 통과되었지만 깊이 테스트는 통과되지 않음
- 두 테스트가 모두 통과됨(또는 스텐실 테스트가 통과되고 깊이가 활성화되지 않음)
이러한 각각의 경우에 대해 검사된 픽셀에 대해 다른 연산을 설정할 수 있다.OpenGL 스텐실 함수에서 기준 값과 마스크는 각각 glStencilFunc 함수를 정의한다.Direct3D에서 이러한 각 구성 요소는 현재 제어 중인 SetRenderState 장치를 사용하여 개별적으로 조정된다.이 방법은 두 개의 매개변수를 예상하는데, 첫 번째 매개변수는 설정된 조건이고 다른 매개변수는 그 값이다.위에서 사용한 순서로, 이러한 조건을 D3DRS_STEENCILFUNC, D3DRS_STEENCILREF, D3DRS_STEENCILMASK라고 한다.
OpenGL의 스텐실 연산은 3개의 값이 예상되는 glStencilOp 함수를 조정한다.Direct3D에서는 각 상태가 SetRenderState라는 특정 방법을 설정한다.수술에 배정할 수 있는 세 가지 상태를 D3DRS_STENCELFAILAY, D3DRENDERSTATE_STENCELZFAIL, D3DRENDERSTATE_STENCELPASS라고 한다.
관리
스텐실 버퍼 어플리케이션의 범위는 다소 넓지만, 우리는 몇몇 잘 알려진 어플리케이션들을 언급할 수 있다.
그림이 있는 지상 위 사진에는 흰 표면 바로 위에 있어 깊은 투쟁의 효과를 막기에는 역부족이다.이와는 대조적으로 스텐실링가(하위 그림)에서는 이 효과가 동일 평면일 때에도 완전히 제거된다.
Z 파이팅
Z-버퍼의 정밀도가 떨어져 단거리 또는 중첩되는 코플라 폴리곤은 불규칙한 단면(단면)으로 묘사할 수 있다.이러한 섹션은 카메라 위치 및 기타 파라미터에 따라 달라질 수 있으며 빠르게 변화하고 있다.이것을 Z 파이팅이라고 한다.이 문제에 대한 해결책은 여러 가지가 있다.
- 극면을 가까이 가져와서 장면의 깊이를 제한하여 Z-버퍼의 정확도를 높이거나 장면에서 물체가 보이는 거리를 줄인다.
- Stencil buffer의 메모리를 희생하여 Z-buffer에 할당된 비트 수를 증가시킨다.
- 다각형을 서로 멀리 떨어져서 이동시켜 예술가가 정교한 장면을 연출할 수 있는 가능성을 제한한다.
문제에 대한 이러한 모든 접근법은 폴리곤이 Z싸움을 경험할 가능성을 줄일 수 있을 뿐, 일반적인 사례에서 결정적인 해결책을 보장하지는 않는다.
스텐실 버퍼를 포함하는 용액은 어떤 폴리곤이 다른 폴리곤들 앞에 있어야 하는지 아는 것에 기초한다.전면 폴리곤의 실루엣이 스텐실 버퍼에 그려진다.그 후 나머지 장면은 실루엣이 음수인 곳에만 렌더링할 수 있어 전면 다각형과 충돌하지 않는다.
섀도 볼륨
섀도 볼륨은 렌더링된 장면에 그림자를 추가하기 위해 3D 컴퓨터 그래픽에서 사용되는 기법이다.그것들은 1977년[2] Frank Crow에 의해 그 지역의 3D 모양을 설명하는 기하학으로 처음 제안되었다.그림자 볼륨은 가상 세계를 그림자에 있는 영역과 그렇지 않은 영역으로 나눈다.
섀도 볼륨의 스텐실 버퍼 구현은 일반적으로 현대의 3D 그래픽 하드웨어에서 사용하기 위한 가장 실용적인 범용 실시간 섀도잉 기법 중 하나로 간주된다.비디오 게임 Doom 3에 의해 대중화되었고, 이 게임에서 사용되는 기술의 특정한 변형은 카맥의 리버스라고 알려지게 되었다.
반사
씬(scene)의 반사는 씬(scene) 자체가 "미러" 면에 상대적으로 변환되고 반사되면서 그려지는데, 여기에는 여러 번의 렌더 패스와 현재 렌더 패스가 작동하는 영역을 제한하기 위한 스텐실 버퍼 사용이 필요하다.
- 미러 영역을 제외한 장면 그리기 – 각 미러에 대해 Z-버퍼 및 컬러 버퍼 잠금
- 미러의 가시적 부분 렌더링
- 각 픽셀이 최대값을 입력하기 위해 통과되고 항상 통과되도록 깊이 테스트를 설정함
- 각 미러에 대해:
- 픽셀의 거리가 현재보다 작은 경우에만 통과하도록 깊이 테스트를 설정(기본 동작)
- 거울 평면에 상대적인 장면을 반영하도록 행렬 변환이 변경됨
- Z-버퍼 및 컬러 버퍼 잠금 해제
- 장면만 그리되, 거울 평면과 카메라 사이에 놓여 있는 부분만 그려라.즉, 거울 평면도 클리핑 평면이다.
- 색상 버퍼 잠김, 깊이 테스트를 항상 통과하도록 설정하고 다음 미러에 대해 스텐실을 재설정하십시오.
평면 그림자
그림자의 평면을 그리는 동안 두 가지 주요 문제가 있다.첫 번째는 그림자와 바깥의 그림자로 덮인 부분에 평탄한 기하학이 수여되지 않을 경우에 대비한 깊은 투쟁의 문제에 관한 것이다.이와 관련된 섹션을 참조하십시오.또 다른 문제는 비행기가 있는 지역 바깥의 그림자의 범위와 관련이 있다.
기법에 따라 더 많은 폴리곤의 디자인이 나타나게 되어 같은 음영에서 더 어둡고 가벼운 부분이 생기게 되는 또 다른 문제.세 가지 문제 모두 기하학적으로 해결할 수 있지만, 하드웨어 가속을 직접 사용할 가능성이 있기 때문에 스텐실 완충장치를 이용한 훨씬 품위 있는 구현이다. 1. 조명과 조명을 활성화하라 2.그림자를 투영해야 하는 다각형이 없는 장면을 3으로 그려라.그림자를 투사해야 하지만 빛이 없는 모든 다각형을 그리십시오.그렇게 함으로써 각 폴리곤의 픽셀인 스텐실 버퍼는 그들이 속한 지면에 대한 특정 값에 할당된다.각 평면이 두 상태, 즉 그림자와 밝기에 대해 두 개의 값을 사용하기 때문에 이 값 사이의 거리는 최소 두 개여야 한다. 4. 모든 전역 조명을 비활성화하십시오(다음 단계가 개별 선택된 빛에만 영향을 미치도록 보장). 각 평면에 대해:각 조명에 대해: 1.선택한 수준에 대한 특정 값을 포함하는 픽셀만 스텐실 버퍼 편집주어진 레벨의 날짜와 밝은 날짜 사이에 투사되는 모든 픽셀의 값을 증가시킨다. 2. 그가 선택한 빛만 그녀의 특정 값의 일부가 변경되지 않은 레벨을 그리도록 허용한다.
공간 그림자
공간 도면 그림자의 스텐실 버퍼 구현은 그 볼륨이 그 안에 있는 장면의 일부를 포함하는 기하학적 본체의 그림자다.장면의 어느 부분이 이 볼륨에 속할 경우, 빛이 주어지지 않으며, 그렇지 않을 경우 불이 켜지지 않는다.이 문제는 빛의 수가 증가함에 따라 복합적으로 작용하지만 그림자가 드리워지는 지역의 수는 다루지 않는다.이 문제에 대한 몇 가지 해결책이 있지만, 우리는 다음과 같은 알고리즘을 따랐다: 1. 빛 없는 장면을 그려라 2.Z-버퍼와 컬러 버퍼를 잠가 두 개가 각 조명 1에 대해 변경할 수 없도록 하십시오.볼륨 섀도가 존재하지 않거나 기존 건물에서 보이지 않는 장면 일부에만 스텐실 버퍼를 채우기 위해 장면에 대한 심층 정보(Z-버퍼)를 사용한다.2색상에 대한 버퍼를 잠금 해제하고 Z-버퍼의 기능을 조정하여 깊이 값이 기존 3과 동일한 경우에만 수정이 가능하도록 한다.스텐실 테스트를 통과한 씬(scene)의 일부에 대해서만 이 조명으로 조명되는 씬(scene)을 그리십시오.
이 각각의 구절은 깨끗한 스텐실 버퍼를 사용할 수 있다는 것을 암시한다.
그림자에 대해서는, 이 기법을 사용하여 강한 빛 아래 있는 공간의 일부를 밝힐 수 있다.예를 들어 공기 중에 먼지가 많은 어두운 방에서 스포트라이트의 밝기가 적절한 공간의 부피를 밝히는 것을 볼 수 있었다.
기타 응용 프로그램
또 다른 예로 장면의 조명과 그림자 사이의 전환이 초점이 맞지 않는 이른바 부드러운 그림자가 있다.구체적으로는 이러한 효과 스텐실 완충재를 달성하는 한 가지 방법은 그림자의 부피를 곱하는 것이며, 카피로서 각각 1.04와 같이 저배율의 기하학적 시리즈에 따라 크기가 조정되는 것이다.스케일 중심은 최상위 볼륨을 나타내는 폴리곤의 무게 중심이 될 수 있다.이것 자체가 원하는 효과를 주는 일련의 복합적인 그림자를 줄 것이다.
또 다른 구현에는 모델링 기법 고형물인 CSG(Projective Solid Geometry, CSG) 중 시각화 분야가 포함된다. 여기서 스텐실 버퍼는 Z-버퍼와 함께 SOLiD의 부울 연산의 문제를 성공적으로 해결할 수 있다.
오픈GL
glEnable(GL_스텐실_테스트); // 기본적으로 활성화되지 않음 글라스텐실마스크(스텐실마스크); // 스텐실 버퍼에 쓰기를 허용하며, 기본적으로(0xFF) 마스크 없음 글레클리어스텐실(클리어스텐실값); // 스텐실 값 지우기(기본값 = 0) 글스텐실펑크(펑크, 참조하다, 가면을 쓰다); // 기본적으로 GL_ALSE, 0, 0xFF, 항상 스텐실 테스트 통과 글스텐실롭(실패하다,zfail,zpass); // 기본적으로 GL_KEEP, GL_KEEP, GL_KEEP, 스텐실 버퍼 변경 안 함 글클리어(GL_스텐실_BUFFER_BIT); // 스텐실 버퍼 지우기, (스텐실 값 지우기 & 스텐실 마스크)
검정: (Ref & 마스크 ) 펑크(stencilValue & 마스크)
스텐실 기능/깊이 기능의 가능한 세 가지 조건에 따라 달라진다.
1. Stencil Test Function 실패:
펑크가 GL_NEVENE라고 말하면 스텐실 테스트는 항상 실패한다.컬러/Z-버퍼가 모두 수정되지 않음.스텐실 버퍼는 glStencilOp 실패에 따라 수정된다.glStencilOp(GL_REPlace, GL_KEEP, GL_KEEP)이라고 말하면 GL_REPlace가 발생하고 stencilValue = (ref & stencilMask) //가 ref가 된다.
2. 스텐실 시험 기능 통과/깊이 시험 기능 실패:
펑크가 GL_ALLES라고 말하면 스텐실 테스트는 항상 통과하지만 깊이 테스트는 실패할 수 있다.컬러/Z-버퍼가 모두 수정되지 않았다.스텐실 버퍼는 glStencilOp zfail에 따라 수정된다.만약 GlStencilOp(GL_KEEP, GL_INCR, GL_KEEP)이라고 말하면 GL_INCR이 발생하고 StencilValue = (stencilValue+1) //가 1이 된다.
3. 스텐실 함수 패스/깊이 함수 패스:
펑크가 GL_ALSE라고 말하면 스텐실 테스트는 항상 통과한다.깊이 테스트도 통과하면.컬러/Z-버퍼가 모두 수정되었다.스텐실 버퍼는 glStencilOp zpass에 따라 수정된다.예를 들어, glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)이라고 말하면 StencilOp 값은 변경되지 않고 Color와 Z-buffer만 수정된다.
일반적으로 Stencil buffer는 Z-buffer와 컬러 버퍼 마스크를 false로 설정하여 초기화된다.그런 다음 매번 스텐실 테스트를 통과하지 못하여 적절한 ref 값을 스텐실 버퍼로 설정하십시오.
// 색상 및 Z-버퍼 비활성화 글로컬러마스크(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); 글스텐실펑크(GL_NEVERSE, 1, 0xFF); // 스텐실 테스트를 통과하지 않음 글스텐실롭(GL_REFACE, GL_KEEP, GL_KEEP); // stencil 버퍼 값을 ref=1로 바꾸기 글라스텐실마스크(0xFF); // 스텐실 버퍼 쓰기 가능 글클리어(GL_스텐실_BUFFER_BIT); // 먼저 모든 스텐실 버퍼에 기본 스텐실 값(0)을 작성하여 스텐실 버퍼를 삭제하십시오. draw_stencil_snites(); // 스텐실 버퍼의 스텐실 모양 픽셀 위치에서 스텐실 버퍼 값을 기준 = 1로 바꾸기
이제 초기화된 스텐실 버퍼 및 스텐실 테스트를 사용하여 스텐실 값이 1인 위치에만 기록하십시오.
// 색상 및 Z-버퍼를 활성화하십시오. 글로컬러마스크(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); // 스텐실 및 깊이 패스의 스텐실 버퍼 수정 안 함. 글라스텐실마스크(0x00); // 또한 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)을 통해 달성할 수 있다. // 스텐실 테스트: 스텐실 값 == 1에서 스텐실 테스트만 통과(깊이 테스트는 합격) // 그리고 스텐실 모양 위치에서만 실제 내용을 깊이와 색상 버퍼에 쓰십시오. 글스텐실펑크(GL_EQAL, 1, 0xFF); draw_protection_content();
참고 항목
참조
- ^ https://msdn.microsoft.com/en-us/library/windows/desktop/bb206123(v=vs.85).aspx
- ^ Crow, Franklin C: "컴퓨터 그래픽을 위한 그림자 알고리즘", 컴퓨터 그래픽스 (SIGGRAPH '77 Procedures), 제11권, 제2권, 제242-248권.