interesting libraries
webgl 2 is a browser api for controlling gpu graphics processing from javascript. it is based on opengl es 3.0.
webgl provides mechanisms for:
webgl does not define scenes, objects, cameras, animation, transforms, materials, or a rendering architecture. these are application-level concepts.
a webgl context is the javascript object representing one webgl instance.
a resource is an object created and managed through a context. resources hold persistent data or configuration.
state is persistent configuration stored by the context and consulted by later commands.
a command is a webgl api operation that creates resources, changes state, transfers data, or performs graphics processing.
a binding point is a state location that refers to one selected resource.
binding a resource assigns it to a binding point. commands associated with that binding point then operate on the selected resource.
context = (resources, state) command(context, arguments) -> context'
webgl is therefore stateful: the meaning of many commands depends on state established by earlier commands.
the graphics pipeline is the ordered gpu process that converts application-supplied data into modifications of image storage.
a draw call is a command that invokes this pipeline.
the pipeline operates on vertices, constructs geometric primitives, determines which image locations they cover, computes output values for those locations, and conditionally stores those values.
a vertex is one logical geometric input item processed by a draw call.
a primitive is one basic geometric object constructed from vertices.
webgl primitive classes are:
a primitive mode determines how a sequence of vertices is grouped into primitives.
webgl has no built-in polygon, mesh, cube, sphere, or surface primitive. such geometry is represented as collections of points, lines, or triangles.
a shader is a gpu program used by the graphics pipeline.
a vertex shader is the shader executed once for each processed vertex. it computes the vertex position required by later pipeline stages and may produce additional values.
a shader invocation is one execution of a shader for one pipeline input.
primitive assembly is the pipeline stage that groups processed vertices into primitives according to the selected primitive mode.
rasterization is the process of determining which image locations are covered by a primitive.
a fragment is one candidate contribution to an image location produced by rasterization.
a fragment shader is the shader executed for fragments. it computes values, normally colors, that may subsequently be stored.
a program is a linked collection of compatible shader stages used by a draw call.
in ordinary webgl drawing:
program = vertex_shader + fragment_shader
shader compilation validates and translates one shader.
program linking validates the interfaces between attached shaders and produces a program that can be selected for drawing.
a vertex attribute is a shader input whose value can differ for each vertex.
an attribute location is the integer slot through which a program receives one vertex attribute.
a uniform is a shader input whose value remains constant across all shader invocations belonging to one draw call unless the application changes it between draw calls.
a vertex shader output is a value produced for one vertex for use by later pipeline stages.
a matching fragment shader input receives values derived from vertex shader outputs. for ordinary numeric values, webgl interpolates the values across the primitive before each fragment shader invocation.
a fragment shader output is a value proposed for storage by later pipeline stages.
the principal data classes are therefore:
attribute = per-vertex input uniform = per-draw shared input vertex output = per-vertex intermediate value fragment input = interpolated intermediate value fragment output = candidate stored value
a buffer is a webgl resource containing unstructured binary data.
a buffer has no intrinsic semantic type. the same resource type can hold positions, colors, indices, matrices, or arbitrary numeric data.
buffer storage is allocated and optionally initialized with bufferdata.
existing buffer storage can be modified with buffersubdata.
a buffer target is a binding point associated with a particular use of buffer data.
array_buffer is the binding point used while defining how buffer data supplies vertex attributes.
element_array_buffer is the binding point used for index data.
static_draw, dynamic_draw, and related values are usage hints describing the application's expected modification pattern. they do not impose mutability restrictions.
a vertex attribute array is a sequence of values used to supply one vertex attribute across successive vertices.
vertexattribpointer defines how bytes in a buffer are interpreted as elements of a vertex attribute array.
its configuration specifies:
the buffer associated with the attribute is the buffer bound to array_buffer when the attribute configuration is established.
vertexattribpointer records an interpretation of existing buffer storage. it does not transfer data.
a vertex array object, abbreviated vao, is a webgl resource containing vertex-input configuration.
a vao records:
element_array_buffer bindinga vao does not contain vertex data. buffers contain the data; the vao describes how that data becomes vertex shader input.
sequential drawing derives vertex identifiers from a consecutive integer range.
drawarrays performs sequential drawing.
indexed drawing derives vertex identifiers from integer values stored in an element buffer.
an index is an integer identifying which element of each enabled vertex attribute array supplies a vertex.
drawelements performs indexed drawing.
indexed drawing permits multiple primitive vertices to reuse the same stored attribute elements.
the distinction is:
drawarrays -> vertex identifiers generated sequentially drawelements -> vertex identifiers read from an element buffer
a vertex shader must produce gl_position, a four-component position:
(x, y, z, w)
these values are clip coordinates.
the clip volume is the region retained for subsequent rasterization. its bounds are expressed relative to w.
after clipping, perspective division produces normalized device coordinates:
(x / w, y / w, z / w)
normalized device coordinates use the range [-1, 1] along each visible axis.
a viewport is the rectangular image region to which normalized device coordinates are mapped.
the viewport therefore connects gpu geometry coordinates to destination pixel coordinates.
webgl does not prescribe coordinates before gl_position. model coordinates, world coordinates, view coordinates, projection matrices, and camera systems are application conventions.
the application only has to ensure that the vertex shader eventually produces the intended clip coordinates.
a framebuffer is the image-storage destination used by drawing commands.
an attachment is one storage component of a framebuffer.
a color attachment stores color values.
a depth attachment stores depth values.
a stencil attachment stores integer values used by stencil testing.
the default framebuffer is the browser-provided framebuffer associated with the canvas.
a framebuffer object is an application-created webgl resource that allows the application to define a different drawing destination.
binding a framebuffer selects the destination used by subsequent drawing commands.
a texture is a webgl resource containing structured multidimensional data that shaders can read.
a texel is one element of a texture.
a texture has dimensions, a data format, and sampling behavior.
a texture can also serve as framebuffer attachment storage, allowing drawing results to become later shader input.
a renderbuffer is image storage intended for use as a framebuffer attachment. unlike a texture, its contents are not directly sampled by shaders.
a texture unit is context state that associates shader texture access with bound texture resources.
a sampler is a shader value describing access to texture data.
a sampler uniform selects a texture unit.
texture access therefore depends on both shader state and texture-unit bindings.
fragment operations determine whether and how fragment shader outputs modify framebuffer attachments.
depth is a value associated with a fragment's position.
depth testing compares incoming fragment depth with depth already stored in a depth attachment.
the depth function specifies the comparison rule.
depth writing controls whether accepted fragment depth replaces the stored depth.
stencil testing compares and modifies stencil values according to configured rules.
blending combines a fragment shader output with a value already present in a color attachment.
a blend function specifies how source and existing destination values contribute to the stored result.
face culling rejects selected triangle orientations before rasterization.
scissor testing restricts framebuffer modification to a rectangular region.
these operations are controlled by context state. they are independent of the application-level meaning of the geometry.
framebuffer attachment contents persist until modified.
clearing replaces selected framebuffer attachment contents with configured clear values.
color, depth, and stencil storage are cleared independently.
clearing is not an intrinsic frame boundary. it is an explicit modification of framebuffer storage.
the drawing buffer is the pixel storage backing the default framebuffer.
the canvas element has a css display size and a drawing-buffer size.
these sizes are independent.
canvas.clientwidth and canvas.clientheight describe layout size in css pixels.
canvas.width and canvas.height determine drawing-buffer dimensions.
the viewport is independent of both and must represent the region the application intends to draw into.
a draw call uses the webgl state current when the command is issued.
relevant state includes:
the draw-call arguments therefore do not fully describe the operation.
conceptually:
draw_result = pipeline(vertex_selection, current_state, resources)
this state dependency is the reason webgl code contains separate selection, binding, configuration, data-transfer, and drawing commands.
the main webgl concepts have distinct responsibilities:
context = resource namespace + mutable webgl state buffer = unstructured binary storage texture = structured sampleable storage renderbuffer = framebuffer-oriented image storage shader = one gpu processing stage program = linked shader configuration vao = vertex-input configuration framebuffer = drawing destination uniform = shared shader input attribute = per-vertex shader input draw call = pipeline invocation
these concepts are orthogonal. a higher-level graphics object such as a mesh or material generally consists of several of them rather than corresponding to one webgl object.
webgl resources persist across draw calls until modified, deleted, or invalidated by context loss.
context state likewise persists until changed.
resource creation, resource contents, configuration, and drawing are therefore separate concerns.
stable data and configuration can remain established across many draw calls.
changing application state requires changing only the webgl resources or context state on which the next draw call depends.
animation is consequently not a webgl concept. repeated drawing is produced by the application changing relevant state or data and issuing further draw calls.
the webgl drawing process can be compressed to:
application data -> webgl resources -> vertex input -> vertex shader -> primitive assembly -> clipping -> rasterization -> fragment shader -> fragment operations -> framebuffer
the application determines:
what data means how data is transformed which program interprets it which vertices form primitives where results are stored which fragment operations apply when drawing occurs
webgl supplies the mechanisms and execution semantics for those decisions.