Просмотр исходного кода

Addons: Removed `TiledLighting` (#33751)

sunag 1 неделя назад
Родитель
Сommit
8a03dbdfb8

+ 0 - 1
examples/files.json

@@ -366,7 +366,6 @@
 		"webgpu_lights_rectarealight",
 		"webgpu_lights_selective",
 		"webgpu_lights_spotlight",
-		"webgpu_lights_tiled",
 		"webgpu_lines_fat_raycasting",
 		"webgpu_lines_fat_wireframe",
 		"webgpu_lines_fat",

+ 0 - 42
examples/jsm/lighting/TiledLighting.js

@@ -1,42 +0,0 @@
-import { Lighting } from 'three/webgpu';
-import { tiledLights } from '../tsl/lighting/TiledLightsNode.js';
-
-/**
- * A custom lighting implementation based on Tiled-Lighting that overwrites the default
- * implementation in {@link WebGPURenderer}.
- *
- * ```js
- * const lighting = new TiledLighting();
- * renderer.lighting = lighting; // set lighting system
- * ```
- *
- * @augments Lighting
- * @three_import import { TiledLighting } from 'three/addons/lighting/TiledLighting.js';
- */
-export class TiledLighting extends Lighting {
-
-	/**
-	 * Constructs a new lighting system.
-	 */
-	constructor() {
-
-		super();
-
-	}
-
-	/**
-	 * Creates a new tiled lights node for the given array of lights.
-	 *
-	 * This method is called internally by the renderer and must be overwritten by
-	 * all custom lighting implementations.
-	 *
-	 * @param {Array<Light>} lights - The render object.
-	 * @return {TiledLightsNode} The tiled lights node.
-	 */
-	createNode( lights = [] ) {
-
-		return tiledLights().setLights( lights );
-
-	}
-
-}

+ 0 - 442
examples/jsm/tsl/lighting/TiledLightsNode.js

@@ -1,442 +0,0 @@
-import { DataTexture, FloatType, RGBAFormat, Vector2, Vector3, LightsNode, NodeUpdateType } from 'three/webgpu';
-
-import {
-	attributeArray, nodeProxy, int, float, vec2, ivec2, ivec4, uniform, Break, Loop, positionView,
-	Fn, If, Return, textureLoad, instanceIndex, screenCoordinate, directPointLight
-} from 'three/tsl';
-
-/**
- * TSL function that checks if a circle intersects with an axis-aligned bounding box (AABB).
- *
- * @tsl
- * @function
- * @param {Node<vec2>} circleCenter - The center of the circle.
- * @param {Node<float>} radius - The radius of the circle.
- * @param {Node<vec2>} minBounds - The minimum bounds of the AABB.
- * @param {Node<vec2>} maxBounds - The maximum bounds of the AABB.
- * @return {Node<bool>} True if the circle intersects the AABB.
- */
-export const circleIntersectsAABB = /*@__PURE__*/ Fn( ( [ circleCenter, radius, minBounds, maxBounds ] ) => {
-
-	// Find the closest point on the AABB to the circle's center using method chaining
-	const closestX = minBounds.x.max( circleCenter.x.min( maxBounds.x ) );
-	const closestY = minBounds.y.max( circleCenter.y.min( maxBounds.y ) );
-
-	// Compute the distance between the circle's center and the closest point
-	const distX = circleCenter.x.sub( closestX );
-	const distY = circleCenter.y.sub( closestY );
-
-	// Calculate the squared distance
-	const distSquared = distX.mul( distX ).add( distY.mul( distY ) );
-
-	return distSquared.lessThanEqual( radius.mul( radius ) );
-
-} ).setLayout( {
-	name: 'circleIntersectsAABB',
-	type: 'bool',
-	inputs: [
-		{ name: 'circleCenter', type: 'vec2' },
-		{ name: 'radius', type: 'float' },
-		{ name: 'minBounds', type: 'vec2' },
-		{ name: 'maxBounds', type: 'vec2' }
-	]
-} );
-
-const _vector3 = /*@__PURE__*/ new Vector3();
-const _size = /*@__PURE__*/ new Vector2();
-
-/**
- * A custom version of `LightsNode` implementing tiled lighting. This node is used in
- * {@link TiledLighting} to overwrite the renderer's default lighting with
- * a custom implementation.
- *
- * @augments LightsNode
- * @three_import import { tiledLights } from 'three/addons/tsl/lighting/TiledLightsNode.js';
- */
-class TiledLightsNode extends LightsNode {
-
-	static get type() {
-
-		return 'TiledLightsNode';
-
-	}
-
-	/**
-	 * Constructs a new tiled lights node.
-	 *
-	 * @param {number} [maxLights=1024] - The maximum number of lights.
-	 * @param {number} [tileSize=32] - The tile size.
-	 */
-	constructor( maxLights = 1024, tileSize = 32 ) {
-
-		super();
-
-		this.materialLights = [];
-		this.tiledLights = [];
-
-		/**
-		 * The maximum number of lights.
-		 *
-		 * @type {number}
-		 * @default 1024
-		 */
-		this.maxLights = maxLights;
-
-		/**
-		 * The tile size.
-		 *
-		 * @type {number}
-		 * @default 32
-		 */
-		this.tileSize = tileSize;
-
-		this._bufferSize = null;
-		this._lightIndexes = null;
-		this._screenTileIndex = null;
-		this._compute = null;
-		this._lightsTexture = null;
-
-		this._lightsCount = uniform( 0, 'int' );
-		this._tileLightCount = 8;
-		this._screenSize = uniform( new Vector2() );
-		this._cameraProjectionMatrix = uniform( 'mat4' );
-		this._cameraViewMatrix = uniform( 'mat4' );
-
-		this.updateBeforeType = NodeUpdateType.RENDER;
-
-	}
-
-	customCacheKey() {
-
-		return this._compute.getCacheKey() + super.customCacheKey();
-
-	}
-
-	updateLightsTexture() {
-
-		const { _lightsTexture: lightsTexture, tiledLights } = this;
-
-		const data = lightsTexture.image.data;
-		const lineSize = lightsTexture.image.width * 4;
-
-		this._lightsCount.value = tiledLights.length;
-
-		for ( let i = 0; i < tiledLights.length; i ++ ) {
-
-			const light = tiledLights[ i ];
-
-			// world position
-
-			_vector3.setFromMatrixPosition( light.matrixWorld );
-
-			// store data
-
-			const offset = i * 4;
-
-			data[ offset + 0 ] = _vector3.x;
-			data[ offset + 1 ] = _vector3.y;
-			data[ offset + 2 ] = _vector3.z;
-			data[ offset + 3 ] = light.distance;
-
-			data[ lineSize + offset + 0 ] = light.color.r * light.intensity;
-			data[ lineSize + offset + 1 ] = light.color.g * light.intensity;
-			data[ lineSize + offset + 2 ] = light.color.b * light.intensity;
-			data[ lineSize + offset + 3 ] = light.decay;
-
-		}
-
-		lightsTexture.needsUpdate = true;
-
-	}
-
-	updateBefore( frame ) {
-
-		const { renderer, camera } = frame;
-
-		this.updateProgram( renderer );
-
-		this.updateLightsTexture( camera );
-
-		this._cameraProjectionMatrix.value = camera.projectionMatrix;
-		this._cameraViewMatrix.value = camera.matrixWorldInverse;
-
-		renderer.getDrawingBufferSize( _size );
-		this._screenSize.value.copy( _size );
-
-		renderer.compute( this._compute );
-
-	}
-
-	setLights( lights ) {
-
-		const { tiledLights, materialLights } = this;
-
-		let materialindex = 0;
-		let tiledIndex = 0;
-
-		for ( const light of lights ) {
-
-			if ( light.isPointLight === true ) {
-
-				tiledLights[ tiledIndex ++ ] = light;
-
-			} else {
-
-				materialLights[ materialindex ++ ] = light;
-
-			}
-
-		}
-
-		materialLights.length = materialindex;
-		tiledLights.length = tiledIndex;
-
-		return super.setLights( materialLights );
-
-	}
-
-	getBlock( block = 0 ) {
-
-		return this._lightIndexes.element( this._screenTileIndex.mul( int( 2 ).add( int( block ) ) ) );
-
-	}
-
-	getTile( element ) {
-
-		element = int( element );
-
-		const stride = int( 4 );
-		const tileOffset = element.div( stride );
-		const tileIndex = this._screenTileIndex.mul( int( 2 ) ).add( tileOffset );
-
-		return this._lightIndexes.element( tileIndex ).element( element.mod( stride ) );
-
-	}
-
-	getLightData( index ) {
-
-		index = int( index );
-
-		const dataA = textureLoad( this._lightsTexture, ivec2( index, 0 ) );
-		const dataB = textureLoad( this._lightsTexture, ivec2( index, 1 ) );
-
-		const position = dataA.xyz;
-		const viewPosition = this._cameraViewMatrix.mul( position );
-		const distance = dataA.w;
-		const color = dataB.rgb;
-		const decay = dataB.w;
-
-		return {
-			position,
-			viewPosition,
-			distance,
-			color,
-			decay
-		};
-
-	}
-
-	setupLights( builder, lightNodes ) {
-
-		this.updateProgram( builder.renderer );
-
-		//
-
-		const lightingModel = builder.context.reflectedLight;
-
-		// force declaration order, before of the loop
-		lightingModel.directDiffuse.toStack();
-		lightingModel.directSpecular.toStack();
-
-		super.setupLights( builder, lightNodes );
-
-		Fn( () => {
-
-			Loop( this._tileLightCount, ( { i } ) => {
-
-				const lightIndex = this.getTile( i );
-
-				If( lightIndex.equal( int( 0 ) ), () => {
-
-					Break();
-
-				} );
-
-				const { color, decay, viewPosition, distance } = this.getLightData( lightIndex.sub( 1 ) );
-
-				builder.lightsNode.setupDirectLight( builder, this, directPointLight( {
-					color,
-					lightVector: viewPosition.sub( positionView ),
-					cutoffDistance: distance,
-					decayExponent: decay
-				} ) );
-
-			} );
-
-		}, 'void' )();
-
-	}
-
-	getBufferFitSize( value ) {
-
-		const multiple = this.tileSize;
-
-		return Math.ceil( value / multiple ) * multiple;
-
-	}
-
-	setSize( width, height ) {
-
-		width = this.getBufferFitSize( width );
-		height = this.getBufferFitSize( height );
-
-		if ( ! this._bufferSize || this._bufferSize.width !== width || this._bufferSize.height !== height ) {
-
-			this.create( width, height );
-
-		}
-
-		return this;
-
-	}
-
-	updateProgram( renderer ) {
-
-		renderer.getDrawingBufferSize( _size );
-
-		const width = this.getBufferFitSize( _size.width );
-		const height = this.getBufferFitSize( _size.height );
-
-		if ( this._bufferSize === null ) {
-
-			this.create( width, height );
-
-		} else if ( this._bufferSize.width !== width || this._bufferSize.height !== height ) {
-
-			this.create( width, height );
-
-		}
-
-	}
-
-	create( width, height ) {
-
-		const { tileSize, maxLights } = this;
-
-		const bufferSize = new Vector2( width, height );
-		const lineSize = Math.floor( bufferSize.width / tileSize );
-		const count = Math.floor( ( bufferSize.width * bufferSize.height ) / tileSize );
-
-		// buffers
-
-		const lightsData = new Float32Array( maxLights * 4 * 2 ); // 2048 lights, 4 elements(rgba), 2 components, 1 component per line (position, distance, color, decay)
-		const lightsTexture = new DataTexture( lightsData, lightsData.length / 8, 2, RGBAFormat, FloatType );
-
-		const lightIndexesArray = new Int32Array( count * 4 * 2 );
-		const lightIndexes = attributeArray( lightIndexesArray, 'ivec4' ).setName( 'lightIndexes' );
-
-		// compute
-
-		const getBlock = ( index ) => {
-
-			const tileIndex = instanceIndex.mul( int( 2 ) ).add( int( index ) );
-
-			return lightIndexes.element( tileIndex );
-
-		};
-
-		const getTile = ( elementIndex ) => {
-
-			elementIndex = int( elementIndex );
-
-			const stride = int( 4 );
-			const tileOffset = elementIndex.div( stride );
-			const tileIndex = instanceIndex.mul( int( 2 ) ).add( tileOffset );
-
-			return lightIndexes.element( tileIndex ).element( elementIndex.mod( stride ) );
-
-		};
-
-		const compute = Fn( () => {
-
-			const { _cameraProjectionMatrix: cameraProjectionMatrix, _bufferSize: bufferSize, _screenSize: screenSize } = this;
-
-			const tiledBufferSize = bufferSize.clone().divideScalar( tileSize ).floor();
-
-			const tileScreen = vec2(
-				instanceIndex.mod( tiledBufferSize.width ),
-				instanceIndex.div( tiledBufferSize.width )
-			).mul( tileSize ).div( screenSize );
-
-			const blockSize = float( tileSize ).div( screenSize );
-			const minBounds = tileScreen;
-			const maxBounds = minBounds.add( blockSize );
-
-			const index = int( 0 ).toVar();
-
-			getBlock( 0 ).assign( ivec4( 0 ) );
-			getBlock( 1 ).assign( ivec4( 0 ) );
-
-			Loop( this.maxLights, ( { i } ) => {
-
-				If( index.greaterThanEqual( this._tileLightCount ).or( int( i ).greaterThanEqual( int( this._lightsCount ) ) ), () => {
-
-					Return();
-
-				} );
-
-				const { viewPosition, distance } = this.getLightData( i );
-
-				const projectedPosition = cameraProjectionMatrix.mul( viewPosition );
-				const ndc = projectedPosition.div( projectedPosition.w );
-				const screenPosition = ndc.xy.mul( 0.5 ).add( 0.5 ).flipY();
-
-				const distanceFromCamera = viewPosition.z;
-				const pointRadius = distance.div( distanceFromCamera );
-
-				If( circleIntersectsAABB( screenPosition, pointRadius, minBounds, maxBounds ), () => {
-
-					getTile( index ).assign( i.add( int( 1 ) ) );
-					index.addAssign( int( 1 ) );
-
-				} );
-
-			} );
-
-		} )().compute( count ).setName( 'Update Tiled Lights' );
-
-		// screen coordinate lighting indexes
-
-		const screenTile = screenCoordinate.div( tileSize ).floor().toVar();
-		const screenTileIndex = screenTile.x.add( screenTile.y.mul( lineSize ) );
-
-		// assigns
-
-		this._bufferSize = bufferSize;
-		this._lightIndexes = lightIndexes;
-		this._screenTileIndex = screenTileIndex;
-		this._compute = compute;
-		this._lightsTexture = lightsTexture;
-
-	}
-
-	get hasLights() {
-
-		return super.hasLights || this.tiledLights.length > 0;
-
-	}
-
-}
-
-export default TiledLightsNode;
-
-/**
- * TSL function that creates a tiled lights node.
- *
- * @tsl
- * @function
- * @param {number} [maxLights=1024] - The maximum number of lights.
- * @param {number} [tileSize=32] - The tile size.
- * @return {TiledLightsNode} The tiled lights node.
- */
-export const tiledLights = /*@__PURE__*/ nodeProxy( TiledLightsNode );

BIN
examples/screenshots/webgpu_lights_tiled.jpg


+ 0 - 240
examples/webgpu_lights_tiled.html

@@ -1,240 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgpu - tiled lighting</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<meta property="og:title" content="three.js webgpu - tiled lighting">
-		<meta property="og:type" content="website">
-		<meta property="og:url" content="https://threejs.org/examples/webgpu_lights_tiled.html">
-		<meta property="og:image" content="https://threejs.org/examples/screenshots/webgpu_lights_tiled.jpg">
-		<link type="text/css" rel="stylesheet" href="example.css">
-	</head>
-	<body>
-
-		<div id="info">
-			<a href="https://threejs.org/" target="_blank" rel="noopener" class="logo-link"></a>
-
-			<div class="title-wrapper">
-				<a href="https://threejs.org/" target="_blank" rel="noopener">three.js</a><span>Tiled Lighting</span>
-			</div>
-
-			<small>
-				Custom compute-based Tiled Lighting.
-			</small>
-		</div>
-
-		<script type="importmap">
-			{
-				"imports": {
-					"three": "../build/three.webgpu.js",
-					"three/webgpu": "../build/three.webgpu.js",
-					"three/tsl": "../build/three.tsl.js",
-					"three/addons/": "./jsm/"
-				}
-			}
-		</script>
-
-		<script type="module">
-
-			import * as THREE from 'three/webgpu';
-			import { texture, uv, pass, normalMap, uniform } from 'three/tsl';
-			import { bloom } from 'three/addons/tsl/display/BloomNode.js';
-
-			import { TiledLighting } from 'three/addons/lighting/TiledLighting.js';
-
-			import { Inspector } from 'three/addons/inspector/Inspector.js';
-
-			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
-
-			import WebGPU from 'three/addons/capabilities/WebGPU.js';
-
-			let camera, scene, renderer,
-				lights, lightDummy,
-				controls,
-				compose, tileInfluence,
-				lighting,
-				count,
-				renderPipeline;
-
-			init();
-
-			function init() {
-
-				if ( WebGPU.isAvailable() === false ) {
-
-					document.body.appendChild( WebGPU.getErrorMessage() );
-
-					throw new Error( 'No WebGPU support' );
-
-				}
-
-				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 600 );
-				camera.position.z = 200;
-				camera.position.y = 30;
-
-				scene = new THREE.Scene();
-				scene.fog = new THREE.Fog( 0x111111, 300, 500 );
-				scene.background = new THREE.Color( 0x111111 );
-
-				count = 1000;
-
-				const material = new THREE.MeshBasicMaterial();
-
-				lightDummy = new THREE.InstancedMesh( new THREE.SphereGeometry( 0.1, 16, 8 ), material, count );
-				lightDummy.instanceMatrix.setUsage( THREE.DynamicDrawUsage );
-				scene.add( lightDummy );
-
-				// lights
-
-				lights = new THREE.Group();
-				scene.add( lights );
-
-				const addLight = ( hexColor, power = 10, distance = 3 ) => {
-
-					const light = new THREE.PointLight( hexColor, 1, distance );
-					light.position.set( Math.random() * 300 - 150, 1, Math.random() * 300 - 150 );
-					light.power = power;
-					light.userData.fixedPosition = light.position.clone();
-					lights.add( light );
-
-					return light;
-
-				};
-
-				const color = new THREE.Color();
-
-				for ( let i = 0; i < count; i ++ ) {
-
-					const hex = ( Math.random() * 0xffffff ) + 0x666666;
-
-					lightDummy.setColorAt( i, color.setHex( hex ) );
-
-					addLight( hex );
-
-				}
-
-				//
-
-				const lightAmbient = new THREE.AmbientLight( 0xffffff, .1 );
-				scene.add( lightAmbient );
-
-				// textures
-
-				const textureLoader = new THREE.TextureLoader();
-
-				const floorColor = textureLoader.load( 'textures/floors/FloorsCheckerboard_S_Diffuse.jpg' );
-				floorColor.wrapS = THREE.RepeatWrapping;
-				floorColor.wrapT = THREE.RepeatWrapping;
-				floorColor.colorSpace = THREE.SRGBColorSpace;
-
-				const floorNormal = textureLoader.load( 'textures/floors/FloorsCheckerboard_S_Normal.jpg' );
-				floorNormal.wrapS = THREE.RepeatWrapping;
-				floorNormal.wrapT = THREE.RepeatWrapping;
-
-				const uvTile = uv().mul( 50 );
-
-				const planeGeometry = new THREE.PlaneGeometry( 1000, 1000 );
-				const planeMaterial = new THREE.MeshPhongNodeMaterial( {
-					colorNode: texture( floorColor, uvTile ),
-					normalNode: normalMap( texture( floorNormal, uvTile ) ),
-				} );
-
-				const ground = new THREE.Mesh( planeGeometry, planeMaterial );
-				ground.rotation.x = - Math.PI / 2;
-				ground.position.y = 0;
-				ground.castShadow = true;
-				ground.receiveShadow = true;
-				scene.add( ground );
-
-				// renderer
-
-				lighting = new TiledLighting(); // ( maxLights = 1024, tileSize = 32 )
-
-				renderer = new THREE.WebGPURenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.setAnimationLoop( animate );
-				renderer.lighting = lighting; // set lighting system
-				renderer.toneMapping = THREE.NeutralToneMapping;
-				renderer.toneMappingExposure = 5;
-				renderer.inspector = new Inspector();
-				document.body.appendChild( renderer.domElement );
-
-				// controls
-
-				controls = new OrbitControls( camera, renderer.domElement );
-				controls.maxDistance = 400;
-
-				// events
-
-				window.addEventListener( 'resize', onWindowResize );
-
-				// post processing
-
-				const scenePass = pass( scene, camera );
-				const bloomPass = bloom( scenePass, 3, .9, .2 );
-
-				// compose
-
-				compose = scenePass.add( bloomPass );
-				tileInfluence = uniform( 0 );
-
-				renderPipeline = new THREE.RenderPipeline( renderer );
-
-				updatePostProcessing();
-
-				// gui
-
-				const gui = renderer.inspector.createParameters( 'Settings' );
-				gui.add( tileInfluence, 'value', 0, 1 ).name( 'tile indexes debug' );
-
-			}
-
-			function updatePostProcessing() {
-
-				// tile indexes debug, needs to be updated every time the renderer size changes
-
-				const debugBlockIndexes = lighting.getNode( scene ).setSize( window.innerWidth * window.devicePixelRatio, window.innerHeight * window.devicePixelRatio ).getBlock().toColor().div( count * 2 );
-
-				renderPipeline.outputNode = compose.add( debugBlockIndexes.mul( tileInfluence ) );
-				renderPipeline.needsUpdate = true;
-
-			}
-
-			function onWindowResize() {
-
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-				updatePostProcessing();
-
-			}
-
-			function animate() {
-
-				const time = performance.now() / 1000;
-
-				for ( let i = 0; i < lights.children.length; i ++ ) {
-
-					const light = lights.children[ i ];
-					const lightTime = ( time * 0.5 ) + light.id;
-
-					light.position.copy( light.userData.fixedPosition );
-					light.position.x += Math.sin( lightTime * 0.7 ) * 3;
-					light.position.y += Math.cos( lightTime * 0.5 ) * .5;
-					light.position.z += Math.cos( lightTime * 0.3 ) * 3;
-
-					lightDummy.setMatrixAt( i, light.matrixWorld );
-
-				}
-
-				renderPipeline.render();
-
-			}
-
-		</script>
-	</body>
-</html>

粤ICP备19079148号