clean: texture loader huge improvements

This commit is contained in:
Florian Sylvain
2024-06-10 10:17:43 +02:00
parent 5522b18d2b
commit 02e60a4e03
4 changed files with 95 additions and 72 deletions
+3 -3
View File
@@ -8,13 +8,13 @@ importers:
.: .:
dependencies: dependencies:
'@types/three':
specifier: ^0.165.0
version: 0.165.0
three: three:
specifier: ^0.165.0 specifier: ^0.165.0
version: 0.165.0 version: 0.165.0
devDependencies: devDependencies:
'@types/three':
specifier: ^0.165.0
version: 0.165.0
prettier: prettier:
specifier: ^3.3.1 specifier: ^3.3.1
version: 3.3.1 version: 3.3.1
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

+44 -24
View File
@@ -4,6 +4,7 @@ import { OrbitControls } from "three/addons/controls/OrbitControls.js"
import Face from "./face" import Face from "./face"
import Block from "./block" import Block from "./block"
import TextureLoader from "./textureLoader" import TextureLoader from "./textureLoader"
// import TextureLoader from "./textureLoader"
const scene = new THREE.Scene() const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera( const camera = new THREE.PerspectiveCamera(
@@ -20,7 +21,16 @@ const controls = new OrbitControls(camera, renderer.domElement)
controls.update() controls.update()
document.body.appendChild(renderer.domElement) document.body.appendChild(renderer.domElement)
new TextureLoader("/grass.png", 16, 16, onTextureLoaded) let grassTextures = [] as THREE.Texture[]
let dirtTextures = [] as THREE.Texture[]
async function loadTextures() {
const textureLoader = new TextureLoader(16, 16)
grassTextures = await textureLoader.load("/grass.png")
dirtTextures = await textureLoader.load("/dirt.png")
// const debugTextures = await textureLoader.load("/debug.png")
onTextureLoaded()
}
// const gridHelper = new THREE.GridHelper(1000, 1000) // const gridHelper = new THREE.GridHelper(1000, 1000)
// scene.add(gridHelper) // scene.add(gridHelper)
@@ -83,48 +93,58 @@ function countVisibleFaces(
return faceCounts return faceCounts
} }
function onTextureLoaded(textures: THREE.Texture[]) { function onTextureLoaded() {
const chunk = [] as THREE.Vector3[] const chunk = [] as THREE.Vector3[]
const chunkSet = new Set<string>() const chunkSet = new Set<string>()
const radius = 64 const radius = 32
for (let i = -radius; i < radius; i++) { for (let i = 0; i < radius; i++) {
for (let j = -radius; j < radius; j++) { for (let j = 0; j < radius; j++) {
const block = new THREE.Vector3( const max = Math.ceil(Math.sin(i / 30) * 10 + Math.cos(j / 30) * 10)
i, for (let k = -64; k < max; k++) {
Math.ceil(Math.sin(i / 25) * 8 + Math.cos(j / 25) * 8), const vec3 = new THREE.Vector3(i, k, j)
j chunk.push(vec3)
) chunkSet.add(vec3.toArray().toString())
chunk.push(block) }
chunkSet.add(block.toArray().toString())
} }
} }
const faceCounts = countVisibleFaces(chunkSet, chunk) const faceCounts = countVisibleFaces(chunkSet, chunk)
const faces = [ const grassFaces = [
new Face("Up", faceCounts.Up, textures[0]), new Face("Up", faceCounts.Up, grassTextures[0]),
new Face("North", faceCounts.North, textures[1]), new Face("North", faceCounts.North, grassTextures[1]),
new Face("South", faceCounts.South, textures[2]), new Face("South", faceCounts.South, grassTextures[2]),
new Face("East", faceCounts.East, textures[3]), new Face("East", faceCounts.East, grassTextures[3]),
new Face("West", faceCounts.West, textures[4]), new Face("West", faceCounts.West, grassTextures[4]),
new Face("Down", faceCounts.Down, textures[5]) new Face("Down", faceCounts.Down, grassTextures[5])
]
const dirtFaces = [
new Face("Up", faceCounts.Up, dirtTextures[0]),
new Face("North", faceCounts.North, dirtTextures[1]),
new Face("South", faceCounts.South, dirtTextures[2]),
new Face("East", faceCounts.East, dirtTextures[3]),
new Face("West", faceCounts.West, dirtTextures[4]),
new Face("Down", faceCounts.Down, dirtTextures[5])
] ]
const cubes = [] as Block[] const cubes = [] as Block[]
chunk.forEach((block) => { chunk.forEach((block) => {
cubes.push(new Block(filterFaces(faces, block, chunkSet), block)) cubes.push(new Block(filterFaces(grassFaces, block, chunkSet), block))
}) })
faces.forEach((face) => { grassFaces.forEach((face) => {
if (face.instancedMesh) scene.add(face.instancedMesh) if (face.instancedMesh) scene.add(face.instancedMesh)
}) })
} }
camera.position.x = 5 camera.position.x = 15
camera.position.y = 5 camera.position.y = 15
camera.position.z = 5 camera.position.z = 15
function animate(elapsedTimeMs: number) { function animate(elapsedTimeMs: number) {
renderer.render(scene, camera) renderer.render(scene, camera)
controls.update() controls.update()
} }
loadTextures()
+48 -45
View File
@@ -1,55 +1,58 @@
import { NearestFilter, Texture } from "three" import { NearestFilter, Texture } from "three";
export default class TextureLoader { export default class TextureLoader {
private image: HTMLImageElement private image: HTMLImageElement;
private width: number private width: number;
private height: number private height: number;
constructor( constructor(width: number, height: number) {
src: string, this.image = document.createElement("img");
width: number, this.width = width;
height: number, this.height = height;
callback: (textures: Texture[]) => void }
) {
this.image = document.createElement("img")
this.image.src = src
this.width = width
this.height = height
this.image.addEventListener( load(src: string): Promise<Texture[]> {
"load", return new Promise((resolve, reject) => {
() => this.onImageLoaded(callback), this.image.src = src;
false this.image.addEventListener(
) "load",
} () => {
const textures = this.onImageLoaded();
resolve(textures);
},
false
);
this.image.addEventListener("error", (err) => reject(err), false);
});
}
private onImageLoaded(callback: (textures: Texture[]) => void) { private onImageLoaded(): Texture[] {
const textures = [] as Texture[] const textures = [] as Texture[];
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
const canvas = document.createElement("canvas") const canvas = document.createElement("canvas");
canvas.width = this.width canvas.width = this.width;
canvas.height = this.height canvas.height = this.height;
const context = canvas.getContext("2d") const context = canvas.getContext("2d");
context?.drawImage( context?.drawImage(
this.image, this.image,
0, 0,
this.height * i, this.height * i,
this.width, this.width,
this.height, this.height,
0, 0,
0, 0,
this.width, this.width,
this.height this.height
) );
const texture = new Texture(canvas) const texture = new Texture(canvas);
texture.needsUpdate = true texture.needsUpdate = true;
texture.magFilter = NearestFilter texture.magFilter = NearestFilter;
textures.push(texture) textures.push(texture);
} }
callback(textures) return textures;
} }
} }