From 3e5d042624f9bcd1a158468ae5385761468f6c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Sat, 17 Dec 2022 10:56:46 +0100 Subject: [PATCH 1/6] feat: grid --- README.md | 26 ++++++++++ src/core/Grid.tsx | 118 ++++++++++++++++++++++++++++++++++++++++++++++ src/core/index.ts | 1 + 3 files changed, 145 insertions(+) create mode 100644 src/core/Grid.tsx diff --git a/README.md b/README.md index 6384943e3..5d5f7cd1b 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
  • GizmoHelper
  • PivotControls
  • TransformControls
  • +
  • Grid
  • useHelper
  • Abstractions
  • @@ -647,6 +648,31 @@ If you are using other controls (Orbit, Trackball, etc), you will notice how the ``` +#### Grid + +A robust grid implementation with multiple tweakable parameters. + +```tsx +type GridProps = { + axes?: 'xzy' | 'xyz' | 'zyx' + gridSize?: number | [number, number] + cellColor?: THREE.ColorRepresentation + cellSize?: number + cellThickness?: number + sectionColor?: THREE.ColorRepresentation + sectionSize?: number + sectionThickness?: number + followCamera?: boolean + infiniteGrid?: boolean + fadeDistance?: number + fadeStrength?: number +} +``` + +```jsx + +``` + #### useHelper [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/misc-usehelper--default-story) diff --git a/src/core/Grid.tsx b/src/core/Grid.tsx new file mode 100644 index 000000000..f4ee1524b --- /dev/null +++ b/src/core/Grid.tsx @@ -0,0 +1,118 @@ +/** Original grid component https://github.com/threlte/threlte/blob/main/packages/extras/src/lib/components/Grid/Grid.svelte + * By https://github.com/grischaerbe and https://github.com/jerzakm + */ + +import * as React from 'react' +import * as THREE from 'three' +import { shaderMaterial } from './shaderMaterial' + +export type GridProps = { + axes?: 'xzy' | 'xyz' | 'zyx' + gridSize?: number | [number, number] + cellColor?: THREE.ColorRepresentation + cellSize?: number + cellThickness?: number + sectionColor?: THREE.ColorRepresentation + sectionSize?: number + sectionThickness?: number + followCamera?: boolean + infiniteGrid?: boolean + fadeDistance?: number + fadeStrength?: number +} + +export function Grid({ + gridSize = 20, + cellColor = '#000000', + sectionColor = '#0000ee', + cellSize = 1, + sectionSize = 10, + axes = 'xzy', + followCamera = false, + infiniteGrid = false, + fadeDistance = 100, + fadeStrength = 1, + cellThickness = 1, + sectionThickness = 2, + ...props +}: JSX.IntrinsicElements['mesh'] & GridProps) { + const uniforms = { + cellSize, + sectionSize, + cellColor, + sectionColor, + fadeDistance, + fadeStrength, + cellThickness, + sectionThickness, + infiniteGrid, + followCamera, + } + const shader = React.useMemo(() => { + return new (shaderMaterial( + { + ...uniforms, + cellColor: new THREE.Color(cellColor), + sectionColor: new THREE.Color(sectionColor), + infiniteGrid: infiniteGrid ? 1 : 0, + followCamera: followCamera ? 1 : 0, + }, + ` + varying vec3 worldPosition; + uniform float fadeDistance; + uniform float infiniteGrid; + uniform float followCamera; + void main() { + vec3 pos = position.${axes} * (1. + fadeDistance * infiniteGrid); + pos.${axes.slice(0, 2)} += (cameraPosition.${axes.slice(0, 2)} * followCamera); + worldPosition = pos; + gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); + }`, + ` + varying vec3 worldPosition; + uniform float cellSize; + uniform float sectionSize; + uniform vec3 cellColor; + uniform vec3 sectionColor; + uniform float fadeDistance; + uniform float fadeStrength; + uniform float cellThickness; + uniform float sectionThickness; + uniform float infiniteGrid; + float getGrid(float size, float thickness) { + vec2 r = worldPosition.${axes.slice(0, 2)} / size; + vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r); + float line = min(grid.x, grid.y) + 1. - thickness; + return 1.0 - min(line, 1.); + } + void main() { + float g1 = getGrid(cellSize, cellThickness); + float g2 = getGrid(sectionSize, sectionThickness); + float d = 1.0 - min(distance(cameraPosition.${axes.slice(0, 2)}, worldPosition.${axes.slice( + 0, + 2 + )}) / fadeDistance, 1.); + vec3 color = mix(cellColor, sectionColor, min(1.,sectionThickness * g2)); + gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); + gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); + if(gl_FragColor.a <= 0.0) + discard; + } + `, + (material) => { + Object.assign(material!, { + side: THREE.DoubleSide, + transparent: true, + extensions: { derivatives: true }, + }) + } + ))() + }, [axes]) + + return ( + + + + + ) +} diff --git a/src/core/index.ts b/src/core/index.ts index 9d511b0f1..3f9dd3a27 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -41,6 +41,7 @@ export * from './FirstPersonControls' export * from './GizmoHelper' export * from './GizmoViewcube' export * from './GizmoViewport' +export * from './Grid' // Loaders export * from './useCubeTexture' From 45b4aca05b6b354e5e92935c9c13642f6f5b5d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Sat, 17 Dec 2022 10:59:56 +0100 Subject: [PATCH 2/6] chore: cleanup --- src/core/Grid.tsx | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/core/Grid.tsx b/src/core/Grid.tsx index f4ee1524b..44f8bec88 100644 --- a/src/core/Grid.tsx +++ b/src/core/Grid.tsx @@ -49,6 +49,7 @@ export function Grid({ followCamera, } const shader = React.useMemo(() => { + const axis = axes.slice(0, 2) return new (shaderMaterial( { ...uniforms, @@ -57,19 +58,17 @@ export function Grid({ infiniteGrid: infiniteGrid ? 1 : 0, followCamera: followCamera ? 1 : 0, }, - ` - varying vec3 worldPosition; + ` varying vec3 worldPosition; uniform float fadeDistance; uniform float infiniteGrid; uniform float followCamera; void main() { vec3 pos = position.${axes} * (1. + fadeDistance * infiniteGrid); - pos.${axes.slice(0, 2)} += (cameraPosition.${axes.slice(0, 2)} * followCamera); + pos.${axis} += (cameraPosition.${axis} * followCamera); worldPosition = pos; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); }`, - ` - varying vec3 worldPosition; + ` varying vec3 worldPosition; uniform float cellSize; uniform float sectionSize; uniform vec3 cellColor; @@ -80,7 +79,7 @@ export function Grid({ uniform float sectionThickness; uniform float infiniteGrid; float getGrid(float size, float thickness) { - vec2 r = worldPosition.${axes.slice(0, 2)} / size; + vec2 r = worldPosition.${axis} / size; vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r); float line = min(grid.x, grid.y) + 1. - thickness; return 1.0 - min(line, 1.); @@ -88,17 +87,12 @@ export function Grid({ void main() { float g1 = getGrid(cellSize, cellThickness); float g2 = getGrid(sectionSize, sectionThickness); - float d = 1.0 - min(distance(cameraPosition.${axes.slice(0, 2)}, worldPosition.${axes.slice( - 0, - 2 - )}) / fadeDistance, 1.); + float d = 1.0 - min(distance(cameraPosition.${axis}, worldPosition.${axis}) / fadeDistance, 1.); vec3 color = mix(cellColor, sectionColor, min(1.,sectionThickness * g2)); gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); - if(gl_FragColor.a <= 0.0) - discard; - } - `, + if (gl_FragColor.a <= 0.0) discard; + }`, (material) => { Object.assign(material!, { side: THREE.DoubleSide, From 22eddde5092764f97e52769cfbc40b460b14720f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Sat, 17 Dec 2022 14:02:00 +0100 Subject: [PATCH 3/6] fix: axes seems unnecessary if we can just rotate it --- README.md | 3 +- src/core/Grid.tsx | 196 +++++++++++++++++++++++++--------------------- 2 files changed, 108 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 5d5f7cd1b..37514a2c9 100644 --- a/README.md +++ b/README.md @@ -650,11 +650,10 @@ If you are using other controls (Orbit, Trackball, etc), you will notice how the #### Grid -A robust grid implementation with multiple tweakable parameters. +A y-up oriented, robust grid implementation with multiple tweakable parameters. ```tsx type GridProps = { - axes?: 'xzy' | 'xyz' | 'zyx' gridSize?: number | [number, number] cellColor?: THREE.ColorRepresentation cellSize?: number diff --git a/src/core/Grid.tsx b/src/core/Grid.tsx index 44f8bec88..e0694ab5a 100644 --- a/src/core/Grid.tsx +++ b/src/core/Grid.tsx @@ -4,11 +4,10 @@ import * as React from 'react' import * as THREE from 'three' +import { extend } from '@react-three/fiber' import { shaderMaterial } from './shaderMaterial' -export type GridProps = { - axes?: 'xzy' | 'xyz' | 'zyx' - gridSize?: number | [number, number] +export type GridMaterialType = { cellColor?: THREE.ColorRepresentation cellSize?: number cellThickness?: number @@ -21,92 +20,111 @@ export type GridProps = { fadeStrength?: number } -export function Grid({ - gridSize = 20, - cellColor = '#000000', - sectionColor = '#0000ee', - cellSize = 1, - sectionSize = 10, - axes = 'xzy', - followCamera = false, - infiniteGrid = false, - fadeDistance = 100, - fadeStrength = 1, - cellThickness = 1, - sectionThickness = 2, - ...props -}: JSX.IntrinsicElements['mesh'] & GridProps) { - const uniforms = { - cellSize, - sectionSize, - cellColor, - sectionColor, - fadeDistance, - fadeStrength, - cellThickness, - sectionThickness, - infiniteGrid, - followCamera, +export type GridProps = GridMaterialType & { + gridSize?: number | [number, number] +} + +declare global { + namespace JSX { + interface IntrinsicElements { + gridMaterial: JSX.IntrinsicElements['shaderMaterial'] & GridMaterialType + } } - const shader = React.useMemo(() => { - const axis = axes.slice(0, 2) - return new (shaderMaterial( - { - ...uniforms, - cellColor: new THREE.Color(cellColor), - sectionColor: new THREE.Color(sectionColor), - infiniteGrid: infiniteGrid ? 1 : 0, - followCamera: followCamera ? 1 : 0, - }, - ` varying vec3 worldPosition; - uniform float fadeDistance; - uniform float infiniteGrid; - uniform float followCamera; - void main() { - vec3 pos = position.${axes} * (1. + fadeDistance * infiniteGrid); - pos.${axis} += (cameraPosition.${axis} * followCamera); - worldPosition = pos; - gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); - }`, - ` varying vec3 worldPosition; - uniform float cellSize; - uniform float sectionSize; - uniform vec3 cellColor; - uniform vec3 sectionColor; - uniform float fadeDistance; - uniform float fadeStrength; - uniform float cellThickness; - uniform float sectionThickness; - uniform float infiniteGrid; - float getGrid(float size, float thickness) { - vec2 r = worldPosition.${axis} / size; - vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r); - float line = min(grid.x, grid.y) + 1. - thickness; - return 1.0 - min(line, 1.); - } - void main() { - float g1 = getGrid(cellSize, cellThickness); - float g2 = getGrid(sectionSize, sectionThickness); - float d = 1.0 - min(distance(cameraPosition.${axis}, worldPosition.${axis}) / fadeDistance, 1.); - vec3 color = mix(cellColor, sectionColor, min(1.,sectionThickness * g2)); - gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); - gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); - if (gl_FragColor.a <= 0.0) discard; - }`, - (material) => { - Object.assign(material!, { - side: THREE.DoubleSide, - transparent: true, - extensions: { derivatives: true }, - }) +} + +const GridMaterial = shaderMaterial( + { + cellSize: 1, + sectionSize: 10, + fadeDistance: 100, + fadeStrength: 1, + cellThickness: 1, + sectionThickness: 2, + cellColor: new THREE.Color('#000000'), + sectionColor: new THREE.Color('#2080ff'), + infiniteGrid: 0, + followCamera: 0, + }, + ` varying vec3 worldPosition; + uniform float fadeDistance; + uniform float infiniteGrid; + uniform float followCamera; + void main() { + vec3 pos = position.xz * (1. + fadeDistance * infiniteGrid); + pos.xz += (cameraPosition.xz * followCamera); + worldPosition = pos; + gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); + }`, + ` varying vec3 worldPosition; + uniform float cellSize; + uniform float sectionSize; + uniform vec3 cellColor; + uniform vec3 sectionColor; + uniform float fadeDistance; + uniform float fadeStrength; + uniform float cellThickness; + uniform float sectionThickness; + uniform float infiniteGrid; + float getGrid(float size, float thickness) { + vec2 r = worldPosition.xz / size; + vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r); + float line = min(grid.x, grid.y) + 1. - thickness; + return 1.0 - min(line, 1.); } - ))() - }, [axes]) + void main() { + float g1 = getGrid(cellSize, cellThickness); + float g2 = getGrid(sectionSize, sectionThickness); + float d = 1.0 - min(distance(cameraPosition.xz, worldPosition.xz) / fadeDistance, 1.); + vec3 color = mix(cellColor, sectionColor, min(1.,sectionThickness * g2)); + gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); + gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); + if (gl_FragColor.a <= 0.0) discard; + }`, + (material) => { + Object.assign(material!, { + side: THREE.DoubleSide, + transparent: true, + extensions: { derivatives: true }, + }) + } +) - return ( - - - - - ) -} +export const Grid = React.forwardRef( + ( + { + gridSize = 20, + cellColor = '#000000', + sectionColor = '#2080ff', + cellSize = 1, + sectionSize = 10, + followCamera = false, + infiniteGrid = false, + fadeDistance = 100, + fadeStrength = 1, + cellThickness = 1, + sectionThickness = 2, + ...props + }: JSX.IntrinsicElements['mesh'] & GridProps, + fRef: React.ForwardedRef + ) => { + extend({ GridMaterial }) + const uniforms = { + cellSize, + sectionSize, + cellColor, + sectionColor, + fadeDistance, + fadeStrength, + cellThickness, + sectionThickness, + infiniteGrid, + followCamera, + } + return ( + + + + + ) + } +) From a370447592f43874117a31a9498abc0492455ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Sat, 17 Dec 2022 14:27:07 +0100 Subject: [PATCH 4/6] chore: cleanup --- README.md | 28 ++++++++++++++++++---- src/core/Grid.tsx | 59 ++++++++++++++++++++++++----------------------- yarn.lock | 2 +- 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 37514a2c9..9fac5aa2d 100644 --- a/README.md +++ b/README.md @@ -650,22 +650,40 @@ If you are using other controls (Orbit, Trackball, etc), you will notice how the #### Grid -A y-up oriented, robust grid implementation with multiple tweakable parameters. +

    + Demo +

    + +A y-up oriented, shader-based grid implementation. ```tsx -type GridProps = { - gridSize?: number | [number, number] - cellColor?: THREE.ColorRepresentation +export type GridMaterialType = { + /** Cell size, default: 0.5 */ cellSize?: number + /** Cell thickness, default: 0.5 */ cellThickness?: number - sectionColor?: THREE.ColorRepresentation + /** Cell color, default: black */ + cellColor?: THREE.ColorRepresentation + /** Section size, default: 1 */ sectionSize?: number + /** Section thickness, default: 1 */ sectionThickness?: number + /** Section color, default: #2080ff */ + sectionColor?: THREE.ColorRepresentation + /** Follow camera, default: false */ followCamera?: boolean + /** Display the grid infinitely, default: false */ infiniteGrid?: boolean + /** Fade distance, default: 100 */ fadeDistance?: number + /** Fade strength, default: 1 */ fadeStrength?: number } + +export type GridProps = GridMaterialType & { + /** Default plane-geometry arguments */ + args?: ConstructorParameters +} ``` ```jsx diff --git a/src/core/Grid.tsx b/src/core/Grid.tsx index e0694ab5a..4b739937c 100644 --- a/src/core/Grid.tsx +++ b/src/core/Grid.tsx @@ -8,20 +8,31 @@ import { extend } from '@react-three/fiber' import { shaderMaterial } from './shaderMaterial' export type GridMaterialType = { - cellColor?: THREE.ColorRepresentation + /** Cell size, default: 0.5 */ cellSize?: number + /** Cell thickness, default: 0.5 */ cellThickness?: number - sectionColor?: THREE.ColorRepresentation + /** Cell color, default: black */ + cellColor?: THREE.ColorRepresentation + /** Section size, default: 1 */ sectionSize?: number + /** Section thickness, default: 1 */ sectionThickness?: number + /** Section color, default: #2080ff */ + sectionColor?: THREE.ColorRepresentation + /** Follow camera, default: false */ followCamera?: boolean + /** Display the grid infinitely, default: false */ infiniteGrid?: boolean + /** Fade distance, default: 100 */ fadeDistance?: number + /** Fade strength, default: 1 */ fadeStrength?: number } export type GridProps = GridMaterialType & { - gridSize?: number | [number, number] + /** Default plane-geometry arguments */ + args?: ConstructorParameters } declare global { @@ -34,14 +45,14 @@ declare global { const GridMaterial = shaderMaterial( { - cellSize: 1, - sectionSize: 10, + cellSize: 0.5, + sectionSize: 1, fadeDistance: 100, fadeStrength: 1, - cellThickness: 1, - sectionThickness: 2, - cellColor: new THREE.Color('#000000'), - sectionColor: new THREE.Color('#2080ff'), + cellThickness: 0.5, + sectionThickness: 1, + cellColor: new THREE.Color(), + sectionColor: new THREE.Color(), infiniteGrid: 0, followCamera: 0, }, @@ -50,7 +61,7 @@ const GridMaterial = shaderMaterial( uniform float infiniteGrid; uniform float followCamera; void main() { - vec3 pos = position.xz * (1. + fadeDistance * infiniteGrid); + vec3 pos = position.xzy * (1. + fadeDistance * infiniteGrid); pos.xz += (cameraPosition.xz * followCamera); worldPosition = pos; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); @@ -92,7 +103,7 @@ const GridMaterial = shaderMaterial( export const Grid = React.forwardRef( ( { - gridSize = 20, + args, cellColor = '#000000', sectionColor = '#2080ff', cellSize = 1, @@ -101,29 +112,19 @@ export const Grid = React.forwardRef( infiniteGrid = false, fadeDistance = 100, fadeStrength = 1, - cellThickness = 1, - sectionThickness = 2, + cellThickness = 0.5, + sectionThickness = 1, ...props - }: JSX.IntrinsicElements['mesh'] & GridProps, + }: Omit & GridProps, fRef: React.ForwardedRef ) => { extend({ GridMaterial }) - const uniforms = { - cellSize, - sectionSize, - cellColor, - sectionColor, - fadeDistance, - fadeStrength, - cellThickness, - sectionThickness, - infiniteGrid, - followCamera, - } + const uniforms1 = { cellSize, sectionSize, cellColor, sectionColor, cellThickness, sectionThickness } + const uniforms2 = { fadeDistance, fadeStrength, infiniteGrid, followCamera } return ( - - - + + + ) } diff --git a/yarn.lock b/yarn.lock index f1f9a5d76..1053910ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8684,7 +8684,7 @@ lodash.merge@^4.6.2: lodash.omit@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" - integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA= + integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg== lodash.pick@^4.4.0: version "4.4.0" From da7af951af36286933afb74e9cd932bb5efc74f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Sat, 17 Dec 2022 14:33:18 +0100 Subject: [PATCH 5/6] chore: cleanup --- src/core/Grid.tsx | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/core/Grid.tsx b/src/core/Grid.tsx index 4b739937c..c4153d522 100644 --- a/src/core/Grid.tsx +++ b/src/core/Grid.tsx @@ -90,14 +90,9 @@ const GridMaterial = shaderMaterial( gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); if (gl_FragColor.a <= 0.0) discard; - }`, - (material) => { - Object.assign(material!, { - side: THREE.DoubleSide, - transparent: true, - extensions: { derivatives: true }, - }) - } + #include + #include + }` ) export const Grid = React.forwardRef( @@ -122,8 +117,8 @@ export const Grid = React.forwardRef( const uniforms1 = { cellSize, sectionSize, cellColor, sectionColor, cellThickness, sectionThickness } const uniforms2 = { fadeDistance, fadeStrength, infiniteGrid, followCamera } return ( - - + + ) From d11bc6440ebf1aa57e0be19110eac410af2367d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Sat, 17 Dec 2022 14:40:41 +0100 Subject: [PATCH 6/6] chore: add story --- .storybook/stories/Grid.stories.tsx | 28 +++++++++++ README.md | 2 + src/core/Grid.tsx | 78 ++++++++++++++--------------- 3 files changed, 69 insertions(+), 39 deletions(-) create mode 100644 .storybook/stories/Grid.stories.tsx diff --git a/.storybook/stories/Grid.stories.tsx b/.storybook/stories/Grid.stories.tsx new file mode 100644 index 000000000..47563592f --- /dev/null +++ b/.storybook/stories/Grid.stories.tsx @@ -0,0 +1,28 @@ +import * as React from 'react' +import { Vector3 } from 'three' + +import { Setup } from '../Setup' +import { Grid, Box } from '../../src' + +export default { + title: 'Gizmos/Grid', + component: Grid, + decorators: [(storyFn) => {storyFn()}], +} + +function UseGridScene() { + return ( + + + + + + + + ) +} + +export const UseGridSceneSt = () => +UseGridSceneSt.story = { + name: 'Default', +} diff --git a/README.md b/README.md index 9fac5aa2d..3bea7de9d 100644 --- a/README.md +++ b/README.md @@ -650,6 +650,8 @@ If you are using other controls (Orbit, Trackball, etc), you will notice how the #### Grid +[![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/gizmos-grid--use-grid-scene-st) +

    Demo

    diff --git a/src/core/Grid.tsx b/src/core/Grid.tsx index c4153d522..9cbea70ae 100644 --- a/src/core/Grid.tsx +++ b/src/core/Grid.tsx @@ -56,43 +56,43 @@ const GridMaterial = shaderMaterial( infiniteGrid: 0, followCamera: 0, }, - ` varying vec3 worldPosition; - uniform float fadeDistance; - uniform float infiniteGrid; - uniform float followCamera; - void main() { - vec3 pos = position.xzy * (1. + fadeDistance * infiniteGrid); - pos.xz += (cameraPosition.xz * followCamera); - worldPosition = pos; - gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); - }`, - ` varying vec3 worldPosition; - uniform float cellSize; - uniform float sectionSize; - uniform vec3 cellColor; - uniform vec3 sectionColor; - uniform float fadeDistance; - uniform float fadeStrength; - uniform float cellThickness; - uniform float sectionThickness; - uniform float infiniteGrid; - float getGrid(float size, float thickness) { - vec2 r = worldPosition.xz / size; - vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r); - float line = min(grid.x, grid.y) + 1. - thickness; - return 1.0 - min(line, 1.); - } - void main() { - float g1 = getGrid(cellSize, cellThickness); - float g2 = getGrid(sectionSize, sectionThickness); - float d = 1.0 - min(distance(cameraPosition.xz, worldPosition.xz) / fadeDistance, 1.); - vec3 color = mix(cellColor, sectionColor, min(1.,sectionThickness * g2)); - gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); - gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); - if (gl_FragColor.a <= 0.0) discard; - #include - #include - }` + `varying vec3 worldPosition; + uniform float fadeDistance; + uniform float infiniteGrid; + uniform float followCamera; + void main() { + vec3 pos = position.xzy * (1. + fadeDistance * infiniteGrid); + pos.xz += (cameraPosition.xz * followCamera); + worldPosition = pos; + gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); + }`, + `varying vec3 worldPosition; + uniform float cellSize; + uniform float sectionSize; + uniform vec3 cellColor; + uniform vec3 sectionColor; + uniform float fadeDistance; + uniform float fadeStrength; + uniform float cellThickness; + uniform float sectionThickness; + uniform float infiniteGrid; + float getGrid(float size, float thickness) { + vec2 r = worldPosition.xz / size; + vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r); + float line = min(grid.x, grid.y) + 1. - thickness; + return 1.0 - min(line, 1.); + } + void main() { + float g1 = getGrid(cellSize, cellThickness); + float g2 = getGrid(sectionSize, sectionThickness); + float d = 1.0 - min(distance(cameraPosition.xz, worldPosition.xz) / fadeDistance, 1.); + vec3 color = mix(cellColor, sectionColor, min(1.,sectionThickness * g2)); + gl_FragColor = vec4(color, (g1 + g2) * pow(d,fadeStrength)); + gl_FragColor.a = mix(0.75 * gl_FragColor.a, gl_FragColor.a, g2); + if (gl_FragColor.a <= 0.0) discard; + #include + #include + }` ) export const Grid = React.forwardRef( @@ -101,8 +101,8 @@ export const Grid = React.forwardRef( args, cellColor = '#000000', sectionColor = '#2080ff', - cellSize = 1, - sectionSize = 10, + cellSize = 0.5, + sectionSize = 1, followCamera = false, infiniteGrid = false, fadeDistance = 100,