diff --git a/packages/stage-ui/src/components/Scenes/VRM.vue b/packages/stage-ui/src/components/Scenes/VRM.vue index 6b029804..98ae7ccf 100644 --- a/packages/stage-ui/src/components/Scenes/VRM.vue +++ b/packages/stage-ui/src/components/Scenes/VRM.vue @@ -20,7 +20,6 @@ import { } from 'three' import { onMounted, ref, shallowRef, watch } from 'vue' -import DirectionalLightHelper from './Tres/DirectionalLightHelper.vue' import SkyBoxEnvironment from './VRM/SkyBoxEnvironment.vue' import { useVRM } from '../../stores/vrm' @@ -78,7 +77,7 @@ const camera = shallowRef(new PerspectiveCamera()) const controlsRef = shallowRef>() const tresCanvasRef = shallowRef() const skyBoxEnvRef = ref>() -const dirLight = ref>() +const dirLightRef = ref>() function onTresReady(context: TresContext) { tresCanvasRef.value = context @@ -95,6 +94,7 @@ let isUpdatingCamera = true const controlsReady = ref(false) const modelReady = ref(false) const sceneReady = ref(false) +const dirLightReady = ref(false) const raycaster = new Raycaster() const mouse = new Vector2() @@ -107,6 +107,10 @@ function onEnvReady(EnvPayload: { hdri: Texture | null, pmrem?: WebGLRenderTarge irrSHTex.value = EnvPayload.irrSH || null } +function onDirLightReady() { + dirLightReady.value = true +} + watch(cameraFOV, (newFov) => { if (camera.value) { camera.value.fov = newFov @@ -160,9 +164,9 @@ function handleLoadModelProgress() { // Then start to set the camera position and target watch( - [controlsReady, modelReady], + [controlsReady, modelReady, dirLightReady], ([ctrlOk, modelOk]) => { - if (ctrlOk && modelOk && camera.value && controlsRef.value && controlsRef.value.controls) { + if (ctrlOk && modelOk && camera.value && controlsRef.value && controlsRef.value.controls && dirLightRef.value) { isUpdatingCamera = true try { camera.value.aspect = width.value / height.value @@ -178,6 +182,16 @@ watch( camera.value.updateProjectionMatrix() controlsRef.value.controls.update() cameraDistance.value = controlsRef.value!.controls!.getDistance() + + // setup initial target of directional light + dirLightRef.value.parent?.add(dirLightRef.value.target) + dirLightRef.value.target.position.set( + directionalLightTarget.value.x, + directionalLightTarget.value.y, + directionalLightTarget.value.z, + ) + // console.debug("direction light target set: ", dirLightRef.value.target.position) + dirLightRef.value.target.updateMatrixWorld() } finally { isUpdatingCamera = false @@ -242,7 +256,7 @@ function lookAtMouse(mouseX: number, mouseY: number) { } function updateDirLightTarget(newRotation: { x: number, y: number, z: number }) { - const light = dirLight.value + const light = dirLightRef.value if (!light) return @@ -265,9 +279,11 @@ function updateDirLightTarget(newRotation: { x: number, y: number, z: number }) const target = lightPosition.clone().addScaledVector(newForward, distance) light.target.position.copy(target) + light.target.updateMatrixWorld() directionalLightTarget.value = { x: target.x, y: target.y, z: target.z } + // console.debug("directional Light target update!: ", directionalLightTarget.value) } watch(directionalLightRotation, (newRotation) => { @@ -359,11 +375,12 @@ defineExpose({ cast-shadow /> @@ -382,7 +399,6 @@ defineExpose({ @error="(val) => emit('error', val)" /> - diff --git a/packages/stage-ui/src/components/Scenes/VRM/Model.vue b/packages/stage-ui/src/components/Scenes/VRM/Model.vue index f52ad298..3fd288e7 100644 --- a/packages/stage-ui/src/components/Scenes/VRM/Model.vue +++ b/packages/stage-ui/src/components/Scenes/VRM/Model.vue @@ -247,6 +247,9 @@ async function loadModel() { // --- Shader material, further IBL injection needed --- // disable envMap for NPR materials, envMap will be reassigned by default skybox // close tone mapping for NPR materials + // console.debug("Mat: ", mat) + // TODO: stylised shader injection + // Lilia: I plan to replce all injected shader code to be my own, so that it can always avoid double injection and unkown user upload VRM injected shader behaviour... if ('toneMapped' in mat) mat.toneMapped = false if ('envMap' in mat && mat.envMap) diff --git a/packages/stage-ui/src/stores/vrm.ts b/packages/stage-ui/src/stores/vrm.ts index abe3948a..514758e2 100644 --- a/packages/stage-ui/src/stores/vrm.ts +++ b/packages/stage-ui/src/stores/vrm.ts @@ -40,7 +40,7 @@ export const useVRM = defineStore('vrm', () => { const cameraPosition = useLocalStorage('settings/vrm/camera-position', { x: 0, y: 0, z: -1 }) const cameraDistance = useLocalStorage('settings/vrm/cameraDistance', 0) - const directionalLightPosition = useLocalStorage('settings/vrm/scenes/scene/directional-light/position', { x: 0, y: 0, z: -10 }) + const directionalLightPosition = useLocalStorage('settings/vrm/scenes/scene/directional-light/position', { x: 0, y: 0, z: -1 }) const directionalLightTarget = useLocalStorage('settings/vrm/scenes/scene/directional-light/target', { x: 0, y: 0, z: 0 }) const directionalLightRotation = useLocalStorage('settings/vrm/scenes/scene/directional-light/rotation', { x: 0, y: 0, z: 0 }) // TODO: Manual directional light intensity will not work for other