From 2bc45cb0c8468ca205207fa64b15a3d90c2d8812 Mon Sep 17 00:00:00 2001
From: Laszlo Agocs <laszlo.agocs@qt.io>
Date: Tue, 10 Mar 2020 10:21:18 +0100
Subject: [PATCH] Enable, in theory, SSAO for custom materials

In practice the ambient occlusion factor calculated is not used in any
of the built-in custom materials, so SSAO has no effect (even though
enabling it will generate the AO map). This is out of this patch's scope
to solve. What this ensures is that the textures are correctly exposed.

Also note that SSDO is not supported in the code base (it never was, and
has no public API to enable it), so we will not bother with the cbAoShadow
uniform block that would only be used by SSDO.

Change-Id: Ic4cb90f52276ecf364c20fffd1c9355702773c5d
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
---
 .../graphobjects/qssgrenderlayer_p.h          |  2 +-
 .../qssgrendercustommaterialsystem.cpp        | 26 +++++++++++++++++++
 .../qssgrendererimpllayerrenderdata_rhi.cpp   |  3 ++-
 .../effectlib/rhi/SSAOCustomMaterial.glsllib  |  2 +-
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/runtimerender/graphobjects/qssgrenderlayer_p.h b/src/runtimerender/graphobjects/qssgrenderlayer_p.h
index a2400482d..54724e92b 100644
--- a/src/runtimerender/graphobjects/qssgrenderlayer_p.h
+++ b/src/runtimerender/graphobjects/qssgrenderlayer_p.h
@@ -157,7 +157,7 @@ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderLayer : public QSSGRenderNode
     qint32 aoSamplerate;
     bool aoDither;
 
-    // Direct occlusion
+    // Direct occlusion [NOT SUPPORTED]
     float shadowStrength;
     float shadowDist;
     float shadowSoftness;
diff --git a/src/runtimerender/qssgrendercustommaterialsystem.cpp b/src/runtimerender/qssgrendercustommaterialsystem.cpp
index a1cf1633a..10ecd1b03 100644
--- a/src/runtimerender/qssgrendercustommaterialsystem.cpp
+++ b/src/runtimerender/qssgrendercustommaterialsystem.cpp
@@ -2045,6 +2045,32 @@ void QSSGMaterialSystem::prepareRhiSubset(QSSGCustomMaterialRenderContext &custo
             }
         }
 
+        if (shaderPipeline->depthTexture()) {
+            int binding = bindingForTexture(QByteArrayLiteral("depthTexture"), samplerVars);
+            if (binding >= 0) {
+                samplerBindingsSpecified.setBit(binding);
+                // nearest min/mag, no mipmap
+                QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
+                                                         QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge });
+                bindings.append(QRhiShaderResourceBinding::sampledTexture(binding,
+                                                                          QRhiShaderResourceBinding::FragmentStage,
+                                                                          shaderPipeline->depthTexture(), sampler));
+            } // else ignore, not an error
+        }
+
+        if (shaderPipeline->ssaoTexture()) {
+            int binding = bindingForTexture(QByteArrayLiteral("aoTexture"), samplerVars);
+            if (binding >= 0) {
+                samplerBindingsSpecified.setBit(binding);
+                // linear min/mag, no mipmap
+                QRhiSampler *sampler = rhiCtx->sampler({ QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
+                                                         QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge });
+                bindings.append(QRhiShaderResourceBinding::sampledTexture(binding,
+                                                                          QRhiShaderResourceBinding::FragmentStage,
+                                                                          shaderPipeline->ssaoTexture(), sampler));
+            } // else ignore, not an error
+        }
+
         QVarLengthArray<QRhiShaderResourceBinding::TextureAndSampler, 16> texSamplers;
         QRhiSampler *dummySampler = rhiCtx->sampler({ QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
                                                       QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge });
diff --git a/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderdata_rhi.cpp b/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderdata_rhi.cpp
index b729ab04c..580b718a9 100644
--- a/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderdata_rhi.cpp
+++ b/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderdata_rhi.cpp
@@ -343,7 +343,8 @@ static bool rhiPrepareDepthPassForObject(QSSGRhiContext *rhiCtx,
         }
 
     } else if (obj->renderableFlags.isCustomMaterialMeshSubset()) {
-        // ### TODO custom materials
+        QSSGCustomMaterialRenderable &renderable(static_cast<QSSGCustomMaterialRenderable &>(*obj));
+        ps->cullMode = QSSGRhiGraphicsPipelineState::toCullMode(renderable.material.cullMode);
     }
 
     // the rest is common
diff --git a/src/runtimerender/res/effectlib/rhi/SSAOCustomMaterial.glsllib b/src/runtimerender/res/effectlib/rhi/SSAOCustomMaterial.glsllib
index bd1d500fe..762e51c0e 100644
--- a/src/runtimerender/res/effectlib/rhi/SSAOCustomMaterial.glsllib
+++ b/src/runtimerender/res/effectlib/rhi/SSAOCustomMaterial.glsllib
@@ -35,7 +35,7 @@
 /*{
     "uniforms": [
         { "type": "sampler2D", "name": "depthTexture", "condition": "QSSG_ENABLE_SSDO" },
-        { "type": "sampler2D", "name": "aoTexture" }
+        { "type": "sampler2D", "name": "aoTexture" , "condition": "QSSG_ENABLE_SSAO" }
     ]
 }*/
 #endif // QQ3D_SHADER_META
-- 
GitLab