JSFiddle - React, Tailwind, and code Playground
by tfoller
HTML
<canvas id="main_canvas" style="border: solid 1px red;" width=600 height=600></canvas>
<script type="x-shader/x-vertex" id="vs">
varying vec2 vuv;
void main() {
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
vuv = uv;
}
</script>
<script type='x-shader/x-fragment' id='fs'>
varying vec2 vuv;
uniform sampler2D map;
uniform mat3 mapctrl;
void main() {
vec2 muv = (mapctrl * vec3(vuv, 1.0)).xy;
vec3 clr = texture2D(map, muv).rgb;
gl_FragColor = vec4(clr, 1.0);
}
</script>
CSS
body {
background: #000;
}
JavaScript
//import * as THREE from 'https://alikim.com/_v1_jsm/three.module.js'
import * as THREE from 'https://alikim.com/_v1_jsm/three141.showshader.js'
const get = (id) => document.getElementById(id);
const canvas = get('main_canvas');
const [w2, h2] = [canvas.width / 2, canvas.height / 2];
const renderer = new THREE.WebGLRenderer({
antialias: false,
alpha: true,
canvas,
});
const [near, far] = [0, 1];
const camera = new THREE.OrthographicCamera(-w2, w2, h2, -h2, near, far);
const render = () => {
renderer.render(scene, camera)
};
const geo = new THREE.PlaneBufferGeometry(300, 300, 1, 1);
const map = new THREE.TextureLoader().load('https://alikim.com/_v1_jsm/textures/uv.png', render);
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.offset = new THREE.Vector2(0.1, 0.1);
const mat = new THREE.MeshBasicMaterial({map});
const mtx = {
scaleX: 0.5,
scaleY: 0.3,
skewX: 40,
skewY: 40,
offU: 0.2,
offV: 0.3,
};
const mat1 = new THREE.ShaderMaterial({
vertexShader: get('vs').textContent,
fragmentShader: get('fs').textContent,
uniforms: {
map: {
value: map
},
mapctrl: {
get value() {
const degToRad = Math.PI / 180;
const [sX, sY, skX, skY, tX, tY] = [
1 / mtx.scaleX || 1, 1 / mtx.scaleY || 1, degToRad * mtx.skewX || 0,
degToRad * mtx.skewY || 0, mtx.offU || 0, mtx.offV || 0
];
return [
sX * Math.cos(skY), sX * Math.sin(skY), 0,
-sY * Math.sin(skX), sY * Math.cos(skX), 0,
tX, tY, 0
];
}
}
},
});
const msh = new THREE.Mesh(geo, mat1);
const scene = new THREE.Scene().add(msh);