{"Document":{"ObjectName":"Scenario::ScenarioDocumentModel","id":1,"BaseScenario":{"ObjectName":"Scenario::BaseScenario","id":0,"Constraint":{"ObjectName":"Scenario::IntervalModel","id":0,"Metadata":{"ScriptingName":"text-to-mesh","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Inlet":{"uuid":"a1574bb0-cbd4-4c7d-9417-0c25cfd1187b","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Audio In","Exposed":"audio in"},"Outlet":{"uuid":"a1d97535-18ac-444a-8417-0cbc1692d897","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Audio Out","Exposed":"audio out","Address":"audio:/out/main","GainInlet":{"uuid":"9a13fb32-269a-47bf-99a9-930188c1f19c","ObjectName":"Inlet","id":10000,"Hidden":false,"Custom":"Gain","Exposed":"gain","Value":{},"Init":{},"Domain":{"Float":{"Min":0.0,"Max":1.0}}},"PanInlet":{"uuid":"9a13fb32-269a-47bf-99a9-930188c1f19c","ObjectName":"Inlet","id":10001,"Hidden":false,"Custom":"Pan","Exposed":"pan","Value":{},"Init":{},"Domain":{}},"Gain":1.0,"Pan":[1.0,1.0],"Propagate":true},"Processes":[{"uuid":"c8f2a4d5-6e9b-4d3a-b7f1-5c4e2d8a9f6b","ObjectName":"text_to_mesh","id":8,"Metadata":{"ScriptingName":"Text to Mesh.2","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[-528.7128092634016,-146.3],"Size":[402.0,163.5],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Text","Exposed":"text","Value":{"String":"sierra"},"Init":{"String":"Hello"},"Domain":{}},{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Font family","Exposed":"font family","Value":{"String":"Sans"},"Init":{"String":"Sans"},"Domain":{}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Font size","Exposed":"font size","Value":{"Int":64},"Init":{"Int":72},"Domain":{"Int":{"Min":4,"Max":512}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Bold","Exposed":"bold","Value":{"Bool":true},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Italic","Exposed":"italic","Value":{"Bool":true},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Height","Exposed":"height","Value":{"Float":4.630886554718018},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Center X","Exposed":"center x","Value":{"Bool":true},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Position","Exposed":"position","Value":{"Vec3f":[-0.01027161069214344,0.41354677081108093,-0.048647742718458176]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-8388608.0,-8388608.0,-8388608.0],"Max":[8388608.0,8388608.0,8388608.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Rotation","Exposed":"rotation","Value":{"Vec3f":[45.299110412597656,0.0,0.030915621668100357]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[360.0,360.0,360.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Scale","Exposed":"scale","Value":{"Vec3f":[1.0188908576965332,1.0,1.0]},"Init":{"Vec3f":[1.0,1.0,1.0]},"Domain":{"Vec3f":{"Min":[0.000009999999747378752,0.000009999999747378752,0.000009999999747378752],"Max":[1000.0,1000.0,1000.0],"Values":[[],[],[]]}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene Out","Exposed":"scene out"}]},{"uuid":"a8f2c6d0-1b4e-4c7a-9d3f-5e8b2c1a7f0d","ObjectName":"gfxProcess","id":9,"Metadata":{"ScriptingName":"Scene Preprocessor.3","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[-104.27280926340154,-152.5],"Size":[179.0,22.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"Scene In","Exposed":"scene in"}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Geometry Out","Exposed":"geometry out"}]},{"uuid":"4c91b5e2-8d76-4ab3-9f14-6e0d8b3a2c57","ObjectName":"camera_avnd","id":10,"Metadata":{"ScriptingName":"Camera.4","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[-401.8328092634015,63.34],"Size":[274.0,177.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Eye","Exposed":"eye","Value":{"Vec3f":[0.0,-21.943117141723633,4.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Target","Exposed":"target","Value":{"Vec3f":[0.0,0.20000000298023224,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-10000.0,-10000.0,-10000.0],"Max":[10000.0,10000.0,10000.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"FOV","Exposed":"fov","Value":{"Float":45.0},"Init":{"Float":60.0},"Domain":{"Float":{"Min":5.0,"Max":170.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Near","Exposed":"near","Value":{"Float":0.10000000149011612},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.0010000000474974513,"Max":10.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Far","Exposed":"far","Value":{"Float":1000.0},"Init":{"Float":1000.0},"Domain":{"Float":{"Min":1.0,"Max":100000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Roll","Exposed":"roll","Value":{"Float":0.0},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"dbfc2101-40d7-4807-8804-571e88992e7e","ObjectName":"gfxProcess","id":13,"Metadata":{"ScriptingName":"Render Pipeline.7","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[663.7128092634015,-151.84236112050553],"Size":[787.0,160.0],"Loops":false,"FoldMode":0,"Vertex":"// Full-PBR variant — extends classic_pbr_textured with TANGENT for TBN\n// normal-map reconstruction in the fragment stage.\n//\n// Vertex inputs + varyings come from the sibling .frag's VERTEX_INPUTS /\n// VERTEX_OUTPUTS blocks; redeclaring them here triggers \"redefinition\".\n\nvoid main()\n{\n    isf_vertShaderInit();\n\n    // Unified-MDI cmd-index lookup: per-instance VERTEX_INPUT carries\n    // the drawID directly. Replaces the prior `gl_BaseInstanceARB`\n    // path, which broke as soon as instanceCount > 1 (firstInstance\n    // becomes the per-instance slot offset, no longer the cmd index)\n    // AND was always 0 on the CPU-fallback drawIndexed loop. Reading\n    // a per-instance attribute works uniformly on both indirect and\n    // CPU-fallback paths (firstInstance is honoured by every QRhi\n    // backend that supports instancing).\n    uint drawId = draw_id;\n    v_drawID = drawId;\n\n    PerDraw pd = per_draws.data[drawId];\n    mat3 instLinear = pd.normal[3].x > 0.5\n        ? mat3(inst_matrix0.xyz, inst_matrix1.xyz, inst_matrix2.xyz)\n        : mat3(1.0);\n    mat4 model = pd.model;\n    mat3 normalMatrix = mat3(pd.normal) * transpose(inverse(instLinear));\n\n    // Per-instance translation offset: zero for non-instanced draws via\n    // the REQUIRED:false fallback (identity broadcast); the actual\n    // particle position for unified-MDI instance groups.\n    vec4 wp = model * vec4(instLinear * position + inst_translation, 1.0);\n    v_worldPos = wp.xyz;\n    v_normal = normalize(normalMatrix * normal);\n    // Tangent carries xyz = unit tangent in mesh space + w = handedness.\n    // Apply the normal matrix to the xyz (same basis as the normal) and\n    // forward w untouched. Consumer reconstructs bitangent as\n    //   bitangent = cross(N, T.xyz) * T.w\n    v_tangent = vec4(normalize(normalMatrix * tangent.xyz), tangent.w);\n    v_uv = texcoord_0;\n    // glTF TEXCOORD_1 (secondary UV set — lightmaps, per-channel UV\n    // override). Falls back to zero for meshes without it (slab\n    // uploader fills with zeros).\n    v_uv1 = texcoord_1;\n    // glTF COLOR_0 (defaults to vec4(1) when the mesh doesn't carry\n    // one — the slab uploader fills the buffer with white).\n    v_color = color_0;\n    // VERTEX_INPUTS aren't directly visible to the fragment stage —\n    // forward the per-instance broadcast colour as a varying so the\n    // .frag can multiply baseColor by it.\n    v_inst_color = pd.normal[3].y > 0.5 ? inst_color0 : vec4(1.0);\n    v_inst_emissive = pd.normal[3].z > 0.5 ? inst_custom0 : vec4(0.0);\n\n    gl_Position = clipSpaceCorrMatrix * camera.viewProjection * wp;\n\n    isf_vertShaderFinish();\n}\n","Fragment":"/*{\n  \"CREDIT\": \"ossia team\",\n  \"ISFVSN\": \"2\",\n  \"MODE\": \"RAW_RASTER_PIPELINE\",\n  \"ALPHA\": \"straight\",\n  \"DESCRIPTION\": \"Full glTF metallic-roughness rasterizer for a Scene Preprocessor output: draws the whole scene in one indirect draw with every material texture (base colour, metal-rough, normal map with tangents, emissive, occlusion; texcoord sets, KHR_texture_transform, wrap modes, alpha MASK and BLEND, double-sided), the scene's lights (directional, point and spot, with range and falloff; procedural lights written by the presets/lighting CSFs included), the Environment node's ambient, exposure and linear fog, and per-instance transforms, colours and emissive from an Instancer. No image-based lighting and no shadows: a fixed Fresnel term stands in for reflections (classic_pbr_openpbr adds IBL and cascaded shadows). Output is linear HDR, so follow it with a tone mapper such as shaderlib/post-process/ToneMapping.fs. Alpha-to-coverage smooths MASK edges under MSAA; the volumetric toggle composites the presets/volumetric fog chain.\",\n  \"CATEGORIES\": [\n    \"3D\",\n    \"Scene\",\n    \"MDI\",\n    \"Textured\",\n    \"Normal-Mapped\"\n  ],\n  \"VERTEX_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"position\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_0\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"color_0\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"texcoord_1\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"inst_translation\",\n      \"SEMANTIC\": \"translation\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_color0\",\n      \"SEMANTIC\": \"instance_color0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_custom0\",\n      \"SEMANTIC\": \"instance_custom0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix0\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix1\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"inst_matrix2\",\n      \"REQUIRED\": false\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"draw_id\",\n      \"SEMANTIC\": \"instance_draw_id\"\n    }\n  ],\n  \"VERTEX_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_INPUTS\": [\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_worldPos\"\n    },\n    {\n      \"TYPE\": \"vec3\",\n      \"NAME\": \"v_normal\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv\"\n    },\n    {\n      \"TYPE\": \"uint\",\n      \"NAME\": \"v_drawID\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_tangent\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_color\"\n    },\n    {\n      \"TYPE\": \"vec2\",\n      \"NAME\": \"v_uv1\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_color\"\n    },\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"v_inst_emissive\"\n    }\n  ],\n  \"FRAGMENT_OUTPUTS\": [\n    {\n      \"TYPE\": \"vec4\",\n      \"NAME\": \"isf_FragColor\"\n    }\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"camera\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"view\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"projection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"viewProjection\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"cameraPosition\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"renderSize\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"params\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_lights\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Light[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_light_indices\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"uint[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"world_transforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"mat4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_materials\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"Material[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_material_uv_xforms\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"MatUVXform[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"per_draws\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"vertex+fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"PerDraw[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"indirect_draw_cmds\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"none\",\n      \"BUFFER_USAGE\": \"indirect_draw_indexed\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cmds\",\n          \"TYPE\": \"DrawIndexedCmd[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"scene_counts\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"light_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"material_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"draw_count\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"env\",\n      \"TYPE\": \"uniform\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"ambient\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_color_density\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"fog_range\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"exposure_gamma\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"alpha_a2c_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Alpha-to-coverage (writes gl_SampleMask under MSAA). Best for foliage edges when MSAA is enabled. Adapts to the framebuffer sample count (1/2/4/8/16); degrades to a 0.5 binary cutoff when MSAA is off.\"\n    },\n    {\n      \"NAME\": \"volumetric_enabled\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 0,\n      \"MIN\": 0,\n      \"MAX\": 1,\n      \"LABEL\": \"Volumetric fog composite (1=on)\",\n      \"DESCRIPTION\": \"Sample the upstream vol_integrated SSBO (built by the volumetric_inject / scatter / integrate chain) and apply finalColor = finalColor * transmittance + accum * intensity per fragment. Default off so rasterizers without the volumetric chain wired don't multiply by an unbound (zero-init) transmittance and go pure black.\"\n    },\n    {\n      \"NAME\": \"volumetric_intensity\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.0,\n      \"MAX\": 4.0,\n      \"LABEL\": \"Volumetric intensity\",\n      \"DESCRIPTION\": \"Scalar on the in-scattered radiance contribution. 1.0 = physical; <1 dampens the fog look; >1 over-blooms the air for stylized output. Has no effect when volumetric_enabled=0.\"\n    }\n  ],\n  \"AUXILIARY\": [\n    {\n      \"NAME\": \"scene_material_wrap\",\n      \"TYPE\": \"storage\",\n      \"ACCESS\": \"read_only\",\n      \"VISIBILITY\": \"fragment\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"entries\",\n          \"TYPE\": \"uvec4[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"cluster_config\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"cluster_x\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_y\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"cluster_z\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"max_lights_per_cluster\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"vol_integrated\",\n      \"ACCESS\": \"read_only\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"data\",\n          \"TYPE\": \"FroxelIntegrated[]\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"materialArray0\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray1\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray2\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray3\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray4\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray5\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray6\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialArray7\",\n      \"TYPE\": \"image\",\n      \"IS_ARRAY\": true,\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn0\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn1\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn2\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn3\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn4\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn5\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn6\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    },\n    {\n      \"NAME\": \"materialDyn7\",\n      \"TYPE\": \"image\",\n      \"WRAP\": \"repeat\"\n    }\n  ],\n  \"TYPES\": [\n    {\n      \"NAME\": \"Light\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"color\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"local_direction\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"range_cone\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"shadow_enabled\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"decay_mode\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"transform_slot\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"normal_bias\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"Material\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"baseColor\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"metallicRoughnessOcclusionUnlit\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"emissive_strength\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"textureRefs\",\n          \"TYPE\": \"uvec4\"\n        },\n        {\n          \"NAME\": \"feature_mask\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"hit_group_id\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"occlusion_textureRef\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"alpha_cutoff\",\n          \"TYPE\": \"float\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"PerDraw\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"model\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"normal\",\n          \"TYPE\": \"mat4\"\n        },\n        {\n          \"NAME\": \"material_index\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"tag_hash\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad0\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"_pad1\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"DrawIndexedCmd\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"indexCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"instanceCount\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"firstIndex\",\n          \"TYPE\": \"uint\"\n        },\n        {\n          \"NAME\": \"baseVertex\",\n          \"TYPE\": \"int\"\n        },\n        {\n          \"NAME\": \"baseInstance\",\n          \"TYPE\": \"uint\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"MatUVXform\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"bc_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"mr_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"normal_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"em_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"occ_offset_scale\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations0\",\n          \"TYPE\": \"vec4\"\n        },\n        {\n          \"NAME\": \"rotations1\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    },\n    {\n      \"NAME\": \"FroxelIntegrated\",\n      \"LAYOUT\": [\n        {\n          \"NAME\": \"accum_transmittance\",\n          \"TYPE\": \"vec4\"\n        }\n      ]\n    }\n  ],\n  \"PIPELINE_STATE\": {\n    \"DEPTH_TEST\": true,\n    \"DEPTH_WRITE\": true,\n    \"CULL_MODE\": \"back\"\n  }\n}*/\n\n// Sample a material texture channel given its packed textureRef. Matches\n// the SceneFlattener encoding:\n//   bits 31..30 : source (0=NONE/sentinel, 1=STATIC bucket, 2=DYNAMIC slot)\n//   bits 29..23 : bucket index (0..127); the ladder below covers the\n//                 first 16 — higher bucket ids fall back.\n//   bits 23..0  : layer index within the bucket's texture array (static)\n//                 OR slot index in the channel's dynamic sampler set.\n//\n// Each channel declares `kShaderBuckets` sampler2DArrays,\n// one per bucket. Materials with textures of different (format, pixelSize)\n// tuples land in different buckets; the switch ladder below dispatches\n// to the right sampler. Scenes with a single bucket hit case 0 only —\n// all other cases compile in but never execute.\n//\n// Dynamic slots resolve to per-channel sampler2D uniforms `*Dyn0` /\n// `*Dyn1` populated by ScenePreprocessor's aux-texture path — used for\n// large runtime textures (8K video, HDR shader outputs) that can't\n// round-trip through the bucket pool.\nconst uint kShaderBuckets = 16u;\n\n// ─── Manual N-tap anisotropic sampling ──────────────────────────────\n// Qt RHI hard-codes maxAnisotropy=1.0 in every backend; there is no\n// public API to enable hardware anisotropic filtering. Workaround: do\n// it in the shader. Standard \"sum of cones\" formulation:\n//\n//   1. Compute UV gradients dx/dy. Pick the longer one as the major\n//      axis, the shorter as minor.\n//   2. The footprint is an ellipse on the texture; ratio = |major|/|minor|\n//      gives the anisotropy needed (typical value at grazing angles is\n//      4-16).\n//   3. Take 4 hardware-filtered samples spaced along the major axis,\n//      each forced to the minor-axis LOD via textureGrad(minor, minor).\n//      Average them. The minor-axis grad keeps each sample sharp; the\n//      4 spaced taps integrate over the elongated footprint.\n//\n// Shortcut: when the footprint is roughly isotropic (ratio² < 4) we\n// drop to a plain hardware texture() — the 4-tap path is wasted cost.\n//\n// Cost: ~4× texture lookups when the path triggers (only at grazing\n// angles), 1× otherwise. We apply this only to base_color and normal\n// — the channels where the user can see the difference. metallic /\n// roughness / occlusion / emissive stay on plain texture().\nvec4 anisoSample2DArray(sampler2DArray tex, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(tex, vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(tex, vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(tex, vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(tex, vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DArraySep(texture2DArray tex, sampler smp, vec3 uv)\n{\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2DArray(tex, smp), uv);\n\n    // 4 taps at -3/8, -1/8, 1/8, 3/8 of the major axis (uniform spacing,\n    // mean-zero, covers the elongated footprint without touching the\n    // tile borders that a -1/2..1/2 spacing would).\n    float layer = uv.z;\n    vec4 s0 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.375, layer), minor, minor);\n    vec4 s1 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major * -0.125, layer), minor, minor);\n    vec4 s2 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.125, layer), minor, minor);\n    vec4 s3 = textureGrad(sampler2DArray(tex, smp), vec3(uv.xy + major *  0.375, layer), minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\nvec4 anisoSample2D(sampler2D tex, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(tex, uv);\n\n    vec4 s0 = textureGrad(tex, uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(tex, uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(tex, uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(tex, uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\nvec4 anisoSample2DSep(texture2D tex, sampler smp, vec2 uv)\n{\n    vec2 dx = dFdx(uv);\n    vec2 dy = dFdy(uv);\n    float lx2 = dot(dx, dx);\n    float ly2 = dot(dy, dy);\n    vec2 major, minor;\n    float ratio2;\n    if(lx2 > ly2)\n    {\n        major = dx; minor = dy;\n        ratio2 = lx2 / max(ly2, 1e-12);\n    }\n    else\n    {\n        major = dy; minor = dx;\n        ratio2 = ly2 / max(lx2, 1e-12);\n    }\n    if(ratio2 < 4.0) return texture(sampler2D(tex, smp), uv);\n\n    vec4 s0 = textureGrad(sampler2D(tex, smp), uv + major * -0.375, minor, minor);\n    vec4 s1 = textureGrad(sampler2D(tex, smp), uv + major * -0.125, minor, minor);\n    vec4 s2 = textureGrad(sampler2D(tex, smp), uv + major *  0.125, minor, minor);\n    vec4 s3 = textureGrad(sampler2D(tex, smp), uv + major *  0.375, minor, minor);\n    return (s0 + s1 + s2 + s3) * 0.25;\n}\n\n// One decoder for every material channel. The pool is shared, so the bucket\n// field of the ref is all that picks the array -- including its colourspace,\n// which is part of the bucket key rather than of the channel.\n// Per-texture wrap modes from scene_material_wrap, loaded once per fragment\n// from the material's entry. Four bits per texture ref: wrap_s in the low two,\n// wrap_t in the high two; 0 = repeat, 1 = clamp to edge, 2 = mirror. Slots\n// 0..4 are the main refs (base colour, metal-rough, normal, emissive,\n// occlusion), 5.. the extension refs in MaterialExt.textureRefs order. The\n// pool samples every array with one repeat sampler, so a non-repeat mode is\n// applied to the coordinate here.\nuvec3 g_matWrap = uvec3(0u);\nuint matWrap(uint slot)\n{\n    if(slot < 5u) return (g_matWrap.x >> (4u * slot)) & 0xFu;\n    uint e = slot - 5u;\n    uint word = e < 8u ? g_matWrap.y : g_matWrap.z;\n    return (word >> (4u * (e & 7u))) & 0xFu;\n}\nfloat wrapAxis(float x, uint mode, float halfTexel)\n{\n    if(mode == 1u) return clamp(x, halfTexel, 1.0 - halfTexel);\n    if(mode == 2u) { float t = mod(x, 2.0); return t > 1.0 ? 2.0 - t : t; }\n    return x;\n}\nvec2 applyWrap(vec2 uv, uint wrap, vec2 halfTexel)\n{\n    return vec2(wrapAxis(uv.x, wrap & 3u, halfTexel.x),\n                wrapAxis(uv.y, (wrap >> 2u) & 3u, halfTexel.y));\n}\n// Clamping stays inside the edge texel of the coarsest mip level the\n// trilinear filter reads, so a minified clamped texture does not bleed across\n// the repeat sampler's seam.\nvec2 wrapInset(texture2DArray tex, sampler smp, vec2 dx, vec2 dy)\n{\n    vec2 sz = vec2(textureSize(sampler2DArray(tex, smp), 0).xy);\n    float lod = max(0.0, log2(max(length(dx * sz), length(dy * sz))));\n    return min(vec2(0.5), 0.5 * exp2(ceil(lod)) / sz);\n}\n// anisoSample2DArray's wrapped counterpart. A single trilinear tap whose\n// gradients come from the unwrapped coordinate, so a mirror fold or a clamp\n// edge does not spike the mip selection; repeat, the common case, keeps the\n// anisotropic path untouched.\nvec4 anisoSample2DArrayWrapped(texture2DArray tex, sampler smp, vec3 uv, uint wrap)\n{\n    if(wrap == 0u) return anisoSample2DArraySep(tex, smp, uv);\n    vec2 dx = dFdx(uv.xy);\n    vec2 dy = dFdy(uv.xy);\n    return textureGrad(sampler2DArray(tex, smp),\n                       vec3(applyWrap(uv.xy, wrap, wrapInset(tex, smp, dx, dy)), uv.z),\n                       dx, dy);\n}\n\n\nvec4 sample_material_slot(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    if(ref == 0xFFFFFFFFu) return fallback;\n    uint source = (ref >> 30) & 3u;\n    uint bucket = (ref >> 23) & 0x7Fu;\n    uint idx    = ref & 0x007FFFFFu;\n    if(source == 2u)\n    {\n        switch(idx)\n        {\n            case 0u: return anisoSample2DSep(materialDyn_tex[0], materialDyn_smp, uv);\n            case 1u: return anisoSample2DSep(materialDyn_tex[1], materialDyn_smp, uv);\n            case 2u: return anisoSample2DSep(materialDyn_tex[2], materialDyn_smp, uv);\n            case 3u: return anisoSample2DSep(materialDyn_tex[3], materialDyn_smp, uv);\n            case 4u: return anisoSample2DSep(materialDyn_tex[4], materialDyn_smp, uv);\n            case 5u: return anisoSample2DSep(materialDyn_tex[5], materialDyn_smp, uv);\n            case 6u: return anisoSample2DSep(materialDyn_tex[6], materialDyn_smp, uv);\n            case 7u: return anisoSample2DSep(materialDyn_tex[7], materialDyn_smp, uv);\n        }\n        return fallback;\n    }\n    switch(bucket)\n    {\n        case 0u: return anisoSample2DArrayWrapped(materialArray_tex[0], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 1u: return anisoSample2DArrayWrapped(materialArray_tex[1], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 2u: return anisoSample2DArrayWrapped(materialArray_tex[2], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 3u: return anisoSample2DArrayWrapped(materialArray_tex[3], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 4u: return anisoSample2DArrayWrapped(materialArray_tex[4], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 5u: return anisoSample2DArrayWrapped(materialArray_tex[5], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 6u: return anisoSample2DArrayWrapped(materialArray_tex[6], materialArray_smp, vec3(uv, float(idx)), wrap);\n        case 7u: return anisoSample2DArrayWrapped(materialArray_tex[7], materialArray_smp, vec3(uv, float(idx)), wrap);\n    }\n    return fallback;\n}\n\nvec4 sample_slot_bc(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_mr(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_nrm(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\nvec4 sample_slot_em(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// Separate glTF occlusionTexture (single-channel data, R = occlusion).\n// Sampled only when feature_mask carries `has_separate_occlusion`;\n// otherwise the main path falls back to MR.r per the common packed-MR\n// convention. fallback = 1 → identity (no occlusion).\nvec4 sample_slot_occ(uint ref, uint wrap, vec2 uv, vec4 fallback)\n{\n    return sample_material_slot(ref, wrap, uv, fallback);\n}\n\n\n// glTF feature_mask bits — must mirror SceneGPUState.hpp's\n// material_feature namespace.\nconst uint kFeat_alpha_mask           = 1u << 16u;\nconst uint kFeat_alpha_blend          = 1u << 17u;\nconst uint kFeat_double_sided         = 1u << 18u;\nconst uint kFeat_has_separate_occ     = 1u << 19u;\n// Per-channel texcoord_set bits (20-29). 2 bits per channel, value\n// 0 = TEXCOORD_0, value 1 = TEXCOORD_1. Out-of-range values collapse\n// to TEXCOORD_0 (the shift-mask in packMaterial clamps to 0/1).\nconst uint kFeat_tcset_bc_shift       = 20u;\nconst uint kFeat_tcset_mr_shift       = 22u;\nconst uint kFeat_tcset_nrm_shift      = 24u;\nconst uint kFeat_tcset_em_shift       = 26u;\nconst uint kFeat_tcset_occ_shift      = 28u;\n\nvec2 pick_uv(uint feature_mask, uint shift, vec2 uv0, vec2 uv1)\n{\n    return ((feature_mask >> shift) & 0x3u) == 1u ? uv1 : uv0;\n}\n\n// KHR_texture_transform helper: glTF defines the transform in UV space\n// as `uv' = R(rotation) * S(scale) * uv + offset`, with rotation\n// applied AFTER scale and BEFORE the offset shift. Identity defaults\n// (offset=0, scale=1, rotation=0) pass through unchanged.\nvec2 apply_uv_xform(vec2 uv, vec4 offset_scale, float rotation)\n{\n    vec2 scaled = uv * offset_scale.zw;\n    float c = cos(rotation), s = sin(rotation);\n    vec2 rotated = vec2(c * scaled.x - s * scaled.y,\n                        s * scaled.x + c * scaled.y);\n    return rotated + offset_scale.xy;\n}\n\n// Shader-level alpha-to-coverage. QRhi (6.12) doesn't expose\n// AlphaToCoverage on QRhiGraphicsPipeline, so we replicate the\n// behaviour at the shader level: gl_SampleMask[0] is a writable\n// per-fragment built-in where each bit selects whether the\n// corresponding MSAA sample is written. Convert alpha to a sample\n// count, set that many bits, screen-space-rotate per pixel so the\n// MSAA resolve smooths the silhouette into a soft edge.\n//\n// Sample count comes from MSAA_SAMPLES, an integer auto-injected by\n// libisf into the renderer UBO at binding=0 — score writes the active\n// RenderList's sample count there each frame. (We can't use\n// gl_NumSamples: glslang strips it when targeting SPIR-V.) Score lets\n// users pick any of {1, 2, 4, 8, 16}. With MSAA off, MSAA_SAMPLES=1\n// and we degrade to a 0.5 binary cutoff. Vulkan caps multisample\n// rasterization at 16x in practice; clamp there so the rotation math\n// stays defined for 32-bit uints.\n//\n// Returns false when the fragment is fully transparent → caller\n// discards (early-out skips the rest of main()).\nbool applyAlphaToCoverage(float alpha)\n{\n    if(alpha <= 0.0)\n        return false;\n\n    int samples = clamp(MSAA_SAMPLES, 1, 16);\n    uint full = (samples >= 32) ? 0xFFFFFFFFu\n                                : ((1u << uint(samples)) - 1u);\n\n    if(alpha >= 1.0)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n    int n = int(round(alpha * float(samples)));\n    if(n <= 0)\n        return false;\n    if(n >= samples)\n    {\n        gl_SampleMask[0] = int(full);\n        return true;\n    }\n\n    // MSAA sample counts are powers of two, so (S-1) is a valid mask.\n    // shift lands in [0, S-1]; rotation handles shift==0 cleanly\n    // because base >> S is well-defined for S<=16 (< 32 bits).\n    uint S = uint(samples);\n    uint hash = uint(gl_FragCoord.x) * 1597u\n              + uint(gl_FragCoord.y) * 2731u;\n    uint shift = hash & (S - 1u);\n    uint base  = (1u << uint(n)) - 1u;\n    uint rot   = ((base << shift) | (base >> (S - shift))) & full;\n    gl_SampleMask[0] = int(rot);\n    return true;\n}\n\n// Map gl_FragCoord + view-space Z to a froxel index. Same log-spaced Z\n// slicing build_cluster_aabbs.csf uses, same (z*Y + y)*X + x flattening\n// volumetric_integrate.csf writes — keep these three formulas in sync\n// or sampling lands in the wrong cell.\nuint scoreClusterId(vec2 fragCoord, float viewZ)\n{\n    vec2 uv = fragCoord / camera.renderSize.xy;\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n\n    uint tx = uint(clamp(floor(uv.x * float(gx)), 0.0, float(gx) - 1.0));\n    uint ty = uint(clamp(floor(uv.y * float(gy)), 0.0, float(gy) - 1.0));\n\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float t = float(gz) * log(depth / zNear) / log(zFar / zNear);\n    uint tz = uint(clamp(t, 0.0, float(gz) - 1.0));\n\n    return (tz * gy + ty) * gx + tx;\n}\n\n// Inline volumetric fog composite — see classic_pbr_openpbr.frag for\n// the full rationale. Two production-grade refinements vs the naive\n// nearest-cell lookup:\n//   1. Trilinear interpolation across the 8 surrounding froxels —\n//      hides the cluster grid (16x9x24 default) which otherwise\n//      shows up as a hard checkerboard at cell boundaries.\n//   2. volumetric_intensity blends toward identity rather than just\n//      scaling accum, so low intensity == \"less fog\" rather than\n//      \"no source + tiny in-scatter\".\n// Identity fallback when the toggle is off or cluster_x == 0u.\nvec3 applyVolumetric(vec3 inColor, vec2 fragCoord, float viewZ)\n{\n    if(volumetric_enabled == 0)\n        return inColor;\n\n    uint gx = cluster_config.cluster_x;\n    uint gy = cluster_config.cluster_y;\n    uint gz = cluster_config.cluster_z;\n    if(gx == 0u || gy == 0u || gz == 0u)\n        return inColor;\n\n    vec2  uv = fragCoord / camera.renderSize.xy;\n    float zNear = camera.params.y;\n    float zFar  = camera.params.z;\n    float depth = max(-viewZ, zNear);\n    float fx = uv.x * float(gx) - 0.5;\n    float fy = uv.y * float(gy) - 0.5;\n    float fz = float(gz) * log(depth / zNear) / log(zFar / zNear) - 0.5;\n\n    vec3 cf = clamp(vec3(fx, fy, fz), vec3(0.0),\n                    vec3(float(gx) - 1.0001,\n                         float(gy) - 1.0001,\n                         float(gz) - 1.0001));\n    vec3 cb = floor(cf);\n    vec3 t  = cf - cb;\n    uvec3 i0 = uvec3(cb);\n    uvec3 i1 = min(i0 + 1u, uvec3(gx - 1u, gy - 1u, gz - 1u));\n\n    #define IDX(ix, iy, iz) (((iz) * gy + (iy)) * gx + (ix))\n    vec4 c000 = vol_integrated.data[IDX(i0.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c100 = vol_integrated.data[IDX(i1.x, i0.y, i0.z)].accum_transmittance;\n    vec4 c010 = vol_integrated.data[IDX(i0.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c110 = vol_integrated.data[IDX(i1.x, i1.y, i0.z)].accum_transmittance;\n    vec4 c001 = vol_integrated.data[IDX(i0.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c101 = vol_integrated.data[IDX(i1.x, i0.y, i1.z)].accum_transmittance;\n    vec4 c011 = vol_integrated.data[IDX(i0.x, i1.y, i1.z)].accum_transmittance;\n    vec4 c111 = vol_integrated.data[IDX(i1.x, i1.y, i1.z)].accum_transmittance;\n    #undef IDX\n\n    vec4 v = mix(mix(mix(c000, c100, t.x), mix(c010, c110, t.x), t.y),\n                 mix(mix(c001, c101, t.x), mix(c011, c111, t.x), t.y),\n                 t.z);\n\n    float transm = clamp(v.a, 0.0, 1.0);\n    vec3  accum  = v.rgb;\n\n    float k       = volumetric_intensity;\n    float k_blend = clamp(k, 0.0, 1.0);\n    float transm_eff = mix(1.0, transm, k_blend);\n    vec3  accum_eff  = accum * k;\n\n    return inColor * transm_eff + accum_eff;\n}\n\nvoid main()\n{\n    // Default coverage: keep every MSAA sample. Once applyAlphaToCoverage\n    // exists in the module, the SPIR-V output declares gl_SampleMask, and\n    // any path that doesn't assign it leaves the value undefined — most\n    // drivers default that to 0 and cull every sample, producing block-\n    // speckle artifacts on non-alpha-mask materials. Seeding to all-ones\n    // here makes the non-A2C paths render correctly; the A2C branch\n    // overrides this for masked fragments.\n    gl_SampleMask[0] = -1;\n\n    PerDraw pd = per_draws.data[v_drawID];\n    Material mat = scene_materials.entries[pd.material_index];\n    MatUVXform mx = scene_material_uv_xforms.entries[pd.material_index];\n    g_matWrap = scene_material_wrap.entries[pd.material_index].xyz;\n\n    // glTF doubleSided: pipeline-side culling is OFF (cull_mode=none\n    // in the MDI batch) so we get both faces. For SINGLE-sided materials\n    // we discard back-facing fragments here to mimic CULL_BACK. For\n    // DOUBLE-sided materials we keep the fragment and flip the normal\n    // below so lighting on the back side works correctly.\n    bool is_double_sided = (mat.feature_mask & kFeat_double_sided) != 0u;\n    if(!is_double_sided && !gl_FrontFacing)\n        discard;\n\n    // Pick the per-channel texcoord source (TEXCOORD_0 vs TEXCOORD_1)\n    // before applying the KHR_texture_transform. glTF allows each\n    // texture_info to override its texcoord_set independently — BC\n    // might use TEXCOORD_0 while Emissive uses TEXCOORD_1, etc.\n    vec2 base_uv_bc  = pick_uv(mat.feature_mask, kFeat_tcset_bc_shift,  v_uv, v_uv1);\n    vec2 base_uv_mr  = pick_uv(mat.feature_mask, kFeat_tcset_mr_shift,  v_uv, v_uv1);\n    vec2 base_uv_nrm = pick_uv(mat.feature_mask, kFeat_tcset_nrm_shift, v_uv, v_uv1);\n    vec2 base_uv_em  = pick_uv(mat.feature_mask, kFeat_tcset_em_shift,  v_uv, v_uv1);\n    vec2 base_uv_occ = pick_uv(mat.feature_mask, kFeat_tcset_occ_shift, v_uv, v_uv1);\n\n    // Per-channel UVs after KHR_texture_transform.\n    vec2 uv_bc  = apply_uv_xform(base_uv_bc,  mx.bc_offset_scale,     mx.rotations0.x);\n    vec2 uv_mr  = apply_uv_xform(base_uv_mr,  mx.mr_offset_scale,     mx.rotations0.y);\n    vec2 uv_nrm = apply_uv_xform(base_uv_nrm, mx.normal_offset_scale, mx.rotations0.z);\n    vec2 uv_em  = apply_uv_xform(base_uv_em,  mx.em_offset_scale,     mx.rotations0.w);\n    vec2 uv_occ = apply_uv_xform(base_uv_occ, mx.occ_offset_scale,    mx.rotations1.x);\n\n    // Pre-pull env knobs so the early-out (unlit) and main path both\n    // see the same values. Defaults come from EnvironmentLoader if the\n    // user wired one; otherwise the merged scene_environment carries\n    // safe identity-ish values (ambient=0, exposure=1, gamma=2.2,\n    // fog disabled).\n    vec3  ambient_col   = env.ambient.rgb * env.ambient.w;\n    float exposure_mul  = max(env.exposure_gamma.x, 1e-6);\n    float gamma         = max(env.exposure_gamma.y, 1e-3);\n\n    // ─── Base color ────────────────────────────────────────────────────\n    // glTF: final base = baseColorFactor × baseColorTexture × COLOR_0\n    // (vertex color). v_color defaults to white when the mesh doesn't\n    // have COLOR_0 (slab uploader fills with vec4(1) in that case).\n    vec4 bc = sample_slot_bc(mat.textureRefs.x, matWrap(0u), uv_bc, vec4(1.0));\n\n    // Alpha-mask edge-bleed compensation. Source PNGs for foliage / hair\n    // / fence-style cutouts have alpha=0 in transparent regions with\n    // RGB=0 there too (standard authoring). Mip / aniso filtering\n    // averages RGB and alpha independently — near a leaf edge the\n    // sampled RGB ends up `leaf_color × alpha_avg`, so post-alpha-test\n    // surviving fragments read a darkened RGB and the silhouette gets a\n    // black halo. Dividing RGB by alpha inverts the alpha-weighted\n    // averaging and recovers the source colour. Skip when alpha is near\n    // zero (would discard anyway) and when the material isn't\n    // alpha-masked (BLEND / OPAQUE both want the literal sampled RGB).\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u && bc.a > 1e-3)\n        bc.rgb /= bc.a;\n\n    // Per-instance broadcast colour rides through `v_inst_color` from\n    // the vertex stage. For non-instanced draws the REQUIRED:false\n    // fallback fires identity (1,1,1,1) so the modulation collapses\n    // to the per-vertex × material × baseColor product.\n    vec3 base = mat.baseColor.rgb * bc.rgb * v_color.rgb * v_inst_color.rgb;\n    float alpha = mat.baseColor.a * bc.a * v_color.a * v_inst_color.a;\n\n    // glTF alphaMode=MASK — early discard before any expensive work.\n    // Two paths:\n    //   alpha_a2c_enabled = 1 → shader-level alpha-to-coverage via\n    //                            gl_SampleMask. Best edge quality when\n    //                            MSAA is on; degrades gracefully to a\n    //                            hard cutoff when MSAA is off (round\n    //                            saturates to 0 / 8).\n    //   default               → classic binary cutoff.\n    if((mat.feature_mask & kFeat_alpha_mask) != 0u)\n    {\n        if(alpha_a2c_enabled != 0)\n        {\n            if(!applyAlphaToCoverage(alpha))\n                discard;\n        }\n        else\n        {\n            if(alpha < mat.alpha_cutoff)\n                discard;\n        }\n    }\n\n    // ─── Metal-Rough-Occlusion (glTF packing: R=occ, G=rough, B=metal) ─\n    vec4 mr = sample_slot_mr(mat.textureRefs.y, matWrap(1u), uv_mr, vec4(1.0, 1.0, 1.0, 1.0));\n    float metallic\n        = mat.metallicRoughnessOcclusionUnlit.x * mr.b;\n    float roughness\n        = clamp(mat.metallicRoughnessOcclusionUnlit.y * mr.g, 0.04, 1.0);\n    // Occlusion: prefer separate occlusionTexture when set; else fall\n    // back to MR.r (the common packed-MR convention).\n    float occ_sample;\n    if((mat.feature_mask & kFeat_has_separate_occ) != 0u)\n        occ_sample = sample_slot_occ(mat.occlusion_textureRef, matWrap(4u), uv_occ, vec4(1.0)).r;\n    else\n        occ_sample = mr.r;\n    float occlusion = occ_sample * mat.metallicRoughnessOcclusionUnlit.z;\n    float unlit     = mat.metallicRoughnessOcclusionUnlit.w;\n\n    // ─── Emissive ─────────────────────────────────────────────────────\n    vec4 em = sample_slot_em(mat.textureRefs.w, matWrap(3u), uv_em, vec4(1.0));\n    vec3 emissive\n        = mat.emissive_strength.xyz * em.rgb * mat.emissive_strength.w;\n    emissive += v_inst_emissive.rgb;\n\n    if(unlit > 0.5)\n    {\n        // Volumetric composite BEFORE exposure_mul — accum is in raw\n        // light units (same scale as the BSDF result), so both sides\n        // of `inColor * transm + accum` stay in matched units.\n        // Output is linear HDR — the downstream tonemap owns the\n        // HDR→display compression and sRGB encode. (Doing pow(_,1/gamma)\n        // here would clip everything > 1 post-exposure to flat white\n        // before the tonemap could read the HDR signal — that's what\n        // made volumetric in-scatter blow out to saturated pink.)\n        vec3 color = base + emissive;\n        float viewZ_unlit = (camera.view * vec4(v_worldPos, 1.0)).z;\n        color = applyVolumetric(color, gl_FragCoord.xy, viewZ_unlit);\n        color *= exposure_mul;\n        isf_FragColor = vec4(max(color, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n        return;\n    }\n\n    // ─── Surface normal (tangent-space normal map if present) ─────────\n    vec3 N = normalize(v_normal);\n    // Double-sided: flip the surface normal for back-facing fragments\n    // so the BRDF evaluates with the correct hemisphere on both sides\n    // of the surface. (Single-sided materials never reach here for\n    // back faces — they were discarded above.)\n    if(is_double_sided && !gl_FrontFacing)\n        N = -N;\n    // Toksvig variance accumulator (Olano-Baker 2010). Captures the\n    // amount of normal-map variance lost to mip-level averaging /\n    // multi-tap anisotropic averaging — info the GPU's bilinear+mip\n    // filter normally throws away when shaders re-normalize sampled\n    // normals. Folded into the specular-AA block below alongside the\n    // screen-space (Tokuyoshi-Kaplanyan) variance.\n    float toksvig_sigma2 = 0.0;\n    uint normRef = mat.textureRefs.z;\n    if(normRef != 0xFFFFFFFFu && length(v_tangent.xyz) > 0.5)\n    {\n        vec3 T = normalize(v_tangent.xyz);\n        vec3 B = normalize(cross(N, T) * v_tangent.w);\n        mat3 TBN = mat3(T, B, N);\n        // Normal map sampling goes through the bucket ladder so\n        // mixed-resolution / compressed normal atlases work. The\n        // default (0.5,0.5,1.0) fallback decodes to a zero tangent-\n        // space delta — same as no normal map at all — if the bucket\n        // slot isn't populated.\n        //\n        // Keep the UN-NORMALIZED sample so its length can drive the\n        // Toksvig boost: anisoSample averages multiple weighted taps\n        // and mip filtering averages within texels, both of which\n        // shorten |n| when sub-pixel normals had directional spread.\n        // (1 - |n|²) is the \"lost variance\" added back as roughness.\n        vec3 nm_raw = sample_slot_nrm(normRef, matWrap(2u), uv_nrm,\n                                      vec4(0.5, 0.5, 1.0, 1.0)).xyz\n                      * 2.0 - 1.0;\n        toksvig_sigma2 = max(0.0, 1.0 - dot(nm_raw, nm_raw));\n        N = normalize(TBN * normalize(nm_raw));\n    }\n\n    vec3 V = normalize(camera.cameraPosition.xyz - v_worldPos);\n    float NdotV = max(dot(N, V), 1e-4);\n\n    // Metallic workflow.\n    vec3 F0 = mix(vec3(0.04), base, metallic);\n    vec3 kd = (1.0 - metallic) * base;\n\n    // Cheap environment term — same \"fake IBL\" as classic_pbr_textured;\n    // classic_pbr_ibl is the cubemap-sampled variant.\n    vec3 Fv = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);\n    vec3 fake_env = Fv * base * 0.25;\n\n    // Ambient comes from EnvironmentLoader (env.ambient.rgb × intensity\n    // in .w). When the user hasn't wired one, ambient_col is zero and\n    // the fake_env term + lights carry the lighting. The 0.04 floor is\n    // gone — letting users actually dial ambient down to black.\n    vec3 result = ambient_col * base * occlusion\n                  + emissive\n                  + fake_env * occlusion;\n\n    float alpha_g = max(roughness * roughness, 1e-4);\n    float alpha2 = alpha_g * alpha_g;\n    float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n\n    // ─── Specular antialiasing — Tokuyoshi-Kaplanyan + Toksvig ───────\n    //\n    // Three variance sources combined into a single roughness boost:\n    //\n    //   (A) Tokuyoshi-Kaplanyan 2019, \"Improved Geometric Specular\n    //       Antialiasing\" — screen-space derivatives of the world-\n    //       space normal. Captures sub-pixel-footprint normal\n    //       variance from geometry, normal-map silhouettes, and\n    //       interpolation across neighbours.\n    //\n    //   (B) Toksvig 2005, \"Mipmapping Normal Maps\" — texture-space\n    //       variance from filtered-normal shortening. Captures\n    //       variance lost to mip averaging + our multi-tap\n    //       anisotropic sampler that the GPU's linear filter and\n    //       shader's normalize() throw away.\n    //\n    //   (C) Grazing-angle amplification — a heuristic 1/NdotV scale\n    //       (capped) on the screen-space variance, approximating\n    //       Tokuyoshi-Kaplanyan's anisotropic Jacobian projection of\n    //       normal variance onto the half-vector tangent plane. The\n    //       full anisotropic form derives this matrix-multiply\n    //       explicitly; the 1/NdotV scalar captures the leading-\n    //       order behaviour at grazing where the BRDF stretches\n    //       most. Targets the \"noisy floor at grazing light\"\n    //       failure mode: at grazing, the half-vector becomes\n    //       perpendicular to the surface, NdotH gets small, and the\n    //       GGX D term's denominator hyperbola makes small N\n    //       variations move the highlight in/out of pixels.\n    //\n    // (A)+(B) cover variance from BOTH variance domains — the\n    // screen-space and texture-space sources are independent and\n    // additive. (C) amplifies (A) where the BRDF Jacobian demands it.\n    vec3 dNdx = dFdx(N);\n    vec3 dNdy = dFdy(N);\n    float kernelRoughness2 = 2.0 * (dot(dNdx, dNdx) + dot(dNdy, dNdy));\n\n    // (C) grazing amplification. NdotV floor of 0.05 prevents\n    // runaway at near-tangent view; cap at 8× keeps the boost\n    // bounded so we don't blow specular into pure diffuse.\n    float grazing_aa = clamp(1.0 / max(NdotV, 0.05), 1.0, 8.0);\n    kernelRoughness2 *= grazing_aa;\n\n    // Combine (A)·grazing + (B). Cap to keep alpha² in [0, 1] after\n    // the boost; 0.5 is the standard upper bound used by Filament +\n    // the Tokuyoshi-Kaplanyan reference.\n    const float specAaSigma2Max = 0.5;\n    float total_aa_sigma2 = clamp(kernelRoughness2 + toksvig_sigma2,\n                                  0.0, specAaSigma2Max);\n    alpha2 = clamp(alpha2 + total_aa_sigma2, 0.0, 1.0);\n    alpha_g = sqrt(alpha2);\n    // Re-derive Schlick-Smith k from the filtered roughness too so the\n    // G term widens in lockstep with D — otherwise rough-but-filtered\n    // surfaces still get an over-tight visibility term.\n    float roughness_f = sqrt(alpha_g);\n    k = (roughness_f + 1.0) * (roughness_f + 1.0) / 8.0;\n\n    uint n = scene_counts.light_count;\n    for(uint i = 0u; i < n; ++i)\n    {\n        uint slot = scene_light_indices.data[i];\n        Light L = scene_lights.entries[slot];\n\n        // Two paths for resolving the light's world-space placement:\n        //\n        //   transform_slot == 0xFFFFFFFF (sentinel):\n        //     The light was authored procedurally (e.g. by a compute CSF\n        //     reading a point cloud or particle system) and carries its\n        //     world position inline in local_direction.xyz. Skip the\n        //     world_transforms lookup — there's no matching scene-node\n        //     entry. Only point lights (type == 1) are well-defined\n        //     under this convention; directional with sentinel falls\n        //     back to treating .xyz as a direction, spot is unsupported.\n        //\n        //   transform_slot != sentinel:\n        //     Classic scene-node-attached light. World direction and\n        //     position come from the node's accumulated world transform\n        //     (published by ScenePreprocessor's FlattenVisitor).\n        float _type_f = L.local_direction.w;\n        vec3 ld_world;\n        vec3 lp_world;\n        if(L.transform_slot == 0xFFFFFFFFu)\n        {\n            if(_type_f < 0.5)\n            {\n                // Directional: .xyz is the world direction (same\n                // convention the scene-node path uses — no transform to\n                // apply since the light isn't parented to any node).\n                ld_world = normalize(L.local_direction.xyz);\n                lp_world = vec3(0.0);\n            }\n            else\n            {\n                // Point: .xyz is the world position. A default direction\n                // lets spot-cone code below degenerate gracefully for\n                // spot lights authored this way (cone attenuation will\n                // be effectively wide-open, since we have no real axis).\n                lp_world = L.local_direction.xyz;\n                ld_world = vec3(0.0, -1.0, 0.0);\n            }\n        }\n        else\n        {\n            mat4 W = world_transforms.data[L.transform_slot];\n            ld_world = normalize(mat3(W) * L.local_direction.xyz);\n            lp_world = W[3].xyz;\n        }\n        // Reconstruct the old LightGPU-shape vec4s so the BRDF body\n        // below (which references pos_type / color_i / dir_r) stays\n        // unchanged. type enum stays in .w; for directional lights the\n        // xyz holds the world direction, for point/spot it holds the\n        // world position — matching the prior packLight convention.\n        vec4 pos_type = vec4(\n            (_type_f < 0.5) ? ld_world : lp_world,\n            _type_f);\n        vec4 color_i  = L.color;\n        vec4 dir_r    = vec4(ld_world, L.range_cone.x);\n\n        vec3 Ldir;\n        float atten = 1.0;\n        if(pos_type.w < 0.5)\n        {\n            // Directional: no distance, no decay — per glTF / OpenPBR\n            // convention the 1/d² term doesn't apply.\n            Ldir = normalize(-pos_type.xyz);\n        }\n        else\n        {\n            vec3 toL = pos_type.xyz - v_worldPos;\n            float d = length(toL);\n            Ldir = toL / max(d, 1e-5);\n\n            // Hard cutoff: range == 0 is the \"no cutoff\" sentinel (glTF\n            // + ossia convention). Otherwise linearly fade over the\n            // last interval so the light doesn't pop off at exactly the\n            // range boundary.\n            if(dir_r.w > 0.0) atten = max(0.0, 1.0 - d / dir_r.w);\n\n            // Distance decay — switches on L.decay_mode so linear / none /\n            // cubic authored by the user or extracted from FBX actually\n            // reach the shader instead of being silently collapsed to\n            // the quadratic curve. Modes:\n            //   0 = none       (constant — legitimate for area lights\n            //                   and stylised looks)\n            //   1 = linear     1 / (1 + d)\n            //   2 = quadratic  1 / (1 + d²)   — physically correct default\n            //   3 = cubic      1 / (1 + d³)   — exaggerated falloff\n            uint decay = L.decay_mode;\n            if(decay == 1u)\n                atten *= 1.0 / (1.0 + d);\n            else if(decay == 2u)\n                atten *= 1.0 / (1.0 + d * d);\n            else if(decay == 3u)\n                atten *= 1.0 / (1.0 + d * d * d);\n            // decay == 0u → no distance attenuation; `atten` keeps the\n            // range cutoff contribution only.\n\n            // Spot-cone attenuation. Inner / outer cones are stored as\n            // cosines (packed CPU-side in Light.cpp) so the fragment-side\n            // test is one dot product + a linear ramp, matching the glTF\n            // KHR_lights_punctual reference formula:\n            //   t = clamp((cos_angle - outer) / (inner - outer), 0, 1)\n            //   atten *= t\n            // Outside the outer cone → t = 0, light doesn't contribute.\n            // Inside the inner cone → t = 1, full spot intensity.\n            // Between → linear falloff. type ≈ 2 = spot (local_direction.w\n            // packs the enum; see RawLightData::local_direction in\n            // SceneGPUState.hpp). Point lights (type ≈ 1) skip this\n            // block, so the spot-specific math doesn't perturb them.\n            if(pos_type.w > 1.5 && pos_type.w < 2.5)\n            {\n                float cos_to_frag = dot(-Ldir, normalize(dir_r.xyz));\n                float inner_cos   = L.range_cone.y;\n                float outer_cos   = L.range_cone.z;\n                atten *= clamp(\n                    (cos_to_frag - outer_cos)\n                        / max(inner_cos - outer_cos, 1e-5),\n                    0.0, 1.0);\n            }\n        }\n\n        float NdotL = max(dot(N, Ldir), 0.0);\n        if(NdotL <= 0.0) continue;\n\n        vec3 H = normalize(Ldir + V);\n        float NdotH = max(dot(N, H), 0.0);\n        float VdotH = max(dot(V, H), 0.0);\n\n        float denom_d = NdotH * NdotH * (alpha2 - 1.0) + 1.0;\n        float D = alpha2 / (3.14159 * denom_d * denom_d);\n\n        float G_v = NdotV / (NdotV * (1.0 - k) + k);\n        float G_l = NdotL / (NdotL * (1.0 - k) + k);\n        float G = G_v * G_l;\n\n        vec3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);\n\n        vec3 spec = (D * G * F) / max(4.0 * NdotV * NdotL, 1e-4);\n        vec3 diffuse_term = (vec3(1.0) - F) * kd / 3.14159;\n\n        vec3 lightCol = color_i.rgb * color_i.w;\n        result += atten * lightCol * NdotL * (diffuse_term + spec);\n    }\n\n    // Linear fog: blend with fog_color over [start, end]. fog_range.w\n    // is the enabled flag (set by EnvironmentLoader). When disabled\n    // we skip the work.\n    if(env.fog_range.w > 0.5)\n    {\n        float view_z = distance(camera.cameraPosition.xyz, v_worldPos);\n        float f_s = env.fog_range.x;\n        float f_e = max(env.fog_range.y, f_s + 1e-3);\n        float t = clamp((view_z - f_s) / (f_e - f_s), 0.0, 1.0);\n        result = mix(result, env.fog_color_density.rgb, t);\n    }\n\n    // Volumetric composite BEFORE exposure_mul. accum from the integrate\n    // pass is in raw light units (same scale as the BSDF result), so\n    // both sides of `inColor * transm + accum` stay in matched units —\n    // applying after exposure makes accum dominate dim surfaces and\n    // lose to bright/specular surfaces, which was the original\n    // \"foliage punches through fog\" symptom.\n    //\n    // view_z above is `distance(eye, worldPos)` (positive); applyVolumetric /\n    // scoreClusterId need view-space Z (negative). Recompute from\n    // camera.view to keep the cluster lookup consistent with\n    // build_cluster_aabbs / volumetric_integrate.\n    float viewZ = (camera.view * vec4(v_worldPos, 1.0)).z;\n    result = applyVolumetric(result, gl_FragCoord.xy, viewZ);\n\n    result *= exposure_mul;\n\n    // Output is LINEAR HDR. The downstream tonemap node owns the\n    // HDR→display compression (ACES / Reinhard / filmic / etc.) and\n    // the sRGB encode. The previous `pow(result, 1/gamma)` here was\n    // sRGB-encoding the HDR before the tonemap could read it: any\n    // radiance > 1.0 post-exposure clipped to flat white at gamma\n    // encode, which is what made volumetric in-scatter blow out to\n    // saturated pink.\n    isf_FragColor = vec4(max(result, vec3(0.0)), (mat.feature_mask & (1u << 17u)) != 0u ? alpha : 1.0);\n}\n","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":1000,"Hidden":false,"Custom":"Geometry In","Exposed":"geometry in"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Mode","Exposed":"mode","Value":{"Int":3},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["Triangles",{"Int":0}],["Points",{"Int":1}],["Lines",{"Int":2}],["Geometry",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"EnableBlend","Exposed":"enableblend","Value":{"Bool":true},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"SrcColor","Exposed":"srccolor","Value":{"Int":1},"Init":{"Int":6},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"DstColor","Exposed":"dstcolor","Value":{"Int":1},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"OpColor","Exposed":"opcolor","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"SrcAlpha","Exposed":"srcalpha","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"DstAlpha","Exposed":"dstalpha","Value":{"Int":7},"Init":{"Int":7},"Domain":{"Int":{"Values":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}},"Values":[["Zero",{"Int":0}],["One",{"Int":1}],["SrcColor",{"Int":2}],["OneMinusSrcColor",{"Int":3}],["DstColor",{"Int":4}],["OneMinusDstColor",{"Int":5}],["SrcAlpha",{"Int":6}],["OneMinusSrcAlpha",{"Int":7}],["DstAlpha",{"Int":8}],["OneMinusDstAlpha",{"Int":9}],["ConstantColor",{"Int":10}],["OneMinusConstantColor",{"Int":11}],["ConstantAlpha",{"Int":12}],["OneMinusConstantAlpha",{"Int":13}],["SrcAlphaSaturate",{"Int":14}]],"FolderPort":"","FileExtensions":""},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"OpAlpha","Exposed":"opalpha","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Add",{"Int":0}],["Substract",{"Int":1}],["Reverse Substract",{"Int":2}],["Min",{"Int":3}],["Max",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":8,"Hidden":false,"Custom":"camera","Exposed":"camera","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":9,"Hidden":false,"Custom":"scene_lights","Exposed":"scene_lights","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":10,"Hidden":false,"Custom":"scene_light_indices","Exposed":"scene_light_indices","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":11,"Hidden":false,"Custom":"world_transforms","Exposed":"world_transforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":12,"Hidden":false,"Custom":"scene_materials","Exposed":"scene_materials","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":13,"Hidden":false,"Custom":"scene_material_uv_xforms","Exposed":"scene_material_uv_xforms","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":14,"Hidden":false,"Custom":"per_draws","Exposed":"per_draws","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":15,"Hidden":false,"Custom":"indirect_draw_cmds","Exposed":"indirect_draw_cmds","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":16,"Hidden":false,"Custom":"scene_counts","Exposed":"scene_counts","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"5ac86198-2d03-4830-9e41-a6d529922d29","ObjectName":"Inlet","id":17,"Hidden":false,"Custom":"env","Exposed":"env","Format":0,"FormatSet":false,"Filter":2,"AddressMode":1,"MipmapMode":0},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":18,"Hidden":true,"Custom":"alpha_a2c_enabled","Exposed":"alpha_a2c_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":19,"Hidden":true,"Custom":"volumetric_enabled","Exposed":"volumetric_enabled","Value":{"Int":0},"Init":{"Int":0},"Domain":{"Int":{"Min":0,"Max":1}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":20,"Hidden":true,"Custom":"volumetric_intensity","Exposed":"volumetric_intensity","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":4.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":1000,"Hidden":false,"Custom":"Texture Out","Exposed":"texture out","Address":"Window:/"}]},{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":14,"Metadata":{"ScriptingName":"AddColor","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":11289600000,"Pos":[377.72719073659846,-151.5],"Size":[275.0,391.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Add or replace the color attribute on geometry. Solid: solidColor. By Index: a rainbow along the vertex order (saturation). Random: a random hue per vertex (seed, saturation). Axis Gradient: colorA at -1 to colorB at +1 along gradientAxis (clamped outside). alpha multiplies the result.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\"Geometry Modifier\"],\n  \"RESOURCES\": [\n    {\n      \"NAME\": \"geo\",\n      \"TYPE\": \"geometry\",\n      \"ATTRIBUTES\": [\n        { \"NAME\": \"position\", \"SEMANTIC\": \"position\", \"TYPE\": \"vec4\", \"ACCESS\": \"read_only\" },\n        { \"NAME\": \"color\",    \"SEMANTIC\": \"color\",    \"TYPE\": \"vec4\", \"ACCESS\": \"read_write\" }\n      ]\n    },\n    {\n      \"NAME\": \"colorMode\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 1,\n      \"VALUES\": [0, 1, 2, 3],\n      \"LABELS\": [\"Solid\", \"By Index\", \"Random\", \"Axis Gradient\"]\n    },\n    {\n      \"NAME\": \"solidColor\",\n      \"TYPE\": \"color\",\n      \"DEFAULT\": [1.0, 1.0, 1.0, 1.0]\n    },\n    {\n      \"NAME\": \"colorA\",\n      \"TYPE\": \"color\",\n      \"DEFAULT\": [0.2, 0.4, 1.0, 1.0]\n    },\n    {\n      \"NAME\": \"colorB\",\n      \"TYPE\": \"color\",\n      \"DEFAULT\": [1.0, 0.3, 0.1, 1.0]\n    },\n    {\n      \"NAME\": \"seed\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 42.0,\n      \"MIN\": 0.0,\n      \"MAX\": 1000.0\n    },\n    {\n      \"NAME\": \"saturation\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 0.7,\n      \"MIN\": 0.0,\n      \"MAX\": 1.0\n    },\n    {\n      \"NAME\": \"alpha\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 1.0,\n      \"MIN\": 0.0,\n      \"MAX\": 1.0\n    },\n    {\n      \"NAME\": \"gradientAxis\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 1,\n      \"VALUES\": [0, 1, 2],\n      \"LABELS\": [\"X\", \"Y\", \"Z\"]\n    }\n  ],\n  \"PASSES\": [\n    { \"LOCAL_SIZE\": [64, 1, 1], \"EXECUTION_MODEL\": { \"TYPE\": \"PER_VERTEX\" } }\n  ]\n}*/\n\nuint pcg(uint s)\n{\n  s ^= s >> 17u; s *= 0xed5ad4bbu;\n  s ^= s >> 11u; s *= 0xac4c1b51u;\n  s ^= s >> 15u; s *= 0x31848babu;\n  s ^= s >> 14u;\n  return s;\n}\n\nfloat rand01(uint s) { return float(pcg(s)) / 4294967296.0; }\n\n// HSV to RGB\nvec3 hsv2rgb(float h, float s, float v)\n{\n  vec3 c = vec3(h, s, v);\n  vec3 p = abs(fract(c.xxx + vec3(1.0, 2.0/3.0, 1.0/3.0)) * 6.0 - 3.0);\n  return c.z * mix(vec3(1.0), clamp(p - 1.0, 0.0, 1.0), c.y);\n}\n\nvoid main()\n{\n  uint idx = gl_GlobalInvocationID.x;\n  uint count = uint(ISF_READ(geo, position).length());\n  if(idx >= count)\n    return;\n\n  vec4 col;\n\n  // Mode 0: Solid color\n  if(colorMode == 0)\n  {\n    col = solidColor;\n  }\n  // Mode 1: By index (HSV rainbow)\n  else if(colorMode == 1)\n  {\n    float t = float(idx) / max(float(count - 1u), 1.0);\n    col = vec4(hsv2rgb(t, saturation, 1.0), 1.0);\n  }\n  // Mode 2: Random per-vertex\n  else if(colorMode == 2)\n  {\n    uint s = idx * 7919u + uint(seed * 65537.0);\n    float hue = rand01(s);\n    col = vec4(hsv2rgb(hue, saturation, 0.8 + 0.2 * rand01(s + 1u)), 1.0);\n  }\n  // Mode 3: Axis gradient (colorA -> colorB)\n  else\n  {\n    vec3 pos = ISF_READ(geo, position)[idx].xyz;\n    float v = pos[gradientAxis];\n\n    // Auto-normalize: scan is too expensive, use a reasonable range\n    // Map [-1, 1] to [0, 1] — works for most generators\n    float t = clamp(v * 0.5 + 0.5, 0.0, 1.0);\n    col = mix(colorA, colorB, t);\n  }\n\n  col.a *= alpha;\n  ISF_WRITE(geo, color)[idx] = col;\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/modifiers/AddColor.cs","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"geo","Exposed":"geo"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"colorMode","Exposed":"colormode","Value":{"Int":2},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2,3]}},"Values":[["Solid",{"Int":0}],["By Index",{"Int":1}],["Random",{"Int":2}],["Axis Gradient",{"Int":3}]],"FolderPort":"","FileExtensions":""},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"solidColor","Exposed":"solidcolor","Value":{"Vec4f":[0.37309834361076355,0.9100022912025452,0.8704509139060974,1.0]},"Init":{"Vec4f":[1.0,1.0,1.0,1.0]},"Domain":{}},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"colorA","Exposed":"colora","Value":{"Vec4f":[0.9507285952568054,1.0,0.800000011920929,1.0]},"Init":{"Vec4f":[0.20000000298023224,0.4000000059604645,1.0,1.0]},"Domain":{}},{"uuid":"8f38638e-9f9f-48b0-ae36-1cba86ef5703","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"colorB","Exposed":"colorb","Value":{"Vec4f":[0.60990309715271,0.3199969530105591,1.0,1.0]},"Init":{"Vec4f":[1.0,0.30000001192092896,0.10000000149011612,1.0]},"Domain":{}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"seed","Exposed":"seed","Value":{"Float":42.0},"Init":{"Float":42.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"saturation","Exposed":"saturation","Value":{"Float":0.699999988079071},"Init":{"Float":0.699999988079071},"Domain":{"Float":{"Min":0.0,"Max":1.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"alpha","Exposed":"alpha","Value":{"Float":1.0},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":1.0}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"gradientAxis","Exposed":"gradientaxis","Value":{"Int":1},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2]}},"Values":[["X",{"Int":0}],["Y",{"Int":1}],["Z",{"Int":2}]],"FolderPort":"","FileExtensions":""}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"geo_out","Exposed":"geo_out"}]},{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":15,"Metadata":{"ScriptingName":"Deform","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":11289600000,"Pos":[83.72719073659846,-154.5],"Size":[285.0,161.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Procedural deformation around center, along axis. amount means: Twist = radians of rotation per unit along the axis; Bend = curvature (1 / bend radius) per unit along the axis, bending toward the first perpendicular axis; Taper = change of the cross-section scale per unit along the axis (1 + amount x distance); Spherize = blend from the shape (0) to a sphere of the given radius (1), negative values push away; Quantize = snap to a grid of gridSize (amount unused). radius is used by Spherize only, gridSize by Quantize only. Normals are re-derived from the deformation; a geometry without normals is deformed too.\",\n  \"CREDIT\": \"ossia score\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\"Geometry Modifier\"],\n  \"RESOURCES\": [\n    {\n      \"NAME\": \"geo\",\n      \"TYPE\": \"geometry\",\n      \"ATTRIBUTES\": [\n        { \"NAME\": \"position\", \"SEMANTIC\": \"position\", \"TYPE\": \"vec4\", \"ACCESS\": \"read_write\" },\n        { \"NAME\": \"normal\",   \"SEMANTIC\": \"normal\",   \"TYPE\": \"vec4\", \"ACCESS\": \"read_write\", \"REQUIRED\": false }\n      ]\n    },\n    { \"NAME\": \"deformType\", \"TYPE\": \"long\", \"VALUES\": [0, 1, 2, 3, 4], \"LABELS\": [\"Twist\", \"Bend\", \"Taper\", \"Spherize\", \"Quantize\"], \"DEFAULT\": 0 },\n    { \"NAME\": \"amount\",     \"TYPE\": \"float\",   \"DEFAULT\": 1.0,  \"MIN\": -10.0, \"MAX\": 10.0 },\n    { \"NAME\": \"axis\",       \"TYPE\": \"long\",    \"VALUES\": [0, 1, 2], \"LABELS\": [\"X\", \"Y\", \"Z\"], \"DEFAULT\": 1 },\n    { \"NAME\": \"center\",     \"TYPE\": \"point3D\", \"DEFAULT\": [0, 0, 0], \"MIN\": [-100, -100, -100], \"MAX\": [100, 100, 100] },\n    { \"NAME\": \"radius\",     \"TYPE\": \"float\",   \"DEFAULT\": 1.0,  \"MIN\": 0.01,  \"MAX\": 100.0 },\n    { \"NAME\": \"gridSize\",   \"TYPE\": \"float\",   \"DEFAULT\": 0.1,  \"MIN\": 0.01,  \"MAX\": 10.0 }\n  ],\n  \"PASSES\": [\n    { \"LOCAL_SIZE\": [64, 1, 1], \"EXECUTION_MODEL\": { \"TYPE\": \"PER_VERTEX\" } }\n  ]\n}*/\n\n// Extract the component along the chosen axis and the two perpendicular components.\n// Returns vec3(along_axis, perp1, perp2) and sets up indices for reassembly.\n// axis: 0=X, 1=Y, 2=Z\n\nfloat getAxisComponent(vec3 p, int ax)\n{\n    if(ax == 0) return p.x;\n    if(ax == 1) return p.y;\n    return p.z;\n}\n\nvec3 setAxisComponent(vec3 p, int ax, float v)\n{\n    if(ax == 0) p.x = v;\n    else if(ax == 1) p.y = v;\n    else p.z = v;\n    return p;\n}\n\n// Get the two perpendicular axis indices\nivec2 perpAxes(int ax)\n{\n    if(ax == 0) return ivec2(1, 2);\n    if(ax == 1) return ivec2(0, 2);\n    return ivec2(0, 1);\n}\n\nfloat getComp(vec3 p, int i)\n{\n    if(i == 0) return p.x;\n    if(i == 1) return p.y;\n    return p.z;\n}\n\nvec3 setComp(vec3 p, int i, float v)\n{\n    if(i == 0) p.x = v;\n    else if(i == 1) p.y = v;\n    else p.z = v;\n    return p;\n}\n\nvec3 doTwist(vec3 pos, vec3 ctr, int ax, float amt)\n{\n    vec3 p = pos - ctr;\n    float along = getAxisComponent(p, ax);\n    float angle = amt * along;\n    float c = cos(angle), s = sin(angle);\n\n    ivec2 perp = perpAxes(ax);\n    float u = getComp(p, perp.x);\n    float v = getComp(p, perp.y);\n\n    float nu = c * u - s * v;\n    float nv = s * u + c * v;\n\n    p = setComp(p, perp.x, nu);\n    p = setComp(p, perp.y, nv);\n    return p + ctr;\n}\n\nvec3 doBend(vec3 pos, vec3 ctr, int ax, float amt)\n{\n    vec3 p = pos - ctr;\n    float along = getAxisComponent(p, ax);\n    float angle = amt * along;\n\n    // Bend in the plane of (axis, first perpendicular axis)\n    ivec2 perp = perpAxes(ax);\n    float u = getComp(p, perp.x);\n\n    // If amount is near zero, skip to avoid division by zero\n    if(abs(amt) < 0.0001)\n        return pos;\n\n    float bendRadius = 1.0 / amt;\n    // Circular arc: the along-axis coordinate maps to an angle,\n    // and the perpendicular offset shifts the radius\n    float r = bendRadius + u;\n    float newAlong = r * sin(angle);\n    float newPerp  = r * cos(angle) - bendRadius;\n\n    p = setAxisComponent(p, ax, newAlong);\n    p = setComp(p, perp.x, newPerp);\n    return p + ctr;\n}\n\nvec3 doTaper(vec3 pos, vec3 ctr, int ax, float amt)\n{\n    vec3 p = pos - ctr;\n    float along = getAxisComponent(p, ax);\n    float taperScale = 1.0 + amt * along;\n    taperScale = max(taperScale, 0.0);\n\n    ivec2 perp = perpAxes(ax);\n    float u = getComp(p, perp.x) * taperScale;\n    float v = getComp(p, perp.y) * taperScale;\n\n    p = setComp(p, perp.x, u);\n    p = setComp(p, perp.y, v);\n    return p + ctr;\n}\n\nvec3 doSpherize(vec3 pos, vec3 ctr, float r, float amt)\n{\n    vec3 d = pos - ctr;\n    float len = length(d);\n    if(len < 0.0001)\n        return pos;\n\n    vec3 spherePos = normalize(d) * r + ctr;\n    return mix(pos, spherePos, clamp(amt, -1.0, 1.0));\n}\n\nvec3 doQuantize(vec3 pos, float grid)\n{\n    return round(pos / grid) * grid;\n}\n\n// Approximate normal after deformation by computing the Jacobian via finite differences.\nvec3 deformNormal(vec3 pos, vec3 nrm, vec3 ctr, int ax, int dtype, float amt, float r, float grid)\n{\n    float eps = 0.001;\n    vec3 tangentX, tangentY, tangentZ;\n\n    // Compute displaced neighbors along each axis\n    vec3 px, mx, py, my, pz, mz;\n\n    // We compute the deformed positions at small offsets to approximate partial derivatives\n    vec3 ppx = pos + vec3(eps, 0.0, 0.0);\n    vec3 pmx = pos - vec3(eps, 0.0, 0.0);\n    vec3 ppy = pos + vec3(0.0, eps, 0.0);\n    vec3 pmy = pos - vec3(0.0, eps, 0.0);\n    vec3 ppz = pos + vec3(0.0, 0.0, eps);\n    vec3 pmz = pos - vec3(0.0, 0.0, eps);\n\n    if(dtype == 0) // Twist\n    {\n        px = doTwist(ppx, ctr, ax, amt); mx = doTwist(pmx, ctr, ax, amt);\n        py = doTwist(ppy, ctr, ax, amt); my = doTwist(pmy, ctr, ax, amt);\n        pz = doTwist(ppz, ctr, ax, amt); mz = doTwist(pmz, ctr, ax, amt);\n    }\n    else if(dtype == 1) // Bend\n    {\n        px = doBend(ppx, ctr, ax, amt); mx = doBend(pmx, ctr, ax, amt);\n        py = doBend(ppy, ctr, ax, amt); my = doBend(pmy, ctr, ax, amt);\n        pz = doBend(ppz, ctr, ax, amt); mz = doBend(pmz, ctr, ax, amt);\n    }\n    else if(dtype == 2) // Taper\n    {\n        px = doTaper(ppx, ctr, ax, amt); mx = doTaper(pmx, ctr, ax, amt);\n        py = doTaper(ppy, ctr, ax, amt); my = doTaper(pmy, ctr, ax, amt);\n        pz = doTaper(ppz, ctr, ax, amt); mz = doTaper(pmz, ctr, ax, amt);\n    }\n    else if(dtype == 3) // Spherize\n    {\n        px = doSpherize(ppx, ctr, r, amt); mx = doSpherize(pmx, ctr, r, amt);\n        py = doSpherize(ppy, ctr, r, amt); my = doSpherize(pmy, ctr, r, amt);\n        pz = doSpherize(ppz, ctr, r, amt); mz = doSpherize(pmz, ctr, r, amt);\n    }\n    else // Quantize - normals are meaningless after quantize, keep original\n    {\n        return nrm;\n    }\n\n    // Jacobian columns (partial derivatives of deformation)\n    vec3 dFdx = (px - mx) / (2.0 * eps);\n    vec3 dFdy = (py - my) / (2.0 * eps);\n    vec3 dFdz = (pz - mz) / (2.0 * eps);\n\n    // Transform normal by inverse-transpose of Jacobian:\n    // n' = normalize( inv(J)^T * n )\n    // For a 3x3 matrix, inv(J)^T can be computed via cofactor matrix.\n    // cofactor(J) = transpose of adjugate\n    mat3 J = mat3(dFdx, dFdy, dFdz);\n\n    // Cofactor matrix (each element is the 2x2 minor determinant with sign)\n    mat3 cof;\n    cof[0][0] = J[1][1]*J[2][2] - J[1][2]*J[2][1];\n    cof[0][1] = J[1][2]*J[2][0] - J[1][0]*J[2][2];\n    cof[0][2] = J[1][0]*J[2][1] - J[1][1]*J[2][0];\n    cof[1][0] = J[0][2]*J[2][1] - J[0][1]*J[2][2];\n    cof[1][1] = J[0][0]*J[2][2] - J[0][2]*J[2][0];\n    cof[1][2] = J[0][1]*J[2][0] - J[0][0]*J[2][1];\n    cof[2][0] = J[0][1]*J[1][2] - J[0][2]*J[1][1];\n    cof[2][1] = J[0][2]*J[1][0] - J[0][0]*J[1][2];\n    cof[2][2] = J[0][0]*J[1][1] - J[0][1]*J[1][0];\n\n    // inv(J)^T * n = cofactor * n (unnormalized)\n    vec3 newNormal = cof * nrm;\n    float len = length(newNormal);\n    return len > 0.0001 ? newNormal / len : nrm;\n}\n\nvoid main()\n{\n    uint idx = gl_GlobalInvocationID.x;\n    uint count = uint(ISF_WRITE(geo, position).length());\n    if(idx >= count)\n        return;\n\n    vec3 pos = ISF_READ(geo, position)[idx].xyz;\n    vec3 nrm = ISF_READ(geo, normal)[idx].xyz;\n\n    int dtype = int(deformType);\n    int ax = int(axis);\n\n    // Compute deformed normal (uses original position for Jacobian)\n    nrm = deformNormal(pos, nrm, center, ax, dtype, amount, radius, gridSize);\n\n    // Deform position\n    vec3 newPos;\n    if(dtype == 0)\n        newPos = doTwist(pos, center, ax, amount);\n    else if(dtype == 1)\n        newPos = doBend(pos, center, ax, amount);\n    else if(dtype == 2)\n        newPos = doTaper(pos, center, ax, amount);\n    else if(dtype == 3)\n        newPos = doSpherize(pos, center, radius, amount);\n    else\n        newPos = doQuantize(pos, gridSize);\n\n    ISF_WRITE(geo, position)[idx] = vec4(newPos, ISF_READ(geo, position)[idx].w);\n    ISF_WRITE(geo, normal)[idx] = vec4(nrm, 0.0);\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/modifiers/Deform.cs","Inlets":[{"uuid":"f2ab26ea-415d-45a2-bfbc-2968c7c92a33","ObjectName":"Inlet","id":0,"Hidden":false,"Custom":"geo","Exposed":"geo"},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"deformType","Exposed":"deformtype","Value":{"Int":4},"Init":{"Int":0},"Domain":{"Int":{"Values":[0,1,2,3,4]}},"Values":[["Twist",{"Int":0}],["Bend",{"Int":1}],["Taper",{"Int":2}],["Spherize",{"Int":3}],["Quantize",{"Int":4}]],"FolderPort":"","FileExtensions":""},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"amount","Exposed":"amount","Value":{"Float":-1.563799262046814},"Init":{"Float":1.0},"Domain":{"Float":{"Min":-10.0,"Max":10.0}}},{"uuid":"485680cc-b8b9-4a01-acc7-3e8334bdc016","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"axis","Exposed":"axis","Value":{"Int":0},"Init":{"Int":1},"Domain":{"Int":{"Values":[0,1,2]}},"Values":[["X",{"Int":0}],["Y",{"Int":1}],["Z",{"Int":2}]],"FolderPort":"","FileExtensions":""},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"center","Exposed":"center","Value":{"Vec3f":[0.0,0.07422865182161331,0.0]},"Init":{"Vec3f":[0.0,0.0,0.0]},"Domain":{"Vec3f":{"Min":[-100.0,-100.0,-100.0],"Max":[100.0,100.0,100.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"radius","Exposed":"radius","Value":{"Float":6.297386646270752},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.009999999776482582,"Max":100.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"gridSize","Exposed":"gridsize","Value":{"Float":0.5875222682952881},"Init":{"Float":0.10000000149011612},"Domain":{"Float":{"Min":0.009999999776482582,"Max":10.0}}}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"geo_out","Exposed":"geo_out"}]},{"uuid":"d3f5a8c1-8b47-4e91-9c2d-6f1a9b5e3c82","ObjectName":"environment_loader","id":12,"Metadata":{"ScriptingName":"Environment.6","Comment":"","Color":"Transparent1","Label":"","Touched":false},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":10584000000,"Pos":[-474.27280926340154,-361.5],"Size":[352.0,176.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"Ambient Color","Exposed":"ambient color","Value":{"Vec3f":[1.0,1.0,1.0]},"Init":{"Vec3f":[0.029999999329447746,0.029999999329447746,0.029999999329447746]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Ambient Intensity","Exposed":"ambient intensity","Value":{"Float":2.6363744735717773},"Init":{"Float":1.0},"Domain":{"Float":{"Min":0.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":2,"Hidden":true,"Custom":"Exposure EV100","Exposed":"exposure ev100","Value":{"Float":-1.7068499326705933},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-6.0,"Max":18.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":3,"Hidden":true,"Custom":"Exposure (stops)","Exposed":"exposure (stops)","Value":{"Float":-2.727250814437866},"Init":{"Float":0.0},"Domain":{"Float":{"Min":-8.0,"Max":8.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":4,"Hidden":true,"Custom":"Gamma","Exposed":"gamma","Value":{"Float":2.200000047683716},"Init":{"Float":2.200000047683716},"Domain":{"Float":{"Min":1.0,"Max":3.0}}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":5,"Hidden":true,"Custom":"Fog","Exposed":"fog","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}},{"uuid":"377e8205-b442-4d54-8832-3761def522b2","ObjectName":"Inlet","id":6,"Hidden":true,"Custom":"Fog Color","Exposed":"fog color","Value":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Init":{"Vec3f":[0.800000011920929,0.800000011920929,0.800000011920929]},"Domain":{"Vec3f":{"Min":[0.0,0.0,0.0],"Max":[1.0,1.0,1.0],"Values":[[],[],[]]}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":7,"Hidden":true,"Custom":"Fog Start","Exposed":"fog start","Value":{"Float":10.0},"Init":{"Float":10.0},"Domain":{"Float":{"Min":0.0,"Max":1000.0}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":8,"Hidden":true,"Custom":"Fog End","Exposed":"fog end","Value":{"Float":100.0},"Init":{"Float":100.0},"Domain":{"Float":{"Min":0.0,"Max":10000.0}}},{"uuid":"0adbbdda-fda4-451e-91cc-1da731bde9d5","ObjectName":"Inlet","id":9,"Hidden":true,"Custom":"Render target size","Exposed":"render target size","Value":{"Vec2f":[0.0,0.0]},"Init":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[16384.0,16384.0],"Values":[[],[]]}},"Integral":true}],"Outlets":[{"uuid":"848061c5-e8a0-4a13-9985-e8df30ce6d4f","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"Scene","Exposed":"scene"}]},{"uuid":"a5bbffe0-93d2-4e70-995c-cf46c2c43520","ObjectName":"CSF","id":16,"Metadata":{"ScriptingName":"17-03_bit_glitch","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":11289600000,"Pos":[-614.804207027565,-576.6285953954568],"Size":[166.0,67.0],"Loops":false,"FoldMode":0,"Compute":"/*{\n  \"DESCRIPTION\": \"Bit-plane glitch: per-voxel XOR of integer coordinates, shifted with time. Very 8-bit.\",\n  \"CREDIT\": \"ossia 3D catalog\",\n  \"ISFVSN\": \"2.0\",\n  \"MODE\": \"COMPUTE_SHADER\",\n  \"CATEGORIES\": [\n    \"3D-GENERATOR\",\n    \"EXOTIC\"\n  ],\n  \"INPUTS\": [\n    {\n      \"NAME\": \"shift\",\n      \"TYPE\": \"long\",\n      \"DEFAULT\": 4,\n      \"MIN\": 1,\n      \"MAX\": 8,\n      \"LABEL\": \"Bit shift\"\n    },\n    {\n      \"NAME\": \"speed\",\n      \"TYPE\": \"float\",\n      \"DEFAULT\": 2.0,\n      \"MIN\": 0.0,\n      \"MAX\": 8.0,\n      \"LABEL\": \"Speed\"\n    }\n  ],\n  \"RESOURCES\": [\n    {\n      \"NAME\": \"volume\",\n      \"TYPE\": \"image\",\n      \"ACCESS\": \"write_only\",\n      \"WIDTH\": \"64\",\n      \"HEIGHT\": \"64\",\n      \"DEPTH\": \"64\"\n    }\n  ],\n  \"PASSES\": [\n    {\n      \"LOCAL_SIZE\": [\n        4,\n        4,\n        4\n      ],\n      \"EXECUTION_MODEL\": {\n        \"TYPE\": \"3D_IMAGE\",\n        \"TARGET\": \"volume\"\n      }\n    }\n  ]\n}*/\n\nvoid main()\n{\n    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n    ivec3 size = imageSize(volume);\n    if(any(greaterThanEqual(pos, size))) return;\n    vec3 p  = (vec3(pos) + 0.5) / vec3(size);   // [0,1]^3\n    vec3 pc = p * 2.0 - 1.0;                     // [-1,1]^3\n\n    uint x = uint(pos.x), y = uint(pos.y), z = uint(pos.z);\n    uint t = uint(TIME * speed * 8.0);\n    uint v = ((x ^ y) >> uint(shift)) ^ ((y ^ z) >> uint(shift)) ^ t;\n    float g = float(v & 7u) / 7.0;\n    float b = float((v >> 3u) & 7u) / 7.0;\n    float r = float((v >> 6u) & 7u) / 7.0;\n    imageStore(volume, pos, vec4(r, g, b, 1.0));\n\n}\n","Root":"<LIBRARY>:packages/score-csf-testers/shaderlib/volume/17-exotic/17-03_bit_glitch.cs","Inlets":[{"uuid":"238399a0-7e81-47e3-896f-08e8856e2973","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"shift","Exposed":"shift","Value":{"Int":4},"Init":{"Int":4},"Domain":{"Int":{"Min":1,"Max":8}}},{"uuid":"af2b4fc3-aecb-4c15-a5aa-1c573a239925","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"speed","Exposed":"speed","Value":{"Float":2.0},"Init":{"Float":2.0},"Domain":{"Float":{"Min":0.0,"Max":8.0}}}],"Outlets":[{"uuid":"f1c71046-b754-49a5-8e66-d01374773dfc","ObjectName":"Outlet","id":0,"Hidden":false,"Custom":"volume","Exposed":"volume"}]},{"uuid":"7be51631-fb4b-4152-9ca7-86fdafa8a989","ObjectName":"Display","id":17,"Metadata":{"ScriptingName":"Text Box","Comment":"","Color":"Transparent1","Label":"","Touched":true},"Duration":11289600000,"Height":300.0,"StartOffset":0,"LoopDuration":11289600000,"Pos":[-106.48420702756496,-213.02859539545676],"Size":[454.0,23.0],"Loops":false,"FoldMode":0,"Inlets":[{"uuid":"9ae797ea-d94c-4792-acec-9ec1932bae5d","ObjectName":"Inlet","id":0,"Hidden":true,"Custom":"in","Exposed":"in","Value":{"String":"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\np, li { white-space: pre-wrap; }\nhr { height: 1px; border-width: 0; }\nli.unchecked::marker { content: \"\\2610\"; }\nli.checked::marker { content: \"\\2612\"; }\n</style></head><body style=\" font-family:'Ubuntu'; font-size:13px; font-weight:400; font-style:normal;\">\n<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">This example shows the text to mesh object, which turns text into a 3D mesh</p></body></html>"},"Init":{"String":"(Double-click to edit)"},"Domain":{}},{"uuid":"fb27e4cb-ea7f-41e2-ad92-2354498c1b6b","ObjectName":"Inlet","id":1,"Hidden":true,"Custom":"Auto-reflow","Exposed":"auto-reflow","Value":{"Bool":false},"Init":{"Bool":false},"Domain":{"Bool":null}}],"Outlets":[]}],"SmallViewRack":[{"Processes":[8,9,10,12,13,14,15,16,17],"Process":null,"Height":200.0,"Nodal":true}],"FullViewRack":[{"Process":0,"Nodal":true}],"DefaultDuration":11289600000,"MinDuration":11289600000,"MaxDuration":11854080000,"GuiDuration":12418560000,"Speed":1.0,"Rigidity":false,"MinNull":false,"MaxInf":true,"Signatures":[[0,[4,4]]],"StartState":0,"EndState":1,"StartDate":0,"HeightPercentage":0.0,"NodalSlotHeight":100.0,"QuantizationRate":-1.0,"Zoom":16128000.0,"Center":0,"NodalCenter":[372.315792972435,-472.2285953954567],"NodalScale":0.6944444444444444,"ViewMode":1,"SmallViewShown":true,"HasSignature":true},"StartTimeNode":{"ObjectName":"Scenario::TimeSyncModel","id":0,"Metadata":{"ScriptingName":"Sync.start","Comment":"","Color":"Gray","Label":"","Touched":true},"Date":0,"Events":[0],"MusicalSync":-1.0,"AutoTrigger":false,"Start":true,"Active":false,"Expression":" { true == false } "},"EndTimeNode":{"ObjectName":"Scenario::TimeSyncModel","id":1,"Metadata":{"ScriptingName":"Sync.end","Comment":"","Color":"Gray","Label":"","Touched":true},"Date":11289600000,"Events":[1],"MusicalSync":-1.0,"AutoTrigger":false,"Start":false,"Active":true,"Expression":" { true == false } "},"StartEvent":{"ObjectName":"Scenario::EventModel","id":0,"Metadata":{"ScriptingName":"Event.start","Comment":"","Color":"Emphasis4","Label":"","Touched":true},"TimeNode":0,"States":[0],"Condition":"","Date":0,"Offset":0},"EndEvent":{"ObjectName":"Scenario::EventModel","id":1,"Metadata":{"ScriptingName":"Event.end","Comment":"","Color":"Emphasis4","Label":"","Touched":true},"TimeNode":1,"States":[1],"Condition":"","Date":11289600000,"Offset":0},"StartState":{"ObjectName":"Scenario::StateModel","id":0,"Metadata":{"ScriptingName":"State.start","Comment":"","Color":"Base1","Label":"","Touched":true},"Event":0,"PreviousConstraint":null,"NextConstraint":0,"HeightPercentage":0.0,"Messages":{"Name":"","Accessors":[],"Unit":"none","Previous":[],"Following":[],"User":null,"Priorities":[1,2,0]},"StateProcesses":[]},"EndState":{"ObjectName":"Scenario::StateModel","id":1,"Metadata":{"ScriptingName":"State.end","Comment":"","Color":"Base1","Label":"","Touched":true},"Event":1,"PreviousConstraint":0,"NextConstraint":null,"HeightPercentage":0.0,"Messages":{"Name":"","Accessors":[],"Unit":"none","Previous":[],"Following":[],"User":null,"Priorities":[1,2,0]},"StateProcesses":[]}},"Speed":1.0,"Cables":[{"ObjectName":"Process::Cable","id":11,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":9},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":15},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":2,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"camera_avnd","ObjectId":10},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":9},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":12,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":15},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":14},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":4,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"environment_loader","ObjectId":12},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":9},{"ObjectName":"Inlet","ObjectId":0}]},{"ObjectName":"Process::Cable","id":10,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"CSF","ObjectId":14},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":13},{"ObjectName":"Inlet","ObjectId":1000}]},{"ObjectName":"Process::Cable","id":8,"Type":0,"Source":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"text_to_mesh","ObjectId":8},{"ObjectName":"Outlet","ObjectId":0}],"Sink":[{"ObjectName":"Scenario::ScenarioDocumentModel","ObjectId":1},{"ObjectName":"Scenario::BaseScenario","ObjectId":0},{"ObjectName":"Scenario::IntervalModel","ObjectId":0},{"ObjectName":"gfxProcess","ObjectId":9},{"ObjectName":"Inlet","ObjectId":0}]}],"BusIntervals":[]},"Plugins":[{"uuid":"aac1402f-6851-4a1a-ab50-5f213acd1262","Name":"","Author":"","Description":"","Url":"","Platforms":"","Created":"2026-09-30T02:52:42.967Z","LastSaved":"2026-10-04T16:41:27.493Z","Thumbnail":"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","AutomaticThumbnail":true},{"uuid":"1f923578-08c3-49be-9ba9-69c144ee2e32","Refresh":false,"Reconnect":false,"MidiRatio":1.0},{"uuid":"6e610e1f-9de2-4c36-90dd-0ef570002a21","RootNode":{},"Children":[{"Device":{"Name":"Window","Protocol":"5a181207-7d40-4ad8-814e-879fcdf8cc31","Mode":1,"Outputs":[],"InputWidth":1920,"InputHeight":1080,"SwapchainFlag":0,"SwapchainFormat":0},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[1298.0,994.0]},"Domain":{},"Name":"size"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{},"Name":"rendersize"}},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"cursor"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Float":{"Min":0.0,"Max":1.0}},"Name":"scaled"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Float":{"Min":0.0,"Max":1.0}},"Name":"gl"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[163.0,220.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[1298.0,983.0],"Values":[[],[]]}},"Name":"absolute"}}]},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"tablet"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Float":{"Min":0.0,"Max":1.0}},"Name":"scaled"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Vec2f":[0.0,0.0]},"Domain":{"Vec2f":{"Min":[0.0,0.0],"Max":[1298.0,983.0],"Values":[[],[]]}},"Name":"absolute"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Int":0},"Domain":{},"Name":"z"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{},"Name":"pressure"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-1.0,"Max":1.0}},"Name":"tangential"}},{"Address":{"ioType":"<->","ClipMode":"Free","Unit":"angle.degree","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-180.0,"Max":180.0}},"Name":"rotation"}},{"Address":{"ioType":"<->","ClipMode":"Free","Unit":"angle.degree","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-60.0,"Max":60.0}},"Name":"tilt_x"}},{"Address":{"ioType":"<->","ClipMode":"Free","Unit":"angle.degree","RepetitionFilter":false,"Value":{"Float":0.0},"Domain":{"Float":{"Min":-60.0,"Max":60.0}},"Name":"tilt_y"}}]},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"key"},"Children":[{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"press"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Int":0},"Domain":{},"Name":"code"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"String":""},"Domain":{},"Name":"text"}}]},{"Address":{"ClipMode":"Free","RepetitionFilter":false,"Value":{},"Domain":{},"Name":"release"},"Children":[{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"Int":0},"Domain":{},"Name":"code"}},{"Address":{"ioType":"<->","ClipMode":"Free","RepetitionFilter":false,"Value":{"String":""},"Domain":{},"Name":"text"}}]}]}]}]},{"uuid":"05e72689-e02c-4c9d-a0bf-fe84c32d3d96","Data":""}],"Version":5,"Commit":"0c9a91e597012946960316e688b1ac8b00f5a0c1","Tag":"3.8.2"}