Skip to content

Commit

Permalink
Shadow clipping (#2765)
Browse files Browse the repository at this point in the history
* cleanup and wall to floor fix

* fixed shadow rotation bug
  • Loading branch information
elalish authored Sep 9, 2021
1 parent 7e6c920 commit bc9899a
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 14 deletions.
2 changes: 1 addition & 1 deletion packages/model-viewer/src/features/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export const ARMixin = <T extends Constructor<ModelViewerElementBase>>(
}

if (changedProperties.has('arPlacement')) {
this[$scene].setShadowIntensity(this[$scene].shadowIntensity);
this[$scene].updateShadow();
this[$needsRender]();
}

Expand Down
21 changes: 11 additions & 10 deletions packages/model-viewer/src/three-components/ModelScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ export class ModelScene extends Scene {
const side =
(this.element as any).arPlacement === 'wall' ? 'back' : 'bottom';
shadow.setScene(this, this.shadowSoftness, side);
shadow.setRotation(this.yaw);
}
}

Expand All @@ -553,17 +554,17 @@ export class ModelScene extends Scene {
if (this._currentGLTF == null) {
return;
}
let shadow = this.shadow;
const side =
(this.element as any).arPlacement === 'wall' ? 'back' : 'bottom';
if (shadow != null) {
shadow.setIntensity(shadowIntensity);
shadow.setScene(this, this.shadowSoftness, side);
} else if (shadowIntensity > 0) {
shadow = new Shadow(this, this.shadowSoftness, side);
shadow.setIntensity(shadowIntensity);
this.shadow = shadow;
if (shadowIntensity <= 0 && this.shadow == null) {
return;
}

if (this.shadow == null) {
const side =
(this.element as any).arPlacement === 'wall' ? 'back' : 'bottom';
this.shadow = new Shadow(this, this.shadowSoftness, side);
this.shadow.setRotation(this.yaw);
}
this.shadow.setIntensity(shadowIntensity);
}

/**
Expand Down
12 changes: 9 additions & 3 deletions packages/model-viewer/src/three-components/Shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const ANIMATION_SCALING = 2;
* softer shadows faster, but less precise.
*/
export class Shadow extends DirectionalLight {
private shadowMaterial = new ShadowMaterial;
private shadowMaterial = new ShadowMaterial();
private floor: Mesh;
private boundingBox = new Box3;
private size = new Vector3;
Expand Down Expand Up @@ -92,6 +92,9 @@ export class Shadow extends DirectionalLight {
[this.size.y, this.size.z] = [this.size.z, this.size.y];
this.rotation.x = Math.PI / 2;
this.rotation.y = Math.PI;
} else {
this.rotation.x = 0;
this.rotation.y = 0;
}
const {boundingBox, size} = this;

Expand All @@ -108,11 +111,10 @@ export class Shadow extends DirectionalLight {
const shadowOffset = boundingBox.max.y + size.y * OFFSET;
if (side === 'bottom') {
this.position.y = shadowOffset;
this.shadow.camera.up.set(0, 0, 1);
this.position.z = 0;
} else {
this.position.y = 0;
this.position.z = shadowOffset;
this.shadow.camera.up.set(0, 1, 0);
}

this.setSoftness(softness);
Expand All @@ -137,6 +139,8 @@ export class Shadow extends DirectionalLight {
const {camera, mapSize, map} = this.shadow;
const {size, boundingBox} = this;

// This feels like a three.js bug; changing the mapSize has no effect unless
// the map is manually disposed of.
if (map != null) {
(map as any).dispose();
(this.shadow.map as any) = null;
Expand Down Expand Up @@ -165,6 +169,7 @@ export class Shadow extends DirectionalLight {

this.floor.scale.set(size.x + 2 * widthPad, size.z + 2 * heightPad, 1);
this.needsUpdate = true;
this.shadow.needsUpdate = true;
}

/**
Expand Down Expand Up @@ -194,6 +199,7 @@ export class Shadow extends DirectionalLight {
setRotation(radiansY: number) {
if (this.side !== 'bottom') {
// We don't support rotation about a horizontal axis yet.
this.shadow.camera.up.set(0, 1, 0);
this.shadow.updateMatrices(this);
return;
}
Expand Down

0 comments on commit bc9899a

Please sign in to comment.