JSFiddle - React, Tailwind, and code Playground
by tfoller
HTML
<canvas id="main_canvas" width="550" height="550"></canvas>
<div id="ui">
<button id="psw">...</button>
</div>
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"alikim/": "https://alikim.com/",
"jsm/": "https://alikim.com/_v1_jsm/"
}
}
</script>
<script type="x-shader/x-vertex" id="vs">
varying vec3 nrm;
void main() {
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
nrm = normal;
}
</script>
<script type="x-shader/x-fragment" id="dxdy_fs">
varying vec3 nrm;
void main() {
vec3 dif = dFdy(nrm); //, dFdy(nrm));
gl_FragColor = vec4(32.0 * dif, 1.0);
}
</script>
CSS
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.noselect {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#ctrl_over {
position: absolute;
opacity: 0.5;
bottom: 9px;
right: 5px;
color: #aaa;
font-family: Arial, Helvetica, sans-serif;
font-size: 13px;
}
#ctrl_sw {
border: solid 1px #aaa;
padding: 3px;
margin-left: 10px;
cursor: pointer;
font-size: 11px;
text-transform: uppercase;
}
#canv_wrap {
position:relative;
margin: 0px;
padding: 0px;
display: inline-block;
}
body {
background: #112233;
width: 100vw;
height: 100vh;
}
button {
padding: 3px;
margin-left: 10px;
color: #333;
filter: invert(100%);
cursor: pointer;
}
canvas {
display: block;
border: solid 1px grey;
box-sizing: content-box;
margin: 10px;
}
JavaScript
import * as THREE from 'jsm/three.module.js'
import * as CONTROLS from 'jsm/controls.js'
import { log, slog, get, getHTML } from 'jsm/utils.js'
import { getShader } from 'jsm/utils_three.js'
import { makeSwitchBtn } from 'jsm/ui.js'
import { GLTFLoader } from 'jsm/GLTFLoader.js'
const html = getHTML();
// 3D
const canvas = get('main_canvas');
const [w, h] = [canvas.width, canvas.height];
const renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: canvas,
});
renderer.setSize(w, h);
const [near, far] = [1, 10];
const mid = -0.5 * (near + far);
const camera = new THREE.PerspectiveCamera(45, w / h, near, far);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0, 0, 0.3);
const dir2 = new THREE.DirectionalLight(0xffffff, 1);
dir2.position.set(-1, -1, -1);
scene.add(dir2);
const dir = new THREE.DirectionalLight(0xffffff, 1);
dir.position.set(1, 1, 1);
scene.add(dir);
const shmat = new THREE.ShaderMaterial({
vertexShader: getShader('vs'),
fragmentShader: getShader('dxdy_fs'),
uniforms: { },
});
let planet;
const gltfldr = new GLTFLoader();
gltfldr.load(
'https://alikim.com/jsfiddle/planet.glb',
gltf => {
log(`loaded GLTF`);
planet = gltf.scene.children[0];
planet.scale.set(1, 1, 1); log(planet)
const mat_ori = planet.material;
const normap = mat_ori.normalMap;
const mat = planet.material = shmat;//new THREE.MeshNormalMaterial();
// const mat = planet.material = new THREE.MeshLambertMaterial();
// mat.normalMap = normap;
// mat.normalScale = new THREE.Vector2(5, 5);
initScene();
},
undefined,
err => {
log('error loading gltf:', err);
}
);
const hlp = new THREE.AxesHelper(10);
const initScene = () => {
[hlp, planet].forEach(mesh => {
mesh.position.z = mid;
scene.add(mesh);
});
render();
};
const anim = () => {
cube.rotation.x += 0.013;
cube.rotation.y += 0.007;
};
const framerate = 60;
const fpsint = 1000 / framerate;
let elapsed, now,...