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
refreshFogUniforms
method that behaves like the one inWebGLMaterials
but 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 )