bug fix - VRM - directional light adjustment persistance (#556)

This commit is contained in:
Lilia_Chen authored and GitHub committed 2025-09-05 00:41:48 +01:00
1 parent d64bfa33fa
commit 08d579df4a
3 files changed
+27 -8

No files matched your search

@@ -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<InstanceType<typeof OrbitControls>>()
const tresCanvasRef = shallowRef<TresContext>()
const skyBoxEnvRef = ref<InstanceType<typeof SkyBoxEnvironment>>()
const dirLight = ref<InstanceType<typeof DirectionalLight>>()
const dirLightRef = ref<InstanceType<typeof DirectionalLight>>()
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
/>
<TresDirectionalLight
ref="dirLight"
ref="dirLightRef"
:color="formatHex(directionalLightColor)"
:position="[directionalLightPosition.x, directionalLightPosition.y, directionalLightPosition.z]"
:intensity="directionalLightIntensity"
cast-shadow
@ready="onDirLightReady"
/>
<Suspense>
<EffectComposerPmndrs>
@@ -382,7 +399,6 @@ defineExpose({
@error="(val) => emit('error', val)"
/>
<TresAxesHelper v-if="props.showAxes" :size="1" />
<DirectionalLightHelper :directional-light="dirLight" />
</TresCanvas>
</div>
</template>
@@ -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)
+1 -1
View File
@@ -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