body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.module.js";
import {OrbitControls} from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 10, 20);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 1));
let g = new THREE.TorusKnotBufferGeometry(5, 1, 128, 16);
g.rotateX(-Math.PI * 0.5);
g.computeBoundingBox();
let uniforms = {
bbMin: {value: g.boundingBox.min},
bbMax: {value: g.boundingBox.max},
color1: {value: new THREE.Color(0xff0000)},
color2: {value: new THREE.Color(0xffff00)}
}
console.log(g);
let m = new THREE.MeshStandardMaterial({
roughness: 0.25,
metalness: 0.75,
map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/floors/FloorsCheckerboard_S_Diffuse.jpg", tex => {
tex.wrapS = THREE.RepeatWrapping;
tex.wrapT = THREE.RepeatWrapping;
tex.repeat.set( 16, 1 );
}),
onBeforeCompile: shader => {
shader.uniforms.bbMin = uniforms.bbMin;
shader.uniforms.bbMax = uniforms.bbMax;
shader.uniforms.color1 = uniforms.color1;
shader.uniforms.color2 = uniforms.color2;
shader.vertexShader = `
varying vec3 vPos;
${shader.vertexShader}
`.replace(
`#include <begin_vertex>`,
`#include <begin_vertex>
vPos = transformed;
`
);
shader.fragmentShader = `
uniform vec3 bbMin;
uniform vec3 bbMax;
uniform vec3 color1;
uniform vec3 color2;
varying vec3 vPos;
${shader.fragmentShader}
`.replace(
`vec4 diffuseColor = vec4( diffuse, opacity );`,
`
float f = clamp((vPos.z - bbMin.z) / (bbMax.z - bbMin.z), 0., 1.);
vec3 col = mix(color1, color2, f);
vec4 diffuseColor = vec4( col, opacity );`
);
console.log(shader.vertexShader);
console.log(shader.fragmentShader);
}
});
let o = new THREE.Mesh(g, m);
scene.add(o);
renderer.setAnimationLoop(()=>{
renderer.render(scene, camera);
});
</script>