Effect QML Type
후처리 효과를 생성하기 위한 기본 구성 요소. 더 보기...
| Import Statement: | import QtQuick3D |
| Inherits: |
속성
- passes : list
상세 설명
'효과' 유형을 사용하면 사용자가 QtQuick3D 에 대한 자체 후처리 효과를 구현할 수 있습니다.
후처리 효과
포스트 프로세싱 이펙트는 개념적으로 Qt Quick 의 ‘ ShaderEffect ’ 항목과 매우 유사합니다. 이펙트가 적용되면, 먼저 장면이 별도의 텍스처로 렌더링됩니다. 그런 다음 View3D 의 render mode 에 따라 텍스처가 적용된 사각형을 메인 렌더 타겟에 그려 이펙트를 적용합니다. 이펙트는 버텍스 셰이더, 프래그먼트 셰이더 또는 둘 다를 제공할 수 있습니다. 이펙트는 항상 View3D 에 따라 전체 씬에 적용됩니다.
이펙트는 SceneEnvironment::effects 속성을 통해 SceneEnvironment 와 연결됩니다. 이 속성은 목록 형태이며, 이펙트를 서로 연결하여 사용할 수 있습니다. 이펙트는 목록에 나열된 순서대로 적용되며, 이전 단계의 출력을 다음 단계의 입력으로 사용합니다. 마지막 이펙트의 출력은 View3D 의 내용을 정의합니다.
참고: SceneEnvironment 및 ExtendedSceneEnvironment 는 피사계 심도, 글로우/블룸, 렌즈 플레어, 컬러 그레이딩, 비네팅과 같은 일련의 내장 이펙트를 제공합니다. 항상 이러한 이펙트만으로도 응용 프로그램의 요구 사항을 충족할 수 있는지 먼저 고려하고, 사용자 정의 후처리 이펙트를 구현하기보다는 내장 기능을 사용하는 것을 우선으로 하십시오.
이펙트는 여러 면에서 custom materials 과 유사합니다. 그러나 사용자 정의 머티리얼은 모델과 연관되어 있으며, 해당 메쉬의 셰이딩을 담당합니다. 반면 이펙트의 버텍스 셰이더는 항상 쿼드(예: 두 개의 삼각형)를 입력으로 받는 반면, 프래그먼트 셰이더는 씬의 콘텐츠와 함께 텍스처를 샘플링합니다.
사용자 정의 머티리얼과 달리, 이펙트는 다중 패스를 지원합니다. 많은 이펙트의 경우 이는 필요하지 않으며, 여러 이펙트를 적용해야 할 때는 the SceneEnvironment 에서 여러 이펙트를 연쇄적으로 연결하여 동일한 결과를 얻을 수 있는 경우가 많습니다. 이는 ‘사용자 정의 이펙트(Custom Effect)’ 예제에서도 확인할 수 있습니다. 그러나 패스는 추가적인 컬러 버퍼(텍스처)를 요청하고, 이러한 추가 버퍼 중 어느 것으로 출력할지 지정할 수 있습니다. 이를 통해 후속 패스가 원본 장면의 콘텐츠와 더불어 하나 이상의 추가 버퍼를 입력으로 사용할 수 있으므로, 더 복잡한 이미지 처리 기법을 구현할 수 있습니다. 필요한 경우, 이러한 추가 버퍼의 수명을 연장할 수 있습니다. 즉, 프레임 간에 내용이 보존되므로 모션 블러와 같이 여러 프레임의 내용을 누적하는 효과 구현이 가능합니다.
Qt Quick 의 2D ShaderEffect 와 비교할 때, 3D 후처리 효과는 깊이 버퍼 데이터를 활용할 수 있다는 장점과 중간 버퍼를 사용하여 여러 패스를 구현할 수 있다는 장점이 있습니다. 또한, 텍스처 관련 기능이 확장되었습니다. ` Qt Quick 3D `를 사용하면 필터링 모드를 더 세밀하게 제어할 수 있으며, RGBA8 이외의 텍스처 형식(예: 부동 소수점 형식)에서도 효과를 적용할 수 있습니다.
참고: 포스트 프로세싱 효과는 현재 View3D 의 renderMode 가 Offscreen, Underlay 또는 Overlay 로 설정되어 있을 때 사용할 수 있습니다. Inline 모드에서는 효과가 렌더링되지 않습니다.
참고: 후처리 효과를 사용할때 , 애플리케이션에서 제공하는 셰이더는 톤 매핑이 적용되지 않은 선형 색상 데이터를 처리할 수 있어야 합니다. tonemapMode 가 SceneEnvironment.TonemapModeNone 이외의 값으로 설정된 경우 메인 렌더 패스(또는 스카이박스가 있는 경우 스카이박스 렌더링) 중에 수행되는 톤 매핑은, SceneEnvironment 에 하나 이상의 후처리 효과가 지정되어 있으면 자동으로 비활성화됩니다. 체인 내의 마지막 이펙트(더 정확하게는 체인 내 마지막 이펙트의 마지막 패스)는 메인 렌더 패스에서 수행되던 것과 동일한 톤 매핑을 수행하도록 프래그먼트 셰이더가 자동으로 수정됩니다.
참고: 자체 톤 매핑을 수행하는이펙트는 tonemapMode 을 SceneEnvironment.TonemapModeNone 로 설정하여 내장 톤 매핑을 비활성화한 SceneEnvironment 에서 사용해야 합니다.
참고: 기본적으로 이펙트의 입력으로 사용되는 텍스처는 16비트 부동소수점 RGBA와 같은 부동소수점 텍스처 형식으로 생성됩니다. 출력 텍스처의 형식은 기본적으로 입력 형식을 따르기 때문에 동일합니다. 이는 Buffer 를 사용하고 이름을 비워두면 재정의할 수 있습니다. 기본값인 RGBA16F는 0-1 범위를 벗어난 색상 값이 클램핑되지 않도록 하여, 톤 매핑되지 않은 선형 데이터로 작업할 수 있게 해주기 때문에 유용합니다.
셰이더에 데이터 노출
CustomMaterial 이나 ShaderEffect 와 마찬가지로, Effect 객체의 동적 속성은 일반적인 QML 및 Qt Quick 기능을 사용하여 변경 및 애니메이션화할 수 있으며, 해당 값은 셰이더에 자동으로 노출됩니다. 다음 목록은 속성이 어떻게 매핑되는지 보여줍니다:
- bool, int, real -> bool, int, float
- QColor, color -> vec4이며, QML에 지정된 색상 값이 sRGB 색 공간을 가정할 경우 색상은 선형(linear)으로 변환됩니다.
"green"과 같은 내장 Qt 색상 역시 sRGB 색 공간에 속하며, DefaultMaterial 및 PrincipledMaterial 의 모든 색상 속성에 대해서도 동일한 변환이 수행되므로, Effect의 이러한 동작은 이와 일치합니다. - QRect, QRectF, rect → vec4
- QPoint, QPointF, point, QSize, QSizeF, size -> vec2
- QVector2D, vector2d -> vec3
- QVector3D, vector3d -> vec3
- QVector4D, vector4d -> vec4
- QMatrix4x4, matrix4x4 -> mat4
- QQuaternion, quaternion -> vec4, 스칼라 값은
w - TextureInput -> sampler2D 또는 samplerCube가 됩니다. 이는 TextureInput 의 texture 속성에 Texture 또는 CubeMapTexture 중 어느 것이 사용되었는지에 따라 달라집니다. enabled 속성을 false로 설정하면 셰이더에 더미 텍스처가 노출되는데, 이는 셰이더가 여전히 작동하지만 불투명한 검은색 이미지가 포함된 텍스처를 샘플링하게 됨을 의미합니다. 샘플러의 속성은 항상 TextureInput 객체를 참조해야 하며, Texture 를 직접 참조해서는 안 된다는 점에 유의하십시오. Texture 의 속성 중 소스, 타일링 및 필터링과 관련된 속성만이 이펙트에서 암시적으로 고려되며, 나머지(예: UV 변환)는 사용자 정의 셰이더에서 필요에 따라 구현해야 합니다.
참고: 셰이더 코드에서 참조된 유니폼에 해당 속성이 없는경우 , 런타임에 이펙트를 처리할 때 셰이더 컴파일 오류가 발생합니다. 이에 대한 몇 가지 예외가 있는데, 예를 들어 샘플러 유니폼의 경우, 해당 QML 속성이 없을 때 더미 텍스처가 바인딩되지만, 일반적인 규칙으로는 모든 유니폼과 샘플러에 대해 Effect 객체에 해당 속성이 선언되어 있어야 합니다.
사용자 정의 이펙트 시작하기
사용자 정의 후처리 이펙트를 구현하려면 최소한 Effect 객체와 프래그먼트 셰이더 스니펫이 필요합니다. 일부 이펙트의 경우 사용자 정의 버텍스 셰이더도 필요할 수 있습니다.
간단한 예로, 씬의 콘텐츠와 이미지를 결합하고, 동시에 적색 채널의 값을 애니메이션 방식으로 변경하는 이펙트를 만들어 보겠습니다:
| |
여기서 image.png 이미지가 담긴 텍스처는 tex 라는 이름으로 셰이더에 노출됩니다. redLevel의 값은 셰이더 내에서 동일한 이름의 float 유니폼을 통해 사용할 수 있습니다.
프래그먼트 셰이더에는 MAIN 이라는 함수가 포함되어야 합니다. 최종 프래그먼트 색상은 FRAGCOLOR 에 의해 결정됩니다. View3D 의 장면 내용을 담은 주요 입력 텍스처는 sampler2D 에서 INPUT 라는 이름으로 접근할 수 있습니다. 쿼드(quad)의 UV 좌표는 INPUT_UV 에 있습니다. 이 UV 값들은 실행 시의 기본 그래픽 API에 관계없이(따라서 Qt Quick 3D 에 의해 필요한 조정이 자동으로 적용되므로 이미지의 Y축 방향과도 관계없이) 항상 INPUT 를 샘플링하는 데 적합합니다. 외부 이미지를 사용하여 텍스처를 샘플링하는 작업은 TEXTURE_UV 를 통해 수행됩니다. INPUT_UV 는 크로스 플랫폼 애플리케이션에서는 적합하지 않습니다. 앞서 언급한 좌표계 차이를 처리하기 위해 V를 반전시켜야 하는데, 이는 이미지를 기반으로 한 텍스처와 렌더 타겟으로 사용되는 텍스처에 따라 서로 다른 논리를 적용해야 하기 때문입니다. 다행히 이 모든 작업은 엔진에서 처리하므로 셰이더 측에서 이를 위한 추가 논리를 구현할 필요가 없습니다.
simpleEffect가 준비되면, 이를 View3D 의 SceneEnvironment 효과 목록에 연결할 수 있습니다:
environment: SceneEnvironment {
effects: [ simpleEffect ]
}결과는 다음과 같이 표시되며, 왼쪽은 원본 장면이고 오른쪽은 효과가 적용된 모습입니다:
|
|
참고: Shader의 shader 속성값은 QML 및 Qt Quick 의 관례에 따라 URL 형식이며, 셰이더 스니펫이 포함된 파일을 참조합니다. 이 방식은 ShaderEffect 또는 Image.source 와 매우 유사하게 작동합니다. file 및 qrc 스키마만 지원됩니다. 또한 file 형식을 생략하여 편리한 방식으로 상대 경로를 지정할 수도 있습니다. 이러한 경로는 컴포넌트( .qml 파일)의 위치를 기준으로 해석됩니다.
참고: 셰이더 코드는 실행 시 Qt가 사용하는 그래픽 API와 관계없이 항상 Vulkan 스타일의 GLSL로 제공됩니다.
참고: 이펙트에서 제공하는 버텍스 및 프래그먼트 셰이더코드는 그 자체로 완전한 GLSL 셰이더가 아닙니다. 오히려 이 코드는 ` MAIN ` 함수와 선택적으로 일련의 ` VARYING ` 선언을 제공하며, 이후 엔진에서 추가 셰이더 코드로 보완됩니다.
참고: 위의예제는 일부 VR/AR 애플리케이션에서 사용되는 선택적 멀티뷰 렌더링 모드와 호환되지 않습니다. 멀티뷰 모드 사용 여부에 관계없이 작동하도록 하려면 MAIN()을 다음과 같이 변경하십시오:
void MAIN()
{
vec4 c = texture(tex, TEXTURE_UV);
c.r *= redLevel;
#if QSHADER_VIEW_COUNT >= 2
FRAGCOLOR = c * texture(INPUT, vec3(INPUT_UV, VIEW_INDEX));
#else
FRAGCOLOR = c * texture(INPUT, INPUT_UV);
#endif
}버텍스 셰이더를 사용하는 이펙트
버텍스 셰이더가 포함된 경우, 반드시 ` MAIN`라는 함수를 제공해야 합니다. 대부분의 경우 사용자 정의 버텍스 셰이더는 동질 버텍스 위치에 대한 자체 계산을 제공하지 않겠지만, ` POSITION`, ` VERTEX`, ` MODELVIEWPROJECTION_MATRIX`를 사용하여 이를 구현할 수 있습니다. 사용자 정의 셰이더 코드에 ` POSITION `가 없는 경우, ` Qt Quick 3D`에 의해 ` POSITION = MODELVIEWPROJECTION_MATRIX * vec4(VERTEX, 1.0); `와 동등한 문장이 자동으로 삽입됩니다.
버텍스 셰이더와 프래그먼트 셰이더 간에 데이터를 전달하려면 VARYING 키워드를 사용합니다. 내부적으로는 이 키워드가 적절한 버텍스 출력 또는 프래그먼트 입력 선언으로 변환됩니다. 프래그먼트 셰이더는 동일한 선언을 사용할 수 있으며, 이를 통해 현재 프래그먼트에 대한 보간된 값을 읽을 수 있습니다.
내장된 DistortionSpiral 효과와 사실상 매우 유사한 예제를 살펴보겠습니다:
| |
이제 Effect 객체의 ` passes ` 목록에는 버텍스 및 프래그먼트 스니펫이 모두 지정되어야 합니다:
passes: Pass {
shaders: [
Shader {
stage: Shader.Vertex
shader: "effect.vert"
},
Shader {
stage: Shader.Fragment
shader: "effect.frag"
}
]
}최종 결과는 다음과 같습니다:
|
|
이펙트 셰이더의 특수 키워드
VARYING- 현재 셰이더의 유형에 따라 버텍스 출력 또는 프래그먼트 입력을 선언합니다.MAIN- 이 함수는 효과 셰이더에 반드시 포함되어야 합니다.FRAGCOLOR-vec4- 최종 프래그먼트 색상; 프래그먼트 셰이더의 출력값입니다. (프래그먼트 셰이더 전용)POSITION-vec4- 버텍스 셰이더에서 계산된 동질 좌표입니다. (버텍스 셰이더 전용)MODELVIEWPROJECTION_MATRIX-mat4- 화면 사각형에 대한 변환 행렬입니다.VERTEX-vec3- 쿼드의 정점; 버텍스 셰이더의 입력값입니다. (버텍스 셰이더 전용)INPUT-sampler2D또는sampler2DArray- 장면이 렌더링된 입력 텍스처에 대한 샘플러입니다. 단, 패스가 BufferInput 객체를 통해 입력을 리디렉션하는 경우에는INPUT가 BufferInput 에 의해 참조되는 추가 색상 버퍼의 텍스처를 가리킵니다. VR/AR 애플리케이션과 관련이 있을 수 있는 멀티뷰 렌더링이 활성화된 경우, 이는 샘플러2D배열(sampler2DArray)이 되며, 입력 텍스처는 2D 텍스처 배열이 됩니다.INPUT_UV-vec2-INPUT에서 샘플링하기 위한 UV 좌표.TEXTURE_UV-vec2- 이미지 파일에서 불러온 내용을 가진 텍스처를 샘플링하는 데 적합한 UV 좌표입니다.INPUT_SIZE-vec2-INPUT텍스처의 크기(픽셀 단위).OUTPUT_SIZE-vec2- 출력 버퍼의 크기(픽셀 단위). 패스가 크기 배율이 적용된 별도의 버퍼로 출력하는 경우가 아니라면, 대개INPUT_SIZE과 동일합니다.FRAME-float- 프레임 카운터로, View3D 의 각 프레임이 끝날 때마다 1씩 증가합니다.DEPTH_TEXTURE-sampler2D또는sampler2DArray- 씬 내 불투명 오브젝트의 깊이 버퍼 내용을 담은 깊이 텍스처입니다. CustomMaterial 와 마찬가지로, 셰이더에 이 키워드가 존재하면 깊이 텍스처가 자동으로 생성됩니다.NORMAL_ROUGHNESS_TEXTURE-sampler2D- 장면의 현재 가시 영역에 있는 불투명 오브젝트의 월드 공간 법선 및 머티리얼 거칠기 정보를 담은 텍스처입니다. CustomMaterial 와 마찬가지로, 셰이더에 이 키워드가 포함되면 법선 텍스처를 생성하기 위한 추가 렌더 패스가 수행됩니다.VIEW_INDEX-uint- 멀티뷰 렌더링이 활성화된 경우, 현재 뷰 인덱스로, 버텍스 셰이더와 프래그먼트 셰이더 모두에서 사용할 수 있습니다. 멀티뷰 렌더링을 사용하지 않을 때는 항상 0입니다.PROJECTION_MATRIX-mat4, 투영 행렬입니다. 멀티뷰 렌더링이 활성화된 경우, 이는 행렬의 배열이라는 점에 유의하십시오.INVERSE_PROJECTION_MATRIX-mat4, 역투영 행렬입니다. 멀티뷰 렌더링이 활성화된 경우, 이는 행렬 배열임을 유의하십시오.VIEW_MATRIX->mat4, 뷰(카메라) 행렬입니다. 멀티뷰 렌더링을 사용할 경우, 이는 행렬 배열임을 유의하십시오.- float
NDC_Y_UP- 정규화된 장치 좌표계에서 Y축이 위를 향할 때 값은1이며, Y축이 아래를 향할 때는-1입니다. Y축이 아래를 향하는 경우는 Vulkan으로 렌더링할 때 해당됩니다. - float
FRAMEBUFFER_Y_UP- 프레임버퍼(텍스처) 좌표계에서 Y축이 위를 향할 때 값은1이며, 이는(0, 0)가 왼쪽 하단 모서리임을 의미합니다. Y축이 아래를 향할 때 값은-1이며,(0, 0)가 왼쪽 상단 모서리가 됩니다. - float
NEAR_CLIP_VALUE- 클리핑 평면 범위가-1에서 시작하여1까지일 때 이 값은-1입니다. 이는 OpenGL을 사용하여 렌더링할 때 해당됩니다. 다른 렌더링 백엔드의 경우 이 속성의 값은0이며, 이는 클리핑 평면 범위가0에서1까지임을 의미합니다.
멀티패스 효과 구축
멀티패스 이펙트는 종종 하나 이상의 셰이더 세트를 사용하며, ` output ` 및 ` commands ` 속성을 활용합니다. 패스 목록의 각 항목은 이펙트의 입력 텍스처와 선택적으로 다른 텍스처도 샘플링하면서, 해당 패스의 출력 텍스처에 사각형을 그리는 렌더 패스로 변환됩니다.
일반적인 멀티패스 이펙트의 구조는 다음과 같습니다:
passes: [
Pass {
shaders: [
Shader {
stage: Shader.Vertex
shader: "pass1.vert"
},
Shader {
stage: Shader.Fragment
shader: "pass1.frag"
}
// This pass outputs to the intermediate texture described
// by the Buffer object.
output: intermediateColorBuffer
],
},
Pass {
shaders: [
Shader {
stage: Shader.Vertex
shader: "pass2.vert"
},
Shader {
stage: Shader.Fragment
shader: "pass2.frag"
}
// The output of the last pass needs no redirection, it is
// the final result of the effect.
],
commands: [
// This pass reads from the intermediate texture, meaning
// INPUT in the shader will refer to the texture associated
// with the Buffer.
BufferInput {
buffer: intermediateColorBuffer
}
]
}
]intermediateColorBuffer 란 무엇인가요?
Buffer {
id: intermediateColorBuffer
name: "tempBuffer"
// format: Buffer.RGBA8
// textureFilterOperation: Buffer.Linear
// textureCoordOperation: Buffer.ClampToEdge
}원하는 값이 기본값과 일치하는 경우, 주석 처리된 속성은 필요하지 않습니다.
내부적으로 이 Buffer 객체가 존재하고, 패스(Pass)의 output 속성에서 이를 참조하면 View3D 와 일치하는 크기의 텍스처가 생성되며, 이는 암시적 입력 및 출력 텍스처의 크기와 동일합니다. 이를 원하지 않는 경우, ` sizeMultiplier ` 속성을 사용하여 다른 크기의 중간 텍스처를 얻을 수 있습니다. 이로 인해 셰이더 내의 ` INPUT_SIZE ` 및 ` OUTPUT_SIZE ` 유니폼 값이 달라질 수 있습니다.
기본적으로 이펙트는 프레임 간에 텍스처의 내용이 유지된다고 가정할 수 없습니다. 새로운 중간 텍스처가 생성되면, 해당 텍스처는 ` vec4(0.0)`로 초기화됩니다. 이후 동일한 텍스처를 다른 용도로 재사용할 수 있습니다. 따라서 이펙트 패스는 패스 시작 시 텍스처의 내용에 대해 어떠한 가정도 하지 말고, 항상 전체 텍스처에 쓰기를 수행해야 합니다. 단, bufferFlags 가 Buffer.SceneLifetime으로 설정된 버퍼 오브젝트의 경우 예외입니다. 이는 텍스처가 이펙트의 특정 패스와 영구적으로 연결되어 있으며 다른 용도로 재사용되지 않음을 나타냅니다. 이러한 컬러 버퍼의 내용은 프레임 간에 유지됩니다. 이는 일반적으로 모션 블러와 같은 이펙트에서 핑퐁 방식으로 사용됩니다. 첫 번째 패스는 이펙트의 주 입력 텍스처 외에도 영속적인 버퍼를 입력으로 받아 다른 중간 버퍼로 출력하고, 두 번째 패스는 영속적인 버퍼로 출력합니다. 이러한 방식으로 첫 번째 프레임에서는 첫 번째 패스가 빈(투명한) 텍스처를 샘플링하는 반면, 이후 프레임에서는 이전 프레임의 두 번째 패스 출력을 샘플링합니다. 그런 다음 세 번째 패스는 이펙트의 입력과 두 번째 패스의 출력을 함께 블렌딩할 수 있습니다.
BufferInput 명령어 유형은 사용자 정의 텍스처 버퍼를 렌더 패스에 노출하는 데 사용됩니다.
예를 들어, 렌더 패스 셰이더에서 mySampler 라는 이름으로 ` someBuffer `에 접근하려면, 다음을 해당 명령 목록에 추가할 수 있습니다.
BufferInput { buffer: someBuffer; sampler: "mySampler" }sampler 이름이 지정되지 않은 경우, INPUT 가 기본값으로 사용됩니다.
버퍼는 렌더 패스 간에 중간 결과를 공유하는 데 유용할 수 있습니다.
사전에 로드된 텍스처를 이펙트에 노출시키려면 대신 ` TextureInput `을 사용해야 합니다. 이러한 텍스처는 이펙트 자체의 속성으로 정의할 수 있으며, 셰이더에서는 해당 속성 이름을 통해 자동으로 접근할 수 있습니다.
property TextureInput tex: TextureInput {
texture: Texture { source: "image.png" }
}여기서 tex 는 이펙트의 모든 패스에 속한 모든 셰이더에서 유효한 샘플러입니다.
속성에서 가져온 유니폼 값의 경우, 이펙트의 모든 패스에서 셰이더가 동일한 값을 읽습니다. 필요한 경우 특정 패스에 대해서만 유니폼 값을 재정의할 수 있습니다. 이는 해당 패스의 명령어 목록에 ` SetUniformValue ` 명령어를 추가함으로써 구현됩니다.
참고: 패스별 유니폼 값 설정명령어인 ` target `는 해당 이펙트의 속성 이름만을 참조할 수 있습니다. 이 명령어는 속성에 대응하는 유니폼의 값을 재정의할 수는 있지만, 새로운 유니폼을 생성할 수는 없습니다.
성능 관련 고려 사항
포스트 프로세싱 이펙트를 사용할 때는 리소스 사용량이 증가하고 성능이 저하될 수 있음을 유의하십시오. Qt Quick 레이어 및 ShaderEffect 와 마찬가지로, 씬을 텍스처로 렌더링한 후 이를 사용하여 쿼드에 텍스처를 적용하는 작업은, 특히 프래그먼트 처리 능력이 제한된 저사양 하드웨어에서는 비용이 많이 드는 작업입니다. 추가적으로 필요한 그래픽 메모리 용량과 GPU 부하 증가는 모두 View3D 의 크기에 따라 달라집니다(윈도우링 시스템이 없는 임베디드 장치의 경우, 이 크기가 화면 해상도만큼 클 수도 있습니다). 멀티패스 효과나 여러 효과를 적용하면 리소스 및 성능 요구 사항이 더욱 증가합니다.
따라서 개발 라이프사이클 초기 단계에서, 대상 기기와 그래픽 스택이 최종 제품의 화면 해상도에서 3D 씬 설계에 포함된 효과를 처리할 수 있는지 확인하는 것이 매우 권장됩니다.
필요할 때 피할 수 없는 기법이지만, DEPTH_TEXTURE 는 해당 텍스처의 내용을 생성하기 위해 추가적인 렌더링 패스를 필요로 하며, 이는 성능이 낮은 하드웨어에서 성능 저하를 초래할 수도 있습니다. 따라서 효과의 셰이더에서 DEPTH_TEXTURE 는 꼭 필요한 경우에만 사용하십시오.
셰이더 내 연산의 복잡도 또한 중요합니다. CustomMaterial 와 마찬가지로, 최적화되지 않은 프래그먼트 셰이더는 렌더링 성능 저하로 쉽게 이어질 수 있습니다.
sizeMultiplier in Buffer 을 사용할 때 값이 1보다 큰 경우에는 주의해야 합니다. 예를 들어, 배율이 4라면 View3D 의 4배 크기의 텍스처를 생성한 후 렌더링해야 합니다. 섀도우 맵이나 멀티샘플링, 슈퍼샘플링과 마찬가지로, GPU 성능이 제한된 시스템에서는 증가된 리소스 및 성능 비용이 화질 개선으로 얻는 이점을 금세 상쇄할 수 있습니다.
VR/AR 관련 고려 사항
Qt Quick 3D XR을 사용하여 가상 현실(VR) 또는 증강 현실(AR)용 애플리케이션을 개발할 때, 후처리 효과는 정상적으로 작동하며 사용할 수 있습니다. 그러나 디자이너와 개발자는 가상 현실 환경에서 어떤 효과, 어떤 종류의 효과가 적합한지 특별히 주의 깊게 파악해야 합니다. ExtendedSceneEnvironment 에 내장된 일부 효과나 더 이상 사용되지 않는 Effects 모듈의 효과 중 일부를 포함한 일부 효과는 VR 환경에서 좋은 시각적 경험을 제공하지 못할 뿐만 아니라, 사용자에게 신체적 영향을 미칠 수도 있습니다(예를 들어, 멀미나 현기증을 유발할 수 있음).
VR/AR 애플리케이션에서 더 효율적인 멀티뷰 렌더링 모드가 활성화되면, 왼쪽 눈과 오른쪽 눈의 콘텐츠에 대해 별도의 렌더링 패스가 수행되지 않습니다. 대신, 두 개의 독립적인 2D 텍스처 대신 두 개의 레이어로 구성된 2D 텍스처 배열을 사용하여 모든 과정이 한 번의 패스로 처리됩니다. 이는 또한 이 모드에서 색상 또는 깊이 텍스처와 같은 많은 중간 버퍼가 텍스처 배열로 변환되어야 함을 의미합니다. 이는 사용자 정의 머티리얼과 후처리 효과에 영향을 미칩니다. 입력 텍스처(INPUT) 및 깊이 텍스처(DEPTH_TEXTURE)와 같은 텍스처는 2D 텍스처 배열이 되며, 셰이더에서는 sampler2D 대신 sampler2DArray 로 노출됩니다. 이는 texture(), textureLod(), textureSize()와 같은 GLSL 함수에 영향을 미칩니다. 따라서 UV 좌표는 vec2가 아닌 vec3이 됩니다. 반면 textureSize()는 vec2가 아닌 vec3을 반환합니다. 렌더링 모드와 관계없이 작동하도록 의도된 이펙트는 적절한 ifdef를 사용하여 작성할 수 있습니다:
#if QSHADER_VIEW_COUNT >= 2
vec4 c = texture(INPUT, vec3(INPUT_UV, VIEW_INDEX));
#else
vec4 c = texture(INPUT, INPUT_UV);
#endif두 경우를 모두 처리하는 매크로를 정의하는 것도 유용할 수 있습니다. 예를 들어:
#if QSHADER_VIEW_COUNT >= 2
#define SAMPLE_INPUT(uv) texture(INPUT, vec3(uv, VIEW_INDEX))
#define SAMPLE_DEPTH(uv) texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)).r
#define PROJECTION PROJECTION_MATRIX[VIEW_INDEX]
#define INVERSE_PROJECTION INVERSE_PROJECTION_MATRIX[VIEW_INDEX]
#else
#define SAMPLE_INPUT(uv) texture(INPUT, uv)
#define SAMPLE_DEPTH(uv) texture(DEPTH_TEXTURE, uv).r
#define PROJECTION PROJECTION_MATRIX
#define INVERSE_PROJECTION INVERSE_PROJECTION_MATRIX
#endif이는 멀티뷰 렌더링이 활성화된 경우에도 항상 2D 텍스처인 ` NORMAL_ROUGHNESS_TEXTURE `에는 적용되지 않습니다:
#define SAMPLE_NORMAL(uv) normalize(texture(NORMAL_ROUGHNESS_TEXTURE, uv).rgb)참고: DEPTH_TEXTURE 와 같은 키워드가존재하면 추가 렌더링 패스가 트리거되며, INVERSE_PROJECTION_MATRIX 와 같은 유니폼은 셰이더 스니펫 내 어디에서든 해당 키워드가 존재할 경우 계산되어 설정됩니다. 이는 성능과 리소스 사용 측면 모두에서 더 많은 부하를 초래합니다. 따라서 텍스처와 행렬이 이펙트에서 실제로 사용될 때에만 이러한 #define을 추가하는 것이 권장됩니다.
Shader, Pass, Buffer, BufferInput 및 Qt Quick 3D - 사용자 정의 이펙트 예제도참조하십시오 .
속성 설명서
passes : list [read-only]
이 효과에서 구현된 렌더링 passes 의 목록이 포함되어 있습니다.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.


