Created
June 16, 2023 11:52
-
-
Save jpgreth/6ce1cb1a451c0866257135e3619ed5bb to your computer and use it in GitHub Desktop.
Static Gradient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script async src="https://ga.jspm.io/npm:es-module-shims@1.6.3/dist/es-module-shims.js" crossorigin="anonymous"></script> | |
<script type="importmap"> | |
{ | |
"imports": { | |
"three": "https://unpkg.com/three@0.153.0/build/three.module.js", | |
"three/addons/": "https://unpkg.com/three@0.153.0/examples/jsm/" | |
} | |
} | |
</script> | |
<canvas id="grd" width="512" height="10"></canvas> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as THREE from "three"; | |
import { OrbitControls } from "three/addons/controls/OrbitControls.js"; | |
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; | |
import { mergeGeometries } from "three/addons/utils/BufferGeometryUtils.js"; | |
import { GUI } from "three/addons/libs/lil-gui.module.min.js"; | |
console.clear(); | |
let scene = new THREE.Scene(); | |
scene.background = new THREE.Color(0x202020); | |
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000); | |
camera.position.set(0, 4, 10); | |
camera.lookAt(scene.position); | |
let renderer = new THREE.WebGLRenderer({ | |
antialias: true | |
}); | |
renderer.setSize(innerWidth, innerHeight); | |
//renderer.setClearColor(0x404040); | |
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(0, 4, 0); | |
controls.enableDamping = true; | |
let light = new THREE.DirectionalLight(0xffffff, 0.8); | |
light.position.setScalar(1); | |
scene.add(light, new THREE.AmbientLight(0xff8888, 0.2)); | |
//scene.add(new THREE.GridHelper()); | |
let gu = { | |
time: {value: 0} | |
} | |
// model | |
let loader = new GLTFLoader(); | |
let result = await loader.loadAsync("https://threejs.org/examples/models/gltf/Xbot.glb"); | |
let model = result.scene; | |
let colors = ['#FF0089', '#CFC91E', '#02E91E', '#00DAFF']; | |
let gradTexture = getGradientTexture(colors); | |
let u = { | |
gradTexture: {value: gradTexture}, | |
box: { | |
min: {value: new THREE.Vector3(-2, 0, -3)}, | |
max: {value: new THREE.Vector3(2, 8.75, 3)} | |
} | |
} | |
scene.add(new THREE.Box3Helper(new THREE.Box3(u.box.min.value, u.box.max.value))); | |
model.traverse(child => { | |
if(child.isMesh){ | |
child.material.onBeforeCompile = shader => { | |
shader.uniforms.gradTexture = u.gradTexture; | |
shader.uniforms.boxMin = u.box.min; | |
shader.uniforms.boxMax = u.box.max; | |
shader.vertexShader = ` | |
varying vec3 wPos; | |
${shader.vertexShader} | |
`.replace( | |
`#include <project_vertex>`, | |
` | |
wPos = vec3(modelMatrix * vec4(transformed, 1.)); | |
#include <project_vertex> | |
` | |
); | |
console.log(shader.vertexShader); | |
shader.fragmentShader = ` | |
uniform sampler2D gradTexture; | |
uniform vec3 boxMin; | |
uniform vec3 boxMax; | |
varying vec3 wPos; | |
${shader.fragmentShader} | |
`.replace( | |
`#include <color_fragment>`, | |
`#include <color_fragment> | |
vec3 diag = boxMax - boxMin; | |
float diagDist = length(diag); | |
vec3 diagN = normalize(diag); | |
vec3 boundPos = wPos - boxMin; | |
float dotted = dot(diagN, boundPos); | |
float dottedN = clamp(dotted / diagDist, 0., 1.); | |
//dottedN = fract(dottedN * 10.); | |
vec3 gradColor = texture(gradTexture, vec2(dottedN, 0.5)).rgb; | |
diffuseColor.rgb = gradColor; | |
` | |
); | |
console.log(shader.fragmentShader); | |
} | |
} | |
}) | |
model.scale.setScalar(5); | |
model.frustumCulled = false; | |
let mixer = new THREE.AnimationMixer(model); | |
let action = mixer.clipAction(result.animations[3]); | |
action.play(); | |
//console.log(result) | |
scene.add(model); | |
let clock = new THREE.Clock(); | |
let time = 0; | |
renderer.setAnimationLoop((_) => { | |
let t = clock.getDelta(); | |
time += t; | |
gu.time.value = time; | |
mixer.update(t); | |
controls.update(); | |
renderer.render(scene, camera); | |
}); | |
function getGradientTexture(colors){ | |
let c = document.getElementById("grd") | |
let ctx = c.getContext("2d"); | |
let grd = ctx.createLinearGradient(0, 0, c.width, 0); | |
let clrStep = 1 / (colors.length - 1); | |
colors.forEach((clr, clrIdx) => { | |
grd.addColorStop(clrIdx * clrStep, clr) | |
}); | |
ctx.fillStyle = grd; | |
ctx.fillRect(0, 0, c.width, c.height); | |
let ct = new THREE.CanvasTexture(c); | |
ct.colorSpace = THREE.SRGBColorSpace | |
return ct; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body{ | |
overflow: hidden; | |
margin: 0; | |
background-color: black; | |
} | |
#grd{ | |
position: absolute; | |
margin: 10px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment