diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2024-04-29 15:08:29 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2024-04-30 15:27:16 +0200 |
commit | 6f2e533c685e3a0870c67cc54663c970fcb7cb56 (patch) | |
tree | e38be84014b0f49f2865a500d6ace579a2eea8b8 | |
parent | 60ed78ac35168fcbb6f6662a76d70149050164cd (diff) |
Make screen texture multiview-aware
Fixes: QTBUG-124842
Change-Id: Ia0c530f90b577484ad2c5dbdd113b138e12abbd0
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
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 Binary files differnew file mode 100644 index 00000000..8809cc05 --- /dev/null +++ b/tests/manual/qmlxr/testscenes/maps/oulu_2.jpeg diff --git a/tests/manual/qmlxr/testscenes/maps/rgba.png b/tests/manual/qmlxr/testscenes/maps/rgba.png Binary files differnew file mode 100644 index 00000000..7b43637e --- /dev/null +++ b/tests/manual/qmlxr/testscenes/maps/rgba.png 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 + } + } +} |