| … | … | @@ -1,4 +1,5 @@ |
| 1 | 1 | #include "proc_volume.h" |
| 2 | #include "../gpu/proc_simplex_glsl.gen.h" |
| 2 | 3 | #include <godot_cpp/variant/utility_functions.hpp> |
| 3 | 4 | #include <godot_cpp/classes/shader_material.hpp> |
| 4 | 5 | #include <godot_cpp/classes/shader.hpp> |
| … | … | @@ -112,6 +113,11 @@ String ProcVolume::build_fog_shader_code() const { |
| 112 | 113 | src += "shader_type fog;\n\n"; |
| 113 | 114 | src += "// Emitted by proc-nodes: ProcNodeGraph::compile_to_glsl_function.\n"; |
| 114 | 115 | src += "// Do not edit here -- edit the graph.\n"; |
| 116 | // The simplex library, for the noise uniforms below. It is #ifndef-guarded, |
| 117 | // so a graph that already emitted it (any Simplex Noise node) includes it |
| 118 | // once -- Godot's shader preprocessor honours the guard, measured. |
| 119 | src += String(PROC_SIMPLEX_GLSL); |
| 120 | src += "\n"; |
| 115 | 121 | src += glsl_source; |
| 116 | 122 | src += "\n"; |
| 117 | 123 | src += "uniform vec3 volume_origin = vec3(0.0);\n"; |
| … | … | @@ -119,10 +125,48 @@ String ProcVolume::build_fog_shader_code() const { |
| 119 | 125 | src += "uniform float edge_softness : hint_range(0.001, 100.0) = 4.0;\n"; |
| 120 | 126 | src += "uniform float density_scale : hint_range(0.0, 32.0) = 1.0;\n"; |
| 121 | 127 | src += "uniform vec4 volume_albedo : source_color = vec4(1.0, 1.0, 1.0, 1.0);\n"; |
| 122 | | src += "uniform vec3 volume_emission = vec3(0.0);\n\n"; |
| 128 | src += "uniform vec3 volume_emission = vec3(0.0);\n"; |
| 129 | // ── HEIGHT GRADIENT ───────────────────────────────────────────────────── |
| 130 | // Density falls to zero with ALTITUDE, so a cloud thins out at its top |
| 131 | // instead of ending on the SDF's hard shell. Both ends are uniforms: a |
| 132 | // cloud's shape and where it fades are different decisions, and baking the |
| 133 | // fade into the graph would mean recompiling to move it. |
| 134 | // |
| 135 | // WORLD y, not volume-local: "high up" is a property of the world, and a |
| 136 | // cloud moved upward should fade MORE, not carry its gradient with it. |
| 137 | src += "uniform float height_fade_start = 1e20;\n"; |
| 138 | src += "uniform float height_fade_range : hint_range(0.001, 4096.0) = 200.0;\n"; |
| 139 | // ── NOISE VARIABILITY ─────────────────────────────────────────────────── |
| 140 | // Modulates the density the SDF gives, so the volume is a formation rather |
| 141 | // than a smooth solid. Separate from any noise inside the graph: this one is |
| 142 | // tunable on the material without recompiling anything, and it can drift |
| 143 | // with TIME. |
| 144 | // |
| 145 | // ⚠ ps_fbm_noise_3d IS proc_simplex.inc -- the same text the CPU shim and |
| 146 | // the emitted GLSL compile. A second noise implementation for the fog path |
| 147 | // is precisely the divergence this repo spent months removing. |
| 148 | src += "uniform float noise_scale : hint_range(0.0, 1.0) = 0.02;\n"; |
| 149 | src += "uniform float noise_strength : hint_range(0.0, 1.0) = 0.0;\n"; |
| 150 | src += "uniform int noise_octaves : hint_range(1, 8) = 3;\n"; |
| 151 | src += "uniform float noise_drift = 0.0;\n"; |
| 152 | src += "uniform float noise_roughness : hint_range(0.0, 1.0) = 0.5;\n"; |
| 153 | src += "uniform float noise_lacunarity : hint_range(1.0, 4.0) = 2.0;\n\n"; |
| 123 | 154 | src += "void fog() {\n"; |
| 124 | | src += "\tfloat d = proc_density(WORLD_POSITION - volume_origin);\n"; |
| 125 | | src += "\tDENSITY = clamp((d - iso_level) / edge_softness, 0.0, 1.0) * density_scale;\n"; |
| 155 | src += "\tvec3 vp = WORLD_POSITION - volume_origin;\n"; |
| 156 | src += "\tfloat d = proc_density(vp);\n"; |
| 157 | src += "\tfloat dens = clamp((d - iso_level) / edge_softness, 0.0, 1.0);\n"; |
| 158 | src += "\n\t// Altitude fade. The default start is 1e20, so a material that\n"; |
| 159 | src += "\t// sets neither uniform behaves exactly as it did before this existed.\n"; |
| 160 | src += "\tfloat hf = (WORLD_POSITION.y - height_fade_start) / max(height_fade_range, 0.001);\n"; |
| 161 | src += "\tdens *= 1.0 - clamp(hf, 0.0, 1.0);\n"; |
| 162 | src += "\n\t// Noise. strength 0 is a no-op, so this is opt-in too.\n"; |
| 163 | src += "\tif (noise_strength > 0.0) {\n"; |
| 164 | src += "\t\tvec3 np = vp * noise_scale + vec3(noise_drift * TIME, 0.0, 0.0);\n"; |
| 165 | src += "\t\tfloat n = ps_fbm_noise_3d(np.x, np.y, np.z, noise_octaves,\n"; |
| 166 | src += "\t\t\t\tnoise_roughness, noise_lacunarity) * 0.5 + 0.5;\n"; |
| 167 | src += "\t\tdens *= mix(1.0, n, noise_strength);\n"; |
| 168 | src += "\t}\n"; |
| 169 | src += "\n\tDENSITY = dens * density_scale;\n"; |
| 126 | 170 | src += "\tALBEDO = volume_albedo.rgb;\n"; |
| 127 | 171 | src += "\tEMISSION = volume_emission;\n"; |
| 128 | 172 | src += "}\n"; |