From 23b225e9cbc39b57ef2616acd2bc39626a38c67c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Str=C3=B8mme?= <christian.stromme@qt.io>
Date: Fri, 21 Jun 2019 11:18:13 -0400
Subject: [PATCH] Fix custom materials

- Don't close main function if one is provided by the user
- Make it possible to add more then one shader per pass
---
 .../AluminumAnisotropicMaterial.qml           |  2 +-
 .../AluminumAnodizedEmissiveMaterial.qml      |  2 +-
 .../materiallib/AluminumAnodizedMaterial.qml  |  2 +-
 .../materiallib/AluminumBrushedMaterial.qml   |  2 +-
 .../materiallib/AluminumEmissiveMaterial.qml  |  2 +-
 src/imports/materiallib/AluminumMaterial.qml  |  2 +-
 .../AluminumTexturedAnisotropicMaterial.qml   |  2 +-
 src/imports/materiallib/AsphaltMaterial.qml   |  2 +-
 .../BambooNaturalMatteEmissiveMaterial.qml    |  2 +-
 .../BambooNaturalMatteMaterial.qml            |  2 +-
 .../CarPaintBlueStandardMaterial.qml          |  2 +-
 .../CarPaintColorPeel2LayerMaterial.qml       |  2 +-
 .../CarPaintYellowStandardMaterial.qml        |  2 +-
 .../CarbonFiberEmissiveMaterial.qml           |  2 +-
 .../materiallib/CarbonFiberMaterial.qml       |  2 +-
 src/imports/materiallib/ConcreteMaterial.qml  |  2 +-
 src/imports/materiallib/CopperMaterial.qml    |  2 +-
 .../materiallib/FrostedGlassMaterial.qml      | 10 +--
 .../FrostedGlassSinglePassMaterial.qml        |  2 +-
 src/imports/materiallib/GlassMaterial.qml     |  2 +-
 .../materiallib/GlassRefractiveMaterial.qml   |  2 +-
 .../LeatherSmoothedBlackMaterial.qml          |  2 +-
 src/imports/materiallib/MeshFenceMaterial.qml |  2 +-
 .../materiallib/MetalFenceFineMaterial.qml    |  2 +-
 .../materiallib/PaperArtisticMaterial.qml     |  2 +-
 .../materiallib/PaperOfficeMaterial.qml       |  2 +-
 .../PlasticStructuredRedEmissiveMaterial.qml  |  2 +-
 .../PlasticStructuredRedMaterial.qml          |  2 +-
 src/imports/materiallib/PorcelainMaterial.qml |  2 +-
 .../PowderCoatEmissiveMaterial.qml            |  2 +-
 .../materiallib/PowderCoatMaterial.qml        |  2 +-
 .../RubberStuddedEmissiveMaterial.qml         |  2 +-
 .../materiallib/RubberStuddedMaterial.qml     |  2 +-
 .../SteelMilledConcentricMaterial.qml         |  2 +-
 .../materiallib/WalnutMatteMaterial.qml       |  2 +-
 .../shaders/frostedThinGlassBlurX.frag        |  3 +-
 .../shaders/frostedThinGlassBlurY.frag        |  2 +-
 .../shaders/frostedThinGlassNoop.frag         |  1 +
 .../shaders/frostedThinGlassPreBlur.frag      |  2 +-
 src/quick3d/qdemoncustommaterial.cpp          | 64 ++++++++++++---
 src/quick3d/qdemoncustommaterial.h            | 13 +++-
 ...monrendercustommaterialshadergenerator.cpp | 78 ++++++++++++++-----
 .../qdemonrendercustommaterialsystem.cpp      | 10 ++-
 .../qdemonrendercustommaterialsystem.h        |  4 +-
 ...onrenderdefaultmaterialshadergenerator.cpp |  4 +-
 ...emonrenderdefaultmaterialshadergenerator.h |  4 +-
 .../qdemonrenderdynamicobjectsystem.cpp       |  6 +-
 src/runtimerender/qdemonrenderpathmanager.cpp | 16 ++--
 src/runtimerender/qdemonrendershadercache.cpp |  2 +-
 .../qdemonrendererimplshaders.cpp             | 11 ++-
 .../rendererimpl/qdemonvertexpipelineimpl.h   |  4 +-
 51 files changed, 199 insertions(+), 103 deletions(-)

diff --git a/src/imports/materiallib/AluminumAnisotropicMaterial.qml b/src/imports/materiallib/AluminumAnisotropicMaterial.qml
index 76644755..5e8b4f8f 100644
--- a/src/imports/materiallib/AluminumAnisotropicMaterial.qml
+++ b/src/imports/materiallib/AluminumAnisotropicMaterial.qml
@@ -87,7 +87,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumAnisoFragShader
+            shaders: aluminumAnisoFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/AluminumAnodizedEmissiveMaterial.qml b/src/imports/materiallib/AluminumAnodizedEmissiveMaterial.qml
index cee0cf71..dbf023f9 100644
--- a/src/imports/materiallib/AluminumAnodizedEmissiveMaterial.qml
+++ b/src/imports/materiallib/AluminumAnodizedEmissiveMaterial.qml
@@ -72,7 +72,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumAnodizedEmissiveShader
+            shaders: aluminumAnodizedEmissiveShader
         }
     ]
 
diff --git a/src/imports/materiallib/AluminumAnodizedMaterial.qml b/src/imports/materiallib/AluminumAnodizedMaterial.qml
index 19c51428..0b79fc12 100644
--- a/src/imports/materiallib/AluminumAnodizedMaterial.qml
+++ b/src/imports/materiallib/AluminumAnodizedMaterial.qml
@@ -44,7 +44,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumAnodizedShader
+            shaders: aluminumAnodizedShader
         }
     ]
 }
