Mips TEXTURE_BASE_LEVEL

by Cody Bennett

HTML

<canvas id="canvas"></canvas>
Mip: <input id="activeMip" type="range" min="0" max="1" value="0">

CSS

body {
  margin: 0;
}

canvas {
  display: block;
  position: absolute;
  z-index: -1;
}

JavaScript

(async () => {

canvas.width = innerWidth
canvas.height = innerHeight

const gl = canvas.getContext('webgl2')

const vertex = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(
  vertex,
  /* glsl */ `#version 300 es
    out vec2 vUv;

    void main() {
      vUv = vec2(gl_VertexID << 1 & 2, gl_VertexID & 2);
      gl_Position = vec4(vUv * 2.0 - 1.0, 0, 1);
    }
  `,
)
gl.compileShader(vertex)

const fragment = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(
  fragment,
  /* glsl */ `#version 300 es
    precision lowp float;

    uniform sampler2D cat;

    in vec2 vUv;
    out vec4 color;

    void main() {
      color = texture(cat, vUv);
    }
  `,
)
gl.compileShader(fragment)

const downsample = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(
  downsample,
  /* glsl */ `#version 300 es
    precision lowp float;

    uniform sampler2D mips;

    in vec2 vUv;
    out vec4 color;

    void main() {
      color = texture(mips, vUv);
    }
  `,
)
gl.compileShader(downsample)

const composite = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(
  composite,
  /* glsl */ `#version 300 es
    precision lowp float;

    uniform sampler2D mips;
    uniform float lod;

    in vec2 vUv;
    out vec4 color;

    void main() {
      color = textureLod(mips, vUv, lod);
    }
  `,
)
gl.compileShader(composite)

const catProgram = gl.createProgram()
gl.attachShader(catProgram, vertex)
gl.attachShader(catProgram, fragment)
gl.linkProgram(catProgram)
gl.useProgram(catProgram)

const downsampleProgram = gl.createProgram()
gl.attachShader(downsampleProgram, vertex)
gl.attachShader(downsampleProgram, downsample)
gl.linkProgram(downsampleProgram)
gl.useProgram(downsampleProgram)

const compositeProgram = gl.createProgram()
gl.attachShader(compositeProgram, vertex)
gl.attachShader(compositeProgram, composite)
gl.linkProgram(compositeProgram)
gl.useProgram(compositeProgram)

const MIPS = 1 + Math.floor(Math.log2(Math.max(innerWidth, innerHeight)))
activeMip.max = MIPS -...