Skip to content

Commit a768f0e

Browse files
sunagRuthySheffi
authored andcommitted
SpotLightShadow: Introduce aspect property (mrdoob#31020)
* TSL: Fix convert `.set*()` value to node-object * SpotLightShadow: Introduce `aspect` * improve custom aspect example * cleanup * Update webgpu_lights_spotlight.html * Update webgpu_lights_spotlight.html
1 parent 47b2229 commit a768f0e

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

examples/webgpu_lights_spotlight.html

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

2828
import * as THREE from 'three';
29-
import { Fn, vec2, length, abs, max, min, div, mul, clamp, acos } from 'three/tsl';
29+
import { Fn, vec2, length, uniform, abs, max, min, sub, div, saturate, acos } from 'three/tsl';
3030

3131
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
3232

@@ -41,6 +41,8 @@
4141

4242
function init() {
4343

44+
// Renderer
45+
4446
renderer = new THREE.WebGPURenderer( { antialias: true } );
4547
renderer.setPixelRatio( window.devicePixelRatio );
4648
renderer.setSize( window.innerWidth, window.innerHeight );
@@ -58,15 +60,16 @@
5860
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 100 );
5961
camera.position.set( 7, 4, 1 );
6062

63+
// Controls
64+
6165
const controls = new OrbitControls( camera, renderer.domElement );
6266
controls.minDistance = 2;
6367
controls.maxDistance = 10;
6468
controls.maxPolarAngle = Math.PI / 2;
6569
controls.target.set( 0, 1, 0 );
6670
controls.update();
6771

68-
const ambient = new THREE.HemisphereLight( 0xffffff, 0x8d8d8d, 0.15 );
69-
scene.add( ambient );
72+
// Textures
7073

7174
const loader = new THREE.TextureLoader().setPath( 'textures/' );
7275
const filenames = [ 'disturb.jpg', 'colors.png', 'uv_grid_opengl.jpg' ];
@@ -87,8 +90,15 @@
8790

8891
}
8992

93+
// Lights
94+
95+
const ambient = new THREE.HemisphereLight( 0xffffff, 0x8d8d8d, 0.15 );
96+
scene.add( ambient );
97+
9098
const boxAttenuationFn = Fn( ( [ lightNode ], builder ) => {
9199

100+
const light = lightNode.light;
101+
92102
const sdBox = Fn( ( [ p, b ] ) => {
93103

94104
const d = vec2( abs( p ).sub( b ) ).toVar();
@@ -97,13 +107,13 @@
97107

98108
} );
99109

100-
const penumbraCos = lightNode.penumbraCosNode;
110+
const penumbraCos = uniform( 'float' ).onRenderUpdate( () => Math.min( Math.cos( light.angle * ( 1 - light.penumbra ) ), .99999 ) );
101111
const spotLightCoord = lightNode.getSpotLightCoord( builder );
102112
const coord = spotLightCoord.xyz.div( spotLightCoord.w );
103113

104114
const boxDist = sdBox( coord.xy.sub( vec2( 0.5 ) ), vec2( 0.5 ) );
105-
const angleFactor = div( 1.0, acos( penumbraCos ).sub( 1.0 ) );
106-
const attenuation = clamp( mul( 2.0, boxDist ).mul( angleFactor ), 0.0, 1.0 );
115+
const angleFactor = div( -1.0, sub( 1.0, acos( penumbraCos ) ).sub( 1.0 ) );
116+
const attenuation = saturate( boxDist.mul( - 2.0 ).mul( angleFactor ) );
107117

108118
return attenuation;
109119

@@ -140,7 +150,7 @@
140150
mesh.receiveShadow = true;
141151
scene.add( mesh );
142152

143-
//
153+
// Models
144154

145155
new PLYLoader().load( 'models/ply/binary/Lucy100k.ply', function ( geometry ) {
146156

@@ -246,8 +256,12 @@
246256

247257
spotLight.attenuationNode = val ? boxAttenuationFn : null;
248258

259+
aspectGUI.setValue( 1 ).enable( val );
260+
249261
} );
250262

263+
const aspectGUI = gui.add( spotLight.shadow, 'aspect', 0, 2 ).enable( false );
264+
251265
gui.open();
252266

253267
}

src/lights/SpotLightShadow.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,22 @@ class SpotLightShadow extends LightShadow {
3434
*/
3535
this.focus = 1;
3636

37+
/**
38+
* Texture aspect ratio.
39+
*
40+
* @type {number}
41+
* @default 1
42+
*/
43+
this.aspect = 1;
44+
3745
}
3846

3947
updateMatrices( light ) {
4048

4149
const camera = this.camera;
4250

4351
const fov = RAD2DEG * 2 * light.angle * this.focus;
44-
const aspect = this.mapSize.width / this.mapSize.height;
52+
const aspect = ( this.mapSize.width / this.mapSize.height ) * this.aspect;
4553
const far = light.distance || camera.far;
4654

4755
if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {

src/nodes/tsl/TSLCore.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const shaderNodeHandler = {
8585

8686
prop = parseSwizzleAndSort( prop.slice( 3 ).toLowerCase() );
8787

88-
return ( value ) => nodeObject( new SetNode( node, prop, value ) );
88+
return ( value ) => nodeObject( new SetNode( node, prop, nodeObject( value ) ) );
8989

9090
} else if ( /^flip[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) {
9191

0 commit comments

Comments
 (0)