diff --git a/packages/stage-ui/src/components/Scenarios/Settings/ModelSettings/VRM.vue b/packages/stage-ui/src/components/Scenarios/Settings/ModelSettings/VRM.vue
index e0680ebe4..bc6b82c47 100644
--- a/packages/stage-ui/src/components/Scenarios/Settings/ModelSettings/VRM.vue
+++ b/packages/stage-ui/src/components/Scenarios/Settings/ModelSettings/VRM.vue
@@ -28,8 +28,6 @@ const {
cameraDistance,
trackingMode,
- directionalLightPosition,
- directionalLightTarget,
directionalLightRotation,
directionalLightIntensity,
directionalLightColor,
@@ -127,32 +125,15 @@ const tabList = [
/>
-
-
-
import type { TresContext } from '@tresjs/core'
-import type { SphericalHarmonics3, Texture, WebGLRenderTarget,
-} from 'three'
+import type { DirectionalLight, SphericalHarmonics3, Texture, WebGLRenderTarget } from 'three'
import { TresCanvas } from '@tresjs/core'
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
@@ -11,6 +10,8 @@ import { storeToRefs } from 'pinia'
import { BlendFunction } from 'postprocessing'
import {
ACESFilmicToneMapping,
+ Euler,
+ MathUtils,
PerspectiveCamera,
Plane,
Raycaster,
@@ -19,6 +20,7 @@ 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'
@@ -53,10 +55,11 @@ const {
lookAtTarget,
eyeHeight,
- directionalLightPosition,
- directionalLightRotation,
directionalLightIntensity,
directionalLightColor,
+ directionalLightPosition,
+ directionalLightRotation,
+ directionalLightTarget,
ambientLightIntensity,
ambientLightColor,
@@ -75,6 +78,7 @@ const camera = shallowRef(new PerspectiveCamera())
const controlsRef = shallowRef>()
const tresCanvasRef = shallowRef()
const skyBoxEnvRef = ref>()
+const dirLight = ref>()
function onTresReady(context: TresContext) {
tresCanvasRef.value = context
@@ -237,6 +241,39 @@ function lookAtMouse(mouseX: number, mouseY: number) {
modelRef.value?.lookAtUpdate(lookAtTarget.value)
}
+function updateDirLightTarget(newRotation: { x: number, y: number, z: number }) {
+ const light = dirLight.value
+ if (!light)
+ return
+
+ const { x: rx, y: ry, z: rz } = newRotation
+ const lightPosition = new Vector3(
+ directionalLightPosition.value.x,
+ directionalLightPosition.value.y,
+ directionalLightPosition.value.z,
+ )
+ const origin = new Vector3(0, 0, 0)
+ const euler = new Euler(
+ MathUtils.degToRad(rx),
+ MathUtils.degToRad(ry),
+ MathUtils.degToRad(rz),
+ 'XYZ',
+ )
+ const initialForward = origin.clone().sub(lightPosition).normalize()
+ const newForward = initialForward.applyEuler(euler).normalize()
+ const distance = lightPosition.distanceTo(origin)
+ 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 }
+}
+
+watch(directionalLightRotation, (newRotation) => {
+ updateDirLightTarget(newRotation)
+}, { deep: true })
+
watch(cameraPosition, (newPosition) => {
if (!sceneReady.value || !modelRef.value)
return
@@ -322,9 +359,9 @@ defineExpose({
cast-shadow
/>
@@ -345,6 +382,7 @@ defineExpose({
@error="(val) => emit('error', val)"
/>
+