webglo documentation

Architecture, shader interfaces, responsive rendering, diagnostics, inscription mechanics, sandbox behavior, recursion, file limits, portability rules, and project records.

WebGL 1.0GLSL ES 1.00text/htmlcommit / reveal
Jump to a section
Reference

System overview

Webglo is a browser-rendered video-art project in which each artwork can be represented as an HTML inscription containing native JavaScript and GLSL. The browser provides the WebGL API, the GPU executes the shaders, and the Ordinals content server returns the inscribed HTML as web content.

Runtime layer

HTML canvas, native JavaScript, WebGL context, GPU buffers, uniforms, and shaders.

Bitcoin layer

On-chain inscription content, commit/reveal transactions, a carrier sat, and an inscription ID.

WebGL is a low-level, cross-platform browser API based on OpenGL ES. WebGL 1 exposes the OpenGL ES 2.0 feature set; WebGL 2 exposes much of OpenGL ES 3.0.
Rendering

Rendering architecture

Canvas
element
WebGLRendering
Context
Linked
program
Fullscreen
geometry
Fragment
output

Core objects

ObjectResponsibility
HTMLCanvasElementDefines the browser surface and CSS display size.
WebGLRenderingContextExposes WebGL 1 state, resources, shader compilation, and draw calls.
WebGLShaderStores a compiled vertex or fragment shader.
WebGLProgramLinks compatible vertex and fragment stages into an executable GPU program.
WebGLBufferStores fullscreen vertex positions.
WebGLUniformLocationAddresses per-frame values such as time, resolution, and pointer position.

Why fullscreen triangles

The runtime draws two triangles covering clip space from -1 to 1. Every covered pixel invokes the fragment shader, allowing the shader to generate the entire image without textures or scene geometry.

Packaging

Single-file contract

A Webglo inscription should remain understandable as one web response with a valid HTML MIME type. The simplest portable form embeds all CSS, JavaScript, vertex GLSL, and fragment GLSL directly in the HTML document.

  • One HTML document is the entry point.
  • No npm bundle or build artifact is required at viewing time.
  • No ordinary off-chain resources are required for the core render.
  • The canvas has an explicit backing resolution before drawing.
  • Shader compile and program link failures are surfaced visibly.
  • The page remains functional inside an iframe-based inscription viewer.

Recommended MIME type

text/html;charset=utf-8

Lifecycle

Runtime lifecycle

  1. Resolve the canvas.
  2. Create the WebGL context and stop with a visible fallback if unavailable.
  3. Compile the vertex shader.
  4. Compile the fragment shader.
  5. Link both shaders into a program.
  6. Create and upload fullscreen geometry.
  7. Resolve attribute and uniform locations once.
  8. On each frame, resize, set the viewport, update uniforms, and draw.
  9. Handle context loss or recover by reinitializing resources.
WebGL is stateful. Binding the wrong program or buffer, failing to enable an attribute, or using a stale location can produce a blank frame without a JavaScript exception.
GLSL interface

Shader interface

WebGL 1 vertex shader

vertex shader
attribute vec2 a_position;

void main() {
  gl_Position = vec4(a_position, 0.0, 1.0);
}

WebGL 1 fragment shader contract

fragment shader interface
precision highp float;

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

void main() {
  vec2 uv = gl_FragCoord.xy / u_resolution.xy;
  gl_FragColor = vec4(uv, 0.5 + 0.5 * sin(u_time), 1.0);
}
NameDirectionNotes
a_positionJavaScript → vertex shaderTwo-component clip-space coordinate.
u_resolutionJavaScript → fragment shaderUse backing pixels, not only CSS pixels.
u_timeJavaScript → fragment shaderSeconds from requestAnimationFrame.
u_mouseJavaScript → fragment shaderNormalized input; optional for noninteractive work.
gl_FragCoordBuilt-in fragment inputCurrent fragment coordinate in window space.
gl_FragColorFragment shader outputWebGL 1 / GLSL ES 1.00 output variable.

WebGL 1 versus WebGL 2

WebGL 1 shaders commonly use attribute, varying, and gl_FragColor. WebGL 2 uses GLSL ES 3.00 conventions such as #version 300 es, in, out, and an explicit fragment output. Do not mix the two syntaxes.

