better looking grid
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { sceneRegistry } from '@pascal-app/core'
|
import { emitter, type GridEvent, sceneRegistry } from '@pascal-app/core'
|
||||||
import { useViewer } from '@pascal-app/viewer'
|
import { useViewer } from '@pascal-app/viewer'
|
||||||
|
|
||||||
import { useFrame } from '@react-three/fiber'
|
import { useFrame } from '@react-three/fiber'
|
||||||
import { useMemo, useRef, useState } from 'react'
|
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { MathUtils, type Mesh } from 'three'
|
import { MathUtils, type Mesh, Vector2 } from 'three'
|
||||||
|
|
||||||
import { color, float, fract, fwidth, mix, positionLocal } from 'three/tsl'
|
import { color, float, fract, fwidth, mix, positionLocal, uniform } from 'three/tsl'
|
||||||
import { MeshBasicNodeMaterial } from 'three/webgpu'
|
import { MeshBasicNodeMaterial } from 'three/webgpu'
|
||||||
import { useGridEvents } from '@/hooks/use-grid-events'
|
import { useGridEvents } from '@/hooks/use-grid-events'
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ export const Grid = ({
|
|||||||
sectionColor = '#000000',
|
sectionColor = '#000000',
|
||||||
fadeDistance = 100,
|
fadeDistance = 100,
|
||||||
fadeStrength = 1,
|
fadeStrength = 1,
|
||||||
|
revealRadius = 10,
|
||||||
}: {
|
}: {
|
||||||
cellSize?: number
|
cellSize?: number
|
||||||
cellThickness?: number
|
cellThickness?: number
|
||||||
@@ -29,11 +30,17 @@ export const Grid = ({
|
|||||||
sectionColor?: string
|
sectionColor?: string
|
||||||
fadeDistance?: number
|
fadeDistance?: number
|
||||||
fadeStrength?: number
|
fadeStrength?: number
|
||||||
|
revealRadius?: number
|
||||||
}) => {
|
}) => {
|
||||||
|
const cursorPositionRef = useRef(new Vector2(0, 0))
|
||||||
|
|
||||||
const material = useMemo(() => {
|
const material = useMemo(() => {
|
||||||
// Use xy since plane geometry is in XY space (before rotation)
|
// Use xy since plane geometry is in XY space (before rotation)
|
||||||
const pos = positionLocal.xy
|
const pos = positionLocal.xy
|
||||||
|
|
||||||
|
// Cursor position uniform
|
||||||
|
const cursorPos = uniform(cursorPositionRef.current)
|
||||||
|
|
||||||
// Grid line function using fwidth for anti-aliasing
|
// Grid line function using fwidth for anti-aliasing
|
||||||
// Returns 1 on grid lines, 0 elsewhere
|
// Returns 1 on grid lines, 0 elsewhere
|
||||||
const getGrid = (size: number, thickness: number) => {
|
const getGrid = (size: number, thickness: number) => {
|
||||||
@@ -65,6 +72,10 @@ export const Grid = ({
|
|||||||
const dist = pos.length()
|
const dist = pos.length()
|
||||||
const fade = float(1).sub(dist.div(fadeDistance).min(1)).pow(fadeStrength)
|
const fade = float(1).sub(dist.div(fadeDistance).min(1)).pow(fadeStrength)
|
||||||
|
|
||||||
|
// Cursor reveal effect - distance from cursor
|
||||||
|
const cursorDist = pos.sub(cursorPos).length()
|
||||||
|
const cursorFade = float(1).sub(cursorDist.div(revealRadius).clamp(0, 1)).smoothstep(0, 1)
|
||||||
|
|
||||||
// Mix colors based on section grid
|
// Mix colors based on section grid
|
||||||
const gridColor = mix(
|
const gridColor = mix(
|
||||||
color(cellColor),
|
color(cellColor),
|
||||||
@@ -72,8 +83,8 @@ export const Grid = ({
|
|||||||
float(sectionThickness).mul(g2).min(1),
|
float(sectionThickness).mul(g2).min(1),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Combined alpha
|
// Combined alpha with cursor fade
|
||||||
const alpha = g1.add(g2).mul(fade)
|
const alpha = g1.add(g2).mul(fade).mul(cursorFade)
|
||||||
const finalAlpha = mix(alpha.mul(0.75), alpha, g2)
|
const finalAlpha = mix(alpha.mul(0.75), alpha, g2)
|
||||||
|
|
||||||
return new MeshBasicNodeMaterial({
|
return new MeshBasicNodeMaterial({
|
||||||
@@ -91,6 +102,7 @@ export const Grid = ({
|
|||||||
sectionColor,
|
sectionColor,
|
||||||
fadeDistance,
|
fadeDistance,
|
||||||
fadeStrength,
|
fadeStrength,
|
||||||
|
revealRadius,
|
||||||
])
|
])
|
||||||
|
|
||||||
const gridRef = useRef<Mesh>(null!)
|
const gridRef = useRef<Mesh>(null!)
|
||||||
@@ -99,6 +111,18 @@ export const Grid = ({
|
|||||||
// Use custom raycasting for grid events (independent of mesh events)
|
// Use custom raycasting for grid events (independent of mesh events)
|
||||||
useGridEvents(gridY)
|
useGridEvents(gridY)
|
||||||
|
|
||||||
|
// Update cursor position from grid:move events
|
||||||
|
useEffect(() => {
|
||||||
|
const onGridMove = (event: GridEvent) => {
|
||||||
|
cursorPositionRef.current.set(event.position[0], -event.position[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter.on('grid:move', onGridMove)
|
||||||
|
return () => {
|
||||||
|
emitter.off('grid:move', onGridMove)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
useFrame((_, delta) => {
|
useFrame((_, delta) => {
|
||||||
const currentLevelId = useViewer.getState().selection.levelId
|
const currentLevelId = useViewer.getState().selection.levelId
|
||||||
let targetY = 0
|
let targetY = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user