glsl shading for sprites, still need to properly animate

This commit is contained in:
ad044 2020-08-29 01:54:23 +04:00
parent f318cee7ed
commit abed34112b

View file

@ -1,10 +1,16 @@
import React, { Suspense } from "react"; import React, { Suspense, useMemo, useState, useEffect, useRef } from "react";
import { useFrame, useLoader, useThree } from "react-three-fiber"; import { useFrame, useLoader, useThree } from "react-three-fiber";
import * as THREE from "three"; import * as THREE from "three";
import movie from "../static/sprites/movie.png"; import movie from "../static/sprites/movie.png";
import movieActive from "../static/sprites/movie_active.png";
import touko from "../static/sprites/touko.png"; import touko from "../static/sprites/touko.png";
import toukoActive from "../static/sprites/touko_active.png";
import s from "../static/sprites/s.png"; import s from "../static/sprites/s.png";
import sActive from "../static/sprites/s_active.png";
import copland from "../static/sprites/copland.png"; import copland from "../static/sprites/copland.png";
import coplandActive from "../static/sprites/copland_active.png";
import { SpriteMaterial } from "three";
import { act } from "react-dom/test-utils";
type LevelSpriteConstructorProps = { type LevelSpriteConstructorProps = {
sprite: string; sprite: string;
@ -14,10 +20,11 @@ type LevelSpriteConstructorProps = {
}; };
type SpriteToPath = { type SpriteToPath = {
[key: string]: string; [key: string]: [string, string];
}; };
const LevelSprite = (props: LevelSpriteConstructorProps) => { const LevelSprite = (props: LevelSpriteConstructorProps) => {
const [test, setTest] = useState(1.0);
// the game only has a couple of sprites that it displays in the hub // the game only has a couple of sprites that it displays in the hub
// dynamically importnig them would be worse for performance, // dynamically importnig them would be worse for performance,
// so we import all of them here and then use this function to // so we import all of them here and then use this function to
@ -25,17 +32,54 @@ const LevelSprite = (props: LevelSpriteConstructorProps) => {
// (yes, imbad at naming them) // (yes, imbad at naming them)
const spriteToPath = (sprite: string) => { const spriteToPath = (sprite: string) => {
return ({ return ({
movie: movie, movie: [movie, movieActive],
touko: touko, touko: [touko, toukoActive],
s: s, s: [s, sActive],
copland: copland, copland: [copland, coplandActive],
} as SpriteToPath)[sprite]; } as SpriteToPath)[sprite];
}; };
const spriteTexture: any = useLoader( const materialRef = useRef();
THREE.TextureLoader,
spriteToPath(props.sprite) const spriteSheet = spriteToPath(props.sprite);
);
const nonActiveTexture: any = useLoader(THREE.TextureLoader, spriteSheet[0]);
const activeTexture: any = useLoader(THREE.TextureLoader, spriteSheet[1]);
const uniforms = {
texture1: { type: "t", value: nonActiveTexture },
texture2: { type: "t", value: activeTexture },
alphaVal: { value: test },
};
const vertexShader = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`;
const fragmentShader = `
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform float alphaVal;
varying vec2 vUv;
void main() {
vec4 tex1 = texture2D (texture1, vUv);
vec4 tex2 = texture2D (texture2, vUv);
vec3 mixCol = mix(tex1.rgb / tex1.a, tex2.rgb / tex2.a, alphaVal);
gl_FragColor = vec4(mixCol.rgb, 1.0);
gl_FragColor.a = max(tex1.a, tex2.a);
}
`;
useFrame(() => {
(materialRef.current! as any).uniforms.alphaVal = test;
});
return ( return (
<mesh <mesh
@ -44,11 +88,15 @@ const LevelSprite = (props: LevelSpriteConstructorProps) => {
rotation={props.rotation} rotation={props.rotation}
> >
<planeBufferGeometry attach="geometry" /> <planeBufferGeometry attach="geometry" />
<meshStandardMaterial <shaderMaterial
side={THREE.DoubleSide} ref={materialRef}
attach="material" attach="material"
map={spriteTexture} uniforms={uniforms}
fragmentShader={fragmentShader}
vertexShader={vertexShader}
side={THREE.DoubleSide}
transparent={true} transparent={true}
uniformsNeedUpdate={true}
/> />
</mesh> </mesh>
); );