mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
working on procedurally generated gray ring, still wip.
This commit is contained in:
parent
acc36a826e
commit
5f473325fc
8 changed files with 165 additions and 76 deletions
Binary file not shown.
|
@ -1,42 +1,142 @@
|
||||||
import { draco } from "drei";
|
import React, { memo, useMemo } from "react";
|
||||||
import React, { memo } from "react";
|
|
||||||
import { useLoader } from "react-three-fiber";
|
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
import lofTexture from "../static/sprites/lof.png";
|
||||||
|
import holeTexture from "../static/sprites/hole.png";
|
||||||
|
import lifeTexture from "../static/sprites/life.png";
|
||||||
|
import { useLoader } from "react-three-fiber";
|
||||||
|
|
||||||
type GrayRingProps = {
|
type GrayRingProps = {
|
||||||
grayRingPosY: number;
|
grayRingPosY: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GLTFResult = GLTF & {
|
|
||||||
nodes: {
|
|
||||||
LainRing: THREE.Mesh;
|
|
||||||
};
|
|
||||||
materials: {
|
|
||||||
RingTexture: THREE.MeshStandardMaterial;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const GrayRing = memo((props: GrayRingProps) => {
|
const GrayRing = memo((props: GrayRingProps) => {
|
||||||
const { nodes, materials } = useLoader<GLTFResult>(
|
const lofTex = useLoader(THREE.TextureLoader, lofTexture);
|
||||||
GLTFLoader,
|
const holeTex = useLoader(THREE.TextureLoader, holeTexture);
|
||||||
"/models/ring0.glb",
|
const lifeTex = useLoader(THREE.TextureLoader, lifeTexture);
|
||||||
draco("/draco-gltf/")
|
|
||||||
|
const uniforms = useMemo(
|
||||||
|
() => ({
|
||||||
|
lof: { type: "t", value: lofTex },
|
||||||
|
hole: { type: "t", value: holeTex },
|
||||||
|
life: { type: "t", value: lifeTex },
|
||||||
|
}),
|
||||||
|
[lofTex, holeTex, lifeTex]
|
||||||
);
|
);
|
||||||
|
|
||||||
// -0.27
|
const vertexShader = `
|
||||||
|
varying vec2 vUv;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const fragmentShader = `
|
||||||
|
varying vec2 vUv;
|
||||||
|
uniform sampler2D lof;
|
||||||
|
uniform sampler2D hole;
|
||||||
|
uniform sampler2D life;
|
||||||
|
|
||||||
|
// transform coordinates to uniform within segment
|
||||||
|
float tolocal(float x, int segments, float step) {
|
||||||
|
float period = 1.0/step*float(segments);
|
||||||
|
return mod(x, period) / period;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if coordinate is within the given height
|
||||||
|
bool isheight(float y, float thin) {
|
||||||
|
return y > 0.5-thin/2.0 && y < 0.5+thin/2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sloping function
|
||||||
|
float slope(float x, float thin) {
|
||||||
|
return x*(1.0-thin)/2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// frag color / texture
|
||||||
|
// #424252 hex in original textures
|
||||||
|
vec4 color(vec2 vUv, int quadnum, bool textureexists, int thinperiod, int quadlen, float step) {
|
||||||
|
if (!textureexists) {
|
||||||
|
return vec4(0.259,0.259,0.322, 1);
|
||||||
|
} else if (quadnum % 2 == 1) {
|
||||||
|
return texture2D(hole, vec2(tolocal(vUv.x, quadlen-thinperiod, step), vUv.y));
|
||||||
|
} else if (quadnum == 0) {
|
||||||
|
return texture2D(lof, vec2(tolocal(vUv.x, quadlen-thinperiod, step), vUv.y));
|
||||||
|
} else {
|
||||||
|
return texture2D(life, vec2(tolocal(vUv.x, quadlen-thinperiod, step), vUv.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// number of segments
|
||||||
|
float step = 64.0;
|
||||||
|
float thin = 0.3;
|
||||||
|
|
||||||
|
// segment within circle
|
||||||
|
int segment = int(floor(vUv.x * step));
|
||||||
|
|
||||||
|
int quadlen = int(step)/4;
|
||||||
|
|
||||||
|
// segment within circle's quad
|
||||||
|
int quadel = int(segment) % quadlen;
|
||||||
|
|
||||||
|
// which quad
|
||||||
|
int quadnum = int(segment) / quadlen;
|
||||||
|
|
||||||
|
// how big thin part is
|
||||||
|
int thinperiod = 12;
|
||||||
|
|
||||||
|
if (quadel < thinperiod && isheight(vUv.y, thin)) {
|
||||||
|
// thin line
|
||||||
|
gl_FragColor = color(vUv, quadnum, false, thinperiod, quadlen, step);
|
||||||
|
} else if (quadel == thinperiod) {
|
||||||
|
// slope up
|
||||||
|
float dist = tolocal(vUv.x, 1, step);
|
||||||
|
if (vUv.y > slope(1.0-dist, thin) && vUv.y < 1.0-slope(1.0-dist, thin)) {
|
||||||
|
gl_FragColor = color(vUv, quadnum, true, thinperiod, quadlen, step);
|
||||||
|
} else {
|
||||||
|
gl_FragColor = vec4(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
} else if (quadel == quadlen-1) {
|
||||||
|
// slope down
|
||||||
|
float dist = tolocal(vUv.x, 1, step);
|
||||||
|
if (vUv.y > slope(dist, thin) && vUv.y < 1.0-slope(dist, thin)) {
|
||||||
|
gl_FragColor = color(vUv, quadnum, true, thinperiod, quadlen, step);
|
||||||
|
} else {
|
||||||
|
gl_FragColor = vec4(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
} else if (quadel > thinperiod) {
|
||||||
|
gl_FragColor = color(vUv, quadnum, true, thinperiod, quadlen, step);
|
||||||
|
} else {
|
||||||
|
// transparent
|
||||||
|
gl_FragColor = vec4(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group
|
<mesh
|
||||||
scale={[1.3, 1.3, 1.3]}
|
|
||||||
position={[0, props.grayRingPosY, 0]}
|
position={[0, props.grayRingPosY, 0]}
|
||||||
rotation={[0, 2.6, 0]}
|
rotation={[0, 3.7, 0]}
|
||||||
|
renderOrder={1}
|
||||||
|
scale={[5, 2.5, 5]}
|
||||||
>
|
>
|
||||||
<mesh
|
<cylinderBufferGeometry
|
||||||
geometry={nodes.LainRing.geometry}
|
args={[0.25, 0.25, 0.027, 64, 64, true]}
|
||||||
rotation={[0, Math.PI / 4, 0]}
|
attach="geometry"
|
||||||
material={materials.RingTexture}
|
/>
|
||||||
></mesh>
|
<shaderMaterial
|
||||||
</group>
|
attach="material"
|
||||||
|
side={THREE.DoubleSide}
|
||||||
|
vertexShader={vertexShader}
|
||||||
|
fragmentShader={fragmentShader}
|
||||||
|
transparent={true}
|
||||||
|
uniforms={uniforms}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ const HUDElement = memo((props: HUDElementProps) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group visible={props.hudVisibility}>
|
<group visible={props.hudVisibility} renderOrder={1}>
|
||||||
<a.sprite
|
<a.sprite
|
||||||
position-x={longHUDPosX}
|
position-x={longHUDPosX}
|
||||||
position-y={currentSpriteHUD["long"]["position"][1]}
|
position-y={currentSpriteHUD["long"]["position"][1]}
|
||||||
|
|
|
@ -17,25 +17,25 @@ const Hub = memo(() => {
|
||||||
<GrayRing grayRingPosY={1.6} />
|
<GrayRing grayRingPosY={1.6} />
|
||||||
<PurpleRing purpleRingPosY={0.4} />
|
<PurpleRing purpleRingPosY={0.4} />
|
||||||
<GrayRing grayRingPosY={-0.27} />
|
<GrayRing grayRingPosY={-0.27} />
|
||||||
{Object.values(level_sprites).map((sprite) => {
|
{/*{Object.values(level_sprites).map((sprite) => {*/}
|
||||||
return (
|
{/* return (*/}
|
||||||
<LevelSprite
|
{/* <LevelSprite*/}
|
||||||
position={sprite.position as [number, number, number]}
|
{/* position={sprite.position as [number, number, number]}*/}
|
||||||
scale={sprite.scale as [number, number, number]}
|
{/* scale={sprite.scale as [number, number, number]}*/}
|
||||||
rotation={
|
{/* rotation={*/}
|
||||||
sprite.rotation as [
|
{/* sprite.rotation as [*/}
|
||||||
number,
|
{/* number,*/}
|
||||||
number,
|
{/* number,*/}
|
||||||
number,
|
{/* number,*/}
|
||||||
(string | undefined)?
|
{/* (string | undefined)?*/}
|
||||||
]
|
{/* ]*/}
|
||||||
}
|
{/* }*/}
|
||||||
sprite={sprite.sprite}
|
{/* sprite={sprite.sprite}*/}
|
||||||
key={sprite.id}
|
{/* key={sprite.id}*/}
|
||||||
active={sprite.id === currentSprite}
|
{/* active={sprite.id === currentSprite}*/}
|
||||||
/>
|
{/* />*/}
|
||||||
);
|
{/* );*/}
|
||||||
})}
|
{/*})}*/}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -92,6 +92,7 @@ const LevelSprite = memo((props: LevelSpriteConstructorProps) => {
|
||||||
position={props.position}
|
position={props.position}
|
||||||
scale={props.scale}
|
scale={props.scale}
|
||||||
rotation={props.rotation}
|
rotation={props.rotation}
|
||||||
|
renderOrder={1}
|
||||||
>
|
>
|
||||||
<planeBufferGeometry attach="geometry" />
|
<planeBufferGeometry attach="geometry" />
|
||||||
{props.active ? (
|
{props.active ? (
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import React, { useMemo, useRef } from "react";
|
import React, {useMemo, useRef} from "react";
|
||||||
import { useFrame, useLoader } from "react-three-fiber";
|
import {useFrame, useLoader} from "react-three-fiber";
|
||||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
||||||
import middleRingTexture from "../../static/sprites/middle_ring_tex.png";
|
import middleRingTexture from "../../static/sprites/middle_ring_tex.png";
|
||||||
|
|
||||||
import { draco } from "drei";
|
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { a, useSpring } from "@react-spring/three";
|
import {a, useSpring} from "@react-spring/three";
|
||||||
import {
|
import {
|
||||||
middleRingNoiseAtom,
|
middleRingNoiseAtom,
|
||||||
middleRingPosYAtom,
|
middleRingPosYAtom,
|
||||||
|
@ -13,24 +10,9 @@ import {
|
||||||
middleRingRotXAtom,
|
middleRingRotXAtom,
|
||||||
middleRingWobbleStrengthAtom,
|
middleRingWobbleStrengthAtom,
|
||||||
} from "./MiddleRingAtom";
|
} from "./MiddleRingAtom";
|
||||||
import { useRecoilValue } from "recoil";
|
import {useRecoilValue} from "recoil";
|
||||||
|
|
||||||
type GLTFResult = GLTF & {
|
|
||||||
nodes: {
|
|
||||||
BezierCircle: THREE.Mesh;
|
|
||||||
};
|
|
||||||
materials: {
|
|
||||||
["Material.001"]: THREE.MeshStandardMaterial;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const MiddleRing = () => {
|
const MiddleRing = () => {
|
||||||
const { nodes, materials } = useLoader<GLTFResult>(
|
|
||||||
GLTFLoader,
|
|
||||||
"/models/ring2.glb",
|
|
||||||
draco("/draco-gltf/")
|
|
||||||
);
|
|
||||||
|
|
||||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
||||||
|
|
||||||
const middleRingWobbleStrength = useRecoilValue(middleRingWobbleStrengthAtom);
|
const middleRingWobbleStrength = useRecoilValue(middleRingWobbleStrengthAtom);
|
||||||
|
@ -205,8 +187,7 @@ const MiddleRing = () => {
|
||||||
varying vec2 vUv;
|
varying vec2 vUv;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_FragColor = texture2D(tex, vUv);
|
gl_FragColor = texture2D( tex, vUv);
|
||||||
gl_FragColor.a = 0.4;
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -227,18 +208,18 @@ const MiddleRing = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a.mesh
|
<a.mesh
|
||||||
material={materials["Material.001"]}
|
|
||||||
geometry={nodes.BezierCircle.geometry}
|
|
||||||
position={[0, 0, 0.3]}
|
position={[0, 0, 0.3]}
|
||||||
position-y={middleRingPosState.middleRingPosY}
|
position-y={middleRingPosState.middleRingPosY}
|
||||||
scale={[0.9, 0.7, 0.9]}
|
|
||||||
ref={middleRingRef}
|
ref={middleRingRef}
|
||||||
rotation={[0, 0.9, 0]}
|
rotation={[0, 0.9, 0]}
|
||||||
rotation-x={middleRingRotState.middleRingRotX}
|
rotation-x={middleRingRotState.middleRingRotX}
|
||||||
>
|
>
|
||||||
|
<cylinderBufferGeometry
|
||||||
|
args={[0.85, 0.85, 0.027, 64, 64, true]}
|
||||||
|
attach="geometry"
|
||||||
|
/>
|
||||||
<shaderMaterial
|
<shaderMaterial
|
||||||
attach="material"
|
attach="material"
|
||||||
color={0x8cffde}
|
|
||||||
side={THREE.DoubleSide}
|
side={THREE.DoubleSide}
|
||||||
uniforms={uniforms}
|
uniforms={uniforms}
|
||||||
vertexShader={vertexShader}
|
vertexShader={vertexShader}
|
||||||
|
|
|
@ -17,7 +17,7 @@ export const middleRingNoiseAtom = atom({
|
||||||
|
|
||||||
export const middleRingPosYAtom = atom({
|
export const middleRingPosYAtom = atom({
|
||||||
key: "middleRingPosYAtom",
|
key: "middleRingPosYAtom",
|
||||||
default: -0.15,
|
default: -0.11,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const middleRingRotXAtom = atom({
|
export const middleRingRotXAtom = atom({
|
||||||
|
|
|
@ -40,5 +40,12 @@
|
||||||
"rotation": [0, 0.09, 0],
|
"rotation": [0, 0.09, 0],
|
||||||
"sprite": "Dc",
|
"sprite": "Dc",
|
||||||
"id": "0513"
|
"id": "0513"
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"position": [-0.9, 1.9, 1],
|
||||||
|
"scale": [0.25, 0.15, 0.25],
|
||||||
|
"rotation": [0, -0.5, 0],
|
||||||
|
"sprite": "Tda",
|
||||||
|
"id": "0515"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue