JSFiddle - React, Tailwind, and code Playground
by Paul West
HTML
<script>
let blocksImg = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAIAAAD4YuoOAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGfSURBVDhPZZMxbsMwEAT5HX8hgDtXKQUYiIE07OVUafIAQ35BnpAfqPDvMvQIi4tCHA57K93ukZTax/Xae/95rmmawJbrupLvy52SnPJxe/+eX4mv8wuxKy/HQ3hzixzNBB7gyMnowShk2pCLEHhZFkvNAiCJzYBOcnajdJjq4WgEzcGKBistMwzSXHEYnchgnBhtnmebsxVKsOObZYYBPRHyZMRkloxLMipIoG4poxn2tWxIYEA/AAlCP4wtcx9uix51lVbIoPSpgGCIltHIYrXG/L3rHQYzD8fgeiMkHxD7FkUHjBbA2bWhlKyK2YdadWcyxPYfqKVN1MkGDMvbqv3JHouKPg05vqLdKWsT6Vi6G4XqiQcn6kGNI4quiiw/fJ0sUWcxim1VxbPCRgZASXhDm4FCisLk9Fl+TjAsgOraEHoA+DplKPUQjDuIojZiyDBgwjdrv4p6/A839OcOCEqxcgJIlphO1YnPt5OljKdEBgPkx39QFZXbqfvC02X7k9USpJTxBcEwoCfNOw9JmGwR0v4MCPYyU1Z8OR5+AaYiqFz1UTlXAAAAAElFTkSuQmCC`;
</script>
CSS
body{
overflow: hidden;
margin: 0;
}
JavaScript
import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";
import {ImprovedNoise} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/math/ImprovedNoise";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 5, 20).setLength(40);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(8, 0, 8);
controls.update();
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
let texAtlas = new THREE.TextureLoader().load(blocksImg);
let texStep = 1 / 2;
let g = new THREE.BoxGeometry(1, 1, 1);
let m = new THREE.MeshLambertMaterial({
onBeforeCompile: shader => {
shader.uniforms.texAtlas = {value: texAtlas};
shader.vertexShader = `
attribute float texIdx;
varying float vTexIdx;
${shader.vertexShader}
`.replace(
`void main() {`,
`void main() {
vTexIdx = texIdx;
`
);
//console.log(shader.vertexShader);
shader.fragmentShader = `
uniform sampler2D texAtlas;
varying float vTexIdx;
${shader.fragmentShader}
`.replace(
`#include <map_fragment>`,
`#include <map_fragment>
vec2 blockUv = ${texStep} * (floor(vTexIdx + 0.1) + vUv);
vec4 blockColor = texture(texAtlas, blockUv);
diffuseColor *= blockColor;
`
);
console.log(shader.fragmentShader);
}
});
m.defines = {"USE_UV" : ""};
let blocks = new THREE.InstancedMesh(g, m, 10240);
let perlin...