Skip to content

Commit

Permalink
feat: scene3 bake correction + screens shaders integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Neosoulink committed Jan 14, 2024
1 parent 8890a26 commit 780d357
Show file tree
Hide file tree
Showing 15 changed files with 575 additions and 40 deletions.
Binary file modified src/assets/models/scene_3/baked_texture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/models/scene_3/model.glb
Binary file not shown.
2 changes: 1 addition & 1 deletion src/experiences/home/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ export class Navigation extends ExperienceBasedBlueprint {
this._config.smallestSide;
}

if (!this._timeline.isActive()) {
if (this._timeline.isActive()) {
// Apply limits
if (this._view.spherical.limits.enabled) {
this._view.spherical.value.radius = Math.min(
Expand Down
16 changes: 9 additions & 7 deletions src/experiences/home/world/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
Box3,
CatmullRomCurve3,
Color,
DoubleSide,
Group,
Mesh,
MeshBasicMaterial,
Expand Down Expand Up @@ -87,6 +88,7 @@ export class World extends ExperienceBasedBlueprint {
opacity: 0.5,
color: new Color(0x000000),
transparent: true,
side: DoubleSide,
});
}

Expand Down Expand Up @@ -160,7 +162,7 @@ export class World extends ExperienceBasedBlueprint {

if (this.sceneContainer?.modelScene instanceof Group) {
const BOUNDING_BOX = new Box3().setFromObject(
this.sceneContainer.modelScene,
this.sceneContainer.modelScene
);
// const WIDTH = BOUNDING_BOX.max.x - BOUNDING_BOX.min.x;
const HEIGHT = BOUNDING_BOX.max.y - BOUNDING_BOX.min.y;
Expand All @@ -169,7 +171,7 @@ export class World extends ExperienceBasedBlueprint {
this._mainSceneConfig.center.set(
this._mainSceneConfig.position.x,
this._mainSceneConfig.position.y + 2.5,
this._mainSceneConfig.position.z,
this._mainSceneConfig.position.z
);
this._mainSceneConfig.cameraPath.points = [
new Vector3(0, 5.5, 21),
Expand All @@ -183,7 +185,7 @@ export class World extends ExperienceBasedBlueprint {
this._projectedSceneConfig.center.set(
this._projectedSceneConfig.position.x,
this._projectedSceneConfig.position.y + 1.5,
this._projectedSceneConfig.position.z,
this._projectedSceneConfig.position.z
);
this._projectedSceneConfig.cameraPath.points = [
new Vector3(0, 5.5, 21).add(this._projectedSceneConfig.position),
Expand All @@ -193,14 +195,14 @@ export class World extends ExperienceBasedBlueprint {
new Vector3(0, 5.5, 21).add(this._projectedSceneConfig.position),
];

(this._projectedSceneContainer =
this.sceneContainer.modelScene.clone()).position.copy(
this._projectedSceneConfig.position,
this._projectedSceneContainer = this.sceneContainer.modelScene.clone();
this._projectedSceneContainer.position.copy(
this._projectedSceneConfig.position
);

this.group?.add(
this.sceneContainer.modelScene,
this._projectedSceneContainer,
this._projectedSceneContainer
);
}

Expand Down
23 changes: 15 additions & 8 deletions src/experiences/home/world/scene-1.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class Scene1Component extends SceneComponentBlueprint {
private _renderer = this._experience.renderer;
private _appTime = this._experience.app.time;
private _mixer?: AnimationMixer;
private _initialPcTopBone?: Object3D;
private _initialPcTopArticulation?: Object3D;

public readonly timeline = gsap.timeline();
public readonly colors = {
Expand Down Expand Up @@ -140,7 +140,7 @@ export class Scene1Component extends SceneComponentBlueprint {
)
return;

this._initialPcTopBone = item.clone();
this._initialPcTopArticulation = item.clone();
this.pcTopArticulation = item;
}

Expand Down Expand Up @@ -396,16 +396,23 @@ export class Scene1Component extends SceneComponentBlueprint {
public togglePcOpening(state?: 0 | 1) {
if (!this._model || !this.modelScene || !this.pcTopArticulation) return;
const isOpen =
this.pcTopArticulation.rotation.z ===
this._initialPcTopBone?.rotation.z || state === 1;
typeof state === "number"
? state === 1
: this.pcTopArticulation.rotation.z !==
this._initialPcTopArticulation?.rotation.z;

const _NEXT_VALUE = isOpen
? this._initialPcTopArticulation?.rotation.z ?? 0
: this.pcTopArticulation.rotation.z + 2.1;

return this.timeline.to(this.pcTopArticulation.rotation, {
z: isOpen
? this.pcTopArticulation.rotation.z + 2.1
: this._initialPcTopBone?.rotation.z ?? 0,
z: _NEXT_VALUE,
duration: Config.GSAP_ANIMATION_DURATION,
onUpdate: () => {},
onComplete: () => {},
onComplete: () => {
if (this.pcTopArticulation?.rotation)
this.pcTopArticulation.rotation.z = Number(_NEXT_VALUE);
},
});
}

Expand Down
197 changes: 177 additions & 20 deletions src/experiences/home/world/scene-3.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import {
Object3D,
type Object3DEventMap,
MeshBasicMaterial,
PerspectiveCamera,
Box3,
Mesh,
ShaderMaterial,
DoubleSide,
} from "three";
import gsap from "gsap";
import { HtmlMixerPlane } from "threex.htmlmixer-continued/lib/html-mixer";
Expand All @@ -16,10 +19,32 @@ import { SceneComponentBlueprint } from "~/blueprints/experiences/scene-componen
// MODELS
import type { Materials } from "~/common/experiences/experience-world.model";

// SHADERS
import phoneScreenFragment from "./shaders/scene-3/phone-screen/fragment.glsl";
import phoneScreenVertex from "./shaders/scene-3/phone-screen/vertex.glsl";
import watchScreenFragment from "./shaders/scene-3/watch-screen/fragment.glsl";
import watchScreenVertex from "./shaders/scene-3/watch-screen/vertex.glsl";
import gamepadLedFragment from "./shaders/scene-3/gamepad_led/fragment.glsl";
import gamepadLedVertex from "./shaders/scene-3/gamepad_led/vertex.glsl";

export class Scene3Component extends SceneComponentBlueprint {
private _appTime = this._experience.app.time;
private _renderer = this._experience.renderer;
private _initialPcTopArticulation?: Object3D<Object3DEventMap>;
private _pcScreenMixerPlane?: HtmlMixerPlane;
private _pcScreenDomElement?: HTMLIFrameElement;
private _phoneScreen?: Mesh;
private _watchScreen?: Mesh;
private _gamepadLed?: Mesh;
private _currentDayTimestamp = (() => {
const currentDate = new Date();
const startOfDay = new Date(currentDate);
startOfDay.setHours(0, 0, 0, 0);

return currentDate.getTime() - startOfDay.getTime();
})();
private _uTime = 0;
private _uTimestamps = 0;

public readonly timeline = gsap.timeline();
public readonly navigationLimits = {
Expand All @@ -40,6 +65,7 @@ export class Scene3Component extends SceneComponentBlueprint {
};

public pcTopArticulation?: Object3D<Object3DEventMap>;
public pcScreen?: Mesh;

constructor() {
super({
Expand All @@ -53,23 +79,54 @@ export class Scene3Component extends SceneComponentBlueprint {
stackoverflow_logo: "scene_3",
linkedin_logo: "scene_3",
pc_top_2: "scene_3",
"eye-glass_glass": "glass",
eye_glass_glasses: "glass",
scene_3_floor: "scene_container",
phone_screen_2: "phone_screen",
watch_screen: "watch_screen",
gamepad_led: "gamepad_led",
},
onTraverseModelScene: (child: Object3D<Object3DEventMap>) => {
this._setPcTopBone(child);
this._setPcTopArticulation(child);
this._setPcScreen(child);
this._setPhoneScreen(child);
this._setWatchScreen(child);
this._setGamepadLed(child);
},
});
}

private _setPcTopBone(item: Object3D<Object3DEventMap>) {
private _setPcTopArticulation(item: Object3D<Object3DEventMap>) {
if (!(item instanceof Object3D) || item.name !== "pc_top_articulation_2")
return;

this._initialPcTopArticulation = item.clone();
this.pcTopArticulation = item;
}

private _setPcScreen(item: Object3D<Object3DEventMap>) {
if (!(item instanceof Mesh) || item.name !== "pc_top_screen_2") return;

this.pcScreen = item;
}

private _setPhoneScreen(item: Object3D<Object3DEventMap>) {
if (!(item instanceof Mesh) || item.name !== "phone_screen_2") return;

this._phoneScreen = item;
}

private _setWatchScreen(item: Object3D<Object3DEventMap>) {
if (!(item instanceof Mesh) || item.name !== "watch_screen") return;

this._watchScreen = item;
}

private _setGamepadLed(item: Object3D<Object3DEventMap>) {
if (!(item instanceof Mesh) || item.name !== "gamepad_led") return;

this._gamepadLed = item;
}

protected _getAvailableMaterials() {
const AVAILABLE_TEXTURE = this._loader?.availableTextures;
const AVAILABLE_MATERIALS: Materials = {};
Expand All @@ -90,6 +147,40 @@ export class Scene3Component extends SceneComponentBlueprint {
alphaMap: AVAILABLE_TEXTURE.cloudAlphaMap,
alphaTest: 1,
map: AVAILABLE_TEXTURE.scene_3_baked_texture,
side: DoubleSide,
});

AVAILABLE_MATERIALS.phone_screen = new ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uTimestamp: { value: 0 },
},
fragmentShader: phoneScreenFragment,
vertexShader: phoneScreenVertex,
transparent: true,
depthWrite: false,
});

AVAILABLE_MATERIALS.watch_screen = new ShaderMaterial({
uniforms: {
uSec: { value: 0 },
uTimestamp: { value: 0 },
uTime: { value: 0 },
},
fragmentShader: watchScreenFragment,
vertexShader: watchScreenVertex,
transparent: true,
depthWrite: false,
});

AVAILABLE_MATERIALS.gamepad_led = new ShaderMaterial({
uniforms: {
uTime: { value: 0 },
},
fragmentShader: gamepadLedFragment,
vertexShader: gamepadLedVertex,
transparent: true,
depthWrite: false,
});

return AVAILABLE_MATERIALS;
Expand All @@ -104,44 +195,110 @@ export class Scene3Component extends SceneComponentBlueprint {
public togglePcOpening(state?: 0 | 1) {
if (!this._model || !this.modelScene || !this.pcTopArticulation) return;
const isOpen =
this.pcTopArticulation.rotation.z ===
this._initialPcTopArticulation?.rotation.z || state === 1;
typeof state === "number"
? state === 1
: this.pcTopArticulation.rotation.z !==
this._initialPcTopArticulation?.rotation.z;

const _NEXT_VALUE = isOpen
? this._initialPcTopArticulation?.rotation.z ?? 0
: this.pcTopArticulation.rotation.z + 1.7;

return this.timeline.to(this.pcTopArticulation.rotation, {
z: isOpen
? this.pcTopArticulation.rotation.z + 1.7
: this._initialPcTopArticulation?.rotation.z ?? 0,
z: _NEXT_VALUE,
duration: Config.GSAP_ANIMATION_DURATION,
onUpdate: () => {},
onComplete: () => {},
onComplete: () => {
if (this.pcTopArticulation?.rotation)
this.pcTopArticulation.rotation.z = Number(_NEXT_VALUE);
},
});
}

public construct(): void {
super.construct();

~(() => {
if (!this._renderer?.mixerContext) return;
if (!this._renderer) return;

this._renderer.enableCssRender = true;
})();

~(() => {
if (
!this._renderer?.mixerContext ||
!this.pcTopArticulation ||
!this.pcScreen
)
return;

const boundingBox = new Box3().setFromObject(this.pcScreen);
const _WIDTH = boundingBox.max.y - boundingBox.min.y - 0.075;
const _HEIGHT = boundingBox.max.x - boundingBox.min.x - 0.076;

const domElement = document.createElement("iframe");
domElement.src = "http://threejs.org/";
domElement.style.border = "none";
this._pcScreenDomElement = document.createElement("iframe");
this._pcScreenDomElement.src = "http://threejs.org/";
this._pcScreenDomElement.style.border = "none";

this._pcScreenMixerPlane = new HtmlMixerPlane(
this._renderer.mixerContext,
domElement
this._pcScreenDomElement,
{ planeH: _HEIGHT, planeW: _WIDTH }
);
this._pcScreenMixerPlane.object3d.position.set(
this.pcScreen.position.x,
0.01,
this.pcScreen.position.z
);
this._pcScreenMixerPlane.object3d.position.y += 3;
this._pcScreenMixerPlane.object3d.scale.multiplyScalar(2);
this._pcScreenMixerPlane.object3d.rotation.set(-4.71, 0, -1.57);

// document.querySelector("#css")?.appendChild(css3dElement);
this._experience.app.scene?.add(this._pcScreenMixerPlane.object3d);
this.pcTopArticulation.add(this._pcScreenMixerPlane.object3d);
})();
}

public intro(): void {
this.togglePcOpening();
}

public update() {}
public update() {
this._uTime = this._appTime.elapsed * 0.001;
this._uTimestamps = this._currentDayTimestamp * 0.001 + this._uTime;

if (
this._phoneScreen?.material instanceof ShaderMaterial &&
typeof this._phoneScreen?.material.uniforms?.uTime?.value === "number"
)
this._phoneScreen.material.uniforms.uTime.value = this._uTime;
if (
this._phoneScreen?.material instanceof ShaderMaterial &&
typeof this._phoneScreen?.material.uniforms?.uTimestamp?.value ===
"number"
)
this._phoneScreen.material.uniforms.uTimestamp.value = this._uTimestamps;

if (
this._watchScreen?.material instanceof ShaderMaterial &&
typeof this._watchScreen?.material.uniforms?.uTime?.value === "number"
)
this._watchScreen.material.uniforms.uTime.value = this._uTime;

if (
this._watchScreen?.material instanceof ShaderMaterial &&
typeof this._watchScreen?.material.uniforms?.uSec?.value === "number"
)
this._watchScreen.material.uniforms.uSec.value = Math.round(this._uTime);

if (
this._watchScreen?.material instanceof ShaderMaterial &&
typeof this._watchScreen?.material.uniforms?.uTimestamp?.value ===
"number"
)
this._watchScreen.material.uniforms.uTimestamp.value = this._uTimestamps;

if (
this._gamepadLed?.material instanceof ShaderMaterial &&
typeof this._gamepadLed?.material.uniforms?.uTime?.value === "number"
)
this._gamepadLed.material.uniforms.uTime.value = this._uTime;
}
}
Loading

0 comments on commit 780d357

Please sign in to comment.