Browse Source

Examples: Added webgpu_shadowmap_pointlight.

Mr.doob 3 months ago
parent
commit
3b0c9cd476

+ 1 - 0
examples/files.json

@@ -445,6 +445,7 @@
 		"webgpu_shadowmap_array",
 		"webgpu_shadowmap_csm",
 		"webgpu_shadowmap_opacity",
+		"webgpu_shadowmap_pointlight",
 		"webgpu_shadowmap_progressive",
 		"webgpu_shadowmap_vsm",
 		"webgpu_skinning",

BIN
examples/screenshots/webgpu_shadowmap_pointlight.jpg


+ 182 - 0
examples/webgpu_shadowmap_pointlight.html

@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgpu - PointLight ShadowMap</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<link type="text/css" rel="stylesheet" href="main.css">
+	</head>
+	<body>
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - WebGPU - PointLight ShadowMap
+		</div>
+
+		<script type="importmap">
+			{
+				"imports": {
+					"three": "../build/three.webgpu.js",
+					"three/addons/": "./jsm/"
+				}
+			}
+		</script>
+
+		<script type="module">
+
+			import * as THREE from 'three';
+
+			import Stats from 'three/addons/libs/stats.module.js';
+
+			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+
+			let camera, scene, renderer, stats;
+			let pointLight, pointLight2;
+
+			init();
+
+			async function init() {
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 0, 10, 40 );
+
+				scene = new THREE.Scene();
+				scene.add( new THREE.AmbientLight( 0x111122, 3 ) );
+
+				// lights
+
+				function createLight( color ) {
+
+					const intensity = 200;
+
+					const light = new THREE.PointLight( color, intensity, 20 );
+					light.castShadow = true;
+					light.shadow.bias = - 0.005; // reduces self-shadowing on double-sided objects
+					light.shadow.mapSize.width = 128;
+					light.shadow.radius = 10;
+
+					let geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
+					let material = new THREE.MeshBasicMaterial( { color: color } );
+					material.color.multiplyScalar( intensity );
+					let sphere = new THREE.Mesh( geometry, material );
+					light.add( sphere );
+
+					const texture = new THREE.CanvasTexture( generateTexture() );
+					texture.magFilter = THREE.NearestFilter;
+					texture.wrapT = THREE.RepeatWrapping;
+					texture.wrapS = THREE.RepeatWrapping;
+					texture.repeat.set( 1, 4.5 );
+
+					geometry = new THREE.SphereGeometry( 2, 32, 8 );
+					material = new THREE.MeshPhongNodeMaterial( {
+						side: THREE.DoubleSide,
+						alphaMap: texture,
+						alphaTest: 0.5
+					} );
+
+					sphere = new THREE.Mesh( geometry, material );
+					sphere.castShadow = true;
+					sphere.receiveShadow = true;
+					light.add( sphere );
+
+					return light;
+
+				}
+
+				pointLight = createLight( 0x0088ff );
+				pointLight.position.x = - 2;
+				scene.add( pointLight );
+
+				pointLight2 = createLight( 0xff8888 );
+				pointLight2.position.x = + 2;
+				scene.add( pointLight2 );
+				//
+
+				const geometry = new THREE.BoxGeometry( 30, 30, 30 );
+
+				const material = new THREE.MeshPhongNodeMaterial( {
+					color: 0xa0adaf,
+					shininess: 10,
+					specular: 0x111111,
+					side: THREE.BackSide
+				} );
+
+				const mesh = new THREE.Mesh( geometry, material );
+				mesh.position.y = 10;
+				mesh.receiveShadow = true;
+				scene.add( mesh );
+
+				//
+
+				renderer = new THREE.WebGPURenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setAnimationLoop( animate );
+				renderer.shadowMap.enabled = true;
+				// renderer.shadowMap.type = THREE.BasicShadowMap;
+				await renderer.init();
+				document.body.appendChild( renderer.domElement );
+
+				const controls = new OrbitControls( camera, renderer.domElement );
+				controls.target.set( 0, 10, 0 );
+				controls.update();
+
+				stats = new Stats();
+				document.body.appendChild( stats.dom );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function generateTexture() {
+
+				const canvas = document.createElement( 'canvas' );
+				canvas.width = 2;
+				canvas.height = 2;
+
+				const context = canvas.getContext( '2d' );
+				context.fillStyle = 'white';
+				context.fillRect( 0, 1, 2, 1 );
+
+				return canvas;
+
+			}
+
+			function animate() {
+
+				let time = performance.now() * 0.001;
+
+				pointLight.position.x = Math.sin( time * 0.6 ) * 9;
+				pointLight.position.y = Math.sin( time * 0.7 ) * 9 + 6;
+				pointLight.position.z = Math.sin( time * 0.8 ) * 9;
+
+				pointLight.rotation.x = time;
+				pointLight.rotation.z = time;
+
+				time += 10000;
+
+				pointLight2.position.x = Math.sin( time * 0.6 ) * 9;
+				pointLight2.position.y = Math.sin( time * 0.7 ) * 9 + 6;
+				pointLight2.position.z = Math.sin( time * 0.8 ) * 9;
+
+				pointLight2.rotation.x = time;
+				pointLight2.rotation.z = time;
+
+				renderer.render( scene, camera );
+
+				stats.update();
+
+			}
+
+		</script>
+	</body>
+</html>

粤ICP备19079148号