mirror of
https://github.com/Floriansylvain/generic-threejs-game.git
synced 2026-08-19 11:43:18 +02:00
feat: world generation first iteration
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 764 KiB |
+12
-6
@@ -3,10 +3,11 @@ import "./App.css";
|
|||||||
import { Canvas } from "@react-three/fiber";
|
import { Canvas } from "@react-three/fiber";
|
||||||
import { KeyboardControls } from "@react-three/drei";
|
import { KeyboardControls } from "@react-three/drei";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { PCFSoftShadowMap, Vector3 } from "three";
|
import { PCFSoftShadowMap, Vector2, Vector3 } from "three";
|
||||||
import { Player } from "./components/Player";
|
import { Player } from "./components/Player";
|
||||||
import { Bloom, EffectComposer, Vignette } from "@react-three/postprocessing";
|
import { Bloom, EffectComposer, Vignette } from "@react-three/postprocessing";
|
||||||
import { Cubes } from "./components/Cubes";
|
import { Cubes } from "./components/Cubes";
|
||||||
|
import { World } from "./components/World";
|
||||||
|
|
||||||
const CUBES_QT = 10;
|
const CUBES_QT = 10;
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ function App() {
|
|||||||
>
|
>
|
||||||
<Cubes cubesPosition={cubes}></Cubes>
|
<Cubes cubesPosition={cubes}></Cubes>
|
||||||
|
|
||||||
<mesh
|
{/* <mesh
|
||||||
rotation={[-Math.PI / 2, 0, 0]}
|
rotation={[-Math.PI / 2, 0, 0]}
|
||||||
position={[0, 0, 0]}
|
position={[0, 0, 0]}
|
||||||
receiveShadow
|
receiveShadow
|
||||||
@@ -53,7 +54,12 @@ function App() {
|
|||||||
toneMapped={false}
|
toneMapped={false}
|
||||||
color={"green"}
|
color={"green"}
|
||||||
></meshStandardMaterial>
|
></meshStandardMaterial>
|
||||||
</mesh>
|
</mesh> */}
|
||||||
|
|
||||||
|
<World position={new Vector2(0, 0)} seed={0.12354}></World>
|
||||||
|
<World position={new Vector2(100, 0)} seed={0.12354}></World>
|
||||||
|
<World position={new Vector2(100, 100)} seed={0.12354}></World>
|
||||||
|
<World position={new Vector2(0, 100)} seed={0.12354}></World>
|
||||||
|
|
||||||
<KeyboardControls
|
<KeyboardControls
|
||||||
map={[
|
map={[
|
||||||
@@ -68,11 +74,11 @@ function App() {
|
|||||||
<Player></Player>
|
<Player></Player>
|
||||||
</KeyboardControls>
|
</KeyboardControls>
|
||||||
|
|
||||||
<ambientLight intensity={Math.PI / 2} />
|
<ambientLight intensity={1} />
|
||||||
|
|
||||||
<color args={["lightblue"]} attach={"background"}></color>
|
<color args={["lightblue"]} attach={"background"}></color>
|
||||||
{/* <gridHelper args={[100, 100]}></gridHelper> */}
|
{/* <gridHelper args={[100, 100]}></gridHelper>
|
||||||
{/* <axesHelper args={[100]}></axesHelper> */}
|
<axesHelper args={[100]}></axesHelper> */}
|
||||||
<EffectComposer enableNormalPass>
|
<EffectComposer enableNormalPass>
|
||||||
<Bloom mipmapBlur luminanceThreshold={0.4} />
|
<Bloom mipmapBlur luminanceThreshold={0.4} />
|
||||||
<Vignette eskil={false} offset={0.2} darkness={0.8} />
|
<Vignette eskil={false} offset={0.2} darkness={0.8} />
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export interface KeyPressed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PLAYER_SPEED = 4.75 * 10;
|
const PLAYER_SPEED = 4.75 * 10;
|
||||||
const DRAW_DISTANCE = 256;
|
const DRAW_DISTANCE = 128;
|
||||||
const SHADOW_RESOLUTION = 4096;
|
const SHADOW_RESOLUTION = 2048;
|
||||||
const MOUSE_X_SENSITIVITY = 0.002;
|
const MOUSE_X_SENSITIVITY = 0.002;
|
||||||
const MOUSE_Y_SENSITIVITY = 0.001;
|
const MOUSE_Y_SENSITIVITY = 0.001;
|
||||||
const ANIM_SPEED = 0.2;
|
const ANIM_SPEED = 0.2;
|
||||||
@@ -177,7 +177,7 @@ export function Player(): JSX.Element {
|
|||||||
function setDirLightPosition(): void {
|
function setDirLightPosition(): void {
|
||||||
dirLightRef.current?.position.set(
|
dirLightRef.current?.position.set(
|
||||||
model.scene.position.x + 100,
|
model.scene.position.x + 100,
|
||||||
100,
|
70,
|
||||||
model.scene.position.z + 100
|
model.scene.position.z + 100
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -199,6 +199,7 @@ export function Player(): JSX.Element {
|
|||||||
child.receiveShadow = true;
|
child.receiveShadow = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
model.scene.position.y = 10;
|
||||||
window.addEventListener("mousemove", onMouseMove);
|
window.addEventListener("mousemove", onMouseMove);
|
||||||
return () => window.removeEventListener("mousemove", onMouseMove);
|
return () => window.removeEventListener("mousemove", onMouseMove);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { RepeatWrapping, TextureLoader, Vector2, Vector3 } from "three";
|
||||||
|
import { ImprovedNoise } from "three/examples/jsm/Addons.js";
|
||||||
|
|
||||||
|
export function World(props: { position: Vector2; seed: number }): JSX.Element {
|
||||||
|
const size = 100;
|
||||||
|
const scale = 3;
|
||||||
|
const amplitude = 30;
|
||||||
|
|
||||||
|
const noise = (x: number, y: number): number => {
|
||||||
|
const noise = new ImprovedNoise();
|
||||||
|
return noise.noise(x, y, props.seed);
|
||||||
|
};
|
||||||
|
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
if (!context) throw new Error("Canvas context not found");
|
||||||
|
const imageData = context.getImageData(0, 0, size, size);
|
||||||
|
const data = imageData.data;
|
||||||
|
for (let x = 0; x < size; x++) {
|
||||||
|
for (let y = 0; y < size; y++) {
|
||||||
|
const n =
|
||||||
|
noise(
|
||||||
|
(x + props.position.x) / (size / scale),
|
||||||
|
(y + props.position.y) / (size / scale)
|
||||||
|
) *
|
||||||
|
127 +
|
||||||
|
127;
|
||||||
|
const id = (x + y * size) * 4;
|
||||||
|
data[id] = n;
|
||||||
|
data[id + 1] = n;
|
||||||
|
data[id + 2] = n;
|
||||||
|
data[id + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.putImageData(imageData, 0, 0);
|
||||||
|
const displacementMap = new TextureLoader().load(canvas.toDataURL());
|
||||||
|
displacementMap.wrapS = displacementMap.wrapT = RepeatWrapping;
|
||||||
|
displacementMap.wrapT = displacementMap.wrapS = RepeatWrapping;
|
||||||
|
|
||||||
|
const grassTexture = new TextureLoader().load("./texture_grass.jpg");
|
||||||
|
grassTexture.wrapS = grassTexture.wrapT = RepeatWrapping;
|
||||||
|
grassTexture.repeat.set(100, 100);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group position={new Vector3(props.position.x, 0, props.position.y)}>
|
||||||
|
<mesh
|
||||||
|
position={[0, 0, 0]}
|
||||||
|
rotation={[-Math.PI / 2, 0, 0]}
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
>
|
||||||
|
<planeGeometry
|
||||||
|
attach="geometry"
|
||||||
|
args={[100, 100, 100, 100]}
|
||||||
|
></planeGeometry>
|
||||||
|
<meshStandardMaterial
|
||||||
|
wireframe
|
||||||
|
toneMapped={false}
|
||||||
|
attach="material"
|
||||||
|
map={grassTexture}
|
||||||
|
displacementMap={displacementMap}
|
||||||
|
displacementScale={amplitude}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user