Explorar el Código

LightProbeHelper: Add WebGPU version. (#29301)

* LightProbeHelper: Add WebGPU version.

* LightProbeHelperGPU: Clean up.
Michael Herzog hace 1 año
padre
commit
6b2b4796f7

+ 1 - 1
examples/jsm/helpers/LightProbeHelper.js

@@ -6,7 +6,7 @@ import {
 
 class LightProbeHelper extends Mesh {
 
-	constructor( lightProbe, size ) {
+	constructor( lightProbe, size = 1 ) {
 
 		const material = new ShaderMaterial( {
 

+ 61 - 0
examples/jsm/helpers/LightProbeHelperGPU.js

@@ -0,0 +1,61 @@
+import {
+	Mesh,
+	NodeMaterial,
+	SphereGeometry
+} from 'three';
+import { float, Fn, getShIrradianceAt, normalWorld, uniformArray, uniform, vec4 } from 'three/tsl';
+
+class LightProbeHelper extends Mesh {
+
+	constructor( lightProbe, size = 1 ) {
+
+		const sh = uniformArray( lightProbe.sh.coefficients );
+		const intensity = uniform( lightProbe.intensity );
+
+		const RECIPROCAL_PI = float( 1 / Math.PI );
+
+		const fragmentNode = Fn( () => {
+
+			const irradiance = getShIrradianceAt( normalWorld, sh );
+
+			const outgoingLight = RECIPROCAL_PI.mul( irradiance ).mul( intensity );
+
+			return vec4( outgoingLight, 1.0 );
+
+		} )();
+
+		const material = new NodeMaterial();
+		material.fragmentNode = fragmentNode;
+
+		const geometry = new SphereGeometry( 1, 32, 16 );
+
+		super( geometry, material );
+
+		this.lightProbe = lightProbe;
+		this.size = size;
+		this.type = 'LightProbeHelper';
+
+		this._intensity = intensity;
+
+		this.onBeforeRender();
+
+	}
+
+	dispose() {
+
+		this.geometry.dispose();
+		this.material.dispose();
+
+	}
+
+	onBeforeRender() {
+
+		this.position.copy( this.lightProbe.position );
+
+		this.scale.set( 1, 1, 1 ).multiplyScalar( this.size );
+
+	}
+
+}
+
+export { LightProbeHelper };

+ 1 - 0
src/nodes/TSL.js

@@ -171,3 +171,4 @@ export * from './lighting/LightUtils.js';
 
 export { default as getGeometryRoughness } from './functions/material/getGeometryRoughness.js';
 export { default as getRoughness } from './functions/material/getRoughness.js';
+export { default as getShIrradianceAt } from './functions/material/getShIrradianceAt.js';

+ 28 - 0
src/nodes/functions/material/getShIrradianceAt.js

@@ -0,0 +1,28 @@
+import { Fn, mul } from '../../tsl/TSLBase.js';
+
+const getShIrradianceAt = /*@__PURE__*/ Fn( ( [ normal, shCoefficients ] ) => {
+
+	// normal is assumed to have unit length
+
+	const x = normal.x, y = normal.y, z = normal.z;
+
+	// band 0
+	let result = shCoefficients.element( 0 ).mul( 0.886227 );
+
+	// band 1
+	result = result.add( shCoefficients.element( 1 ).mul( 2.0 * 0.511664 ).mul( y ) );
+	result = result.add( shCoefficients.element( 2 ).mul( 2.0 * 0.511664 ).mul( z ) );
+	result = result.add( shCoefficients.element( 3 ).mul( 2.0 * 0.511664 ).mul( x ) );
+
+	// band 2
+	result = result.add( shCoefficients.element( 4 ).mul( 2.0 * 0.429043 ).mul( x ).mul( y ) );
+	result = result.add( shCoefficients.element( 5 ).mul( 2.0 * 0.429043 ).mul( y ).mul( z ) );
+	result = result.add( shCoefficients.element( 6 ).mul( z.mul( z ).mul( 0.743125 ).sub( 0.247708 ) ) );
+	result = result.add( shCoefficients.element( 7 ).mul( 2.0 * 0.429043 ).mul( x ).mul( z ) );
+	result = result.add( shCoefficients.element( 8 ).mul( 0.429043 ).mul( mul( x, x ).sub( mul( y, y ) ) ) );
+
+	return result;
+
+} );
+
+export default getShIrradianceAt;

+ 2 - 28
src/nodes/lighting/LightProbeNode.js

@@ -1,9 +1,8 @@
 import AnalyticLightNode from './AnalyticLightNode.js';
 import { normalWorld } from '../accessors/Normal.js';
 import { uniformArray } from '../accessors/UniformArrayNode.js';
-import { Fn } from '../tsl/TSLBase.js';
-import { mul } from '../math/OperatorNode.js';
 import { Vector3 } from '../../math/Vector3.js';
+import getShIrradianceAt from '../functions/material/getShIrradianceAt.js';
 
 class LightProbeNode extends AnalyticLightNode {
 
@@ -43,7 +42,7 @@ class LightProbeNode extends AnalyticLightNode {
 
 	setup( builder ) {
 
-		const irradiance = shGetIrradianceAt( normalWorld, this.lightProbe );
+		const irradiance = getShIrradianceAt( normalWorld, this.lightProbe );
 
 		builder.context.irradiance.addAssign( irradiance );
 
@@ -52,28 +51,3 @@ class LightProbeNode extends AnalyticLightNode {
 }
 
 export default LightProbeNode;
-
-const shGetIrradianceAt = /*@__PURE__*/ Fn( ( [ normal, shCoefficients ] ) => {
-
-	// normal is assumed to have unit length
-
-	const x = normal.x, y = normal.y, z = normal.z;
-
-	// band 0
-	const result = shCoefficients.element( 0 ).mul( 0.886227 );
-
-	// band 1
-	result.addAssign( shCoefficients.element( 1 ).mul( 2.0 * 0.511664 ).mul( y ) );
-	result.addAssign( shCoefficients.element( 2 ).mul( 2.0 * 0.511664 ).mul( z ) );
-	result.addAssign( shCoefficients.element( 3 ).mul( 2.0 * 0.511664 ).mul( x ) );
-
-	// band 2
-	result.addAssign( shCoefficients.element( 4 ).mul( 2.0 * 0.429043 ).mul( x ).mul( y ) );
-	result.addAssign( shCoefficients.element( 5 ).mul( 2.0 * 0.429043 ).mul( y ).mul( z ) );
-	result.addAssign( shCoefficients.element( 6 ).mul( z.mul( z ).mul( 0.743125 ).sub( 0.247708 ) ) );
-	result.addAssign( shCoefficients.element( 7 ).mul( 2.0 * 0.429043 ).mul( x ).mul( z ) );
-	result.addAssign( shCoefficients.element( 8 ).mul( 0.429043 ).mul( mul( x, x ).sub( mul( y, y ) ) ) );
-
-	return result;
-
-} );

粤ICP备19079148号