diff --git a/src/imports/materiallib/AluminumBrushedMaterial.qml b/src/imports/materiallib/AluminumBrushedMaterial.qml
index 80a393cb..00d59748 100644
--- a/src/imports/materiallib/AluminumBrushedMaterial.qml
+++ b/src/imports/materiallib/AluminumBrushedMaterial.qml
@@ -97,7 +97,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumBrushedFragShader
+            shaders: aluminumBrushedFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/AluminumEmissiveMaterial.qml b/src/imports/materiallib/AluminumEmissiveMaterial.qml
index 6e26acdf..2a27af47 100644
--- a/src/imports/materiallib/AluminumEmissiveMaterial.qml
+++ b/src/imports/materiallib/AluminumEmissiveMaterial.qml
@@ -109,7 +109,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumEmissiveShader
+            shaders: aluminumEmissiveShader
         }
     ]
 }
diff --git a/src/imports/materiallib/AluminumMaterial.qml b/src/imports/materiallib/AluminumMaterial.qml
index 0c2406a9..5368bfc2 100644
--- a/src/imports/materiallib/AluminumMaterial.qml
+++ b/src/imports/materiallib/AluminumMaterial.qml
@@ -79,7 +79,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumFragShader
+            shaders: aluminumFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/AluminumTexturedAnisotropicMaterial.qml b/src/imports/materiallib/AluminumTexturedAnisotropicMaterial.qml
index 824c1618..d8e66264 100644
--- a/src/imports/materiallib/AluminumTexturedAnisotropicMaterial.qml
+++ b/src/imports/materiallib/AluminumTexturedAnisotropicMaterial.qml
@@ -87,7 +87,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: aluminumTexturedAnisoFragShader
+            shaders: aluminumTexturedAnisoFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/AsphaltMaterial.qml b/src/imports/materiallib/AsphaltMaterial.qml
index 8f3566ba..e85c36ee 100644
--- a/src/imports/materiallib/AsphaltMaterial.qml
+++ b/src/imports/materiallib/AsphaltMaterial.qml
@@ -81,7 +81,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: asphaltFragShader
+            shaders: asphaltFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/BambooNaturalMatteEmissiveMaterial.qml b/src/imports/materiallib/BambooNaturalMatteEmissiveMaterial.qml
index 9b7d5a69..132abbe4 100644
--- a/src/imports/materiallib/BambooNaturalMatteEmissiveMaterial.qml
+++ b/src/imports/materiallib/BambooNaturalMatteEmissiveMaterial.qml
@@ -107,7 +107,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: bambooEmissiveFragShader
+            shaders: bambooEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/BambooNaturalMatteMaterial.qml b/src/imports/materiallib/BambooNaturalMatteMaterial.qml
index b68fb10a..48a5c068 100644
--- a/src/imports/materiallib/BambooNaturalMatteMaterial.qml
+++ b/src/imports/materiallib/BambooNaturalMatteMaterial.qml
@@ -79,7 +79,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: bambooEmissiveFragShader
+            shaders: bambooEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/CarPaintBlueStandardMaterial.qml b/src/imports/materiallib/CarPaintBlueStandardMaterial.qml
index dfb7c0f9..6b8274c0 100644
--- a/src/imports/materiallib/CarPaintBlueStandardMaterial.qml
+++ b/src/imports/materiallib/CarPaintBlueStandardMaterial.qml
@@ -81,7 +81,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: carpaintFragShader
+            shaders: carpaintFragShader
         }
     ]
 
diff --git a/src/imports/materiallib/CarPaintColorPeel2LayerMaterial.qml b/src/imports/materiallib/CarPaintColorPeel2LayerMaterial.qml
index 2334e50e..80a690fe 100644
--- a/src/imports/materiallib/CarPaintColorPeel2LayerMaterial.qml
+++ b/src/imports/materiallib/CarPaintColorPeel2LayerMaterial.qml
@@ -91,7 +91,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: carpaint2LayerFragShader
+            shaders: carpaint2LayerFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/CarPaintYellowStandardMaterial.qml b/src/imports/materiallib/CarPaintYellowStandardMaterial.qml
index 96e00eca..b8aa7e5a 100644
--- a/src/imports/materiallib/CarPaintYellowStandardMaterial.qml
+++ b/src/imports/materiallib/CarPaintYellowStandardMaterial.qml
@@ -81,7 +81,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: carpaintFragShader
+            shaders: carpaintFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/CarbonFiberEmissiveMaterial.qml b/src/imports/materiallib/CarbonFiberEmissiveMaterial.qml
index 73ba709d..6af3979a 100644
--- a/src/imports/materiallib/CarbonFiberEmissiveMaterial.qml
+++ b/src/imports/materiallib/CarbonFiberEmissiveMaterial.qml
@@ -124,7 +124,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: carbonFiberEmissiveFragShader
+            shaders: carbonFiberEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/CarbonFiberMaterial.qml b/src/imports/materiallib/CarbonFiberMaterial.qml
index aa34b24a..4a028f73 100644
--- a/src/imports/materiallib/CarbonFiberMaterial.qml
+++ b/src/imports/materiallib/CarbonFiberMaterial.qml
@@ -96,7 +96,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: carbonFiberEmissiveFragShader
+            shaders: carbonFiberEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/ConcreteMaterial.qml b/src/imports/materiallib/ConcreteMaterial.qml
index 21a8d698..d7109ea9 100644
--- a/src/imports/materiallib/ConcreteMaterial.qml
+++ b/src/imports/materiallib/ConcreteMaterial.qml
@@ -68,7 +68,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: concreteFragShader
+            shaders: concreteFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/CopperMaterial.qml b/src/imports/materiallib/CopperMaterial.qml
index 5a4ffea6..8b0bf134 100644
--- a/src/imports/materiallib/CopperMaterial.qml
+++ b/src/imports/materiallib/CopperMaterial.qml
@@ -39,7 +39,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: copperFragShader
+            shaders: copperFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/FrostedGlassMaterial.qml b/src/imports/materiallib/FrostedGlassMaterial.qml
index 92971381..3a9ba2b2 100644
--- a/src/imports/materiallib/FrostedGlassMaterial.qml
+++ b/src/imports/materiallib/FrostedGlassMaterial.qml
@@ -166,14 +166,14 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: noopShader
+            shaders: noopShader
             output: dummyBuffer
             commands: [ DemonCustomMaterialBufferBlit {
                     destination: frameBuffer
                 }
             ]
         }, DemonCustomMaterialPass {
-            shader: preBlurShader
+            shaders: preBlurShader
             output: tempBuffer
             commands: [ DemonCustomMaterialBufferInput {
                     buffer: frameBuffer
@@ -181,7 +181,7 @@ DemonCustomMaterial {
                 }
             ]
         }, DemonCustomMaterialPass {
-            shader: blurXShader
+            shaders: blurXShader
             output: blurXBuffer
             commands: [ DemonCustomMaterialBufferInput {
                     buffer: tempBuffer
@@ -189,7 +189,7 @@ DemonCustomMaterial {
                 }
             ]
         }, DemonCustomMaterialPass {
-            shader: blurYShader
+            shaders: blurYShader
             output: blurYBuffer
             commands: [ DemonCustomMaterialBufferInput {
                     buffer: blurXBuffer
@@ -200,7 +200,7 @@ DemonCustomMaterial {
                 }
             ]
         }, DemonCustomMaterialPass {
-            shader: mainShader
+            shaders: mainShader
             commands: [DemonCustomMaterialBufferInput {
                     buffer: blurYBuffer
                     param: "refractiveTexture"
diff --git a/src/imports/materiallib/FrostedGlassSinglePassMaterial.qml b/src/imports/materiallib/FrostedGlassSinglePassMaterial.qml
index 9d9672e8..2ad740ef 100644
--- a/src/imports/materiallib/FrostedGlassSinglePassMaterial.qml
+++ b/src/imports/materiallib/FrostedGlassSinglePassMaterial.qml
@@ -90,7 +90,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: frostedGlassSpFragShader
+            shaders: frostedGlassSpFragShader
             commands: [ DemonCustomMaterialBufferBlit {
                     destination: tempBuffer
                 }, DemonCustomMaterialBufferInput {
diff --git a/src/imports/materiallib/GlassMaterial.qml b/src/imports/materiallib/GlassMaterial.qml
index e8b3e650..a5d28a61 100644
--- a/src/imports/materiallib/GlassMaterial.qml
+++ b/src/imports/materiallib/GlassMaterial.qml
@@ -43,7 +43,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: simpleGlassFragShader
+            shaders: simpleGlassFragShader
             commands: [ DemonCustomMaterialBlending {
                     srcBlending: DemonCustomMaterialBlending.SrcAlpha
                     destBlending: DemonCustomMaterialBlending.OneMinusSrcAlpha
diff --git a/src/imports/materiallib/GlassRefractiveMaterial.qml b/src/imports/materiallib/GlassRefractiveMaterial.qml
index eb70bbed..1216ded1 100644
--- a/src/imports/materiallib/GlassRefractiveMaterial.qml
+++ b/src/imports/materiallib/GlassRefractiveMaterial.qml
@@ -53,7 +53,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: simpleGlassRefractiveFragShader
+            shaders: simpleGlassRefractiveFragShader
             commands: [ DemonCustomMaterialBufferBlit {
                     destination: tempBuffer
                 }, DemonCustomMaterialBufferInput {
diff --git a/src/imports/materiallib/LeatherSmoothedBlackMaterial.qml b/src/imports/materiallib/LeatherSmoothedBlackMaterial.qml
index d95645a3..0b38abdf 100644
--- a/src/imports/materiallib/LeatherSmoothedBlackMaterial.qml
+++ b/src/imports/materiallib/LeatherSmoothedBlackMaterial.qml
@@ -79,7 +79,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: leatherFragShader
+            shaders: leatherFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/MeshFenceMaterial.qml b/src/imports/materiallib/MeshFenceMaterial.qml
index b1c6dcbb..367c11f7 100644
--- a/src/imports/materiallib/MeshFenceMaterial.qml
+++ b/src/imports/materiallib/MeshFenceMaterial.qml
@@ -61,7 +61,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: meshFenceFragShader
+            shaders: meshFenceFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/MetalFenceFineMaterial.qml b/src/imports/materiallib/MetalFenceFineMaterial.qml
index e0e778cc..4a886696 100644
--- a/src/imports/materiallib/MetalFenceFineMaterial.qml
+++ b/src/imports/materiallib/MetalFenceFineMaterial.qml
@@ -69,7 +69,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: metalFenceFineFragShader
+            shaders: metalFenceFineFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PaperArtisticMaterial.qml b/src/imports/materiallib/PaperArtisticMaterial.qml
index ba2819aa..ea2eb25c 100644
--- a/src/imports/materiallib/PaperArtisticMaterial.qml
+++ b/src/imports/materiallib/PaperArtisticMaterial.qml
@@ -71,7 +71,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: paperArtisticFragShader
+            shaders: paperArtisticFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PaperOfficeMaterial.qml b/src/imports/materiallib/PaperOfficeMaterial.qml
index a5e43670..44b79ce6 100644
--- a/src/imports/materiallib/PaperOfficeMaterial.qml
+++ b/src/imports/materiallib/PaperOfficeMaterial.qml
@@ -63,7 +63,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: paperOfficeFragShader
+            shaders: paperOfficeFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PlasticStructuredRedEmissiveMaterial.qml b/src/imports/materiallib/PlasticStructuredRedEmissiveMaterial.qml
index 9c8b52bd..dfad958e 100644
--- a/src/imports/materiallib/PlasticStructuredRedEmissiveMaterial.qml
+++ b/src/imports/materiallib/PlasticStructuredRedEmissiveMaterial.qml
@@ -98,7 +98,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: plasticStructuredRedEmissiveFragShader
+            shaders: plasticStructuredRedEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PlasticStructuredRedMaterial.qml b/src/imports/materiallib/PlasticStructuredRedMaterial.qml
index a6ba490d..c888f2f4 100644
--- a/src/imports/materiallib/PlasticStructuredRedMaterial.qml
+++ b/src/imports/materiallib/PlasticStructuredRedMaterial.qml
@@ -76,7 +76,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: plasticStructuredRedFragShader
+            shaders: plasticStructuredRedFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PorcelainMaterial.qml b/src/imports/materiallib/PorcelainMaterial.qml
index 12afe03b..6aa9f0c2 100644
--- a/src/imports/materiallib/PorcelainMaterial.qml
+++ b/src/imports/materiallib/PorcelainMaterial.qml
@@ -44,7 +44,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: porcelainFragShader
+            shaders: porcelainFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PowderCoatEmissiveMaterial.qml b/src/imports/materiallib/PowderCoatEmissiveMaterial.qml
index cfc41d40..b7639fa9 100644
--- a/src/imports/materiallib/PowderCoatEmissiveMaterial.qml
+++ b/src/imports/materiallib/PowderCoatEmissiveMaterial.qml
@@ -78,7 +78,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: powderCoatEmissiveFragShader
+            shaders: powderCoatEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/PowderCoatMaterial.qml b/src/imports/materiallib/PowderCoatMaterial.qml
index 1d5804a7..bb218187 100644
--- a/src/imports/materiallib/PowderCoatMaterial.qml
+++ b/src/imports/materiallib/PowderCoatMaterial.qml
@@ -54,7 +54,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: powderCoatFragShader
+            shaders: powderCoatFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/RubberStuddedEmissiveMaterial.qml b/src/imports/materiallib/RubberStuddedEmissiveMaterial.qml
index 78cce5fb..26b9bb4f 100644
--- a/src/imports/materiallib/RubberStuddedEmissiveMaterial.qml
+++ b/src/imports/materiallib/RubberStuddedEmissiveMaterial.qml
@@ -78,7 +78,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: rubberStuddedEmissiveFragShader
+            shaders: rubberStuddedEmissiveFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/RubberStuddedMaterial.qml b/src/imports/materiallib/RubberStuddedMaterial.qml
index 079b754b..cd1490e7 100644
--- a/src/imports/materiallib/RubberStuddedMaterial.qml
+++ b/src/imports/materiallib/RubberStuddedMaterial.qml
@@ -53,7 +53,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: rubberStuddedFragShader
+            shaders: rubberStuddedFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/SteelMilledConcentricMaterial.qml b/src/imports/materiallib/SteelMilledConcentricMaterial.qml
index 8e8afaaf..aa6b6ac1 100644
--- a/src/imports/materiallib/SteelMilledConcentricMaterial.qml
+++ b/src/imports/materiallib/SteelMilledConcentricMaterial.qml
@@ -65,7 +65,7 @@ DemonCustomMaterial {
 
     passes: [
         DemonCustomMaterialPass {
-            shader: steelMilledConcentricFragShader
+            shaders: steelMilledConcentricFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/WalnutMatteMaterial.qml b/src/imports/materiallib/WalnutMatteMaterial.qml
index fd70260d..77999e2b 100644
--- a/src/imports/materiallib/WalnutMatteMaterial.qml
+++ b/src/imports/materiallib/WalnutMatteMaterial.qml
@@ -71,7 +71,7 @@ DemonCustomMaterial {
     }
 
     passes: [ DemonCustomMaterialPass {
-            shader: walnutMatteFragShader
+            shaders: walnutMatteFragShader
         }
     ]
 }
diff --git a/src/imports/materiallib/shaders/frostedThinGlassBlurX.frag b/src/imports/materiallib/shaders/frostedThinGlassBlurX.frag
index decf45c5..1e28d6f3 100644
--- a/src/imports/materiallib/shaders/frostedThinGlassBlurX.frag
+++ b/src/imports/materiallib/shaders/frostedThinGlassBlurX.frag
@@ -30,5 +30,4 @@ void main()
 
     gl_FragColor = value / wtsum;
     gl_FragColor.a = 1.0;
-
-    // No close paren because the generator adds it for us.
+}
diff --git a/src/imports/materiallib/shaders/frostedThinGlassBlurY.frag b/src/imports/materiallib/shaders/frostedThinGlassBlurY.frag
index 8e2218b1..0ad6ec6e 100644
--- a/src/imports/materiallib/shaders/frostedThinGlassBlurY.frag
+++ b/src/imports/materiallib/shaders/frostedThinGlassBlurY.frag
@@ -38,4 +38,4 @@ void main()
     gl_FragColor = (value / wtsum);
     gl_FragColor.a = 1.0;
 
-    // No close paren because the generator adds it for us.
+}
diff --git a/src/imports/materiallib/shaders/frostedThinGlassNoop.frag b/src/imports/materiallib/shaders/frostedThinGlassNoop.frag
index 7809157c..d0f071e7 100644
--- a/src/imports/materiallib/shaders/frostedThinGlassNoop.frag
+++ b/src/imports/materiallib/shaders/frostedThinGlassNoop.frag
@@ -12,3 +12,4 @@ void main()
     // pass, and if you do a buffer blit on a pass that outputs to lower-resolution,
     // it only blits a smaller portion of the backbuffer that occupies that number of
     // pixels.  So we need a dummy no-op pass that is full-res in order to blit everything.
+}
diff --git a/src/imports/materiallib/shaders/frostedThinGlassPreBlur.frag b/src/imports/materiallib/shaders/frostedThinGlassPreBlur.frag
index 1ed53d47..9c699d4f 100644
--- a/src/imports/materiallib/shaders/frostedThinGlassPreBlur.frag
+++ b/src/imports/materiallib/shaders/frostedThinGlassPreBlur.frag
@@ -29,4 +29,4 @@ void main()
 
     totSum /= wtSum;
     gl_FragColor = totSum;
-    // No close paren because the generator adds it for us.
+}
diff --git a/src/quick3d/qdemoncustommaterial.cpp b/src/quick3d/qdemoncustommaterial.cpp
index 03c8b241..ef38dc13 100644
--- a/src/quick3d/qdemoncustommaterial.cpp
+++ b/src/quick3d/qdemoncustommaterial.cpp
@@ -342,22 +342,28 @@ QDemonRenderGraphObject *QDemonCustomMaterial::updateSpatialNode(QDemonRenderGra
         QByteArray vertex, geometry, fragment, shaderCode;
         if (!m_passes.isEmpty()) {
             for (const auto &pass : qAsConst(m_passes)) {
-                QDemonCustomMaterialShader *shader = pass->shader;
-                if (!shader) {
+                QDemonCustomMaterialShader *sharedShader = pass->m_shaders.at(int(QDemonCustomMaterialShader::Stage::Shared));
+                QDemonCustomMaterialShader *vertShader = pass->m_shaders.at(int(QDemonCustomMaterialShader::Stage::Vertex));
+                QDemonCustomMaterialShader *fragShader = pass->m_shaders.at(int(QDemonCustomMaterialShader::Stage::Fragment));
+                QDemonCustomMaterialShader *geomShader = pass->m_shaders.at(int(QDemonCustomMaterialShader::Stage::Geometry));
+                if (!sharedShader && !vertShader && !fragShader && !geomShader) {
                     qWarning("Pass with no shader attatched!");
                     continue;
                 }
 
-                if (shader->stage != QDemonCustomMaterialShader::Stage::Fragment) {
-                    qWarning("Only fragment shaders supported in passes");
-                    continue;
-                }
-
                 // Build up shader code
-                const QByteArray &shaderName = shader->shader;
+                const QByteArray &shaderName = fragShader ? fragShader->shader : vertShader->shader;
                 Q_ASSERT(!shaderName.isEmpty());
 
-                const QByteArray fragment = resolveShader(shader->shader);
+                if (sharedShader)
+                    shared += resolveShader(sharedShader->shader);
+                if (vertShader)
+                    vertex = resolveShader(vertShader->shader);
+                if (fragShader)
+                    fragment = resolveShader(fragShader->shader);
+                if (geomShader)
+                    geometry = resolveShader(geomShader->shader);
+
                 shaderCode = mergeShaderCode(shared, vertex, geometry, fragment);
 
                 // Bind shader
@@ -474,4 +480,44 @@ QQmlListProperty<QDemonCustomMaterialRenderCommand> QDemonCustomMaterialRenderPa
                                                                nullptr);
 }
 
+void QDemonCustomMaterialRenderPass::qmlAppendShader(QQmlListProperty<QDemonCustomMaterialShader> *list, QDemonCustomMaterialShader *shader)
+{
+    if (!shader)
+        return;
+
+    QDemonCustomMaterialRenderPass *that = qobject_cast<QDemonCustomMaterialRenderPass *>(list->object);
+    that->m_shaders[int(shader->stage)] = shader;
+}
+
+QDemonCustomMaterialShader *QDemonCustomMaterialRenderPass::qmlShaderAt(QQmlListProperty<QDemonCustomMaterialShader> *list, int index)
+{
+    QDemonCustomMaterialRenderPass *that = qobject_cast<QDemonCustomMaterialRenderPass *>(list->object);
+    return that->m_shaders.at(index);
+}
+
+int QDemonCustomMaterialRenderPass::qmlShaderCount(QQmlListProperty<QDemonCustomMaterialShader> *list)
+{
+    QDemonCustomMaterialRenderPass *that = qobject_cast<QDemonCustomMaterialRenderPass *>(list->object);
+    return that->m_shaders.count();
+}
+
+void QDemonCustomMaterialRenderPass::qmlShaderClear(QQmlListProperty<QDemonCustomMaterialShader> *list)
+{
+    QDemonCustomMaterialRenderPass *that = qobject_cast<QDemonCustomMaterialRenderPass *>(list->object);
+    auto it = that->m_shaders.begin();
+    const auto end = that->m_shaders.end();
+    for (;it != end; ++it)
+        *it = nullptr;
+}
+
+QQmlListProperty<QDemonCustomMaterialShader> QDemonCustomMaterialRenderPass::shaders()
+{
+    return QQmlListProperty<QDemonCustomMaterialShader>(this,
+                                                        nullptr,
+                                                        QDemonCustomMaterialRenderPass::qmlAppendShader,
+                                                        QDemonCustomMaterialRenderPass::qmlShaderCount,
+                                                        QDemonCustomMaterialRenderPass::qmlShaderAt,
+                                                        QDemonCustomMaterialRenderPass::qmlShaderClear);
+}
+
 QT_END_NAMESPACE
diff --git a/src/quick3d/qdemoncustommaterial.h b/src/quick3d/qdemoncustommaterial.h
index 844905e3..7e36d8ec 100644
--- a/src/quick3d/qdemoncustommaterial.h
+++ b/src/quick3d/qdemoncustommaterial.h
@@ -422,7 +422,7 @@ class Q_QUICK3D_EXPORT QDemonCustomMaterialRenderPass : public QObject
     Q_OBJECT
     Q_PROPERTY(QQmlListProperty<QDemonCustomMaterialRenderCommand> commands READ commands)
     Q_PROPERTY(QDemonCustomMaterialBuffer *output MEMBER outputBuffer)
-    Q_PROPERTY(QDemonCustomMaterialShader *shader MEMBER shader)
+    Q_PROPERTY(QQmlListProperty<QDemonCustomMaterialShader> shaders READ shaders)
 public:
     QDemonCustomMaterialRenderPass() = default;
     ~QDemonCustomMaterialRenderPass() override = default;
@@ -431,10 +431,16 @@ public:
     static QDemonCustomMaterialRenderCommand *qmlCommandAt(QQmlListProperty<QDemonCustomMaterialRenderCommand> *list, int index);
     static int qmlCommandCount(QQmlListProperty<QDemonCustomMaterialRenderCommand> *list);
 
+    static void qmlAppendShader(QQmlListProperty<QDemonCustomMaterialShader> *list, QDemonCustomMaterialShader *shader);
+    static QDemonCustomMaterialShader *qmlShaderAt(QQmlListProperty<QDemonCustomMaterialShader> *list, int index);
+    static int qmlShaderCount(QQmlListProperty<QDemonCustomMaterialShader> *list);
+    static void qmlShaderClear(QQmlListProperty<QDemonCustomMaterialShader> *list);
+
     QQmlListProperty<QDemonCustomMaterialRenderCommand> commands();
     QVector<QDemonCustomMaterialRenderCommand *> m_commands;
     QDemonCustomMaterialBuffer *outputBuffer = nullptr;
-    QDemonCustomMaterialShader *shader = nullptr;
+    QQmlListProperty<QDemonCustomMaterialShader> shaders();
+    QVarLengthArray<QDemonCustomMaterialShader *, 5> m_shaders { nullptr, nullptr, nullptr, nullptr, nullptr };
 };
 
 class Q_QUICK3D_EXPORT QDemonCustomMaterialShaderInfo : public QObject
@@ -484,7 +490,8 @@ public:
         Shared,
         Vertex,
         Fragment,
-        Geometry
+        Geometry,
+        Compute
     };
     Q_ENUM(Stage)
 
diff --git a/src/runtimerender/qdemonrendercustommaterialshadergenerator.cpp b/src/runtimerender/qdemonrendercustommaterialshadergenerator.cpp
index 070503dd..3314ea43 100644
--- a/src/runtimerender/qdemonrendercustommaterialshadergenerator.cpp
+++ b/src/runtimerender/qdemonrendercustommaterialshadergenerator.cpp
@@ -384,8 +384,33 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
         return pCB;
     }
 
-    void generateVertexShader()
+    bool generateVertexShader(QDemonShaderDefaultMaterialKey &, const QByteArray &inShaderPathName)
     {
+        QDemonRef<QDemonDynamicObjectSystem> theDynamicSystem(m_renderContext->dynamicObjectSystem());
+        QByteArray vertSource = theDynamicSystem->getShaderSource(inShaderPathName);
+
+        Q_ASSERT(!vertSource.isEmpty());
+
+        // Check if the vertex shader portion already contains a main function
+        // The same string contains both the vertex and the fragment shader
+        // The last "#ifdef FRAGMENT_SHADER" should mark the start of the fragment shader
+        int fragmentDefStart = vertSource.indexOf("#ifdef FRAGMENT_SHADER");
+        int nextIndex = fragmentDefStart;
+        while (nextIndex != -1) {
+            nextIndex = vertSource.indexOf("#ifdef FRAGMENT_SHADER", nextIndex + 1);
+            if (nextIndex != -1)
+                fragmentDefStart = nextIndex;
+        }
+        const int mainStart = vertSource.indexOf("void main()");
+
+        auto &vertGenerator = vertexGenerator();
+
+        if (mainStart != -1 && (fragmentDefStart == -1 || mainStart < fragmentDefStart)) {
+            programGenerator()->beginProgram();
+            vertGenerator << "#define VERTEX_SHADER\n\n";
+            vertGenerator << vertSource;
+            return true;
+        }
         // vertex displacement
         quint32 imageIdx = 0;
         QDemonRenderableImage *displacementImage = nullptr;
@@ -401,6 +426,7 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
 
         // the pipeline opens/closes up the shaders stages
         vertexGenerator().beginVertexGeneration(displacementImageIdx, displacementImage);
+        return false;
     }
 
     QDemonRef<QDemonShaderGeneratorGeneratedShader> getShaderForProgram(const QDemonRef<QDemonRenderShaderProgram> &inProgram)
@@ -890,7 +916,9 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
                             "}\n\n";
     }
 
-    void generateFragmentShader(QDemonShaderDefaultMaterialKey &, const QByteArray &inShaderPathName)
+    bool generateFragmentShader(QDemonShaderDefaultMaterialKey &,
+                                const QByteArray &inShaderPathName,
+                                bool hasCustomVertShader)
     {
         QDemonRef<QDemonDynamicObjectSystem> theDynamicSystem(m_renderContext->dynamicObjectSystem());
         QByteArray fragSource = theDynamicSystem->getShaderSource(inShaderPathName);
@@ -915,10 +943,11 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
             }
         }
 
-        vertexGenerator().generateUVCoords(0);
-        // for lightmaps we expect a second set of uv coordinates
-        if (hasLightmaps) {
-            vertexGenerator().generateUVCoords(1);
+        if (!hasCustomVertShader) {
+            vertexGenerator().generateUVCoords(0);
+            // for lightmaps we expect a second set of uv coordinates
+            if (hasLightmaps)
+                vertexGenerator().generateUVCoords(1);
         }
 
         QDemonDefaultMaterialVertexPipelineInterface &vertexShader(vertexGenerator());
@@ -936,7 +965,9 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
 
         fragmentShader << "#define FRAGMENT_SHADER\n\n";
 
-        if (!srcString.contains("void main()"))
+        const bool hasCustomFragShader = srcString.contains("void main()");
+
+        if (!hasCustomFragShader)
             fragmentShader.addInclude("evalLightmaps.glsllib");
 
         // check dielectric materials
@@ -949,17 +980,21 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
 
         fragmentShader << srcString << "\n";
 
-        if (srcString.contains("void main()")) // If a "main()" is already
-                                               // written, we'll assume that the
-                                               // shader
-        { // pass is already written out and we don't need to add anything.
-            // Nothing beyond the basics, anyway
-            vertexShader.generateWorldNormal();
-            vertexShader.generateVarTangentAndBinormal();
-            vertexShader.generateWorldPosition();
+        // If a "main()" is already
+        // written, we'll assume that the
+        // shader
+        // pass is already written out and we don't need to add anything.
+        // Nothing beyond the basics, anyway
+        if (hasCustomFragShader) {
+            fragmentShader << "#define FRAGMENT_SHADER\n\n";
+            if (!hasCustomVertShader) {
+                vertexShader.generateWorldNormal();
+                vertexShader.generateVarTangentAndBinormal();
+                vertexShader.generateWorldPosition();
 
-            vertexShader.generateViewVector();
-            return;
+                vertexShader.generateViewVector();
+            }
+            return true;
         }
 
         if (material().hasLighting() && lightmapIndirectImage) {
@@ -1033,6 +1068,7 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
             fragmentShader << "  gl_FragColor = rgba;\n";
         else
             fragmentShader << "  fragColor = rgba;\n";
+        return false;
     }
 
     QDemonRef<QDemonRenderShaderProgram> generateCustomMaterialShader(const QByteArray &inShaderPrefix, const QByteArray &inCustomMaterialName)
@@ -1047,12 +1083,12 @@ struct QDemonShaderGenerator : public QDemonMaterialShaderGeneratorInterface
         QDemonShaderDefaultMaterialKey theKey(key());
         theKey.toString(generatedShaderString, m_defaultMaterialShaderKeyProperties);
 
-        generateVertexShader();
+        const bool hasCustomVertShader = generateVertexShader(theKey, inCustomMaterialName);
         // TODO: The material name shouldn't need to be a QString
-        generateFragmentShader(theKey, inCustomMaterialName);
+        const bool hasCustomFragShader = generateFragmentShader(theKey, inCustomMaterialName, hasCustomVertShader);
 
-        vertexGenerator().endVertexGeneration();
-        vertexGenerator().endFragmentGeneration();
+        vertexGenerator().endVertexGeneration(hasCustomVertShader);
+        vertexGenerator().endFragmentGeneration(hasCustomFragShader);
 
         return programGenerator()->compileGeneratedShader(generatedShaderString, QDemonShaderCacheProgramFlags(), m_currentFeatureSet);
     }
diff --git a/src/runtimerender/qdemonrendercustommaterialsystem.cpp b/src/runtimerender/qdemonrendercustommaterialsystem.cpp
index 9489271d..588da76b 100644
--- a/src/runtimerender/qdemonrendercustommaterialsystem.cpp
+++ b/src/runtimerender/qdemonrendercustommaterialsystem.cpp
@@ -366,7 +366,7 @@ void QDemonCustomMaterialVertexPipeline::generateWorldPosition()
 }
 
 // responsible for closing all vertex and fragment generation
-void QDemonCustomMaterialVertexPipeline::endVertexGeneration()
+void QDemonCustomMaterialVertexPipeline::endVertexGeneration(bool customShader)
 {
     if (hasTessellation()) {
         // finalize tess control shader
@@ -384,12 +384,14 @@ void QDemonCustomMaterialVertexPipeline::endVertexGeneration()
         }
     }
 
-    vertex().append("}");
+    if (!customShader)
+        vertex().append("}");
 }
 
-void QDemonCustomMaterialVertexPipeline::endFragmentGeneration()
+void QDemonCustomMaterialVertexPipeline::endFragmentGeneration(bool customShader)
 {
-    fragment().append("}");
+    if (!customShader)
+        fragment().append("}");
 }
 
 QDemonShaderStageGeneratorInterface &QDemonCustomMaterialVertexPipeline::activeStage()
diff --git a/src/runtimerender/qdemonrendercustommaterialsystem.h b/src/runtimerender/qdemonrendercustommaterialsystem.h
index 3ab46f5d..d34c2569 100644
--- a/src/runtimerender/qdemonrendercustommaterialsystem.h
+++ b/src/runtimerender/qdemonrendercustommaterialsystem.h
@@ -216,8 +216,8 @@ struct Q_DEMONRUNTIMERENDER_EXPORT QDemonCustomMaterialVertexPipeline : public Q
     virtual void generateVarTangentAndBinormal() override;
     virtual void generateWorldPosition() override;
     // responsible for closing all vertex and fragment generation
-    virtual void endVertexGeneration() override;
-    virtual void endFragmentGeneration() override;
+    virtual void endVertexGeneration(bool customShader) override;
+    virtual void endFragmentGeneration(bool customShader) override;
     virtual QDemonShaderStageGeneratorInterface &activeStage() override;
     virtual void addInterpolationParameter(const QByteArray &inName, const QByteArray &inType) override;
     virtual void doGenerateUVCoords(quint32 inUVSet) override;
diff --git a/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.cpp b/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.cpp
index 9ec7fe94..7cb5c220 100644
--- a/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.cpp
+++ b/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.cpp
@@ -1360,8 +1360,8 @@ struct QDemonShaderGenerator : public QDemonDefaultMaterialShaderGeneratorInterf
         generateVertexShader();
         generateFragmentShader(theKey);
 
-        vertexGenerator().endVertexGeneration();
-        vertexGenerator().endFragmentGeneration();
+        vertexGenerator().endVertexGeneration(false);
+        vertexGenerator().endFragmentGeneration(false);
 
         return programGenerator()->compileGeneratedShader(generatedShaderString, QDemonShaderCacheProgramFlags(), m_currentFeatureSet);
     }
diff --git a/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.h b/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.h
index bc932a5a..02c914b4 100644
--- a/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.h
+++ b/src/runtimerender/qdemonrenderdefaultmaterialshadergenerator.h
@@ -79,8 +79,8 @@ public:
     virtual bool hasActiveWireframe() = 0; // varEdgeDistance is a valid entity
 
     // responsible for closing all vertex and fragment generation
-    virtual void endVertexGeneration() = 0;
-    virtual void endFragmentGeneration() = 0;
+    virtual void endVertexGeneration(bool customShader) = 0;
+    virtual void endFragmentGeneration(bool customShader) = 0;
 };
 
 class Q_DEMONRUNTIMERENDER_EXPORT QDemonDefaultMaterialShaderGeneratorInterface : public QDemonMaterialShaderGeneratorInterface
diff --git a/src/runtimerender/qdemonrenderdynamicobjectsystem.cpp b/src/runtimerender/qdemonrenderdynamicobjectsystem.cpp
index e5fae838..2a2375d5 100644
--- a/src/runtimerender/qdemonrenderdynamicobjectsystem.cpp
+++ b/src/runtimerender/qdemonrenderdynamicobjectsystem.cpp
@@ -476,9 +476,9 @@ QDemonRef<QDemonRenderShaderProgram> QDemonDynamicObjectSystem::compileShader(co
 
 QByteArray QDemonDynamicObjectSystem::getShaderSource(const QByteArray &inPath)
 {
-    QByteArray source(QByteArrayLiteral("#define FRAGMENT_SHADER\n"));
-    source.append(doLoadShader(inPath));
-    return source;
+//    QByteArray source(QByteArrayLiteral("#define FRAGMENT_SHADER\n"));
+//    source.append(doLoadShader(inPath));
+    return doLoadShader(inPath);
 }
 
 TShaderAndFlags QDemonDynamicObjectSystem::getShaderProgram(const QByteArray &inPath,
diff --git a/src/runtimerender/qdemonrenderpathmanager.cpp b/src/runtimerender/qdemonrenderpathmanager.cpp
index 334d7f12..9ac537c8 100644
--- a/src/runtimerender/qdemonrenderpathmanager.cpp
+++ b/src/runtimerender/qdemonrenderpathmanager.cpp
@@ -426,7 +426,7 @@ struct QDemonPathVertexPipeline : public QDemonVertexPipelineImpl
                  << "\n";
     }
 
-    void endVertexGeneration() override
+    void endVertexGeneration(bool) override
     {
 
         if (hasTessellation()) {
@@ -445,7 +445,7 @@ struct QDemonPathVertexPipeline : public QDemonVertexPipelineImpl
         }
     }
 
-    void endFragmentGeneration() override { fragment().append("}"); }
+    void endFragmentGeneration(bool) override { fragment().append("}"); }
 
     void addInterpolationParameter(const QByteArray &inName, const QByteArray &inType) override
     {
@@ -641,9 +641,9 @@ struct QDemonXYRectVertexPipeline : public QDemonVertexPipelineImpl
                  << "\n";
     }
 
-    void endVertexGeneration() override { vertex().append("}"); }
+    void endVertexGeneration(bool) override { vertex().append("}"); }
 
-    void endFragmentGeneration() override { fragment().append("}"); }
+    void endFragmentGeneration(bool) override { fragment().append("}"); }
 
     void addInterpolationParameter(const QByteArray &inName, const QByteArray &inType) override
     {
@@ -1500,8 +1500,8 @@ struct QDemonPathManager : public QDemonPathManagerInterface
                 thePipeline.beginVertexGeneration(displacementIdx, displacementImage);
                 thePipeline.beginFragmentGeneration();
                 thePipeline.fragment().append("\tfragOutput = vec4(1.0, 1.0, 1.0, 1.0);");
-                thePipeline.endVertexGeneration();
-                thePipeline.endFragmentGeneration();
+                thePipeline.endVertexGeneration(false);
+                thePipeline.endFragmentGeneration(false);
                 const char *shaderName = "path depth";
                 if (displacementImage)
                     shaderName = "path depth displacement";
@@ -1522,8 +1522,8 @@ struct QDemonPathManager : public QDemonPathManagerInterface
                 thePipeline.beginVertexGeneration(0, nullptr);
                 thePipeline.beginFragmentGeneration();
                 thePipeline.fragment().append("\tfragOutput = vec4(1.0, 1.0, 1.0, 1.0);");
-                thePipeline.endVertexGeneration();
-                thePipeline.endFragmentGeneration();
+                thePipeline.endVertexGeneration(false);
+                thePipeline.endFragmentGeneration(false);
                 QDemonShaderCacheProgramFlags theFlags;
                 QDemonRef<QDemonRenderShaderProgram> theProgram = thePipeline.programGenerator()->compileGeneratedShader("path painted depth",
                                                                                                                          theFlags,
diff --git a/src/runtimerender/qdemonrendershadercache.cpp b/src/runtimerender/qdemonrendershadercache.cpp
index a5019893..ffaf2743 100644
--- a/src/runtimerender/qdemonrendershadercache.cpp
+++ b/src/runtimerender/qdemonrendershadercache.cpp
@@ -265,7 +265,7 @@ void QDemonShaderCache::addShaderExtensionStrings(ShaderType shaderType, bool is
         if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment || shaderType == ShaderType::Geometry) {
             if (m_renderContext->renderContextType() != QDemonRenderContextType::GLES2) {
                 m_insertStr += "#extension GL_ARB_gpu_shader5 : enable\n";
-                m_insertStr += "#extension GL_ARB_shading_language_420pack : enable\n";
+//                m_insertStr += "#extension GL_ARB_shading_language_420pack : enable\n";
             }
             if (isGLES && m_renderContext->supportsTextureLod())
                 m_insertStr += "#extension GL_EXT_shader_texture_lod : enable\n";
diff --git a/src/runtimerender/rendererimpl/qdemonrendererimplshaders.cpp b/src/runtimerender/rendererimpl/qdemonrendererimplshaders.cpp
index 810ab64b..c9ec35b7 100644
--- a/src/runtimerender/rendererimpl/qdemonrendererimplshaders.cpp
+++ b/src/runtimerender/rendererimpl/qdemonrendererimplshaders.cpp
@@ -370,7 +370,7 @@ struct QDemonSubsetMaterialVertexPipeline : public QDemonVertexPipelineImpl
         vertex().append("\tvarColor = attr_color;");
     }
 
-    void endVertexGeneration() override
+    void endVertexGeneration(bool customShader) override
     {
 
         if (hasTessellation()) {
@@ -387,10 +387,15 @@ struct QDemonSubsetMaterialVertexPipeline : public QDemonVertexPipelineImpl
             finalizeWireframeGeometryShader();
             geometry().append("}");
         }
-        vertex().append("}");
+        if (!customShader)
+            vertex().append("}");
     }
 
-    void endFragmentGeneration() override { fragment().append("}"); }
+    void endFragmentGeneration(bool customShader) override
+    {
+        if (!customShader)
+            fragment().append("}");
+    }
 
     void addInterpolationParameter(const QByteArray &inName, const QByteArray &inType) override
     {
diff --git a/src/runtimerender/rendererimpl/qdemonvertexpipelineimpl.h b/src/runtimerender/rendererimpl/qdemonvertexpipelineimpl.h
index d1b52cad..bf122a49 100644
--- a/src/runtimerender/rendererimpl/qdemonvertexpipelineimpl.h
+++ b/src/runtimerender/rendererimpl/qdemonvertexpipelineimpl.h
@@ -353,10 +353,10 @@ struct QDemonVertexPipelineImpl : public QDemonDefaultMaterialVertexPipelineInte
 
     void beginVertexGeneration(quint32 displacementImageIdx, QDemonRenderableImage *displacementImage) override = 0;
     void assignOutput(const QByteArray &inVarName, const QByteArray &inVarValueExpr) override = 0;
-    void endVertexGeneration() override = 0;
+    void endVertexGeneration(bool customShader) override = 0;
 
     void beginFragmentGeneration() override = 0;
-    void endFragmentGeneration() override = 0;
+    void endFragmentGeneration(bool customShader) override = 0;
 
     virtual QDemonShaderStageGeneratorInterface &activeStage() = 0;
     virtual void addInterpolationParameter(const QByteArray &inParamName, const QByteArray &inParamType) = 0;
-- 
GitLab