Three's fog is very hardcoded in both the engine internals and the shaders:
- https://github.com/mrdoob/three.js/blob/dev/src/scenes/Fog.js
- https://github.com/mrdoob/three.js/blob/dev/src/scenes/FogExp2.js
- https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/fog_fragment.glsl.js
- https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl.js
A custom fog can't setup custom shaders or custom uniforms. While the shaders are "hackable" by overriding the globals, uniforms aren't since we can't override the refreshFogUniforms method.
Uniforms are copied to shaders here:
function refreshFogUniforms( uniforms, fog ) {
uniforms.fogColor.value.copy( fog.color );
if ( fog.isFog ) {
uniforms.fogNear.value = fog.near;
uniforms.fogFar.value = fog.far;
} else if ( fog.isFogExp2 ) {
uniforms.fogDensity.value = fog.density;
}
}- which is called here https://github.com/mrdoob/three.js/blob/2d9a9f0b546aaf22dc0dcbfe56402bee075b9509/src/renderers/WebGLRenderer.js#L1755-L1759
if ( fog && material.fog === true ) {
materials.refreshFogUniforms( m_uniforms, fog );
}The Fog classes (Fog and FogExp2) are effectively only used to hold configuration and a single flag used in shader compilation.
New Fog class:
- it holds the specific fog shaders in an object ( eg.
this.shaders.fog_fragment) - it has a
refreshFogUniformsmethod that behaves like the one inWebGLMaterialsbut only cares about the specific fog type. - it holds uniform values
WebGLRenderer would NOT call a method on the materials object, calling one on the scene's fog instead:
if ( fog && material.fog === true ) {
fog.refreshFogUniforms( m_uniforms, materials );
}- Fog and FogExp2 should keep working as they do now.
- can they be even kept in the same codepaths ( ie. the fog shader stays where it is, only new fog types add on to it )