Display

Resolution, aspect ratio, and input

CSS controls how large the canvas appears. The width and height properties control the actual backing buffer. A high-DPI display needs a larger backing buffer than its CSS size to avoid blur.

responsive backing resolution
function resizeCanvasToDisplaySize(canvas) {
  const dpr = Math.min(window.devicePixelRatio || 1, 2);
  const width = Math.max(1, Math.round(canvas.clientWidth * dpr));
  const height = Math.max(1, Math.round(canvas.clientHeight * dpr));

  if (canvas.width !== width || canvas.height !== height) {
    canvas.width = width;
    canvas.height = height;
    return true;
  }

  return false;
}

// Call before drawing:
resizeCanvasToDisplaySize(canvas);
gl.viewport(0, 0, canvas.width, canvas.height);

Aspect-correct coordinates

GLSL
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
vec2 p = uv - 0.5;
p.x *= u_resolution.x / u_resolution.y;

Device-pixel-ratio cap

Capping DPR at 2 is a practical performance guard for generative shaders. Removing the cap improves sharpness on very dense displays but can multiply fragment workload.

Debugging

Compilation and link diagnostics

Shader compiler logs are the primary diagnostic source. Always inspect COMPILE_STATUS and LINK_STATUS; do not assume a created object is valid.

reusable shader compiler
function compileShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    const log = gl.getShaderInfoLog(shader);
    gl.deleteShader(shader);
    throw new Error(log || "Shader compilation failed.");
  }

  return shader;
}

Common compiler failures

Error classTypical cause
SyntaxMissing semicolon, unbalanced bracket, malformed numeric literal.
Type mismatchCombining scalar, vector, or matrix types without a valid conversion.
PrecisionNo default float precision in a fragment shader.
Version mismatchUsing WebGL 2 GLSL syntax in a WebGL 1 context or the reverse.
Link mismatchVertex outputs and fragment inputs disagree in name, type, or precision.
Uniform optimized outA declared value is unused, producing a null uniform location.
Execution environment

Ordinals HTML runtime

Ordinals content uses a web-style model: an inscription has a MIME content type and a byte body that can be returned by a content server. HTML and SVG inscriptions are sandboxed in iframes and served with content-security restrictions intended to prevent ordinary off-chain dependencies.

Implications for WebGL work

  • Inline JavaScript and GLSL are the most portable base.
  • Remote CDN scripts, web fonts, images, and APIs should not be required.
  • Audio autoplay and user-input behavior may differ by browser and viewer.
  • The direct content view is the authoritative rendering test, not only a marketplace card.
  • Viewer implementations can differ, so graceful fallback behavior matters.
The inscription content itself is on-chain. A normal web page hosted on GitHub Pages is a separate presentation layer and is not proof that every dependency inside the page is inscribed.
Bitcoin

Commit and reveal model

Inscriptions use a two-transaction process. The commit creates a Taproot output committing to the script that contains the inscription. The reveal spends that output and publishes the inscription content in the witness.

Funded
wallet
Commit
transaction
Taproot
output
Reveal
transaction
Indexed
inscription

Inscription ID

An inscription ID has the form TXIDiN. TXID is the reveal transaction ID and N is the zero-based index of the inscription inside that reveal.

Content envelope

The content type and body are serialized in an unexecuted Taproot script conditional. Large bodies are split across data pushes because individual pushes are limited to 520 bytes.

Capacity

Practical limits and fee model

The current ord wallet guide states that inscription transactions must be below 400,000 weight units to be relayed by Bitcoin Core and recommends keeping content below roughly 390,000 bytes to leave room for transaction overhead.

ConstraintMeaning
Bitcoin block weightUpper capacity of a block; not a safe target for a standard individual inscription transaction.
Standard relay policyDetermines whether ordinary Bitcoin Core nodes relay the transaction.
Tool/service limitMay be lower or use a specialized workflow; follow the active interface.
Browser/GPU limitA tiny file can still be too computationally expensive to render smoothly.

Approximate content fee

