diff --git a/src/imports/materiallib/AluminumAnisotropicMaterial.qml b/src/imports/materiallib/AluminumAnisotropicMaterial.qml
index 76644755467144edf6d463871306d77d2fb9f3c0..5e8b4f8f3dde583b774852ebe724a842af903b5f 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 cee0cf71d34d5ca2e2edd802ce58842381b059eb..dbf023f91f0ffd2d9e801b14c4d476bea3623bc9 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 19c5142846ad09737fda24238ef5b43a95149047..0b79fc12b05dcf1d3b9b039c77458add70b813e8 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 80a393cb3a9823334e32dc1be8b877f26cd89f41..00d59748a1dd178146057b67e8a9e474bd31cce5 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 6e26acdf7bb8b236d587b080b796900cea5bd837..2a27af477865c494dc4872e49fddb93998609b4b 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 0c2406a97c5f435a6015b6d8d31bc6850c8bc702..5368bfc216dada9fd2d7d13ea151075981802d8d 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 824c16187d80d0ae6a2ff9ec60f3cedcc7e659a4..d8e662644fb89a3ae9d3ef70960b91bc46492b1c 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 8f3566ba9536f43f5c6fae162e29a4f37f890ac5..e85c36ee3b4a15252d870e8071a2ad5faf2d3ae6 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 9b7d5a69e89bf74c0c9ba1d656df46ca6f7ef981..132abbe4ebe97547eff9e9b438b4f3da4a2c4b8b 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 b68fb10a988128c4e08067bf0507eb5c44f2b699..48a5c06897dfc341d4546afa897aedb9d2b3d453 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 dfb7c0f92e6d7596dba24eb3526d4f2cf3f4a3c5..6b8274c0d45d5dc94741112bc189ff89358e2773 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 2334e50eef92876f9f676ba364c00d65174c38ae..80a690fe2f99d10d8ee4ac7158184144050474a3 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 96e00eca156e0ed17e636ccd20a0de8128a5cb64..b8aa7e5a1cf027734b4757a02df942d03f02cf01 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 73ba709d2b4b09018122c0972a305d85383f42e1..6af3979add1edc87cefca706354740dead301d5a 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 aa34b24aeb685ecd5ad3450bff73881d2eff97a2..4a028f736177404368e36085882dc42988b157ed 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 21a8d69840ddd88cf45b041bd6f3e5d1b687821b..d7109ea9a397b99bb0521024507f27e7ba78820d 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 5a4ffea63107303623392e7fb63fd5e2ff67a863..8b0bf1348e0546c8cfb0ecea594bb0109e592031 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 929713819367b715829dbde0c5257b880395f387..3a9ba2b28174925e3feb872cddd68bafed4a639b 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 9d9672e8ae2149d9c2fe1d4075c17b8295612467..2ad740efc60441b74c1e8de40a92d9f6ed9b215a 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 e8b3e650810eacab995676e86b76b1e73b52d56c..a5d28a611c34a994030dcd72c3b856dc1baab00b 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 eb70bbedba278f0b7fff540bb19355d36240ebe7..1216ded168e653963fd3c111716df78585968e31 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 d95645a3ee1e3dfc29e5eff02176d8808aa1b81f..0b38abdfef309e4386b078146ab218ce1b5b1010 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 b1c6dcbbf28aa7dfac4d81fe1c9dc7d434fa61f3..367c11f770e0e204440f14bb1669af812318c50e 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 e0e778ccdad51fe0ad8dd43946686a7c9eace728..4a886696d8524d6443d72592325022444ce14140 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 ba2819aadb9369ef2a805b33796ad70e85ce26a2..ea2eb25c65edb9e09c0b0cb6d3d4ff1d9420cead 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 a5e43670bcbd5a1fb74ffda8a07407c2d9f53dce..44b79ce60dcd23180e14d1d8598a55f3d1708d09 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 9c8b52bd0e2f17eace5723e4b6dd59fc93b40516..dfad958e547667a014dd20f4cc9cd6aa568084bf 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 a6ba490db1d024838b43f602955e2bb19504e83a..c888f2f4aa57a3a2010a5be0ebbb135260d7ad7b 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 12afe03bb74e84368988c7d5533d741b15a41728..6aa9f0c2c7ab1a98a71fca3b8d8f9073f17efdbf 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 cfc41d400f2a32d3c8a0c8f8acf8e33251831334..b7639fa9011245fb0d1232aa3ff93799b8193408 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 1d5804a71bfb4e98dc9be1002826bbb2f592105f..bb218187bc02c40b4b65f7750d3f24beaa78bfe0 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 78cce5fbba142c6c0d8818cd127f431e2002eefe..26b9bb4fb83695e367f71e2540184f84c7702059 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 079b754b0d23183d7763324d18ecb605062d5220..cd1490e79703b36aee111605df06d618ed38c8c5 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 8e8afaaf767019d17eb7f964b6624c992140554f..aa6b6ac1dac629e730487587f96a2cf63ed3cf31 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 fd70260d6e89ac14edc12fcd110cde4a3334f21c..77999e2b6bcb850b5bfe334a0d703a912c567e32 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 decf45c57c8c8a9efc961da7dc051ef74f174c3b..1e28d6f31945e5568afc38e2470373d919fd29b4 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 8e2218b1a1ca10199d69ba21528a06da1bef9422..0ad6ec6eca16fe7e9dc6fe7d99cc58374e697a9f 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 7809157ca27c64ca865f7e7d22026df0d3cbc3bc..d0f071e70a9251e7e9a44558ae1f6ee52a15c0a6 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 1ed53d478e2945ef02602d26aa74ce7817125b5f..9c699d4f0d802312ddbf3fb59e168babfe82f440 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 03c8b24167fc5ecac6a26c69f2c952bdae483ced..ef38dc134ecb61b9a1fc0db6ee89501fb36c96aa 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 844905e349f618015a710f6573322151a8da744f..7e36d8ec6eca54076efa136db4c8bc0c364f3b62 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 070503ddc25d93ed0725e0c2066b58ffa48955b6..3314ea43e9de2097117741c6f9f6e8a987305131 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 9489271dcbcdf8c551343b8742f580f2224f8260..588da76ba905821b7cf7ddcba135bfab41652348 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 3ab46f5d3d4ea3f8ba60edbf09531f0b736ada34..d34c2569f7cfa415f78057220c385e3bca942fb7 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 9ec7fe94783f2b48f032c677320f0f7412d65677..7cb5c22030db74e68ec20814174d0b823307039e 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 bc932a5a94b31a278afee1d5aed8e009d2aacaa9..02c914b4b976a878fb9fe5fc3896014004ee3e68 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 e5fae838a0c7acd6954abc433fce3dca5801186b..2a2375d5f96cfb4a6739c0a321e7db5a05282845 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 334d7f12830af378e5a82bf3b9c1a7155a2436a6..9ac537c8b816644d348b80147f8ad0873d809a8f 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 a5019893c4820c51989e60c3b5ed0b571ef4649d..ffaf2743492ee5ef7139031e06156a9f201a3d6e 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 810ab64b51e5c3158b8beee4f5b1a256b7a46033..c9ec35b791814bd6fe0b38379cfcd8a5938c7037 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 d1b52cadcfb44af02977a564e27d406bd279b786..bf122a49e08581b75c219f9d7f2caece604f34cf 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;