Hi, here’s a basic code I wrote for some test rendering:
import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { useRenderer } from "./useRenderer";
const normalizeUvCoordinate = (coordinate: number, range: number) => {
return coordinate / range;
}
/**
* Renders a terrain with tiled textures based on a heightmap and terrainMap.
*/
export const renderTerrainWithTextures = async (
container: HTMLElement,
terrainTextures: string[]
) => {
const width = 64;
const height = 64;
const textureWidth = 32;
const textureHeight = 32;
const scene = new THREE.Scene();
const aspect = container.offsetWidth / container.offsetHeight;
const camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
// Load terrain textures
const textureLoader = new THREE.TextureLoader();
const loadedTextures: { [key: number]: THREE.Texture } = {};
for (let terrainType = 0, l = terrainTextures.length; terrainType < l; terrainType++) {
const textureUrl = terrainTextures[terrainType];
loadedTextures[Number(terrainType)] = await textureLoader.loadAsync(textureUrl);
}
// Create terrain geometry
const geometry = new THREE.PlaneGeometry(width, height, width - 1, height - 1);
// Creating uv
const uvLength = width * height * 2;
const uvArray = new Float32Array(uvLength);
for (let i = 0; i < uvLength; i = i + 2) {
const indexW = (i / 2) % width;
const indexH = Math.floor((i / 2) / width);
uvArray[i] = normalizeUvCoordinate(indexW % textureWidth, textureWidth);
uvArray[i + 1] = 1 - normalizeUvCoordinate(indexH % textureHeight, textureHeight);
}
geometry.setAttribute("uv", new THREE.BufferAttribute(uvArray, 2))
const material = new THREE.MeshBasicMaterial({
map: loadedTextures[0],
side: THREE.DoubleSide,
});
const test = new THREE.Mesh(geometry, material);
scene.add(test);
const renderer = useRenderer(container, scene, camera);
const controls = new OrbitControls( camera, renderer.domElement );
controls.update();
};
The reason I want to provide a uv array manually is because later the mapping is gonna be even more complicated, rigth now I just want my 32x32 texture be repeated 4 times on 64x64 plane. The math looks right, but instead of just repeating the texture I get a tiny “A” in the middle of the plane and some stretched “A” on the main axis (attached). Can someone, please, take a look on that and say what’s wrong with the map?