Skip to content

Commit 1206fbb

Browse files
authored
[Foliage swaying 3D] Precompile foliage shaders to avoid stutters … (#2286)
Each foliage material's shaders are now compiled ahead of time, for both plain and instanced meshes. The Sway properties (type, material name, response, uniform sway) are grouped under a "Sway" group.
1 parent 468db8b commit 1206fbb

1 file changed

Lines changed: 103 additions & 37 deletions

File tree

‎extensions/community/FoliageSwaying3D.json‎

Lines changed: 103 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"name": "FoliageSwaying3D",
1111
"previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/732ef90b7fcf5dd9171fe95d0cf262e09159b487304915a4693baa893d9ce16c_grass.svg",
1212
"shortDescription": "Sway foliage of 3D objects according to the wind.",
13-
"version": "1.0.0",
13+
"version": "1.1.0",
1414
"description": [
1515
"Sway foliage of 3D objects according to wind.",
1616
"",
@@ -30,12 +30,8 @@
3030
"* Hot reload supports all basic behavior property changes, excluding Sway settings (`Material to sway`, `Sway type`, `Enable uniform sway toggle`) and `Distance culling`, `Debug output`, `GPU instancing`, and `Custom PBR settings` toggles. However, if PBR settings are enabled as you start the preview, changes to specific PBR values will be updated on hot-reload.<br><br>",
3131
""
3232
],
33-
"origin": {
34-
"identifier": "FoliageSwaying3D",
35-
"name": "gdevelop-extension-store"
36-
},
3733
"tags": [
38-
"3d",
34+
"3D",
3935
"shader",
4036
"foliage",
4137
"wind",
@@ -5029,6 +5025,67 @@
50295025
"parameterObjects": "",
50305026
"useStrict": true,
50315027
"eventsSheetExpanded": true
5028+
},
5029+
{
5030+
"type": "BuiltinCommonInstructions::JsCode",
5031+
"inlineCode": [
5032+
"// Prepares the shaders of every foliage material ahead of time, so foliage",
5033+
"// becoming visible for the first time (often on a camera turn) does not",
5034+
"// compile its shader on that frame. A foliage material can be drawn by plain",
5035+
"// and by instanced meshes, which use two different programs: one mesh of each",
5036+
"// kind is compiled per material. Compilation runs again when a material is",
5037+
"// added or changes version (new defines, such as wind gusts).",
5038+
"const sceneState = runtimeScene._foliageSwaying3D;",
5039+
"const activeMaterials = sceneState && sceneState.activeMaterials;",
5040+
"if (!activeMaterials || activeMaterials.size === 0) return;",
5041+
"",
5042+
"let materialsSignature = '';",
5043+
"activeMaterials.forEach((material) => {",
5044+
" if (material) materialsSignature += material.uuid + ':' + material.version + '|';",
5045+
"});",
5046+
"if (sceneState._precompiledMaterialsSignature === materialsSignature) return;",
5047+
"",
5048+
"const layerRenderer = runtimeScene.getLayer(\"\").getRenderer();",
5049+
"const threeScene = layerRenderer && layerRenderer.getThreeScene ? layerRenderer.getThreeScene() : null;",
5050+
"if (!threeScene) return;",
5051+
"sceneState._precompiledMaterialsSignature = materialsSignature;",
5052+
"",
5053+
"const meshesToCompile = [];",
5054+
"const foundVariants = new Set();",
5055+
"threeScene.traverse((object3D) => {",
5056+
" if (!object3D.isMesh || !object3D.material) return;",
5057+
" const materials = Array.isArray(object3D.material) ? object3D.material : [object3D.material];",
5058+
" for (const material of materials) {",
5059+
" if (!activeMaterials.has(material)) continue;",
5060+
" const variantKey = material.uuid + (object3D.isInstancedMesh ? ':instanced' : ':plain');",
5061+
" if (foundVariants.has(variantKey)) continue;",
5062+
" foundVariants.add(variantKey);",
5063+
" meshesToCompile.push(object3D);",
5064+
" }",
5065+
"});",
5066+
"if (meshesToCompile.length === 0) return;",
5067+
"",
5068+
"// Compiling outside of a render can produce a program variant that differs",
5069+
"// from the one used to draw (lights and render state are only set up during",
5070+
"// the render), so the compilation is done at the start of the next render.",
5071+
"const previousOnBeforeRender = threeScene.onBeforeRender;",
5072+
"threeScene.onBeforeRender = function (renderer, scene, camera, renderTarget) {",
5073+
" threeScene.onBeforeRender = previousOnBeforeRender;",
5074+
" if (renderer && renderer.compile) {",
5075+
" for (const mesh of meshesToCompile) {",
5076+
" // The compiler only collects visible meshes: show this one just for the call.",
5077+
" const wasVisible = mesh.visible;",
5078+
" mesh.visible = true;",
5079+
" try { renderer.compile(mesh, camera, scene); } catch (error) {}",
5080+
" mesh.visible = wasVisible;",
5081+
" }",
5082+
" }",
5083+
" if (previousOnBeforeRender) previousOnBeforeRender.apply(this, arguments);",
5084+
"};"
5085+
],
5086+
"parameterObjects": "",
5087+
"useStrict": true,
5088+
"eventsSheetExpanded": false
50325089
}
50335090
],
50345091
"parameters": [
@@ -8879,7 +8936,7 @@
88798936
"value": "",
88808937
"type": "Boolean",
88818938
"label": "Use color gradient",
8882-
"description": "Enables top/bottom gradient tint and color grading (default: off).",
8939+
"description": "Enables top/bottom gradient tint and color grading (default: off)",
88838940
"group": "Color",
88848941
"name": "UseColorGradient"
88858942
},
@@ -8935,21 +8992,24 @@
89358992
"value": "",
89368993
"type": "String",
89378994
"label": "Material to sway",
8938-
"description": "Material name to target (empty = auto-pick).",
8995+
"description": "Material name to target. (empty = auto-pick)",
8996+
"group": "Sway",
89398997
"name": "MaterialName"
89408998
},
89418999
{
89429000
"value": "true",
89439001
"type": "Boolean",
89449002
"label": "Enable uniform sway",
8945-
"description": "If enabled, all instances sway similarly. If off, each gets random phase variation (default: on).",
9003+
"description": "If enabled, all instances sway similarly. If off, each gets random phase variation. (default: on)",
9004+
"group": "Sway",
89469005
"name": "UseUniformSway"
89479006
},
89489007
{
8949-
"value": "Grass",
9008+
"value": "",
89509009
"type": "Choice",
89519010
"label": "Sway type",
89529011
"description": "Wind animation model.",
9012+
"group": "Sway",
89539013
"choices": [
89549014
{
89559015
"label": "Grass sway",
@@ -8974,15 +9034,16 @@
89749034
"value": "false",
89759035
"type": "Boolean",
89769036
"label": "Debug output",
8977-
"description": "Prints material/mesh and auto-scale debug info to console (requires object to be in the scene; default: off).",
9037+
"description": "Prints material/mesh and auto-scale debug info to console. (requires object to be in the scene; default: off)",
89789038
"advanced": true,
89799039
"name": "DebugOutput"
89809040
},
89819041
{
89829042
"value": "0",
89839043
"type": "Number",
89849044
"label": "Sway response",
8985-
"description": "How much the object is deformed by the wind. For low-poly models use small number around 0.5. (0-200; 0 = auto)",
9045+
"description": "Sorts unexpected visual behavior. For low-poly models use smaller number. (0-200; 0 = auto)",
9046+
"group": "Sway",
89869047
"name": "SwayResponse"
89879048
},
89889049
{
@@ -8997,15 +9058,15 @@
89979058
"value": "",
89989059
"type": "Boolean",
89999060
"label": "GPU instancing",
9000-
"description": "Uses GPU instancing for supported sway types (better performance; default: off).",
9061+
"description": "Uses GPU instancing for supported sway types. (better performance; default: off).",
90019062
"group": "Instancing",
90029063
"name": "UseGPUInstancing"
90039064
},
90049065
{
90059066
"value": "",
90069067
"type": "Boolean",
90079068
"label": "Distance culling",
9008-
"description": "Enables distance-based dither fade/culling (default: off).",
9069+
"description": "Enables distance-based dither fade/culling. (default: off)",
90099070
"group": "Culling",
90109071
"name": "UseDistanceFade"
90119072
},
@@ -9014,7 +9075,7 @@
90149075
"type": "Number",
90159076
"unit": "Pixel",
90169077
"label": "Fade distance start",
9017-
"description": "Distance where fade-out starts. Requires enabled distance culling (0-100000; default: 1200).",
9078+
"description": "Distance where fade-out starts. Requires enabled distance culling. (0-100000; default: 1200)",
90189079
"group": "Culling",
90199080
"name": "DistanceFadeStart"
90209081
},
@@ -9023,15 +9084,15 @@
90239084
"type": "Number",
90249085
"unit": "Pixel",
90259086
"label": "Fade distance end",
9026-
"description": "Distance where fade reaches zero. Requires enabled distance culling (0-100000; default: 1600).",
9087+
"description": "Distance where fade reaches zero. Requires enabled distance culling. (0-100000; default: 1600)",
90279088
"group": "Culling",
90289089
"name": "DistanceFadeEnd"
90299090
},
90309091
{
90319092
"value": "",
90329093
"type": "Boolean",
90339094
"label": "Custom PBR settings",
9034-
"description": "Enables custom PBR tuning controls (default: off).",
9095+
"description": "Enables custom PBR tuning controls. (default: off)",
90359096
"group": "Custom PBR (experimental)",
90369097
"advanced": true,
90379098
"name": "UseCustomPBR"
@@ -9040,7 +9101,7 @@
90409101
"value": "0",
90419102
"type": "Number",
90429103
"label": "Metallic factor",
9043-
"description": "PBR metallic value (0-1; default: 0).",
9104+
"description": "PBR metallic value. (0-1; default: 0)",
90449105
"group": "Custom PBR (experimental)",
90459106
"advanced": true,
90469107
"name": "Metallic"
@@ -9049,7 +9110,7 @@
90499110
"value": "1",
90509111
"type": "Number",
90519112
"label": "Roughness factor",
9052-
"description": "PBR roughness value (0-1; default: 1).",
9113+
"description": "PBR roughness value. (0-1; default: 1)",
90539114
"group": "Custom PBR (experimental)",
90549115
"advanced": true,
90559116
"name": "Roughness"
@@ -9058,7 +9119,7 @@
90589119
"value": "0.1",
90599120
"type": "Number",
90609121
"label": "Specular factor",
9061-
"description": "Specular intensity (where supported; 0-1; default: 0.1).",
9122+
"description": "Specular intensity. (where supported; 0-1; default: 0.1)",
90629123
"group": "Custom PBR (experimental)",
90639124
"advanced": true,
90649125
"name": "Specular"
@@ -9067,7 +9128,7 @@
90679128
"value": "1",
90689129
"type": "Number",
90699130
"label": "Normal strength",
9070-
"description": "Normal map strength (0-1; default: 1).",
9131+
"description": "Normal map strength. (0-1; default: 1)",
90719132
"group": "Custom PBR (experimental)",
90729133
"advanced": true,
90739134
"name": "NormalStrength"
@@ -9076,7 +9137,7 @@
90769137
"value": "1",
90779138
"type": "Number",
90789139
"label": "Ambient Occlusion strength",
9079-
"description": "Ambient occlusion intensity (0-1; default: 1).",
9140+
"description": "Ambient occlusion intensity. (0-1; default: 1)",
90809141
"group": "Custom PBR (experimental)",
90819142
"advanced": true,
90829143
"name": "AmbientOcclusionStrength"
@@ -9085,13 +9146,13 @@
90859146
"value": "1",
90869147
"type": "Number",
90879148
"label": "Environment strength",
9088-
"description": "Environment reflection intensity (0-1; default: 1).",
9149+
"description": "Environment reflection intensity. (0-1; default: 1)",
90899150
"group": "Custom PBR (experimental)",
90909151
"advanced": true,
90919152
"name": "EnvironmentStrength"
90929153
},
90939154
{
9094-
"value": "UseSource",
9155+
"value": "",
90959156
"type": "Choice",
90969157
"label": "Culling mode",
90979158
"description": "3D model face culling mode.",
@@ -9116,26 +9177,14 @@
91169177
"value": "true",
91179178
"type": "Boolean",
91189179
"label": "Use two sided lighting",
9119-
"description": "If enabled, both frontface and backface are lit. Useful for planes/cards (default: on).",
9180+
"description": "If enabled, both frontface and backface are lit. Useful for planes/cards (default: on)",
91209181
"group": "Color",
91219182
"name": "UseTwoSidedLighting"
91229183
}
91239184
],
91249185
"propertiesFolderStructure": {
91259186
"folderName": "__ROOT",
91269187
"children": [
9127-
{
9128-
"propertyName": "SwayType"
9129-
},
9130-
{
9131-
"propertyName": "MaterialName"
9132-
},
9133-
{
9134-
"propertyName": "SwayResponse"
9135-
},
9136-
{
9137-
"propertyName": "UseUniformSway"
9138-
},
91399188
{
91409189
"folderName": "Color",
91419190
"children": [
@@ -9168,6 +9217,23 @@
91689217
}
91699218
]
91709219
},
9220+
{
9221+
"folderName": "Sway",
9222+
"children": [
9223+
{
9224+
"propertyName": "SwayType"
9225+
},
9226+
{
9227+
"propertyName": "MaterialName"
9228+
},
9229+
{
9230+
"propertyName": "SwayResponse"
9231+
},
9232+
{
9233+
"propertyName": "UseUniformSway"
9234+
}
9235+
]
9236+
},
91719237
{
91729238
"folderName": "Culling",
91739239
"children": [

0 commit comments

Comments
 (0)