Merge remote-tracking branch 'origin/main-dev' into feature/layout-comparison-version
This commit is contained in:
13
app/src/assets/shaders/point/point.frag.glsl
Normal file
13
app/src/assets/shaders/point/point.frag.glsl
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
uniform vec3 uOuterColor;
|
||||||
|
uniform vec3 uInnerColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Define the size of the white square as a proportion of the face
|
||||||
|
float borderThickness = 0.2; // Adjust this value for border thickness
|
||||||
|
if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
|
||||||
|
gl_FragColor = vec4(uInnerColor, 1.0); // Inner square
|
||||||
|
} else {
|
||||||
|
gl_FragColor = vec4(uOuterColor, 1.0); // Border
|
||||||
|
}
|
||||||
|
}
|
||||||
6
app/src/assets/shaders/point/point.vert.glsl
Normal file
6
app/src/assets/shaders/point/point.vert.glsl
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
|
}
|
||||||
42
app/src/assets/shaders/zone/zone1.frag.glsl
Normal file
42
app/src/assets/shaders/zone/zone1.frag.glsl
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#define TAU 6.28318530718
|
||||||
|
#define MAX_ITER 5
|
||||||
|
|
||||||
|
varying vec2 vUv;
|
||||||
|
uniform float uTime;
|
||||||
|
uniform vec3 uOuterColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float time = uTime * 0.25;
|
||||||
|
vec2 uv = vUv;
|
||||||
|
|
||||||
|
vec2 p = mod(uv * TAU, TAU) - 250.0;
|
||||||
|
vec2 i = vec2(p);
|
||||||
|
|
||||||
|
float c = 1.0;
|
||||||
|
float inten = 0.005;
|
||||||
|
|
||||||
|
for (int n = 0; n < MAX_ITER; n++) {
|
||||||
|
float t = time * (1.0 - (3.5 / float(n + 1)));
|
||||||
|
i = p + vec2(
|
||||||
|
cos(t - i.x) + sin(t + i.y),
|
||||||
|
sin(t - i.y) + cos(t + i.x)
|
||||||
|
);
|
||||||
|
c += 1.0 / length(vec2(
|
||||||
|
p.x / (sin(i.x + t) / inten),
|
||||||
|
p.y / (cos(i.y + t) / inten)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
c /= float(MAX_ITER);
|
||||||
|
c = 1.17 - pow(c, 1.4);
|
||||||
|
|
||||||
|
vec3 fractalCol = vec3(pow(abs(c), 8.0));
|
||||||
|
fractalCol = clamp(fractalCol + vec3(0.0, 0.35, 0.5), 0.0, 1.0);
|
||||||
|
|
||||||
|
vec3 darkColor = uOuterColor * 0.4;
|
||||||
|
vec3 col = mix(darkColor, uOuterColor, fractalCol.r);
|
||||||
|
|
||||||
|
float verticalFade = 1.0 - vUv.y;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col * verticalFade, verticalFade);
|
||||||
|
}
|
||||||
6
app/src/assets/shaders/zone/zone1.vert.glsl
Normal file
6
app/src/assets/shaders/zone/zone1.vert.glsl
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
|
}
|
||||||
25
app/src/assets/shaders/zone/zone2.frag.glsl
Normal file
25
app/src/assets/shaders/zone/zone2.frag.glsl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
uniform vec3 uOuterColor;
|
||||||
|
uniform float uTime;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Map vUv into -1..1 range like Shadertoy
|
||||||
|
vec2 uv = (vUv - 1.0) * 0.5;
|
||||||
|
|
||||||
|
// Distortion loop – slowed down (uTime * 0.25)
|
||||||
|
for (float i = 1.0; i < 8.0; i++) {
|
||||||
|
uv.y += 0.1 * sin(uv.x * i * i + uTime * 0.25)
|
||||||
|
* sin(uv.y * i * i + uTime * 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base color influenced by uv + zone color
|
||||||
|
vec3 col = uOuterColor;
|
||||||
|
col.r += uv.y * 0.2;
|
||||||
|
col.g += uv.y * 0.3;
|
||||||
|
col.b += uv.y * 0.4;
|
||||||
|
|
||||||
|
// Vertical fade
|
||||||
|
float verticalFade = 1.0 - vUv.y;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col * verticalFade, verticalFade);
|
||||||
|
}
|
||||||
6
app/src/assets/shaders/zone/zone2.vert.glsl
Normal file
6
app/src/assets/shaders/zone/zone2.vert.glsl
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
|
}
|
||||||
37
app/src/assets/shaders/zone/zone3.frag.glsl
Normal file
37
app/src/assets/shaders/zone/zone3.frag.glsl
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
uniform float uTime;
|
||||||
|
uniform vec3 uOuterColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// UV mapping like fragCoord
|
||||||
|
vec2 uv = vUv;
|
||||||
|
vec2 p = uv * 2.0 - 1.0;
|
||||||
|
float t = uTime * 0.3;
|
||||||
|
|
||||||
|
// Flow direction and movement
|
||||||
|
vec2 flowDir = normalize(vec2(-0.7, -1.0));
|
||||||
|
float flowSpeed = 2.0;
|
||||||
|
float flow = dot(p, flowDir) * flowSpeed + t;
|
||||||
|
|
||||||
|
// Ripples
|
||||||
|
float rippleX = sin(p.x * 12.0 + t * 1.5) * cos(p.y * 8.0 + t * 2.0) * 0.3;
|
||||||
|
float rippleY = cos(p.y * 10.0 - t * 1.2) * sin(p.x * 7.0 + t * 0.8) * 0.4;
|
||||||
|
float distort = rippleX + rippleY;
|
||||||
|
|
||||||
|
// Gradient to drive stripes
|
||||||
|
float gradient = fract(flow + distort * 0.5);
|
||||||
|
|
||||||
|
// Smooth liquid band
|
||||||
|
float band = smoothstep(0.2, 0.6, gradient) - smoothstep(0.6, 0.9, gradient);
|
||||||
|
|
||||||
|
// Darker zone color
|
||||||
|
vec3 darkColor = uOuterColor * 0.4;
|
||||||
|
|
||||||
|
// Mix between dark and bright zone color
|
||||||
|
vec3 col = mix(darkColor, uOuterColor, band);
|
||||||
|
|
||||||
|
// Vertical fade
|
||||||
|
float verticalFade = 1.0 - vUv.y;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col * verticalFade, verticalFade);
|
||||||
|
}
|
||||||
6
app/src/assets/shaders/zone/zone3.vert.glsl
Normal file
6
app/src/assets/shaders/zone/zone3.vert.glsl
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
varying vec2 vUv;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
|
}
|
||||||
@@ -7,9 +7,13 @@ import { useThree } from "@react-three/fiber";
|
|||||||
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
||||||
import { useSelectedPoints } from "../../../store/simulation/useSimulationStore";
|
import { useSelectedPoints } from "../../../store/simulation/useSimulationStore";
|
||||||
import { usePointSnapping } from "./helpers/usePointSnapping";
|
import { usePointSnapping } from "./helpers/usePointSnapping";
|
||||||
|
import useShaderReader from "../../../utils/scene/useShaderReader";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useSceneContext } from "../../scene/sceneContext";
|
import { useSceneContext } from "../../scene/sceneContext";
|
||||||
|
|
||||||
|
import vertexShaderUrl from "../../../assets/shaders/point/point.vert.glsl";
|
||||||
|
import fragmentShaderUrl from "../../../assets/shaders/point/point.frag.glsl";
|
||||||
|
|
||||||
import { upsertAisleApi } from "../../../services/factoryBuilder/aisle/upsertAisleApi";
|
import { upsertAisleApi } from "../../../services/factoryBuilder/aisle/upsertAisleApi";
|
||||||
import { deleteAisleApi } from "../../../services/factoryBuilder/aisle/deleteAisleApi";
|
import { deleteAisleApi } from "../../../services/factoryBuilder/aisle/deleteAisleApi";
|
||||||
import { upsertWallApi } from "../../../services/factoryBuilder/wall/upsertWallApi";
|
import { upsertWallApi } from "../../../services/factoryBuilder/wall/upsertWallApi";
|
||||||
@@ -27,6 +31,8 @@ import { calculateAssetTransformationOnWall } from "../wallAsset/Instances/Insta
|
|||||||
|
|
||||||
function Point({ point }: { readonly point: Point }) {
|
function Point({ point }: { readonly point: Point }) {
|
||||||
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
||||||
|
const vertexShader = useShaderReader(vertexShaderUrl);
|
||||||
|
const fragmentShader = useShaderReader(fragmentShaderUrl);
|
||||||
const { raycaster, camera, pointer } = useThree();
|
const { raycaster, camera, pointer } = useThree();
|
||||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
@@ -42,7 +48,11 @@ function Point({ point }: { readonly point: Point }) {
|
|||||||
const { setPosition: setZonePosition, removePoint: removeZonePoint, getZonesByPointId } = zoneStore();
|
const { setPosition: setZonePosition, removePoint: removeZonePoint, getZonesByPointId } = zoneStore();
|
||||||
const { getWallAssetsByWall, updateWallAsset, removeWallAsset } = wallAssetStore();
|
const { getWallAssetsByWall, updateWallAsset, removeWallAsset } = wallAssetStore();
|
||||||
const { selectedVersion } = versionStore();
|
const { selectedVersion } = versionStore();
|
||||||
const { snapAislePoint, snapAisleAngle, snapWallPoint, snapWallAngle, snapFloorPoint, snapFloorAngle, snapZonePoint, snapZoneAngle } = usePointSnapping({ uuid: point.pointUuid, pointType: point.pointType, position: point.position });
|
const { snapAislePoint, snapAisleAngle, snapWallPoint, snapWallAngle, snapFloorPoint, snapFloorAngle, snapZonePoint, snapZoneAngle } = usePointSnapping({
|
||||||
|
uuid: point.pointUuid,
|
||||||
|
pointType: point.pointType,
|
||||||
|
position: point.position,
|
||||||
|
});
|
||||||
const { hoveredPoint, hoveredLine, setHoveredPoint } = useBuilderStore();
|
const { hoveredPoint, hoveredLine, setHoveredPoint } = useBuilderStore();
|
||||||
const { selectedPoints } = useSelectedPoints();
|
const { selectedPoints } = useSelectedPoints();
|
||||||
const { userId, organization } = getUserData();
|
const { userId, organization } = getUserData();
|
||||||
@@ -695,9 +705,7 @@ function Point({ point }: { readonly point: Point }) {
|
|||||||
}
|
}
|
||||||
}, [selectedPoints]);
|
}, [selectedPoints]);
|
||||||
|
|
||||||
if (!point) {
|
if (!point || !vertexShader || !fragmentShader) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -733,37 +741,18 @@ function Point({ point }: { readonly point: Point }) {
|
|||||||
userData={point}
|
userData={point}
|
||||||
>
|
>
|
||||||
<boxGeometry args={boxScale} />
|
<boxGeometry args={boxScale} />
|
||||||
<shaderMaterial
|
<shaderMaterial ref={materialRef} uniforms={uniforms} vertexShader={vertexShader} fragmentShader={fragmentShader} />
|
||||||
ref={materialRef}
|
|
||||||
uniforms={uniforms}
|
|
||||||
vertexShader={`
|
|
||||||
varying vec2 vUv;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vUv = uv;
|
|
||||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
fragmentShader={`
|
|
||||||
varying vec2 vUv;
|
|
||||||
uniform vec3 uOuterColor;
|
|
||||||
uniform vec3 uInnerColor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// Define the size of the white square as a proportion of the face
|
|
||||||
float borderThickness = 0.2; // Adjust this value for border thickness
|
|
||||||
if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
|
|
||||||
gl_FragColor = vec4(uInnerColor, 1.0); // Inner square
|
|
||||||
} else {
|
|
||||||
gl_FragColor = vec4(uOuterColor, 1.0); // Border
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
</mesh>
|
</mesh>
|
||||||
</DragControls>
|
</DragControls>
|
||||||
) : (
|
) : (
|
||||||
<group key={point.pointUuid} uuid={point.pointUuid} name={`${point.pointType}-Point`} position={[point.position[0], 0.3, point.position[2]]} userData={point} rotation={[Math.PI / 2, 0, 0]}>
|
<group
|
||||||
|
key={point.pointUuid}
|
||||||
|
uuid={point.pointUuid}
|
||||||
|
name={`${point.pointType}-Point`}
|
||||||
|
position={[point.position[0], 0.3, point.position[2]]}
|
||||||
|
userData={point}
|
||||||
|
rotation={[Math.PI / 2, 0, 0]}
|
||||||
|
>
|
||||||
<mesh>
|
<mesh>
|
||||||
<torusGeometry args={[0.4, 0.1, 2, 16]} />
|
<torusGeometry args={[0.4, 0.1, 2, 16]} />
|
||||||
<meshBasicMaterial color="#6F42C1" />
|
<meshBasicMaterial color="#6F42C1" />
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from "three";
|
||||||
import * as Constants from '../../../../types/world/worldConstants';
|
import { useRef, useMemo } from "react";
|
||||||
import { useRef, useMemo } from 'react';
|
import * as Constants from "../../../../types/world/worldConstants";
|
||||||
|
import useShaderReader from "../../../../utils/scene/useShaderReader";
|
||||||
|
|
||||||
|
import vertexShaderUrl from "../../../../assets/shaders/point/point.vert.glsl";
|
||||||
|
import fragmentShaderUrl from "../../../../assets/shaders/point/point.frag.glsl";
|
||||||
|
|
||||||
function ReferencePoint({ point }: { readonly point: Point }) {
|
function ReferencePoint({ point }: { readonly point: Point }) {
|
||||||
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
||||||
|
const vertexShader = useShaderReader(vertexShaderUrl);
|
||||||
|
const fragmentShader = useShaderReader(fragmentShaderUrl);
|
||||||
|
|
||||||
const boxScale: [number, number, number] = Constants.pointConfig.boxScale;
|
const boxScale: [number, number, number] = Constants.pointConfig.boxScale;
|
||||||
const colors = {
|
const colors = {
|
||||||
@@ -12,64 +18,37 @@ function ReferencePoint({ point }: { readonly point: Point }) {
|
|||||||
defaultDeleteColor: Constants.pointConfig.deleteColor,
|
defaultDeleteColor: Constants.pointConfig.deleteColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uniforms = useMemo(() => ({
|
const uniforms = useMemo(
|
||||||
uOuterColor: { value: new THREE.Color(colors.defaultOuterColor) },
|
() => ({
|
||||||
uInnerColor: { value: new THREE.Color(colors.defaultInnerColor) },
|
uOuterColor: { value: new THREE.Color(colors.defaultOuterColor) },
|
||||||
}), [colors.defaultInnerColor, colors.defaultOuterColor, colors.defaultDeleteColor]);
|
uInnerColor: { value: new THREE.Color(colors.defaultInnerColor) },
|
||||||
|
}),
|
||||||
|
[colors.defaultInnerColor, colors.defaultOuterColor, colors.defaultDeleteColor]
|
||||||
|
);
|
||||||
|
|
||||||
if (!point) {
|
if (!point) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pointName = 'Point';
|
let pointName = "Point";
|
||||||
if (point.pointType === 'Wall') {
|
if (point.pointType === "Wall") {
|
||||||
pointName = 'Wall-Point';
|
pointName = "Wall-Point";
|
||||||
} else if (point.pointType === 'Floor') {
|
} else if (point.pointType === "Floor") {
|
||||||
pointName = 'Floor-Point';
|
pointName = "Floor-Point";
|
||||||
} else if (point.pointType === 'Aisle') {
|
} else if (point.pointType === "Aisle") {
|
||||||
pointName = 'Aisle-Point';
|
pointName = "Aisle-Point";
|
||||||
} else if (point.pointType === 'Zone') {
|
} else if (point.pointType === "Zone") {
|
||||||
pointName = 'Zone-Point';
|
pointName = "Zone-Point";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!point || !vertexShader || !fragmentShader) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<mesh
|
<mesh position={new THREE.Vector3(...point.position)} name={pointName} uuid={point.pointUuid} userData={point}>
|
||||||
position={new THREE.Vector3(...point.position)}
|
|
||||||
name={pointName}
|
|
||||||
uuid={point.pointUuid}
|
|
||||||
userData={point}
|
|
||||||
>
|
|
||||||
<boxGeometry args={boxScale} />
|
<boxGeometry args={boxScale} />
|
||||||
<shaderMaterial
|
<shaderMaterial ref={materialRef} uniforms={uniforms} vertexShader={vertexShader} fragmentShader={fragmentShader} />
|
||||||
ref={materialRef}
|
|
||||||
uniforms={uniforms}
|
|
||||||
vertexShader={`
|
|
||||||
varying vec2 vUv;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vUv = uv;
|
|
||||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
fragmentShader={`
|
|
||||||
varying vec2 vUv;
|
|
||||||
uniform vec3 uOuterColor;
|
|
||||||
uniform vec3 uInnerColor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// Define the size of the white square as a proportion of the face
|
|
||||||
float borderThickness = 0.2; // Adjust this value for border thickness
|
|
||||||
if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness &&
|
|
||||||
vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
|
|
||||||
gl_FragColor = vec4(uInnerColor, 1.0); // Inner square
|
|
||||||
} else {
|
|
||||||
gl_FragColor = vec4(uOuterColor, 1.0); // Border
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
</mesh>
|
</mesh>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ReferencePoint;
|
export default ReferencePoint;
|
||||||
|
|||||||
@@ -2,176 +2,27 @@ import { useMemo, useState } from "react";
|
|||||||
import { Color, DoubleSide, ShaderMaterial, Vector3 } from "three";
|
import { Color, DoubleSide, ShaderMaterial, Vector3 } from "three";
|
||||||
import { useFrame } from "@react-three/fiber";
|
import { useFrame } from "@react-three/fiber";
|
||||||
import { useSceneStore } from "../../../../../store/scene/useSceneStore";
|
import { useSceneStore } from "../../../../../store/scene/useSceneStore";
|
||||||
|
import useShaderReader from "../../../../../utils/scene/useShaderReader";
|
||||||
|
|
||||||
|
import vertexShaderUrl from "../../../../../assets/shaders/zone/zone1.vert.glsl";
|
||||||
|
import fragmentShaderUrl from "../../../../../assets/shaders/zone/zone1.frag.glsl";
|
||||||
|
import { RoundedBox } from "@react-three/drei";
|
||||||
|
|
||||||
function ZoneInstance({ zone }: { readonly zone: Zone }) {
|
function ZoneInstance({ zone }: { readonly zone: Zone }) {
|
||||||
|
const vertexShader = useShaderReader(vertexShaderUrl);
|
||||||
|
const fragmentShader = useShaderReader(fragmentShaderUrl);
|
||||||
const zoneLayer = zone.points[0].layer;
|
const zoneLayer = zone.points[0].layer;
|
||||||
const { limitFps } = useSceneStore();
|
const { limitFps } = useSceneStore();
|
||||||
const [time, setTime] = useState<number>();
|
const [time, setTime] = useState<number>();
|
||||||
|
const isCornerReferenceVisible = false;
|
||||||
// const zoneMaterial = useMemo(() => {
|
|
||||||
// return new ShaderMaterial({
|
|
||||||
// side: DoubleSide,
|
|
||||||
// vertexShader: `
|
|
||||||
// varying vec2 vUv;
|
|
||||||
// void main() {
|
|
||||||
// vUv = uv;
|
|
||||||
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
||||||
// }
|
|
||||||
// `,
|
|
||||||
// fragmentShader: `
|
|
||||||
// varying vec2 vUv;
|
|
||||||
// uniform vec3 uOuterColor;
|
|
||||||
// uniform float uTime;
|
|
||||||
|
|
||||||
// void main() {
|
|
||||||
// // Map vUv into -1..1 range like Shadertoy
|
|
||||||
// vec2 uv = (vUv - 1.0) * 0.5;
|
|
||||||
|
|
||||||
// // Distortion loop – slowed down (uTime * 0.25)
|
|
||||||
// for (float i = 1.0; i < 8.0; i++) {
|
|
||||||
// uv.y += 0.1 * sin(uv.x * i * i + uTime * 0.25)
|
|
||||||
// * sin(uv.y * i * i + uTime * 0.25);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Base color influenced by uv + zone color
|
|
||||||
// vec3 col = uOuterColor;
|
|
||||||
// col.r += uv.y * 0.2;
|
|
||||||
// col.g += uv.y * 0.3;
|
|
||||||
// col.b += uv.y * 0.4;
|
|
||||||
|
|
||||||
// // Fade vertically for a nicer top fade-out
|
|
||||||
// float verticalFade = 1.0 - vUv.y;
|
|
||||||
|
|
||||||
// gl_FragColor = vec4(col * verticalFade, verticalFade);
|
|
||||||
// }
|
|
||||||
// `,
|
|
||||||
// uniforms: {
|
|
||||||
// uOuterColor: { value: new Color(zone.zoneColor) },
|
|
||||||
// uTime: { value: time },
|
|
||||||
// },
|
|
||||||
// transparent: true,
|
|
||||||
// depthWrite: false,
|
|
||||||
// });
|
|
||||||
// }, [time]);
|
|
||||||
|
|
||||||
// const zoneMaterial = useMemo(() => {
|
|
||||||
// return new ShaderMaterial({
|
|
||||||
// side: DoubleSide,
|
|
||||||
// vertexShader: `
|
|
||||||
// varying vec2 vUv;
|
|
||||||
// void main(){
|
|
||||||
// vUv = uv;
|
|
||||||
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
||||||
// }
|
|
||||||
// `,
|
|
||||||
// fragmentShader: `
|
|
||||||
// varying vec2 vUv;
|
|
||||||
// uniform float uTime;
|
|
||||||
// uniform vec3 uOuterColor;
|
|
||||||
|
|
||||||
// void main() {
|
|
||||||
// // UV mapping like fragCoord
|
|
||||||
// vec2 uv = vUv;
|
|
||||||
// vec2 p = uv * 2.0 - 1.0;
|
|
||||||
// float t = uTime * 0.3;
|
|
||||||
|
|
||||||
// // Flow direction and movement
|
|
||||||
// vec2 flowDir = normalize(vec2(-0.7, -1.0));
|
|
||||||
// float flowSpeed = 2.0;
|
|
||||||
// float flow = dot(p, flowDir) * flowSpeed + t;
|
|
||||||
|
|
||||||
// // Ripples
|
|
||||||
// float rippleX = sin(p.x * 12.0 + t * 1.5) * cos(p.y * 8.0 + t * 2.0) * 0.3;
|
|
||||||
// float rippleY = cos(p.y * 10.0 - t * 1.2) * sin(p.x * 7.0 + t * 0.8) * 0.4;
|
|
||||||
// float distort = rippleX + rippleY;
|
|
||||||
|
|
||||||
// // Gradient to drive stripes
|
|
||||||
// float gradient = fract(flow + distort * 0.5);
|
|
||||||
|
|
||||||
// // Smooth liquid band
|
|
||||||
// float band = smoothstep(0.2, 0.6, gradient) - smoothstep(0.6, 0.9, gradient);
|
|
||||||
|
|
||||||
// // Darker zone color
|
|
||||||
// vec3 darkColor = uOuterColor * 0.4;
|
|
||||||
|
|
||||||
// // Mix between dark and bright zone color
|
|
||||||
// vec3 col = mix(darkColor, uOuterColor, band);
|
|
||||||
|
|
||||||
// // Vertical fade
|
|
||||||
// float verticalFade = 1.0 - vUv.y;
|
|
||||||
|
|
||||||
// gl_FragColor = vec4(col * verticalFade, verticalFade);
|
|
||||||
// }
|
|
||||||
// `,
|
|
||||||
// uniforms: {
|
|
||||||
// uOuterColor: { value: new Color(zone.zoneColor) },
|
|
||||||
// uTime: { value: time },
|
|
||||||
// },
|
|
||||||
// transparent: true,
|
|
||||||
// depthWrite: false,
|
|
||||||
// });
|
|
||||||
// }, [zone.zoneColor, time]);
|
|
||||||
|
|
||||||
const zoneMaterial = useMemo(() => {
|
const zoneMaterial = useMemo(() => {
|
||||||
|
if (!vertexShader || !fragmentShader) return null;
|
||||||
|
|
||||||
return new ShaderMaterial({
|
return new ShaderMaterial({
|
||||||
side: DoubleSide,
|
side: DoubleSide,
|
||||||
vertexShader: `
|
vertexShader,
|
||||||
varying vec2 vUv;
|
fragmentShader,
|
||||||
void main() {
|
|
||||||
vUv = uv;
|
|
||||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
fragmentShader: `
|
|
||||||
#define TAU 6.28318530718
|
|
||||||
#define MAX_ITER 5
|
|
||||||
|
|
||||||
varying vec2 vUv;
|
|
||||||
uniform float uTime;
|
|
||||||
uniform vec3 uOuterColor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
float time = uTime * 0.25;
|
|
||||||
|
|
||||||
// uv in [0,1]
|
|
||||||
vec2 uv = vUv;
|
|
||||||
|
|
||||||
// convert to p space like Shadertoy
|
|
||||||
vec2 p = mod(uv * TAU, TAU) - 250.0;
|
|
||||||
vec2 i = vec2(p);
|
|
||||||
|
|
||||||
float c = 1.0;
|
|
||||||
float inten = 0.005;
|
|
||||||
|
|
||||||
for (int n = 0; n < MAX_ITER; n++) {
|
|
||||||
float t = time * (1.0 - (3.5 / float(n + 1)));
|
|
||||||
i = p + vec2(
|
|
||||||
cos(t - i.x) + sin(t + i.y),
|
|
||||||
sin(t - i.y) + cos(t + i.x)
|
|
||||||
);
|
|
||||||
c += 1.0 / length(vec2(
|
|
||||||
p.x / (sin(i.x + t) / inten),
|
|
||||||
p.y / (cos(i.y + t) / inten)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
c /= float(MAX_ITER);
|
|
||||||
c = 1.17 - pow(c, 1.4);
|
|
||||||
|
|
||||||
// base fractal color
|
|
||||||
vec3 fractalCol = vec3(pow(abs(c), 8.0));
|
|
||||||
fractalCol = clamp(fractalCol + vec3(0.0, 0.35, 0.5), 0.0, 1.0);
|
|
||||||
|
|
||||||
// Mix between dark and bright zone color
|
|
||||||
vec3 darkColor = uOuterColor * 0.4;
|
|
||||||
vec3 col = mix(darkColor, uOuterColor, fractalCol.r);
|
|
||||||
|
|
||||||
// Vertical fade
|
|
||||||
float verticalFade = 1.0 - vUv.y;
|
|
||||||
|
|
||||||
gl_FragColor = vec4(col * verticalFade, verticalFade);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uOuterColor: { value: new Color(zone.zoneColor) },
|
uOuterColor: { value: new Color(zone.zoneColor) },
|
||||||
uTime: { value: time },
|
uTime: { value: time },
|
||||||
@@ -187,10 +38,13 @@ function ZoneInstance({ zone }: { readonly zone: Zone }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!zoneMaterial) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<mesh name={`Zone-${zone.zoneUuid}`} userData={zone}>
|
<mesh name={`Zone-${zone.zoneUuid}`} userData={zone}>
|
||||||
{zone.points.map((point, index: number) => {
|
{zone.points.map((point, index: number) => {
|
||||||
const nextPoint = zone.points[(index + 1) % zone.points.length];
|
const nextPoint = zone.points[(index + 1) % zone.points.length];
|
||||||
|
const prevPoint = zone.points[(index - 1 + zone.points.length) % zone.points.length];
|
||||||
|
|
||||||
const point1 = new Vector3(...point.position);
|
const point1 = new Vector3(...point.position);
|
||||||
const point2 = new Vector3(...nextPoint.position);
|
const point2 = new Vector3(...nextPoint.position);
|
||||||
@@ -199,14 +53,49 @@ function ZoneInstance({ zone }: { readonly zone: Zone }) {
|
|||||||
const planeHeight = zone.zoneHeight;
|
const planeHeight = zone.zoneHeight;
|
||||||
|
|
||||||
const midpoint = new Vector3((point1.x + point2.x) / 2, zone.zoneHeight / 2 + (zoneLayer - 1) * zone.zoneHeight, (point1.z + point2.z) / 2);
|
const midpoint = new Vector3((point1.x + point2.x) / 2, zone.zoneHeight / 2 + (zoneLayer - 1) * zone.zoneHeight, (point1.z + point2.z) / 2);
|
||||||
|
|
||||||
const angle = Math.atan2(point2.z - point1.z, point2.x - point1.x);
|
const angle = Math.atan2(point2.z - point1.z, point2.x - point1.x);
|
||||||
|
const bottomCorner = new Vector3(point.position[0], (zoneLayer - 1) * zone.zoneHeight, point.position[2]);
|
||||||
|
const halfHeight = zone.zoneHeight / 4;
|
||||||
|
|
||||||
|
const dirNext = new Vector3(nextPoint.position[0] - point.position[0], 0, nextPoint.position[2] - point.position[2]).normalize();
|
||||||
|
const dirPrev = new Vector3(prevPoint.position[0] - point.position[0], 0, prevPoint.position[2] - point.position[2]).normalize();
|
||||||
|
|
||||||
|
const frameThickness = 0.25;
|
||||||
|
|
||||||
|
const position1: [number, number, number] = [bottomCorner.x, bottomCorner.y + halfHeight / 2, bottomCorner.z];
|
||||||
|
const position2: [number, number, number] = [
|
||||||
|
bottomCorner.clone().add(dirNext.clone().multiplyScalar(halfHeight / 2)).x,
|
||||||
|
bottomCorner.clone().add(dirNext.clone().multiplyScalar(halfHeight / 2)).y + frameThickness / 2,
|
||||||
|
bottomCorner.clone().add(dirNext.clone().multiplyScalar(halfHeight / 2)).z,
|
||||||
|
];
|
||||||
|
const position3: [number, number, number] = [
|
||||||
|
bottomCorner.clone().add(dirPrev.clone().multiplyScalar(halfHeight / 2)).x,
|
||||||
|
bottomCorner.clone().add(dirPrev.clone().multiplyScalar(halfHeight / 2)).y + frameThickness / 2,
|
||||||
|
bottomCorner.clone().add(dirPrev.clone().multiplyScalar(halfHeight / 2)).z,
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<mesh key={index} position={midpoint} rotation={[0, -angle, 0]}>
|
<group key={index}>
|
||||||
<planeGeometry args={[planeWidth, planeHeight]} />
|
<mesh position={midpoint} rotation={[0, -angle, 0]}>
|
||||||
<primitive object={zoneMaterial.clone()} attach="material" />
|
<planeGeometry args={[planeWidth, planeHeight]} />
|
||||||
</mesh>
|
<primitive object={zoneMaterial.clone()} attach="material" />
|
||||||
|
</mesh>
|
||||||
|
{isCornerReferenceVisible && (
|
||||||
|
<>
|
||||||
|
<RoundedBox radius={0.1} args={[frameThickness, halfHeight, frameThickness]} position={position1}>
|
||||||
|
<meshStandardMaterial depthWrite={true} color={zone.zoneColor} />
|
||||||
|
</RoundedBox>
|
||||||
|
|
||||||
|
<RoundedBox radius={0.1} args={[halfHeight, frameThickness, frameThickness]} position={position2} rotation={[0, -Math.atan2(dirNext.z, dirNext.x), 0]}>
|
||||||
|
<meshStandardMaterial depthWrite={true} color={zone.zoneColor} />
|
||||||
|
</RoundedBox>
|
||||||
|
|
||||||
|
<RoundedBox radius={0.1} args={[halfHeight, frameThickness, frameThickness]} position={position3} rotation={[0, -Math.atan2(dirPrev.z, dirPrev.x), 0]}>
|
||||||
|
<meshStandardMaterial depthWrite={true} color={zone.zoneColor} />
|
||||||
|
</RoundedBox>
|
||||||
|
</>
|
||||||
|
)}{" "}
|
||||||
|
</group>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { getUserData } from "../../../../functions/getUserData";
|
|||||||
import ReferencePoint from "../../point/reference/referencePoint";
|
import ReferencePoint from "../../point/reference/referencePoint";
|
||||||
import ReferenceZone from "./referenceZone";
|
import ReferenceZone from "./referenceZone";
|
||||||
|
|
||||||
|
import getCenteroidPoint from "../../functions/getCenteroid";
|
||||||
|
|
||||||
import { upsertZoneApi } from "../../../../services/factoryBuilder/zone/upsertZoneApi";
|
import { upsertZoneApi } from "../../../../services/factoryBuilder/zone/upsertZoneApi";
|
||||||
|
|
||||||
function ZoneCreator() {
|
function ZoneCreator() {
|
||||||
@@ -95,14 +97,17 @@ function ZoneCreator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tempPoints.length > 2 && isCreating && snappedPoint && snappedPoint.pointUuid === tempPoints[0].pointUuid) {
|
if (tempPoints.length > 2 && isCreating && snappedPoint && snappedPoint.pointUuid === tempPoints[0].pointUuid) {
|
||||||
|
const vec2Points = tempPoints.map((p) => new THREE.Vector2(parseFloat(p.position[0].toFixed(2)), parseFloat(p.position[2].toFixed(2))));
|
||||||
|
const viewPortPosition = getCenteroidPoint(vec2Points);
|
||||||
|
|
||||||
const zone: Zone = {
|
const zone: Zone = {
|
||||||
zoneUuid: THREE.MathUtils.generateUUID(),
|
zoneUuid: THREE.MathUtils.generateUUID(),
|
||||||
zoneName: `Zone `,
|
zoneName: `Zone `,
|
||||||
points: tempPoints,
|
points: tempPoints,
|
||||||
zoneColor,
|
zoneColor,
|
||||||
zoneHeight,
|
zoneHeight,
|
||||||
viewPortPosition: [0, 0, 0],
|
viewPortPosition: viewPortPosition ? [viewPortPosition.x, 10, viewPortPosition.y] : [0, 0, 0],
|
||||||
viewPortTarget: [0, 0, 0],
|
viewPortTarget: viewPortPosition ? [viewPortPosition.x, 0, viewPortPosition.y] : [0, 0, 0],
|
||||||
};
|
};
|
||||||
|
|
||||||
addZone(zone);
|
addZone(zone);
|
||||||
@@ -147,14 +152,17 @@ function ZoneCreator() {
|
|||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
} else if (pointIntersects) {
|
} else if (pointIntersects) {
|
||||||
if (tempPoints.length > 2 && isCreating && pointIntersects.object.uuid === tempPoints[0].pointUuid) {
|
if (tempPoints.length > 2 && isCreating && pointIntersects.object.uuid === tempPoints[0].pointUuid) {
|
||||||
|
const vec2Points = tempPoints.map((p) => new THREE.Vector2(parseFloat(p.position[0].toFixed(2)), parseFloat(p.position[2].toFixed(2))));
|
||||||
|
const viewPortPosition = getCenteroidPoint(vec2Points);
|
||||||
|
|
||||||
const zone: Zone = {
|
const zone: Zone = {
|
||||||
zoneUuid: THREE.MathUtils.generateUUID(),
|
zoneUuid: THREE.MathUtils.generateUUID(),
|
||||||
zoneName: "Zone",
|
zoneName: "Zone",
|
||||||
points: tempPoints,
|
points: tempPoints,
|
||||||
zoneColor,
|
zoneColor,
|
||||||
zoneHeight,
|
zoneHeight,
|
||||||
viewPortPosition: [0, 0, 0],
|
viewPortPosition: viewPortPosition ? [viewPortPosition.x, 10, viewPortPosition.y] : [0, 0, 0],
|
||||||
viewPortTarget: [0, 0, 0],
|
viewPortTarget: viewPortPosition ? [viewPortPosition.x, 0, viewPortPosition.y] : [0, 0, 0],
|
||||||
};
|
};
|
||||||
|
|
||||||
addZone(zone);
|
addZone(zone);
|
||||||
@@ -208,14 +216,17 @@ function ZoneCreator() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (isCreating) {
|
if (isCreating) {
|
||||||
if (tempPoints.length >= 3) {
|
if (tempPoints.length >= 3) {
|
||||||
|
const vec2Points = tempPoints.map((p) => new THREE.Vector2(parseFloat(p.position[0].toFixed(2)), parseFloat(p.position[2].toFixed(2))));
|
||||||
|
const viewPortPosition = getCenteroidPoint(vec2Points);
|
||||||
|
|
||||||
const zone: Zone = {
|
const zone: Zone = {
|
||||||
zoneUuid: THREE.MathUtils.generateUUID(),
|
zoneUuid: THREE.MathUtils.generateUUID(),
|
||||||
zoneName: "Zone",
|
zoneName: "Zone",
|
||||||
points: tempPoints,
|
points: tempPoints,
|
||||||
zoneColor,
|
zoneColor,
|
||||||
zoneHeight,
|
zoneHeight,
|
||||||
viewPortPosition: [0, 0, 0],
|
viewPortPosition: viewPortPosition ? [viewPortPosition.x, 10, viewPortPosition.y] : [0, 0, 0],
|
||||||
viewPortTarget: [0, 0, 0],
|
viewPortTarget: viewPortPosition ? [viewPortPosition.x, 0, viewPortPosition.y] : [0, 0, 0],
|
||||||
};
|
};
|
||||||
|
|
||||||
addZone(zone);
|
addZone(zone);
|
||||||
|
|||||||
3
app/src/types/declarations.d.ts
vendored
3
app/src/types/declarations.d.ts
vendored
@@ -5,4 +5,5 @@ declare module '*.css';
|
|||||||
declare module '*.scss';
|
declare module '*.scss';
|
||||||
|
|
||||||
declare module '*.glb';
|
declare module '*.glb';
|
||||||
declare module '*.gltf';
|
declare module '*.gltf';
|
||||||
|
declare module '*.glsl';
|
||||||
13
app/src/utils/scene/useShaderReader.ts
Normal file
13
app/src/utils/scene/useShaderReader.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export default function useShaderReader(url: string) {
|
||||||
|
const [source, setSource] = useState<string>("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(url)
|
||||||
|
.then((res) => res.text())
|
||||||
|
.then((txt) => setSource(txt));
|
||||||
|
}, [url]);
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user