Single Pass Instanced 렌더링(’스테레오 인스턴싱’이라고도 불림)을 사용하면 GPU가 단일 렌더 패스를 수행하여 각 드로우 콜을 인스턴스화된 드로우 콜로 교체합니다. 이렇게 하면 두 드로우 콜 간의 캐시 일관성으로 인해 CPU 사용이 대폭 감소하고, GPU 사용은 소폭 감소합니다. 또한 애플리케이션의 전력 소비도 크게 절감됩니다.
VPAndRTArrayIndexFromAnyShaderFeedingRasterizer
확장자를 지원해야 합니다.GL_NV_viewport_array2
GL_AMD_vertex_shader_layer
GL_ARB_shader_viewport_layer_array
이 기능을 활성화하려면 Player 설정(Edit > Project Settings 로 이동한 다음 Player 카테고리 선택)을 엽니다. Player 설정에서 하단의 XR Settings 패널로 이동하고 Virtual Reality Supported 옵션을 선택한 후 Stereo Rendering Method 드롭다운 메뉴에서 Single Pass Instanced (Preview) 를 선택합니다.
기본 Stereo Rendering Method 는 Multi Pass 입니다. 이 설정은 느리지만, 대개 커스텀 셰이더와 사용하면 효과적입니다. 커스텀 셰이더가 있는 경우 Single Pass Instanced 렌더링과 호환되도록 변경해야 할 수 있습니다.
아래의 지침을 따르기 전에 인스턴싱을 사용할 수 있도록 커스텀 셰이더를 업데이트하십시오(GPU 인스턴싱 참조).
그런 다음, 커스텀 셰이더의 프래그먼트 셰이더(Vertex/Hull/Domain/Geometry) 전에 사용된 마지막 셰이더 단계에서 두 가지를 추가로 변경해야 합니다.
각 커스텀 셰이더에 대해 싱글 패스 인스턴스화를 지원하고 싶다면 다음 단계를 따르십시오.
1단계: UNITY_VERTEX_INPUT_INSTANCE_ID
를 appdata struct
에 추가합니다.
예:
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
};
2단계: UNITY_VERTEX_OUTPUT_STEREO
를 v2f output struct
에 추가합니다.
예:
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO //Insert
};
3단계: 메인 vert
메서드 시작 시 UNITY_SETUP_INSTANCE_ID()
매크로를 추가한 후 UNITY_INITIALIZE_OUTPUT(v2f, o)
및 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO()
를 호출합니다.
UNITY_SETUP_INSTANCE_ID()
는 GPU가 어느 쪽 눈을 렌더링하느냐에 따라 빌트인 unity_StereoEyeIndex
및 unity_InstanceID
Unity 셰이더 변수를 계산하여 올바른 값으로 설정합니다.
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO
는 unity_StereoEyeIndex
값을 기반으로 텍스처 배열에서 어느 쪽 눈에 렌더링되어야 하는지 GPU에 알립니다. 또한 이 매크로는 버텍스 셰이더의 unity_StereoEyeIndex
값을 전송하여 프래그먼트 셰이더 frag
메서드에서 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX
가 호출된 경우에만 프래그먼트 셰이더에서 액세스할 수 있도록 만듭니다.
UNITY_INITALIZE_OUTPUT(v2f,o)
는 모든 v2f
값을 0으로 초기화합니다.
예:
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v); //Insert
UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
포스트 프로세싱 셰이더가 싱글 패스 인스턴스화를 지원하도록 만들고 싶으면 커스텀 셰이더의 단계와 아래 단계를 따르십시오. 모든 Unity 기본 셰이더 스크립트는 Unity 웹사이트에서 다운로드할 수 있습니다.
싱글 패스 인스턴스화를 지원하도록 만들 각 포스트 프로세싱 셰이더에 대해 다음을 수행하십시오.
1단계: 특정 스테레오 렌더링 메서드 사용 시 GPU가 그에 적합한 텍스처 샘플러를 사용할 수 있도록 frag 메서드 외부의 UNITY_DECLARE_SCREENSPACE_TEXTURE(tex) 매크로를 셰이더 스크립트에 추가합니다(아래의 배치 예시 참조). 예를 들어, 멀티 패스 렌더링을 사용하는 경우 GPU가 텍스처 2D 샘플러를 사용합니다. 싱글 패스 인스턴스화 또는 멀티 뷰 렌더링의 경우 텍스처 샘플러는 텍스처 배열입니다.
2단계: 프래그먼트 셰이더 frag 메서드 시작 시 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i)
를 추가합니다(아래의 배치 예시 참조). 이 매크로만 추가하면 unity_StereoEyeIndex
빌트인 셰이더 변수를 사용하여 GPU가 어느 쪽 눈에 대해 렌더링하고 있는지 확인할 수 있습니다. 이 기능은 포스트 프로세싱 효과를 테스트할 때 유용합니다.
3단계: UNITY_SAMPLE_SCREENSPACE_TEXTURE()
매크로를 사용하여 2D 텍스처를 샘플링합니다(아래의 배치 예시 참조). 스탠다드 셰이더는 2D 텍스처 기반 백 버퍼를 사용하여 텍스처를 샘플링합니다. 싱글 패스 스테레오 인스턴싱은 이 타입의 백 버퍼를 사용하지 않습니다. 따라서 2D 텍스처 샘플링에 다른 메서드를 지정하지 않으면 셰이더가 제대로 렌더링하지 못합니다. 이러한 렌더링 문제를 막기 위해 UNITY_SAMPLE_SCREENSPACE_TEXTURE()
매크로는 어느 스테레오 렌더링 경로가 사용 중인지 감지한 후 올바른 방식으로 텍스처를 자동 샘플링합니다. 뎁스 텍스처 및 스크린 공간 섀도우 맵에 사용되는 유사한 매크로에 대한 내용은 HLSLSupport.cginc에 대한 Unity 기술 자료를 확인하십시오.
예:
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Insert
fixed4 frag (v2f i) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); //Insert
fixed4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Insert
// just invert the colors
col = 1 - col;
return col;
}
아래는 템플릿 이미지 효과 셰이더의 간단한 예제이며 이전에 언급한 모든 변경 사항을 적용하여 싱글 패스 인스턴스화를 지원하도록 만들었습니다. 셰이더 코드에 대한 추가 부분은 코멘트(//Insert
)로 표시되어 있습니다.
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
};
//v2f output struct
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO //Insert
};
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v); //Insert
UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Insert
fixed4 frag (v2f i) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); //Insert
fixed4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Insert
// invert the colors
col = 1 - col;
return col;
}
Graphics.DrawProceduralIndirect() 및 CommandBuffer.DrawProceduralIndirect() 메서드를 사용하여 GPU의 절차적 지오메트리를 완전히 드로우할 때는 두 메서드 모두 컴퓨트 버퍼에서 인자를 받는다는 점에 유의하십시오. 따라서 런타임 시점에 인스턴스 수를 늘리기가 어렵습니다. 인스턴스 수를 늘리려면 컴퓨트 버퍼에 포함된 인스턴스 수를 수동으로 두 배로 만들어야 합니다.
셰이더 코드를 작성하는 방법은 버텍스 및 프래그먼트 셰이더 예제를 참조하십시오.
다음 셰이더 코드는 사용자의 왼쪽 눈에는 녹색으로, 사용자의 오른쪽 눈에는 적색으로 게임 오브젝트를 렌더링합니다. 이 셰이더를 사용하면 모든 스테레오 그래픽스가 제대로 동작 및 기능하는지 확인할 수 있기 때문에 스테레오 렌더링을 디버그할 때 특히 유용합니다.
Shader "XR/StereoEyeIndexColor"
{
Properties
{
_LeftEyeColor("Left Eye Color", COLOR) = (0,1,0,1)
_RightEyeColor("Right Eye Color", COLOR) = (1,0,0,1)
}
SubShader
{
Tags { "RenderType" = "Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 _LeftEyeColor;
float4 _RightEyeColor;
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_OUTPUT(v2f, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
return lerp(_LeftEyeColor, _RightEyeColor, unity_StereoEyeIndex);
}
ENDCG
}
}
}
2018–09–07 페이지 게시됨
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.