From 414f1a61f095095c42d64a901eed3c88e323770c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Mon, 18 Nov 2024 07:47:44 +0100 Subject: [PATCH] fix: env blur, decal auto orient --- src/core/Decal.tsx | 38 +++++++++++++++++++++++++++++++++++--- src/core/Environment.tsx | 8 +++----- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/core/Decal.tsx b/src/core/Decal.tsx index 77ec4039a..b81e57a9a 100644 --- a/src/core/Decal.tsx +++ b/src/core/Decal.tsx @@ -9,6 +9,7 @@ export type DecalProps = Omit & { debug?: boolean mesh?: React.MutableRefObject position?: FIBER.Vector3 + /** FIBER.Euler for manual orientation or a single float for closest-vertex-normal orient */ rotation?: FIBER.Euler | number scale?: FIBER.Vector3 map?: THREE.Texture @@ -64,9 +65,40 @@ export const Decal: ForwardRefComponent = /* @__PURE__ * if (!rotation || typeof rotation === 'number') { const o = new THREE.Object3D() - o.position.copy(state.position) - o.lookAt(parent.position) + + // Thanks https://x.com/N8Programs ! + const vertices = parent.geometry.attributes.position.array + if (parent.geometry.attributes.normal === undefined) parent.geometry.computeVertexNormals() + const normal = parent.geometry.attributes.normal.array + let distance = Infinity + let closest = new THREE.Vector3() + let closestNormal = new THREE.Vector3() + const ox = o.position.x + const oy = o.position.y + const oz = o.position.z + const vLength = vertices.length + let chosenIdx = -1 + for (let i = 0; i < vLength; i += 3) { + const x = vertices[i] + const y = vertices[i + 1] + const z = vertices[i + 2] + const xDiff = x - ox + const yDiff = y - oy + const zDiff = z - oz + const distSquared = xDiff * xDiff + yDiff * yDiff + zDiff * zDiff + if (distSquared < distance) { + distance = distSquared + chosenIdx = i + } + } + closestNormal.fromArray(normal, chosenIdx) + + // Get vector tangent to normal + o.lookAt(o.position.clone().add(closestNormal)) + o.rotateZ(Math.PI) + o.rotateY(Math.PI) + if (typeof rotation === 'number') o.rotateZ(rotation) applyProps(state as any, { rotation: o.rotation }) } else { @@ -86,7 +118,7 @@ export const Decal: ForwardRefComponent = /* @__PURE__ * target.geometry.dispose() } } - }, [mesh, ...vecToArray(position), ...vecToArray(scale), ...vecToArray(rotation)]) + }, [mesh, debug, ...vecToArray(position), ...vecToArray(scale), ...vecToArray(rotation)]) // } return ( diff --git a/src/core/Environment.tsx b/src/core/Environment.tsx index 35aacabb6..0f5e00cab 100644 --- a/src/core/Environment.tsx +++ b/src/core/Environment.tsx @@ -45,7 +45,7 @@ function setEnvProps( ) { // defaults sceneProps = { - backgroundBlurriness: sceneProps.blur ?? 0, + backgroundBlurriness: 0, backgroundIntensity: 1, backgroundRotation: [0, 0, 0], environmentIntensity: 1, @@ -102,8 +102,7 @@ export function EnvironmentCube({ const defaultScene = useThree((state) => state.scene) React.useLayoutEffect(() => { return setEnvProps(background, scene, defaultScene, texture, { - blur, - backgroundBlurriness, + backgroundBlurriness: blur ?? backgroundBlurriness, backgroundIntensity, backgroundRotation, environmentIntensity, @@ -151,8 +150,7 @@ export function EnvironmentPortal({ gl.autoClear = autoClear } return setEnvProps(background, scene, defaultScene, fbo.texture, { - blur, - backgroundBlurriness, + backgroundBlurriness: blur ?? backgroundBlurriness, backgroundIntensity, backgroundRotation, environmentIntensity,