JSFiddle - React, Tailwind, and code Playground
by tfoller
HTML
<canvas id="main_canvas" style="border: solid 1px grey;" width=700 height=350></canvas>
<div>
<button id="bgrey">grey</button>
<button id="bgreyR601">greyR601</button>
<button id="bgreyR601S">greyR601S</button>
<button id="bgreyPS">greyPS</button>
<button id="reload">reload</button>
</div>
<script type="x-shader/x-function" id="SRGBLinear">
vec3 SRGBLinear(vec3 rgb) {
bvec3 lin = greaterThan(rgb, vec3(0.04045));
float k1 = 1.0 / 1.055;
float k2 = 1.0 / 12.92;
// #version 300 es
vec3 lRgb = mix(k2 * rgb, pow(k1 * (rgb + 0.055), vec3(2.4)), lin);
for(int i = 0; i < 3; i++)
lRgb[i] = lin[i] ? pow(k1 * (rgb[i] + 0.055), 2.4) : k2 * rgb[i];
return lRgb;
}
</script>
<script type="x-shader/x-function" id="linearRGB601">
vec3 linearRGB601(vec3 rgb) { // Rec.601
bvec3 lin = greaterThanEqual(rgb, vec3(0.018));
vec3 lRgb;
for(int i = 0; i < 3; i++)
lRgb[i] = lin[i] ? 1.099 * pow(rgb[i], 0.45) - 0.099 : 4.5 * rgb[i];
return lRgb;
}
</script>
<script type="x-shader/x-function" id="greyR601">
float greyR601(vec3 sRGB) {
vec3 lRGB = pow(sRGB, vec3(2.2));
vec3 rgb601 = linearRGB601(lRGB);
vec3 luma = vec3(0.299, 0.587, 0.114);
return dot(luma, rgb601);
}
</script>
<script type="x-shader/x-function" id="greyR601S">
float greyR601S(vec3 sRGB) {
vec3 lRGB = SRGBLinear(sRGB);
vec3 rgb601 = linearRGB601(lRGB);
vec3 luma = vec3(0.299, 0.587, 0.114);
return dot(luma, rgb601);
}
</script>
<script type="x-shader/x-function" id="grey">
float grey(vec3 sRGB) {
vec3 lRGB = pow(sRGB, vec3(2.2));
vec3 lumi = vec3(0.2126, 0.7152, 0.0722);
float y = dot(lumi, lRGB);
return pow(y, 1.0 / 2.2);
}
</script>
<script type="x-shader/x-function" id="greyPS">
float greyPS(vec3 sRGB) {
// photoshop desaturate
float bw = (min(sRGB.r, min(sRGB.g, sRGB.b)) + max(sRGB.r, max(sRGB.g, sRGB.b))) * 0.5;
...
CSS
body {
background: #000;
}
button {
padding: 3px;
margin-right: 5px;
cursor: pointer;
filter: invert(1);
}
div {
color: #ccc;
}
JavaScript
import * as THREE from 'https://alikim.com/_v1_jsm/three.module.js'
import {
getShader
} from 'https://alikim.com/_v1_jsm/utils_three.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,
});
renderer.setPixelRatio(window.devicePixelRatio);
const [near, far] = [1, 1000];
const camera = new THREE.OrthographicCamera(-w2, w2, h2, -h2, near, far);
const render = () => {
renderer.render(scene, camera)
};
THREE.Cache.enabled = false;
const texldr = new THREE.TextureLoader();
const geo = new THREE.PlaneBufferGeometry(350, 350, 1, 1);
const mat = new THREE.MeshBasicMaterial();
const quad = new THREE.Mesh(geo, mat);
let _map;
const loadMap = () => {
_map = texldr.load(
'https://source.unsplash.com/random/350x350',
() => {
mat.map = _map;
mat.map.needsUpdate = true;
render();
}
)
};
loadMap();
let _mode = 0;
const msh = new THREE.Mesh(
geo,
new THREE.ShaderMaterial({
vertexShader: getShader('vs'),
fragmentShader: getShader('fs'),
uniforms: {
map: {
get value() {
return _map
}
},
mode: {
get value() {
return _mode
}
},
},
})
);
quad.position.x = w2 / 2;
msh.position.x = -w2 / 2;
camera.position.set(0, 0, 180);
const scene = new THREE.Scene().add(msh).add(quad);
get('bgrey').addEventListener('click', () => {
_mode = 0;
render();
});
get('bgreyR601').addEventListener('click', () => {
_mode = 1;
render();
});
get('bgreyR601S').addEventListener('click', () => {
_mode = 2;
render();
});
get('bgreyPS').addEventListener('click', () => {
_mode = 3;
render();
});
get('reload').addEventListener('click', ()=>{location.reload()});//loadMap);