Last active
May 22, 2024 02:13
-
-
Save greggman/ec4441fd538cdda23c27f266a0016a1a to your computer and use it in GitHub Desktop.
WebGL: Test textureGrad vs texture
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
html, body { | |
margin: 0; | |
font-family: monospace; | |
height: 100%; | |
background-color: #333; | |
} | |
canvas { | |
margin: 5px; | |
border: 1px solid #888; | |
display: inline-block; | |
width: 32px; | |
height: 32px; | |
} |
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
/*bug-in-github-api-content-can-not-be-empty*/ |
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 twgl from 'https://twgljs.org/dist/5.x/twgl-full.module.js'; | |
const vs = `#version 300 es | |
uniform mat3 u_texMat; | |
out vec2 v_texCoord; | |
const vec2 position[6] = vec2[6]( | |
vec2(0, 0), | |
vec2(1, 0), | |
vec2(0, 1), | |
vec2(0, 1), | |
vec2(1, 0), | |
vec2(1, 1)); | |
void main() { | |
vec2 p = position[gl_VertexID]; | |
v_texCoord = (u_texMat * vec3(p, 1)).xy; | |
gl_Position = vec4(p * 2.0 - 1.0, 0, 1); | |
} | |
`; | |
const fsTex = `#version 300 es | |
precision highp float; | |
in vec2 v_texCoord; | |
uniform sampler2D u_tex; | |
out vec4 outColor; | |
void main() { | |
outColor = texture(u_tex, v_texCoord); | |
} | |
`; | |
const fsTexGrad = `#version 300 es | |
precision highp float; | |
in vec2 v_texCoord; | |
uniform sampler2D u_tex; | |
uniform vec2 ddx; | |
uniform vec2 ddy; | |
out vec4 outColor; | |
void main() { | |
outColor = textureGrad(u_tex, v_texCoord, ddx, ddy); | |
} | |
`; | |
const colors = [ | |
'#F00', // 128 | |
'#FF0', // 64 | |
'#0F0', // 32 | |
'#0FF', // 16 | |
'#00F', // 8 | |
'#F0F', // 4 | |
'#888', // 2 | |
'#FFF', // 1 | |
'#f84' | |
]; | |
function createMips(colors) { | |
const ctx = document.createElement('canvas').getContext('2d'); | |
const numMips = colors.length; | |
return colors.map((color, i) => { | |
const size = 2 ** (numMips - i - 1); | |
ctx.canvas.width = size; | |
ctx.canvas.height = size; | |
ctx.fillStyle = color; | |
ctx.fillRect(0, 0, size, size); | |
return ctx.getImageData(0, 0, size, size); | |
}); | |
} | |
function main() { | |
const m4 = twgl.m4; | |
const canvas = document.createElement("canvas"); | |
const size = 2 ** (colors.length - 1); | |
canvas.width = size; | |
canvas.height = size; | |
const gl = canvas.getContext("webgl2"); | |
if (!gl) { | |
alert("Sorry, this example requires WebGL 2.0"); // eslint-disable-line | |
return; | |
} | |
const texProgramInfo = twgl.createProgramInfo(gl, [vs, fsTex]); | |
const gradProgramInfo = twgl.createProgramInfo(gl, [vs, fsTexGrad]); | |
const texImage = gl.createTexture(); | |
gl.bindTexture(gl.TEXTURE_2D, texImage); | |
const data = createMips(colors); | |
data.forEach(({width, height, data}, level) => { | |
gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); | |
}); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST); | |
for (let prgInfo of [texProgramInfo, gradProgramInfo]) { | |
for (let i = 0; i < colors.length; ++i) { | |
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); | |
gl.clearColor(0.3, 0.3, 0.3, 1); | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
const s = 2 ** i; | |
const uniforms = { | |
u_texMat: [ | |
s, 0, 0, | |
0, s, 0, | |
0, 0, 1, | |
], | |
ddx: [s / size, 0], | |
ddy: [0, 0], | |
}; | |
gl.useProgram(prgInfo.program); | |
twgl.setUniforms(prgInfo, uniforms); | |
gl.drawArrays(gl.TRIANGLES, 0, 6); | |
const c = document.createElement('canvas'); | |
c.width = 32; | |
c.height = 32; | |
const ctx = c.getContext('2d', {willReadFrequently: true}); | |
ctx.drawImage(gl.canvas, 0, 0); | |
document.body.appendChild(c); | |
} | |
document.body.appendChild(document.createElement('hr')); | |
} | |
} | |
main(); |
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
{"name":"WebGL: Test textureGrad vs texture","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