diff --git a/public/texture_grass.jpg b/public/texture_grass.jpg new file mode 100644 index 0000000..0d4e7f2 Binary files /dev/null and b/public/texture_grass.jpg differ diff --git a/public/texture_rock.jpg b/public/texture_rock.jpg new file mode 100644 index 0000000..6ac26f1 Binary files /dev/null and b/public/texture_rock.jpg differ diff --git a/src/App.tsx b/src/App.tsx index 70e5cab..291778e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,10 +3,11 @@ import "./App.css"; import { Canvas } from "@react-three/fiber"; import { KeyboardControls } from "@react-three/drei"; import { useEffect, useRef, useState } from "react"; -import { PCFSoftShadowMap, Vector3 } from "three"; +import { PCFSoftShadowMap, Vector2, Vector3 } from "three"; import { Player } from "./components/Player"; import { Bloom, EffectComposer, Vignette } from "@react-three/postprocessing"; import { Cubes } from "./components/Cubes"; +import { World } from "./components/World"; const CUBES_QT = 10; @@ -39,7 +40,7 @@ function App() { > - - + */} + + + + + - + - {/* */} - {/* */} + {/* + */} diff --git a/src/components/Player.tsx b/src/components/Player.tsx index 0c71a82..dd852af 100644 --- a/src/components/Player.tsx +++ b/src/components/Player.tsx @@ -21,8 +21,8 @@ export interface KeyPressed { } const PLAYER_SPEED = 4.75 * 10; -const DRAW_DISTANCE = 256; -const SHADOW_RESOLUTION = 4096; +const DRAW_DISTANCE = 128; +const SHADOW_RESOLUTION = 2048; const MOUSE_X_SENSITIVITY = 0.002; const MOUSE_Y_SENSITIVITY = 0.001; const ANIM_SPEED = 0.2; @@ -177,7 +177,7 @@ export function Player(): JSX.Element { function setDirLightPosition(): void { dirLightRef.current?.position.set( model.scene.position.x + 100, - 100, + 70, model.scene.position.z + 100 ); } @@ -199,6 +199,7 @@ export function Player(): JSX.Element { child.receiveShadow = true; } }); + model.scene.position.y = 10; window.addEventListener("mousemove", onMouseMove); return () => window.removeEventListener("mousemove", onMouseMove); }); diff --git a/src/components/World.tsx b/src/components/World.tsx new file mode 100644 index 0000000..cd60b12 --- /dev/null +++ b/src/components/World.tsx @@ -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 ( + + + + + + + ); +}