The ord guide gives the approximation: (content bytes ÷ 4) × fee rate. The total transaction cost is higher because commit/reveal overhead and outputs also consume weight.

Fee rates are dynamic. Use current mempool conditions and the exact estimate from the selected inscription workflow immediately before authorizing.
On-chain composition

Recursive content

Recursion is the allowed exception to the ordinary inscription sandbox. Whitelisted endpoints can load content and data from other inscriptions, making it possible to share code, textures, audio, stylesheets, or generative assets without copying them into every child HTML file.

recursive content paths
<!-- On an Ordinals-compatible content server -->
<script src="/content/<INSCRIPTION_ID>"></script>

<!-- Or load an on-chain image -->
<img src="/content/<INSCRIPTION_ID>" alt="">

Use cases

  • One shared JavaScript or shader library referenced by many artworks.
  • Texture atlases or visual layers assembled by a smaller HTML inscription.
  • Generative collections using inscription IDs or chain data as seeds.
  • Remixes that explicitly depend on previously inscribed media.
Recursive endpoints carry stronger compatibility guarantees than ordinary server endpoints, but code should tolerate additional JSON fields and avoid depending on object property order.
Engineering rules

Portability and resilience

  • Prefer WebGL 1 when the artwork does not require WebGL 2-only features.
  • Use explicit precision declarations and avoid undefined GLSL behavior.
  • Compute aspect ratio from the current resolution rather than hard-coded 640×480 values.
  • Cap device pixel ratio or dynamically reduce quality for expensive shaders.
  • Keep the render meaningful without pointer input.
  • Provide a visible WebGL failure message instead of a silent black page.
  • Handle context loss and recreate GPU resources after restoration.
  • Do not depend on explorer-specific DOM access or unsandboxed behavior.
  • Preserve an unminified source version and inscribe only a tested optimized build.
Compatibility

Browser and device support

WebGL is implemented by modern desktop and mobile browsers, but actual availability still depends on the device GPU, browser settings, driver blocklists, power state, and viewer environment.

TestMinimum recommendation
Desktop browsersCurrent Chrome or Edge plus current Firefox.
SafariTest separately, especially inscription-service controls and mobile behavior.
MobileAt least one iOS Safari device and one Android Chrome device.
OrientationPortrait and landscape.
DPI1× and high-DPI displays.
InputNo pointer, touch pointer, and mouse pointer.
Long runSeveral minutes to detect thermal throttling or context loss.
Project records

Webglo inscriptions

The original Webglo inscription was created on June 12, 2023 at 23:05:38 UTC. Its known record includes inscription number #11635450, inscription ID 5518d36079b3cc854dba0bd6497ec078fbaa996ebd53e908150c845d6a56a463i0, and sat number 849910637619339.

InscriptionExplorer
#11635450Open inscription
#11637749Open inscription
#11805310Open inscription
#11875520Open inscription
#11875521Open inscription
#11875522Open inscription
#11875523Open inscription
#11875524Open inscription
#11875525Open inscription
#11875526Open inscription
#12077747Open inscription
#12077748Open inscription
#12077749Open inscription
#12077750Open inscription
#12077751Open inscription
#12077752Open inscription
#12077753Open inscription
#12077754Open inscription
#12077755Open inscription
#12077756Open inscription
#12102422Open inscription
#12102423Open inscription
#12102424Open inscription
#12102425Open inscription
#12102426Open inscription
Terms

Glossary

TermDefinition
Bitcoin OrdinalA sat tracked under ordinal theory; it may carry an inscription.
InscriptionContent associated with a sat through a reveal transaction.
Commit transactionCreates the Taproot output that commits to the inscription script.
Reveal transactionSpends the commit output and exposes the inscription content.
WebGLBrowser API for GPU-accelerated graphics based on OpenGL ES.
GLSLShader language executed by the graphics pipeline.
Vertex shaderTransforms vertex inputs and produces clip-space positions.
Fragment shaderComputes the output color for covered pixels/fragments.
UniformA constant value supplied to a shader for a draw call.
RecursionLoading whitelisted on-chain content or data from other inscriptions.
MIME typeContent type used to describe how the inscription body should be served.
Primary sources

Technical references