aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2024-04-29 15:08:29 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2024-04-30 15:27:16 +0200
commit6f2e533c685e3a0870c67cc54663c970fcb7cb56 (patch)
treee38be84014b0f49f2865a500d6ace579a2eea8b8
parent60ed78ac35168fcbb6f6662a76d70149050164cd (diff)
Make screen texture multiview-aware
Fixes: QTBUG-124842 Change-Id: Ia0c530f90b577484ad2c5dbdd113b138e12abbd0 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/quick3d/qquick3dcustommaterial.cpp20
-rw-r--r--src/runtimerender/graphobjects/qssgrendercustommaterial_p.h4
-rw-r--r--src/runtimerender/qssgrendershadercodegenerator.cpp7
-rw-r--r--src/runtimerender/qssgrhicontext.cpp14
-rw-r--r--src/runtimerender/qssgrhicontext.h3
-rw-r--r--src/runtimerender/qssgrhicontext_p.h6
-rw-r--r--src/runtimerender/qssgrhicustommaterialsystem.cpp21
-rw-r--r--src/runtimerender/qssgshadermaterialadapter.cpp14
-rw-r--r--src/runtimerender/rendererimpl/qssgrenderhelpers.cpp49
-rw-r--r--src/runtimerender/res/effectlib/transmission.glsllib9
-rw-r--r--src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h4
-rw-r--r--tests/manual/qmlxr/testscenes/customsimpletexture.frag6
-rw-r--r--tests/manual/qmlxr/testscenes/customsimpletexture.qml120
-rw-r--r--tests/manual/qmlxr/testscenes/customsimpletexture.vert11
-rw-r--r--tests/manual/qmlxr/testscenes/customsimpletexture2.frag7
-rw-r--r--tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag17
-rw-r--r--tests/manual/qmlxr/testscenes/maps/oulu_2.jpegbin0 -> 284273 bytes
-rw-r--r--tests/manual/qmlxr/testscenes/maps/rgba.pngbin0 -> 9647 bytes
-rw-r--r--tests/manual/qmlxr/testscenes/transmission_skybox_msaa.qml39
19 files changed, 317 insertions, 34 deletions
diff --git a/src/quick3d/qquick3dcustommaterial.cpp b/src/quick3d/qquick3dcustommaterial.cpp
index 879e0cec..a0426686 100644
--- a/src/quick3d/qquick3dcustommaterial.cpp
+++ b/src/quick3d/qquick3dcustommaterial.cpp
@@ -1107,6 +1107,22 @@ 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
(non-linearized) depth buffer contents is exposed to the shader under this
name. Only opaque objects are included.
@@ -1572,6 +1588,10 @@ static void setCustomMaterialFlagsFromShader(QSSGRenderCustomMaterial *material,
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);
// vertex only
if (meta.flags.testFlag(QSSGCustomShaderMetaData::OverridesPosition))
diff --git a/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h b/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h
index b4e938af..6699ff91 100644
--- a/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h
+++ b/src/runtimerender/graphobjects/qssgrendercustommaterial_p.h
@@ -106,7 +106,9 @@ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderCustomMaterial : public QSSGRende
Skinning = 1 << 11,
Morphing = 1 << 12,
ViewIndex = 1 << 13,
- DepthTextureArray = 1 << 14
+ DepthTextureArray = 1 << 14,
+ ScreenTextureArray = 1 << 15,
+ ScreenMipTextureArray = 1 << 16
};
Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
diff --git a/src/runtimerender/qssgrendershadercodegenerator.cpp b/src/runtimerender/qssgrendershadercodegenerator.cpp
index 0a260c0f..5a4daef7 100644
--- a/src/runtimerender/qssgrendershadercodegenerator.cpp
+++ b/src/runtimerender/qssgrendershadercodegenerator.cpp
@@ -431,7 +431,12 @@ void QSSGProgramGenerator::registerShaderMetaDataFromSource(QSSGShaderResourceMe
for (const QSSGRenderShaderMetadata::Uniform &u : std::as_const(meta.uniforms)) {
if (u.type.startsWith(QByteArrayLiteral("sampler"))) {
- mergeContext->registerSampler(u.type, u.name, u.condition, u.conditionName);
+ if (u.multiview && mergeContext->viewCount >= 2) {
+ // 'sampler2D qt_screenTexture' becomes 'sampler2DArray qt_screenTextureArray'
+ mergeContext->registerSampler(u.type + QByteArrayLiteral("Array"), u.name + QByteArrayLiteral("Array"), u.condition, u.conditionName);
+ } else {
+ mergeContext->registerSampler(u.type, u.name, u.condition, u.conditionName);
+ }
} else {
if (u.multiview && mergeContext->viewCount >= 2) {
const QByteArray name = u.name + "[" + QByteArray::number(mergeContext->viewCount) + "]";
diff --git a/src/runtimerender/qssgrhicontext.cpp b/src/runtimerender/qssgrhicontext.cpp
index df5cc3dc..584a093d 100644
--- a/src/runtimerender/qssgrhicontext.cpp
+++ b/src/runtimerender/qssgrhicontext.cpp
@@ -1373,26 +1373,32 @@ void QSSGRhiContextPrivate::cleanupDrawCallData(const QSSGRenderModel *model)
object is not found. The necessary upload operations are then enqueued on
this given update batch.
+ When \a arraySize is 2 or more, a 2D texture array is returned.
+
The ownership of the returned texture stays with Qt Quick 3D.
*/
QRhiTexture *QSSGRhiContext::dummyTexture(QRhiTexture::Flags flags, QRhiResourceUpdateBatch *rub,
- const QSize &size, const QColor &fillColor)
+ const QSize &size, const QColor &fillColor, int arraySize)
{
Q_D(QSSGRhiContext);
- auto it = d->m_dummyTextures.constFind({flags, size, fillColor});
+ auto it = d->m_dummyTextures.constFind({flags, size, fillColor, arraySize});
if (it != d->m_dummyTextures.constEnd())
return *it;
- QRhiTexture *t = d->m_rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags);
+ QRhiTexture *t = arraySize < 2
+ ? d->m_rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags)
+ : d->m_rhi->newTextureArray(QRhiTexture::RGBA8, arraySize, size, 1, flags);
if (t->create()) {
QImage image(t->pixelSize(), QImage::Format_RGBA8888);
image.fill(fillColor);
rub->uploadTexture(t, image);
+ for (int layer = 1; layer < arraySize; ++layer)
+ rub->uploadTexture(t, QRhiTextureUploadDescription(QRhiTextureUploadEntry(layer, 0, QRhiTextureSubresourceUploadDescription(image))));
} else {
qWarning("Failed to build dummy texture");
}
- d->m_dummyTextures.insert({flags, size, fillColor}, t);
+ d->m_dummyTextures.insert({flags, size, fillColor, arraySize}, t);
return t;
}
diff --git a/src/runtimerender/qssgrhicontext.h b/src/runtimerender/qssgrhicontext.h
index d7ba857b..9c2d69fc 100644
--- a/src/runtimerender/qssgrhicontext.h
+++ b/src/runtimerender/qssgrhicontext.h
@@ -113,7 +113,8 @@ public:
QRhiSampler *sampler(const QSSGRhiSamplerDescription &samplerDescription);
void checkAndAdjustForNPoT(QRhiTexture *texture, QSSGRhiSamplerDescription *samplerDescription);
QRhiTexture *dummyTexture(QRhiTexture::Flags flags, QRhiResourceUpdateBatch *rub,
- const QSize &size = QSize(64, 64), const QColor &fillColor = Qt::black);
+ const QSize &size = QSize(64, 64), const QColor &fillColor = Qt::black,
+ int arraySize = 0);
QRhiCommandBuffer::BeginPassFlags commonPassFlags() const;
diff --git a/src/runtimerender/qssgrhicontext_p.h b/src/runtimerender/qssgrhicontext_p.h
index 766d9979..6da57bbe 100644
--- a/src/runtimerender/qssgrhicontext_p.h
+++ b/src/runtimerender/qssgrhicontext_p.h
@@ -263,6 +263,7 @@ enum class QSSGRhiSamplerBindingHints
AoTexture,
LightmapTexture,
DepthTextureArray,
+ ScreenTextureArray,
BindingMapSize
};
@@ -669,18 +670,19 @@ struct QSSGRhiDummyTextureKey
QRhiTexture::Flags flags;
QSize size;
QColor color;
+ int arraySize;
};
inline size_t qHash(const QSSGRhiDummyTextureKey &k, size_t seed) Q_DECL_NOTHROW
{
return qHash(k.flags, seed)
^ qHash(k.size.width() ^ k.size.height() ^ k.color.red() ^ k.color.green()
- ^ k.color.blue() ^ k.color.alpha());
+ ^ k.color.blue() ^ k.color.alpha() ^ k.arraySize);
}
inline bool operator==(const QSSGRhiDummyTextureKey &a, const QSSGRhiDummyTextureKey &b) Q_DECL_NOTHROW
{
- return a.flags == b.flags && a.size == b.size && a.color == b.color;
+ return a.flags == b.flags && a.size == b.size && a.color == b.color && a.arraySize == b.arraySize;
}
inline bool operator!=(const QSSGRhiDummyTextureKey &a, const QSSGRhiDummyTextureKey &b) Q_DECL_NOTHROW
diff --git a/src/runtimerender/qssgrhicustommaterialsystem.cpp b/src/runtimerender/qssgrhicustommaterialsystem.cpp
index a62b83aa..3d0b1f1f 100644
--- a/src/runtimerender/qssgrhicustommaterialsystem.cpp
+++ b/src/runtimerender/qssgrhicustommaterialsystem.cpp
@@ -376,9 +376,9 @@ void QSSGCustomMaterialSystem::rhiPrepareRenderable(QSSGRhiGraphicsPipelineState
}
if (shaderPipeline->screenTexture()) {
- int binding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
- if (binding >= 0) {
- samplerBindingsSpecified.setBit(binding);
+ const int screenTextureBinding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
+ const int screenTextureArrayBinding = shaderPipeline->bindingForTexture("qt_screenTextureArray", int(QSSGRhiSamplerBindingHints::ScreenTextureArray));
+ if (screenTextureBinding >= 0 || screenTextureArrayBinding >= 0) {
// linear min/mag, mipmap filtering depends on the
// texture, with SCREEN_TEXTURE there are no mipmaps, but
// once SCREEN_MIP_TEXTURE is seen the texture (the same
@@ -387,9 +387,18 @@ void QSSGCustomMaterialSystem::rhiPrepareRenderable(QSSGRhiGraphicsPipelineState
? QRhiSampler::Linear : QRhiSampler::None;
QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Linear, QRhiSampler::Linear, mipFilter,
QRhiSampler::Repeat, QRhiSampler::Repeat, QRhiSampler::Repeat });
- bindings.addTexture(binding,
- QRhiShaderResourceBinding::FragmentStage,
- shaderPipeline->screenTexture(), sampler);
+ if (screenTextureBinding >= 0) {
+ samplerBindingsSpecified.setBit(screenTextureBinding);
+ bindings.addTexture(screenTextureBinding,
+ QRhiShaderResourceBinding::FragmentStage,
+ shaderPipeline->screenTexture(), sampler);
+ }
+ if (screenTextureArrayBinding >= 0) {
+ samplerBindingsSpecified.setBit(screenTextureArrayBinding);
+ bindings.addTexture(screenTextureArrayBinding,
+ QRhiShaderResourceBinding::FragmentStage,
+ shaderPipeline->screenTexture(), sampler);
+ }
} // else ignore, not an error
}
diff --git a/src/runtimerender/qssgshadermaterialadapter.cpp b/src/runtimerender/qssgshadermaterialadapter.cpp
index 6f88565c..ed82fe1d 100644
--- a/src/runtimerender/qssgshadermaterialadapter.cpp
+++ b/src/runtimerender/qssgshadermaterialadapter.cpp
@@ -725,6 +725,8 @@ static const QSSGCustomMaterialVariableSubstitution qssg_var_subst_tab[] = {
// 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 },
@@ -990,6 +992,10 @@ QSSGShaderCustomMaterialAdapter::prepareCustomShader(QByteArray &dst,
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) {
@@ -1084,8 +1090,6 @@ QSSGShaderCustomMaterialAdapter::prepareCustomShader(QByteArray &dst,
result += '\n';
StringPairList allUniforms = baseUniforms;
- if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenTexture) || md.flags.testFlag(QSSGCustomShaderMetaData::UsesScreenMipTexture))
- allUniforms.append({ "sampler2D", "qt_screenTexture" });
// We either have qt_depthTexture or qt_depthTextureArray (or none of them),
// but never both. We do not generally support binding a 2D texture to a
@@ -1097,6 +1101,12 @@ QSSGShaderCustomMaterialAdapter::prepareCustomShader(QByteArray &dst,
if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesDepthTextureArray) && multiViewCompatible)
allUniforms.append({ "sampler2DArray", "qt_depthTextureArray" });
+ // 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::UsesAoTexture))
allUniforms.append({ "sampler2D", "qt_aoTexture" });
if (md.flags.testFlag(QSSGCustomShaderMetaData::UsesLightmap))
diff --git a/src/runtimerender/rendererimpl/qssgrenderhelpers.cpp b/src/runtimerender/rendererimpl/qssgrenderhelpers.cpp
index eed2629e..d074c7cb 100644
--- a/src/runtimerender/rendererimpl/qssgrenderhelpers.cpp
+++ b/src/runtimerender/rendererimpl/qssgrenderhelpers.cpp
@@ -638,16 +638,27 @@ static void rhiPrepareResourcesForShadowMap(QSSGRhiContext *rhiCtx,
// custom material may rely on it, and an object with that material
// can end up in the shadow map's object list. So bind a dummy
// texture then due to the lack of other options.
- int binding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
- if (binding >= 0) {
+ const int screenTextureBinding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
+ const int screenTextureArrayBinding = shaderPipeline->bindingForTexture("qt_screenTextureArray", int(QSSGRhiSamplerBindingHints::ScreenTextureArray));
+ if (screenTextureBinding >= 0 || screenTextureArrayBinding >= 0) {
QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
QRhiSampler::Repeat, QRhiSampler::Repeat, QRhiSampler::Repeat });
- QRhiResourceUpdateBatch *resourceUpdates = rhiCtx->rhi()->nextResourceUpdateBatch();
- QRhiTexture *dummyTexture = rhiCtx->dummyTexture({}, resourceUpdates);
- rhiCtx->commandBuffer()->resourceUpdate(resourceUpdates);
- bindings.addTexture(binding,
- QRhiShaderResourceBinding::FragmentStage,
- dummyTexture, sampler);
+ if (screenTextureBinding >= 0) {
+ QRhiResourceUpdateBatch *resourceUpdates = rhiCtx->rhi()->nextResourceUpdateBatch();
+ QRhiTexture *dummyTexture = rhiCtx->dummyTexture({}, resourceUpdates);
+ rhiCtx->commandBuffer()->resourceUpdate(resourceUpdates);
+ bindings.addTexture(screenTextureBinding,
+ QRhiShaderResourceBinding::FragmentStage,
+ dummyTexture, sampler);
+ }
+ if (screenTextureArrayBinding >= 0) {
+ QRhiResourceUpdateBatch *resourceUpdates = rhiCtx->rhi()->nextResourceUpdateBatch();
+ QRhiTexture *dummyTexture = rhiCtx->dummyTexture({}, resourceUpdates, QSize(64, 64), Qt::black, rhiCtx->mainPassViewCount());
+ rhiCtx->commandBuffer()->resourceUpdate(resourceUpdates);
+ bindings.addTexture(screenTextureArrayBinding,
+ QRhiShaderResourceBinding::FragmentStage,
+ dummyTexture, sampler);
+ }
}
QRhiShaderResourceBindings *srb = rhiCtxD->srb(bindings);
@@ -895,8 +906,9 @@ void RenderHelpers::rhiPrepareRenderable(QSSGRhiContext *rhiCtx,
// Screen Texture
if (shaderPipeline->screenTexture()) {
- int binding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
- if (binding >= 0) {
+ const int screenTextureBinding = shaderPipeline->bindingForTexture("qt_screenTexture", int(QSSGRhiSamplerBindingHints::ScreenTexture));
+ const int screenTextureArrayBinding = shaderPipeline->bindingForTexture("qt_screenTextureArray", int(QSSGRhiSamplerBindingHints::ScreenTextureArray));
+ if (screenTextureBinding >= 0 || screenTextureArrayBinding >= 0) {
// linear min/mag, mipmap filtering depends on the
// texture, with SCREEN_TEXTURE there are no mipmaps, but
// once SCREEN_MIP_TEXTURE is seen the texture (the same
@@ -905,9 +917,16 @@ void RenderHelpers::rhiPrepareRenderable(QSSGRhiContext *rhiCtx,
? QRhiSampler::Linear : QRhiSampler::None;
QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Linear, QRhiSampler::Linear, mipFilter,
QRhiSampler::Repeat, QRhiSampler::Repeat, QRhiSampler::Repeat });
- bindings.addTexture(binding,
- QRhiShaderResourceBinding::FragmentStage,
- shaderPipeline->screenTexture(), sampler);
+ if (screenTextureBinding >= 0) {
+ bindings.addTexture(screenTextureBinding,
+ QRhiShaderResourceBinding::FragmentStage,
+ shaderPipeline->screenTexture(), sampler);
+ }
+ if (screenTextureArrayBinding >= 0) {
+ bindings.addTexture(screenTextureArrayBinding,
+ QRhiShaderResourceBinding::FragmentStage,
+ shaderPipeline->screenTexture(), sampler);
+ }
} // else ignore, not an error
}
@@ -1654,7 +1673,9 @@ bool RenderHelpers::rhiPrepareScreenTexture(QSSGRhiContext *rhiCtx, const QSize
}
renderableTex->resetRenderTarget();
QRhiTextureRenderTargetDescription desc;
- desc.setColorAttachments({ QRhiColorAttachment(renderableTex->texture) });
+ QRhiColorAttachment colorAttachment(renderableTex->texture);
+ colorAttachment.setMultiViewCount(rhiCtx->mainPassViewCount());
+ desc.setColorAttachments({ colorAttachment });
if (renderableTex->depthStencil)
desc.setDepthStencilBuffer(renderableTex->depthStencil);
else if (renderableTex->depthTexture)
diff --git a/src/runtimerender/res/effectlib/transmission.glsllib b/src/runtimerender/res/effectlib/transmission.glsllib
index 81651a76..93d6a9d7 100644
--- a/src/runtimerender/res/effectlib/transmission.glsllib
+++ b/src/runtimerender/res/effectlib/transmission.glsllib
@@ -6,7 +6,7 @@
#ifdef QQ3D_SHADER_META
/*{
"uniforms": [
- { "type": "sampler2D", "name": "qt_screenTexture" },
+ { "type": "sampler2D", "name": "qt_screenTexture", "multiview_dependent": true },
{ "type": "mat4", "name": "qt_modelMatrix" },
{ "type": "mat4", "name": "qt_viewProjectionMatrix", "multiview_dependent": true }
]
@@ -51,9 +51,14 @@ vec2 qt_correctFrambufferUV(in vec2 uv)
vec3 qt_getTransmissionSample(in vec2 fragCoord, in float roughness, in float ior)
{
- const float framebufferLod = log2(float(textureSize(qt_screenTexture, 0).x)) * qt_applyIorToRoughness(roughness, ior);
const vec2 fbCoord = qt_correctFrambufferUV(fragCoord);
+#if QSHADER_VIEW_COUNT >= 2
+ const float framebufferLod = log2(float(textureSize(qt_screenTextureArray, 0).x)) * qt_applyIorToRoughness(roughness, ior);
+ vec3 transmittedLight = textureLod(qt_screenTextureArray, vec3(fbCoord, qt_viewIndex), framebufferLod).rgb;
+#else
+ const float framebufferLod = log2(float(textureSize(qt_screenTexture, 0).x)) * qt_applyIorToRoughness(roughness, ior);
vec3 transmittedLight = textureLod(qt_screenTexture, fbCoord, framebufferLod).rgb;
+#endif
return transmittedLight;
}
diff --git a/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h b/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h
index 10f6f13f..e32faccd 100644
--- a/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h
+++ b/src/runtimerender/resourcemanager/qssgrendershaderlibrarymanager_p.h
@@ -49,7 +49,9 @@ struct QSSGCustomShaderMetaData
UsesSkinning = 1 << 11,
UsesMorphing = 1 << 12,
UsesViewIndex = 1 << 13,
- UsesDepthTextureArray = 1 << 14
+ UsesDepthTextureArray = 1 << 14,
+ UsesScreenTextureArray = 1 << 15,
+ UsesScreenMipTextureArray = 1 << 16
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/tests/manual/qmlxr/testscenes/customsimpletexture.frag b/tests/manual/qmlxr/testscenes/customsimpletexture.frag
new file mode 100644
index 00000000..928e45e0
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/customsimpletexture.frag
@@ -0,0 +1,6 @@
+VARYING vec2 texcoord;
+
+void MAIN()
+{
+ BASE_COLOR = texture(tex1, texcoord);
+}
diff --git a/tests/manual/qmlxr/testscenes/customsimpletexture.qml b/tests/manual/qmlxr/testscenes/customsimpletexture.qml
new file mode 100644
index 00000000..10cc42b7
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/customsimpletexture.qml
@@ -0,0 +1,120 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick3D
+import QtQuick
+
+Node {
+ id: root
+ property vector3d qmlxr_originPosition: Qt.vector3d(0, 0, 600)
+ property SceneEnvironment qmlxr_environment: SceneEnvironment {
+ backgroundMode: SceneEnvironment.Color
+ clearColor: "#444845"
+ }
+ property real time: 10
+ property real amplitude: 4
+ DirectionalLight {
+ position: Qt.vector3d(-500, 500, -100)
+ color: Qt.rgba(0.2, 0.2, 0.2, 1.0)
+ ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0)
+ }
+ // texture disabled (result should be black)
+ Model {
+ source: "#Sphere"
+ scale: Qt.vector3d(2, 2, 2)
+ x: -200
+ materials: [
+ CustomMaterial {
+ property alias time: root.time
+ property alias amplitude: root.amplitude
+ vertexShader: "customsimpletexture.vert"
+ fragmentShader: "customsimpletexture.frag"
+ property TextureInput tex1: TextureInput {
+ enabled: false
+ }
+ }
+ ]
+ }
+ // texture enabled but no actual Texture is given (should survive with
+ // dummy texture, result is expected to be black)
+ Model {
+ source: "#Sphere"
+ scale: Qt.vector3d(2, 2, 2)
+ materials: [
+ CustomMaterial {
+ property alias time: root.time
+ property alias amplitude: root.amplitude
+ vertexShader: "customsimpletexture.vert"
+ fragmentShader: "customsimpletexture.frag"
+ property TextureInput tex1: TextureInput {
+ enabled: true
+ }
+ }
+ ]
+ }
+ Model {
+ source: "#Sphere"
+ scale: Qt.vector3d(2, 2, 2)
+ x: 200
+ materials: [
+ CustomMaterial {
+ property alias time: root.time
+ property alias amplitude: root.amplitude
+ vertexShader: "customsimpletexture.vert"
+ fragmentShader: "customsimpletexture.frag"
+ property TextureInput tex1: TextureInput {
+ enabled: true
+ texture: Texture {
+ source: "maps/oulu_2.jpeg"
+ }
+ }
+ }
+ ]
+ }
+ // sample two textures
+ Model {
+ source: "#Cube"
+ scale: Qt.vector3d(1.5, 1.5, 1.5)
+ y: -200
+ materials: [
+ CustomMaterial {
+ property real time: 0
+ property real amplitude: 0
+ vertexShader: "customsimpletexture.vert"
+ fragmentShader: "customsimpletexture2.frag"
+ property TextureInput tex1: TextureInput {
+ enabled: true
+ texture: Texture {
+ source: "maps/oulu_2.jpeg"
+ }
+ }
+ property TextureInput tex2: TextureInput {
+ enabled: true
+ texture: Texture {
+ source: "maps/rgba.png"
+ }
+ }
+ }
+ ]
+ }
+ // not so simple after all: combine SCREEN_TEXTURE with another texture
+ Model {
+ source: "#Rectangle"
+ scale: Qt.vector3d(1.5, 1.5, 1.5)
+ y: 200
+ materials: [
+ CustomMaterial {
+ property real time: 0
+ property real amplitude: 0
+ vertexShader: "customsimpletexture.vert"
+ fragmentShader: "customsimpletexturescreen.frag"
+ property TextureInput tex1: TextureInput {
+ enabled: true
+ texture: Texture {
+ source: "maps/oulu_2.jpeg"
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/manual/qmlxr/testscenes/customsimpletexture.vert b/tests/manual/qmlxr/testscenes/customsimpletexture.vert
new file mode 100644
index 00000000..cd73fc14
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/customsimpletexture.vert
@@ -0,0 +1,11 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+VARYING vec2 texcoord;
+
+void MAIN()
+{
+ texcoord = UV0;
+ VERTEX.x += sin(time * 4.0 + VERTEX.y) * amplitude;
+ POSITION = MODELVIEWPROJECTION_MATRIX * vec4(VERTEX, 1.0);
+}
diff --git a/tests/manual/qmlxr/testscenes/customsimpletexture2.frag b/tests/manual/qmlxr/testscenes/customsimpletexture2.frag
new file mode 100644
index 00000000..7e606e0a
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/customsimpletexture2.frag
@@ -0,0 +1,7 @@
+VARYING vec2 texcoord;
+
+void MAIN()
+{
+ BASE_COLOR = texture(tex1, texcoord);
+ BASE_COLOR *= texture(tex2, texcoord);
+}
diff --git a/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag b/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag
new file mode 100644
index 00000000..afcbe686
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/customsimpletexturescreen.frag
@@ -0,0 +1,17 @@
+VARYING vec2 texcoord;
+
+void MAIN()
+
+{
+ BASE_COLOR = texture(tex1, texcoord);
+ vec2 screencoord = texcoord;
+ // the tex coords from the rectangle (or cube etc.) are almost suitable,
+ // except that on non-GL we need to flip them
+ 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));
+#else
+ BASE_COLOR *= texture(SCREEN_TEXTURE, screencoord);
+#endif
+}
diff --git a/tests/manual/qmlxr/testscenes/maps/oulu_2.jpeg b/tests/manual/qmlxr/testscenes/maps/oulu_2.jpeg
new file mode 100644
index 00000000..8809cc05
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/maps/oulu_2.jpeg
Binary files differ
diff --git a/tests/manual/qmlxr/testscenes/maps/rgba.png b/tests/manual/qmlxr/testscenes/maps/rgba.png
new file mode 100644
index 00000000..7b43637e
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/maps/rgba.png
Binary files differ
diff --git a/tests/manual/qmlxr/testscenes/transmission_skybox_msaa.qml b/tests/manual/qmlxr/testscenes/transmission_skybox_msaa.qml
new file mode 100644
index 00000000..a1d7fe9e
--- /dev/null
+++ b/tests/manual/qmlxr/testscenes/transmission_skybox_msaa.qml
@@ -0,0 +1,39 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick
+import QtQuick3D
+import QtQuick3D.Helpers
+
+Node {
+ property vector3d qmlxr_originPosition: Qt.vector3d(0, 0, 360)
+ property SceneEnvironment qmlxr_environment: SceneEnvironment {
+ clearColor: "white"
+ backgroundMode: SceneEnvironment.SkyBox
+ antialiasingMode: SceneEnvironment.MSAA
+ antialiasingQuality: SceneEnvironment.High
+ lightProbe: proceduralSky
+ }
+ Texture {
+ id: proceduralSky
+ textureData: ProceduralSkyTextureData {
+ sunLongitude: -115
+ }
+ }
+ Node {
+ DirectionalLight {
+ eulerRotation: Qt.vector3d(-45, 25, 0)
+ }
+ PrincipledMaterial {
+ id: glassMaterial
+ baseColor: "#aaaacc"
+ transmissionFactor: 0.95
+ thicknessFactor: 1
+ roughness: 0.05
+ }
+ Model {
+ source: "#Sphere"
+ materials: glassMaterial
+ }
+ }
+}