Skip to content

Commit 8d55664

Browse files
authored
TSL: Improve fog approach. (mrdoob#30080)
1 parent cfd6985 commit 8d55664

File tree

14 files changed

+121
-251
lines changed

14 files changed

+121
-251
lines changed

examples/webgpu_custom_fog_background.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<script type="module">
3737

3838
import * as THREE from 'three';
39-
import { pass, color, rangeFog } from 'three/tsl';
39+
import { pass, color, rangeFogFactor } from 'three/tsl';
4040

4141
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
4242

@@ -75,7 +75,7 @@
7575

7676
// get fog factor from scene pass context
7777
// equivalent to: scene.fog = new THREE.Fog( 0x0066ff, 2.7, 4 );
78-
const fogFactor = rangeFog( null, 2.7, 4 ).context( { getViewZ: () => scenePassViewZ } );
78+
const fogFactor = rangeFogFactor( 2.7, 4 ).context( { getViewZ: () => scenePassViewZ } );
7979

8080
// tone mapping scene pass
8181
const scenePassTM = scenePass.toneMapping( THREE.ACESFilmicToneMapping );

examples/webgpu_lights_phong.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<script type="module">
2828

2929
import * as THREE from 'three';
30-
import { color, rangeFog, checker, uv, mix, texture, lights, normalMap } from 'three/tsl';
30+
import { color, fog, rangeFogFactor, checker, uv, mix, texture, lights, normalMap } from 'three/tsl';
3131

3232
import Stats from 'three/addons/libs/stats.module.js';
3333

@@ -46,7 +46,7 @@
4646
camera.position.z = 7;
4747

4848
scene = new THREE.Scene();
49-
scene.fogNode = rangeFog( color( 0xFF00FF ), 12, 30 );
49+
scene.fogNode = fog( color( 0xFF00FF ), rangeFogFactor( 12, 30 ) );
5050

5151
const sphereGeometry = new THREE.SphereGeometry( 0.1, 16, 8 );
5252

examples/webgpu_lights_selective.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<script type="module">
2828

2929
import * as THREE from 'three';
30-
import { rangeFog, color, lights, texture, normalMap } from 'three/tsl';
30+
import { fog, rangeFogFactor, color, lights, texture, normalMap } from 'three/tsl';
3131

3232
import Stats from 'three/addons/libs/stats.module.js';
3333

@@ -48,7 +48,7 @@
4848
camera.position.z = 7;
4949

5050
scene = new THREE.Scene();
51-
scene.fogNode = rangeFog( color( 0xFF00FF ), 12, 30 );
51+
scene.fogNode = fog( color( 0xFF00FF ), rangeFogFactor( 12, 30 ) );
5252

5353
const sphereGeometry = new THREE.SphereGeometry( 0.1, 16, 8 );
5454

examples/webgpu_particles.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
camera.position.set( 1300, 500, 0 );
4545

4646
scene = new THREE.Scene();
47-
//scene.fogNode = rangeFog( color( 0x0000ff ), 1500, 2100 );
4847

4948
// textures
5049

examples/webgpu_sprites.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<script type="module">
2626

2727
import * as THREE from 'three';
28-
import { texture, uv, userData, rangeFog, color } from 'three/tsl';
28+
import { texture, uv, userData, fog, rangeFogFactor, color } from 'three/tsl';
2929

3030
let camera, scene, renderer;
3131

@@ -46,7 +46,7 @@
4646
camera.position.z = 1500;
4747

4848
scene = new THREE.Scene();
49-
scene.fogNode = rangeFog( color( 0x0000ff ), 1500, 2100 );
49+
scene.fogNode = fog( color( 0x0000ff ), rangeFogFactor( 1500, 2100 ) );
5050

5151
// create sprites
5252

src/Three.TSL.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export const defined = TSL.defined;
131131
export const degrees = TSL.degrees;
132132
export const deltaTime = TSL.deltaTime;
133133
export const densityFog = TSL.densityFog;
134+
export const densityFogFactor = TSL.densityFogFactor;
134135
export const depth = TSL.depth;
135136
export const depthPass = TSL.depthPass;
136137
export const difference = TSL.difference;
@@ -370,6 +371,7 @@ export const radians = TSL.radians;
370371
export const rand = TSL.rand;
371372
export const range = TSL.range;
372373
export const rangeFog = TSL.rangeFog;
374+
export const rangeFogFactor = TSL.rangeFogFactor;
373375
export const reciprocal = TSL.reciprocal;
374376
export const reference = TSL.reference;
375377
export const referenceBuffer = TSL.referenceBuffer;

src/materials/nodes/NodeMaterial.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,13 @@ class NodeMaterial extends Material {
576576

577577
const fogNode = builder.fogNode;
578578

579-
if ( fogNode ) outputNode = vec4( fogNode.mix( outputNode.rgb, fogNode.colorNode ), outputNode.a );
579+
if ( fogNode ) {
580+
581+
const fog = vec4( fogNode );
582+
583+
outputNode = vec4( fog.a.mix( outputNode.rgb, fog.rgb ), outputNode.a );
584+
585+
}
580586

581587
}
582588

src/nodes/Nodes.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,6 @@ export { default as FunctionNode } from './code/FunctionNode.js';
104104
export { default as ScriptableNode } from './code/ScriptableNode.js';
105105
export { default as ScriptableValueNode } from './code/ScriptableValueNode.js';
106106

107-
// fog
108-
export { default as FogNode } from './fog/FogNode.js';
109-
export { default as FogRangeNode } from './fog/FogRangeNode.js';
110-
export { default as FogExp2Node } from './fog/FogExp2Node.js';
111-
112107
// geometry
113108
export { default as RangeNode } from './geometry/RangeNode.js';
114109

src/nodes/TSL.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,7 @@ export * from './code/ScriptableNode.js';
115115
export * from './code/ScriptableValueNode.js';
116116

117117
// fog
118-
export * from './fog/FogNode.js';
119-
export * from './fog/FogRangeNode.js';
120-
export * from './fog/FogExp2Node.js';
118+
export * from './fog/Fog.js';
121119

122120
// geometry
123121
export * from './geometry/RangeNode.js';

src/nodes/fog/Fog.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { positionView } from '../accessors/Position.js';
2+
import { smoothstep } from '../math/MathNode.js';
3+
import { Fn, vec4 } from '../tsl/TSLBase.js';
4+
5+
/**
6+
* Returns a node that represents the `z` coordinate in view space
7+
* for the current fragment. It's a different representation of the
8+
* default depth value.
9+
*
10+
* This value can be part of a computation that defines how the fog
11+
* density increases when moving away from the camera.
12+
*
13+
* @param {NodeBuilder} builder - The current node builder.
14+
* @return {Node} The viewZ node.
15+
*/
16+
function getViewZNode( builder ) {
17+
18+
let viewZ;
19+
20+
const getViewZ = builder.context.getViewZ;
21+
22+
if ( getViewZ !== undefined ) {
23+
24+
viewZ = getViewZ( this );
25+
26+
}
27+
28+
return ( viewZ || positionView.z ).negate();
29+
30+
}
31+
32+
/**
33+
* Constructs a new range factor node.
34+
*
35+
* @param {Node} near - Defines the near value.
36+
* @param {Node} far - Defines the far value.
37+
*/
38+
export const rangeFogFactor = Fn( ( [ near, far ], builder ) => {
39+
40+
const viewZ = getViewZNode( builder );
41+
42+
return smoothstep( near, far, viewZ );
43+
44+
} );
45+
46+
/**
47+
* Represents an exponential squared fog. This type of fog gives
48+
* a clear view near the camera and a faster than exponentially
49+
* densening fog farther from the camera.
50+
*
51+
* @param {Node} density - Defines the fog density.
52+
*/
53+
export const densityFogFactor = Fn( ( [ density ], builder ) => {
54+
55+
const viewZ = getViewZNode( builder );
56+
57+
return density.mul( density, viewZ, viewZ ).negate().exp().oneMinus();
58+
59+
} );
60+
61+
/**
62+
* This class can be used to configure a fog for the scene.
63+
* Nodes of this type are assigned to `Scene.fogNode`.
64+
*
65+
* @param {Node} color - Defines the color of the fog.
66+
* @param {Node} factor - Defines how the fog is factored in the scene.
67+
*/
68+
export const fog = Fn( ( [ color, factor ] ) => {
69+
70+
return vec4( color.toVec3(), factor.toFloat() );
71+
72+
} );
73+
74+
// Deprecated
75+
76+
export function rangeFog( color, near, far ) { // @deprecated, r171
77+
78+
console.warn( 'THREE.TSL: "rangeFog( color, near, far )" is deprecated. Use "fog( color, rangeFog( near, far ) )" instead.' );
79+
return fog( color, rangeFogFactor( near, far ) );
80+
81+
}
82+
83+
export function densityFog( color, density ) { // @deprecated, r171
84+
85+
console.warn( 'THREE.TSL: "densityFog( color, density )" is deprecated. Use "fog( color, densityFogFactor( density ) )" instead.' );
86+
return fog( color, densityFogFactor( density ) );
87+
88+
}

0 commit comments

Comments
 (0)