Skip to content

Instantly share code, notes, and snippets.

@asc0910
Last active February 25, 2023 19:12
Show Gist options
  • Save asc0910/79579ef5e4e6589ffc38effa2c042dba to your computer and use it in GitHub Desktop.
Save asc0910/79579ef5e4e6589ffc38effa2c042dba to your computer and use it in GitHub Desktop.
bluring
@import url("https://webglfundamentals.org/webgl/resources/webgl-tutorials.css");
body {
margin: 0;
}
#canvas {
width: 3000px;
height: 3000px;
display: block;
}
<canvas id="canvas"></canvas>
<!-- vertex shader -->
<script src="https://www.lactame.com/lib/image-js/0.21.2/image.min.js"></script>
<script id="vertex-shader-2d" type="x-shader/x-vertex">
attribute vec2 a_position;
attribute vec2 a_texCoord;
uniform vec2 u_resolution;
varying vec2 v_texCoord;
void main() {
// convert the rectangle from pixels to 0.0 to 1.0
vec2 zeroToOne = a_position / u_resolution;
// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;
// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
// pass the texCoord to the fragment shader
// The GPU will interpolate this value between points.
v_texCoord = a_texCoord;
}
</script>
<!-- fragment shader -->
<script id="fragment-shader-2d" type="x-shader/x-fragment">
precision highp float;
// our textures
uniform sampler2D inputa;
uniform sampler2D zdepth;
uniform float width;
uniform float height;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
vec4 getColor(vec2 p, float dx, float dy) {
vec2 coord = vec2(p.x + dx / width, p.y + dy / height);
return texture2D(inputa, coord);
}
void main() {
vec4 result = getColor(v_texCoord, 0.0, 0.0);
float zdepthu = texture2D(zdepth, v_texCoord).r;
float Size = (1.0 - zdepthu) * 7.0 - 0.5;
float weight = 1.0;
if (Size > 0.0) {
float sigma = Size;
for (float dx = -10.0; dx <= 10.0; dx += 1.0) {
for (float dy = -10.0; dy <= 10.0; dy += 1.0) {
float w = 1.0 / sqrt(6.28 * sigma * sigma) * exp(- (dx * dx + dy * dy) / (2.0 * sigma * sigma));
result += w * getColor(v_texCoord, dx, dy);
weight += w;
}
}
result /= weight;
}
gl_FragColor = result; //vec4(zdepthu, zdepthu, zdepthu, 1);
}
</script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script src="https://www.lactame.com/lib/image-js/0.21.2/image.min.js"></script>
"use strict";
const assets = {
input: 'https://res.cloudinary.com/casestry-com/image/upload/v1677099413/test/download_4_yszcgh.png',
zdepth: 'https://res.cloudinary.com/casestry-com/image/upload/v1677092667/test/zdepth_vnhyk4.png',
}
async function loadImage(url) {
return new Promise((resolve) => {
var image = new Image();
requestCORSIfNotSameOrigin(image, url)
image.src = url;
image.onload = () => {
resolve(image)
};
})
}
async function main() {
const input = await loadImage(assets.input)
const zdepth = await loadImage(assets.zdepth);
render([input, zdepth])
}
var documentCanvas = document.querySelector('#canvas');
function render(images) {
var starttime = Date.now();
// Get A WebGL context
/** @type {HTMLCanvasElement} */
var canvas = document.createElement("canvas");
canvas = documentCanvas;
canvas.width = images[1].width;
canvas.height = images[1].height;
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
var program = twgl.createProgramFromScripts(gl, ["vertex-shader-2d", "fragment-shader-2d"]);
gl.useProgram(program);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
var texcoordLocation = gl.getAttribLocation(program, "a_texCoord");
// Create a buffer to put three 2d clip space points in
var positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Set a rectangle the same size as the image.
setRectangle(gl, 0, 0, canvas.width, canvas.height);
// provide texture coordinates for the rectangle.
var texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0,
]), gl.STATIC_DRAW);
// create 2 textures
var textures = [];
for (var ii = 0; ii < 2; ++ii) {
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Set the parameters so we can render any size image.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
// Upload the image into the texture.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, images[ii]);
// add the texture to the array of textures.
textures.push(texture);
}
// lookup uniforms
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
// lookup the sampler locations.
var inputLocation = gl.getUniformLocation(program, "inputa");
var zdepthLocation = gl.getUniformLocation(program, "zdepth");
var widthLocation = gl.getUniformLocation(program, "width");
var heightLocation = gl.getUniformLocation(program, "height");
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Clear the canvas
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Tell it to use our program (pair of shaders)
gl.useProgram(program);
// Turn on the position attribute
gl.enableVertexAttribArray(positionLocation);
// Bind the position buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.FLOAT; // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer(
positionLocation, size, type, normalize, stride, offset);
// Turn on the texcoord attribute
gl.enableVertexAttribArray(texcoordLocation);
// bind the texcoord buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
// Tell the texcoord attribute how to get data out of texcoordBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.FLOAT; // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer(
texcoordLocation, size, type, normalize, stride, offset);
// set the resolution
gl.uniform2f(resolutionLocation, gl.canvas.width, gl.canvas.height);
// set which texture units to render with.
gl.uniform1i(inputLocation, 0); // texture unit 0
gl.uniform1i(zdepthLocation, 1); // texture unit 1
gl.uniform1f(widthLocation, gl.canvas.width); // texture unit 3
gl.uniform1f(heightLocation, gl.canvas.height); // texture unit 4
// Set each texture unit to use a particular texture.
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, textures[0]);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, textures[2]);
gl.activeTexture(gl.TEXTURE3);
gl.bindTexture(gl.TEXTURE_2D, textures[3]);
// Draw the rectangle.
gl.drawArrays(gl.TRIANGLES, 0, 6);
console.log('Elapsed: ', Date.now() - starttime);
}
function setRectangle(gl, x, y, width, height) {
var x1 = x;
var x2 = x + width;
var y1 = y;
var y2 = y + height;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2,
]), gl.STATIC_DRAW);
}
main();
// This is needed if the images are not on the same domain
// NOTE: The server providing the images must give CORS permissions
// in order to be able to use the image with WebGL. Most sites
// do NOT give permission.
// See: https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html
function requestCORSIfNotSameOrigin(img, url) {
if ((new URL(url, window.location.href)).origin !== window.location.origin) {
img.crossOrigin = "";
}
}
{"name":"bluring","settings":{},"filenames":["index.html","index.css","index.js"]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment