mirror of
https://github.com/Floriansylvain/generic-threejs-game.git
synced 2026-08-19 11:43:18 +02:00
feat: postprocessing + shadows
This commit is contained in:
+35
-32
@@ -1,16 +1,12 @@
|
||||
import "./App.css";
|
||||
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import {
|
||||
KeyboardControls,
|
||||
Sparkles,
|
||||
Text,
|
||||
TransformControls,
|
||||
} from "@react-three/drei";
|
||||
import { KeyboardControls } from "@react-three/drei";
|
||||
import { MutableRefObject, useEffect, useRef, useState } from "react";
|
||||
import { Vector3 } from "three";
|
||||
import { Cubes } from "./components/Cubes";
|
||||
import { Player } from "./components/Player";
|
||||
import { Bloom, EffectComposer, Vignette } from "@react-three/postprocessing";
|
||||
|
||||
function App() {
|
||||
const CUBES_QT = 20;
|
||||
@@ -35,35 +31,21 @@ function App() {
|
||||
className="container"
|
||||
onClick={() => container.current?.requestPointerLock()}
|
||||
>
|
||||
<Canvas className="canvas" ref={container}>
|
||||
<Canvas className="canvas" ref={container} shadows>
|
||||
<Cubes cubesPosition={cubes}></Cubes>
|
||||
<TransformControls position={[20, 10, 0]}>
|
||||
<Text
|
||||
color={"green"}
|
||||
fontSize={8}
|
||||
anchorX={"center"}
|
||||
anchorY={"middle"}
|
||||
>
|
||||
Bonsoir
|
||||
</Text>
|
||||
</TransformControls>
|
||||
<group>
|
||||
<Sparkles
|
||||
color={"blue"}
|
||||
count={100}
|
||||
size={20}
|
||||
scale={[20, 10, 20]}
|
||||
speed={25}
|
||||
position={[20, 0, 20]}
|
||||
></Sparkles>
|
||||
</group>
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, 0, 0]}>
|
||||
|
||||
<mesh
|
||||
rotation={[-Math.PI / 2, 0, 0]}
|
||||
position={[0, 0, 0]}
|
||||
receiveShadow
|
||||
>
|
||||
<planeGeometry attach={"geometry"} args={[100, 100]}></planeGeometry>
|
||||
<meshStandardMaterial
|
||||
attach={"material"}
|
||||
color={"lightblue"}
|
||||
color={"green"}
|
||||
></meshStandardMaterial>
|
||||
</mesh>
|
||||
|
||||
<KeyboardControls
|
||||
map={[
|
||||
{ keys: ["w", "ArrowUp"], name: "moveForward" },
|
||||
@@ -80,11 +62,32 @@ function App() {
|
||||
}
|
||||
></Player>
|
||||
</KeyboardControls>
|
||||
|
||||
<ambientLight intensity={Math.PI / 2} />
|
||||
<directionalLight
|
||||
intensity={Math.PI / 2}
|
||||
position={[2, 2, 2]}
|
||||
></directionalLight>
|
||||
castShadow
|
||||
position={[100, 100, 100]}
|
||||
shadow-mapSize={[4096, 4096]}
|
||||
intensity={5}
|
||||
>
|
||||
<orthographicCamera
|
||||
attach="shadow-camera"
|
||||
args={[-50, 50, 50, -50]}
|
||||
/>
|
||||
</directionalLight>
|
||||
|
||||
<color args={["lightblue"]} attach={"background"}></color>
|
||||
<fog attach={"fog"} args={["lightblue", 0, 100]}></fog>
|
||||
<gridHelper args={[100, 100]}></gridHelper>
|
||||
<axesHelper args={[100]}></axesHelper>
|
||||
<EffectComposer>
|
||||
<Bloom
|
||||
luminanceThreshold={0.2}
|
||||
luminanceSmoothing={0.8}
|
||||
height={300}
|
||||
/>
|
||||
<Vignette eskil={false} offset={0.2} darkness={0.8} />
|
||||
</EffectComposer>
|
||||
</Canvas>
|
||||
</main>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useFrame } from "@react-three/fiber";
|
||||
export function Cubes(props: { cubesPosition: Vector3[] }) {
|
||||
const CUBE_SPEED = 10;
|
||||
const CUBE_AMPLITUDE = 2;
|
||||
const CUBE_HEIGHT = 2;
|
||||
const CUBE_HEIGHT = 4;
|
||||
|
||||
const [cubes, setCubes] = useState<Vector3[]>(
|
||||
Array.from(props.cubesPosition)
|
||||
@@ -30,7 +30,12 @@ export function Cubes(props: { cubesPosition: Vector3[] }) {
|
||||
return cubes.map((cube) => {
|
||||
if (!cube) return;
|
||||
return (
|
||||
<mesh position={cube} key={`${cube.x}-${cube.z}`}>
|
||||
<mesh
|
||||
position={cube}
|
||||
key={`${cube.x}-${cube.z}`}
|
||||
castShadow
|
||||
receiveShadow
|
||||
>
|
||||
<boxGeometry attach={"geometry"}></boxGeometry>
|
||||
<meshStandardMaterial
|
||||
attach={"material"}
|
||||
|
||||
+12
-10
@@ -1,7 +1,7 @@
|
||||
import { useAnimations, useGLTF, useKeyboardControls } from "@react-three/drei";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { MutableRefObject, useCallback, useEffect, useState } from "react";
|
||||
import { Euler, Quaternion, Vector2, Vector3 } from "three";
|
||||
import { Euler, Mesh, Quaternion, Vector2, Vector3 } from "three";
|
||||
import { degToRad } from "three/src/math/MathUtils.js";
|
||||
|
||||
export interface KeyPressed {
|
||||
@@ -13,13 +13,15 @@ export interface KeyPressed {
|
||||
sprint: boolean;
|
||||
}
|
||||
|
||||
const PLAYER_SPEED = 4.75; // TODO NERF
|
||||
|
||||
export function Player(props: {
|
||||
container: MutableRefObject<HTMLCanvasElement>;
|
||||
}): JSX.Element {
|
||||
const model = useGLTF("/Adventurer.glb");
|
||||
const animations = useAnimations(model.animations, model.scene);
|
||||
|
||||
// const walk = animations.actions["CharacterArmature|Walk"];
|
||||
// const walk = animations.actions["CharacterArmature|Walk"];
|
||||
const run = animations.actions["CharacterArmature|Run"];
|
||||
const idle = animations.actions["CharacterArmature|Idle"];
|
||||
|
||||
@@ -30,6 +32,7 @@ export function Player(props: {
|
||||
const [pivotY, setPivotY] = useState(0);
|
||||
const [player, setPlayer] = useState<Vector3>(new Vector3(0, 0, 0));
|
||||
const [mouseRef, setMouseRef] = useState(new Vector2());
|
||||
|
||||
const camera = useThree((state) => state.camera);
|
||||
|
||||
const radius = 2;
|
||||
@@ -37,20 +40,21 @@ export function Player(props: {
|
||||
|
||||
useEffect(() => {
|
||||
idle?.play();
|
||||
model.scene.traverse((child) => {
|
||||
if (child instanceof Mesh) child.castShadow = true;
|
||||
});
|
||||
});
|
||||
|
||||
useFrame((_, delta) => {
|
||||
const speed = 8;
|
||||
const move = new Vector3();
|
||||
// TODO Replace getKeys with the subscription system
|
||||
// const keyPressed = getKeys() as unknown as KeyPressed;
|
||||
if (getKeys().moveForward) move.z += 1;
|
||||
if (getKeys().moveBackward) move.z -= 1;
|
||||
if (getKeys().moveLeft) move.x += 1;
|
||||
if (getKeys().moveRight) move.x -= 1;
|
||||
|
||||
move.applyEuler(new Euler(0, pivotX - degToRad(180), 0));
|
||||
move.multiplyScalar(speed * delta);
|
||||
move.multiplyScalar(PLAYER_SPEED * delta);
|
||||
|
||||
camera.position.x = radius * Math.sin(pivotX) * Math.cos(pivotY) + player.x;
|
||||
camera.position.y = radius * Math.sin(pivotY) + player.y + yOffset;
|
||||
@@ -66,11 +70,7 @@ export function Player(props: {
|
||||
if (Object.values(getKeys()).some((key) => key)) {
|
||||
setPlayer(player.clone().add(move));
|
||||
setIsWalking(true);
|
||||
} else {
|
||||
setIsWalking(false);
|
||||
}
|
||||
|
||||
if (isWalking) {
|
||||
const targetRotation = new Quaternion();
|
||||
targetRotation.setFromEuler(
|
||||
new Euler(
|
||||
@@ -89,7 +89,9 @@ export function Player(props: {
|
||||
new Quaternion().setFromEuler(new Euler(0, -cameraRotation.y, 0))
|
||||
);
|
||||
|
||||
model.scene.quaternion.slerp(targetRotation, 0.05);
|
||||
model.scene.quaternion.slerp(targetRotation, 0.2);
|
||||
} else {
|
||||
setIsWalking(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user