diff options
10 files changed, 63 insertions, 108 deletions
diff --git a/src/quick3d/doc/src/qtquick3d-custom.qdoc b/src/quick3d/doc/src/qtquick3d-custom.qdoc index 2d45dcb9..ea1598d8 100644 --- a/src/quick3d/doc/src/qtquick3d-custom.qdoc +++ b/src/quick3d/doc/src/qtquick3d-custom.qdoc @@ -1310,20 +1310,6 @@ void MAIN() Here the rectangle is textured with \c SCREEN_TEXTURE, while replacing transparent pixels with purple. -Custom materials written to be used with Qt Quick 3D XR should consider relying -on \c DEPTH_TEXTURE_ARRAY instead of \c DEPTH_TEXTURE, and \c -SCREEN_TEXTURE_ARRAY instead of \c SCREEN_TEXTURE. This needs to be ifdefed so -that referencing the texture array is only done when multiview rendering is in -use: - -\badcode - #if QSHADER_VIEW_COUNT >= 2 - vec4 depthSample = texture(DEPTH_TEXTURE_ARRAY, vec3(uv, VIEW_INDEX)); - #else - vec4 depthSample = texture(DEPTH_TEXTURE, uv); - #endif -\endcode - \section2 Light processor functions An advanced feature of \l CustomMaterial is the ability to define functions in the diff --git a/src/quick3d/qquick3dcustommaterial.cpp b/src/quick3d/qquick3dcustommaterial.cpp index 73c2a18e..4329258d 100644 --- a/src/quick3d/qquick3dcustommaterial.cpp +++ b/src/quick3d/qquick3dcustommaterial.cpp @@ -1098,6 +1098,16 @@ QT_BEGIN_NAMESPACE BASE_COLOR = vec4(vec3(c), alpha); } \endcode + With multiview rendering, \c SCREEN_TEXTURE is a \c sampler2DArray. Use + \c VIEW_INDEX to select the layer to use. For VR/AR applications that wish to + support both types of rendering, the portable approach is the following: + \badcode + #if QSHADER_VIEW_COUNT >= 2 + vec4 c = texture(SCREEN_TEXTURE, vec3(uv, VIEW_INDEX)); + #else + vec4 c = texture(SCREEN_TEXTURE, uv); + #endif + \endcode \li \c SCREEN_MIP_TEXTURE - Identical to \c SCREEN_TEXTURE in most ways, the difference being that this texture has mipmaps generated. This can be @@ -1107,23 +1117,7 @@ QT_BEGIN_NAMESPACE relying on the texture mip levels (e.g. using \c textureLod in the shader) is implemented by the custom material. - \li \c SCREEN_TEXTURE_ARRAY - When present, a texture array (sampler2DArray) - with the color buffer from a rendering pass containing the contents of the - scene excluding any transparent materials or any materials also using the - screen texture is exposed to the shader under this name. Use \c VIEW_INDEX - to select the layer to use. When multiview rendering is not active, this - should not relied on. Therefore, the portable approach is the following: \badcode - #if QSHADER_VIEW_COUNT >= 2 - vec4 c = texture(SCREEN_TEXTURE_ARRAY, vec3(uv, VIEW_INDEX)); - #else - vec4 c = texture(SCREEN_TEXTURE, uv); - #endif - \endcode - - \li \c SCREEN_MIP_TEXTURE_ARRAY - Identical to \c SCREEN_TEXTURE_ARRAY, - except that the texture has mipmaps generated. - - \li \c DEPTH_TEXTURE - When present, a texture (sampler2D) with the + \li \c DEPTH_TEXTURE - When present, a texture (\c sampler2D) with the (non-linearized) depth buffer contents is exposed to the shader under this name. Only opaque objects are included. For example, a fragment shader could contain the following: \badcode @@ -1137,14 +1131,12 @@ QT_BEGIN_NAMESPACE float d = 2.0 * zNear * zFar / (zFar + zNear - z_n * zRange); d /= zFar; \endcode - - \li \c DEPTH_TEXTURE_ARRAY - When present, a texture array (sampler2DArray) - with the (non-linearized) depth buffer contents is exposed to the shader - under this name. Only opaque objects are included. Use \c VIEW_INDEX to - select the layer to use. When multiview rendering is not active, this - should not relied on. Therefore, the portable approach is the following: \badcode + With multiview rendering, \c DEPTH_TEXTURE is a \c sampler2DArray. Use + \c VIEW_INDEX to select the layer to use. For VR/AR applications that wish to + support both types of rendering, the portable approach is the following: + \badcode #if QSHADER_VIEW_COUNT >= 2 - vec4 depthSample = texture(DEPTH_TEXTURE_ARRAY, vec3(uv, VIEW_INDEX)); + vec4 depthSample = texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec4 depthSample = texture(DEPTH_TEXTURE, uv); #endif @@ -1162,16 +1154,14 @@ QT_BEGIN_NAMESPACE vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); float aoFactor = texture(AO_TEXTURE, aoUV).x; \endcode - - \li \c AO_TEXTURE_ARRAY - Available only when multiview rendering is in use. - Similar to \c AO_TEXTURE, but this is a 2D texture array (sampler2DArray). - Use \c VIEW_INDEX as the layer (the third coordinate in the \c uv argument in - \c{texture()}). Portable custom materials that wish to function both with and - without multiview rendering, can do the following: \badcode + With multiview rendering, \c AO_TEXTURE is a \c sampler2DArray. Use + \c VIEW_INDEX to select the layer to use. For VR/AR applications that wish to + support both types of rendering, the portable approach is the following: + \badcode #if QSHADER_VIEW_COUNT >= 2 - ivec2 aoSize = textureSize(AO_TEXTURE_ARRAY, 0).xy; + ivec2 aoSize = textureSize(AO_TEXTURE, 0).xy; vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); - float aoFactor = texture(AO_TEXTURE_ARRAY, vec3(aoUV, VIEW_INDEX)).x; + float aoFactor = texture(AO_TEXTURE, vec3(aoUV, VIEW_INDEX)).x; #else ivec2 aoSize = textureSize(AO_TEXTURE, 0); vec2 aoUV = (FRAGCOORD.xy) / vec2(aoSize); @@ -1193,8 +1183,8 @@ QT_BEGIN_NAMESPACE \li \c VIEW_INDEX - When used in the custom shader code, this is a (non-interpolated) uint variable. When multiview rendering is not used, the value is always 0. With multiview rendering, the value is the current view - index (e.g., gl_ViewIndex). Useful in particular in combination with \c - DEPTH_TEXTURE_ARRAY and similar. + index (e.g., gl_ViewIndex). Useful in particular in combination with + \c DEPTH_TEXTURE and similar when multiview rendering is enabled. \endlist @@ -1602,14 +1592,6 @@ static void setCustomMaterialFlagsFromShader(QSSGRenderCustomMaterial *material, material->m_renderFlags.setFlag(QSSGRenderCustomMaterial::RenderFlag::Morphing, true); if (meta.flags.testFlag(QSSGCustomShaderMetaData::UsesViewIndex)) material->m_renderFlags.setFlag(QSSGRenderCustomMaterial::RenderFlag::ViewIndex, true); - if (meta.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTextureArray)) - material->m_renderFlags.setFlag(QSSGRenderCustomMaterial::RenderFlag::DepthTextureArray, true); - if (meta.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenTextureArray)) - material->m_renderFlags.setFlag(QSSGRenderCustomMaterial::RenderFlag::ScreenTextureArray, true); - if (meta.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenMipTextureArray)) - material->m_renderFlags.setFlag(QSSGRenderCustomMaterial::RenderFlag::ScreenMipTextureArray, true); - if (meta.flags.testFlag(QSSGCustomShaderMetaData::UsesAoTextureArray)) - material->m_renderFlags.setFlag(QSSGRenderCustomMaterial::RenderFlag::AoTextureArray, true); // vertex only if (meta.flags.testFlag(QSSGCustomShaderMetaData::OverridesPosition)) diff --git a/src/quick3d/qquick3deffect.cpp b/src/quick3d/qquick3deffect.cpp index e883cebb..db5905be 100644 --- a/src/quick3d/qquick3deffect.cpp +++ b/src/quick3d/qquick3deffect.cpp @@ -812,11 +812,8 @@ QSSGRenderGraphObject *QQuick3DEffect::updateSpatialNode(QSSGRenderGraphObject * uniforms, builtinVertexOutputs); } - if (result.second.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTexture) - || result.second.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTextureArray)) - { + if (result.second.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTexture)) effectNode->requiresDepthTexture = true; - } code = result.first + shaderCodeMeta; diff --git a/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h b/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h index 2e8432da..299c8245 100644 --- a/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h +++ b/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h @@ -105,11 +105,7 @@ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderCustomMaterial : public QSSGRende Lightmap = 1 << 10, Skinning = 1 << 11, Morphing = 1 << 12, - ViewIndex = 1 << 13, - DepthTextureArray = 1 << 14, - ScreenTextureArray = 1 << 15, - ScreenMipTextureArray = 1 << 16, - AoTextureArray = 1 << 17 + ViewIndex = 1 << 13 }; Q_DECLARE_FLAGS(RenderFlags, RenderFlag) diff --git a/src/runtimerender/qssgshadermaterialadapter.cpp b/src/runtimerender/qssgshadermaterialadapter.cpp index d2598e03..22f5f5ba 100644 --- a/src/runtimerender/qssgshadermaterialadapter.cpp +++ b/src/runtimerender/qssgshadermaterialadapter.cpp @@ -723,14 +723,10 @@ static const QSSGCustomMaterialVariableSubstitution qssg_var_subst_tab[] = { { "IBL_PROBE", "qt_iblProbeProcessor", false }, // textures - { "SCREEN_TEXTURE", "qt_screenTexture", false }, - { "SCREEN_MIP_TEXTURE", "qt_screenTexture", false }, // same resource as SCREEN_TEXTURE under the hood - { "SCREEN_TEXTURE_ARRAY", "qt_screenTextureArray", false }, - { "SCREEN_MIP_TEXTURE_ARRAY", "qt_screenTextureArray", false }, - { "DEPTH_TEXTURE", "qt_depthTexture", false }, - { "DEPTH_TEXTURE_ARRAY", "qt_depthTextureArray", false }, - { "AO_TEXTURE", "qt_aoTexture", false }, - { "AO_TEXTURE", "qt_aoTextureArray", false }, + { "SCREEN_TEXTURE", "qt_screenTexture", true }, + { "SCREEN_MIP_TEXTURE", "qt_screenTexture", true }, // same resource as SCREEN_TEXTURE under the hood + { "DEPTH_TEXTURE", "qt_depthTexture", true }, + { "AO_TEXTURE", "qt_aoTexture", true }, { "IBL_TEXTURE", "qt_lightProbe", false }, { "LIGHTMAP", "qt_lightmap", false }, @@ -975,8 +971,6 @@ QSSGShaderCustomMaterialAdapter::prepareCustomShader(QByteArray &dst, md.flags |= QSSGCustomShaderMetaData::UsesDepthTexture; else if (trimmedId == QByteArrayLiteral("AO_TEXTURE")) md.flags |= QSSGCustomShaderMetaData::UsesAoTexture; - else if (trimmedId == QByteArrayLiteral("AO_TEXTURE_ARRAY")) - md.flags |= QSSGCustomShaderMetaData::UsesAoTextureArray; else if (trimmedId == QByteArrayLiteral("POSITION")) md.flags |= QSSGCustomShaderMetaData::OverridesPosition; else if (trimmedId == QByteArrayLiteral("PROJECTION_MATRIX")) @@ -993,19 +987,20 @@ QSSGShaderCustomMaterialAdapter::prepareCustomShader(QByteArray &dst, md.flags |= QSSGCustomShaderMetaData::UsesLightmap; else if (trimmedId == QByteArrayLiteral("VIEW_INDEX")) md.flags |= QSSGCustomShaderMetaData::UsesViewIndex; - else if (trimmedId == QByteArrayLiteral("DEPTH_TEXTURE_ARRAY")) - md.flags |= QSSGCustomShaderMetaData::UsesDepthTextureArray; - else if (trimmedId == QByteArrayLiteral("SCREEN_TEXTURE_ARRAY")) - md.flags |= QSSGCustomShaderMetaData::UsesScreenTextureArray; - else if (trimmedId == QByteArrayLiteral("SCREEN_MIP_TEXTURE_ARRAY")) - md.flags |= QSSGCustomShaderMetaData::UsesScreenMipTextureArray; for (const QSSGCustomMaterialVariableSubstitution &subst : qssg_var_subst_tab) { if (trimmedId == subst.builtin) { QByteArray newExpr; newExpr.assign(subst.actualName); - if (subst.multiViewDependent && multiViewCompatible) - newExpr += QByteArrayLiteral("[qt_viewIndex]"); + if (subst.multiViewDependent && multiViewCompatible) { + if (subst.builtin.endsWith(QByteArrayLiteral("_TEXTURE")) + || subst.builtin == QByteArrayLiteral("INPUT")) + { + newExpr += QByteArrayLiteral("Array"); // e.g. qt_depthTexture -> qt_depthTextureArray + } else { + newExpr += QByteArrayLiteral("[qt_viewIndex]"); // e.g. qt_viewProjectionMatrix -> qt_viewProjectionMatrix[qt_viewIndex] + } + } id.replace(subst.builtin, newExpr); // replace, not assignment, to keep whitespace etc. if (trimmedId == QByteArrayLiteral("BONE_TRANSFORMS")) { useJointTexState = 0; @@ -1099,22 +1094,28 @@ QSSGShaderCustomMaterialAdapter::prepareCustomShader(QByteArray &dst, // sampler2DArray binding point and vice versa. Therefore it is up to the // shader snippet to ifdef with QSHADER_VIEW_COUNT if it wants to support // both multiview and non-multiview rendering. - if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTexture) && !multiViewCompatible) - allUniforms.append({ "sampler2D", "qt_depthTexture" }); - if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTextureArray) && multiViewCompatible) - allUniforms.append({ "sampler2DArray", "qt_depthTextureArray" }); + if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTexture)) { + if (multiViewCompatible) + allUniforms.append({ "sampler2DArray", "qt_depthTextureArray" }); + else + allUniforms.append({ "sampler2D", "qt_depthTexture" }); + } // And the same pattern for qt_screenTexture(Array). - if ((md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenTexture) || md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenMipTexture)) && !multiViewCompatible) - allUniforms.append({ "sampler2D", "qt_screenTexture" }); - if ((md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenTextureArray) || md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenMipTextureArray)) && multiViewCompatible) - allUniforms.append({ "sampler2DArray", "qt_screenTextureArray" }); + if ((md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenTexture) || md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenMipTexture))) { + if (multiViewCompatible) + allUniforms.append({ "sampler2DArray", "qt_screenTextureArray" }); + else + allUniforms.append({ "sampler2D", "qt_screenTexture" }); + } // And for SSAO. - if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesAoTexture)) - allUniforms.append({ "sampler2D", "qt_aoTexture" }); - if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesAoTextureArray)) - allUniforms.append({ "sampler2DArray", "qt_aoTextureArray" }); + if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesAoTexture)) { + if (multiViewCompatible) + allUniforms.append({ "sampler2DArray", "qt_aoTextureArray" }); + else + allUniforms.append({ "sampler2D", "qt_aoTexture" }); + } if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesLightmap)) allUniforms.append({ "sampler2D", "qt_lightmap" }); diff --git a/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp b/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp index e13e7fa8..13ba375a 100644 --- a/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp +++ b/src/runtimerender/rendererimpl/qssglayerrenderdata.cpp @@ -1368,9 +1368,6 @@ QSSGDefaultMaterialPreparationResult QSSGLayerRenderData::prepareCustomMaterialF if (inMaterial.m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::DepthTexture)) ioFlags.setRequiresDepthTexture(true); - if (inMaterial.m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::DepthTextureArray)) - ioFlags.setRequiresDepthTexture(true); - if (inMaterial.m_renderFlags.testFlag(QSSGRenderCustomMaterial::RenderFlag::AoTexture)) { ioFlags.setRequiresDepthTexture(true); ioFlags.setRequiresSsaoPass(true); diff --git a/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h b/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h index 1a4938b6..317c43e3 100644 --- a/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h +++ b/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h @@ -48,11 +48,7 @@ struct QSSGCustomShaderMetaData UsesLightmap = 1 << 10, UsesSkinning = 1 << 11, UsesMorphing = 1 << 12, - UsesViewIndex = 1 << 13, - UsesDepthTextureArray = 1 << 14, - UsesScreenTextureArray = 1 << 15, - UsesScreenMipTextureArray = 1 << 16, - UsesAoTextureArray = 1 << 17 + UsesViewIndex = 1 << 13 }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/tests/baseline/data/custommaterial/custom_unshaded_depth_array.frag b/tests/baseline/data/custommaterial/custom_unshaded_depth_array.frag index ba25ff00..911fbfef 100644 --- a/tests/baseline/data/custommaterial/custom_unshaded_depth_array.frag +++ b/tests/baseline/data/custommaterial/custom_unshaded_depth_array.frag @@ -6,8 +6,8 @@ void MAIN() // not really using the texture array version, unless multiview rendering is active, // nonetheless this test verifies that QSHADER_VIEW_COUNT is defined etc. #if QSHADER_VIEW_COUNT >= 2 - vec2 uv = (gl_FragCoord.xy) / vec2(textureSize(DEPTH_TEXTURE_ARRAY, 0).xy); - vec4 depthSample = texture(DEPTH_TEXTURE_ARRAY, vec3(uv, VIEW_INDEX)); + vec2 uv = (gl_FragCoord.xy) / vec2(textureSize(DEPTH_TEXTURE, 0).xy); + vec4 depthSample = texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec2 uv = (gl_FragCoord.xy) / vec2(textureSize(DEPTH_TEXTURE, 0)); vec4 depthSample = texture(DEPTH_TEXTURE, uv); diff --git a/tests/manual/qmlxr/testscenes/custom_unshaded_depth.frag b/tests/manual/qmlxr/testscenes/custom_unshaded_depth.frag index 48f637aa..b73bb4c6 100644 --- a/tests/manual/qmlxr/testscenes/custom_unshaded_depth.frag +++ b/tests/manual/qmlxr/testscenes/custom_unshaded_depth.frag @@ -4,8 +4,8 @@ void MAIN() { #if QSHADER_VIEW_COUNT >= 2 - vec2 uv = (gl_FragCoord.xy) / vec2(textureSize(DEPTH_TEXTURE_ARRAY, 0).xy); - vec4 depthSample = texture(DEPTH_TEXTURE_ARRAY, vec3(uv, VIEW_INDEX)); + vec2 uv = (gl_FragCoord.xy) / vec2(textureSize(DEPTH_TEXTURE, 0).xy); + vec4 depthSample = texture(DEPTH_TEXTURE, vec3(uv, VIEW_INDEX)); #else vec2 uv = (gl_FragCoord.xy) / vec2(textureSize(DEPTH_TEXTURE, 0)); vec4 depthSample = texture(DEPTH_TEXTURE, uv); diff --git a/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag b/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag index afcbe686..5d1ee70f 100644 --- a/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag +++ b/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag @@ -10,7 +10,7 @@ void MAIN() if (FRAMEBUFFER_Y_UP < 0.0) screencoord.y = 1.0 - screencoord.y; #if QSHADER_VIEW_COUNT >= 2 - BASE_COLOR *= texture(SCREEN_TEXTURE_ARRAY, vec3(screencoord, VIEW_INDEX)); + BASE_COLOR *= texture(SCREEN_TEXTURE, vec3(screencoord, VIEW_INDEX)); #else BASE_COLOR *= texture(SCREEN_TEXTURE, screencoord); #endif |