Class: WebGLHelper

ol/webgl/Helper~WebGLHelper


import WebGLHelper from 'ol/webgl/Helper';

This class is intended to provide low-level functions related to WebGL rendering, so that accessing directly the WebGL API should not be required anymore.

Several operations are handled by the WebGLHelper class:

Define custom shaders and uniforms

Shaders are low-level programs executed on the GPU and written in GLSL. There are two types of shaders:

Vertex shaders are used to manipulate the position and attribute of vertices of rendered primitives (ie. corners of a square). Outputs are:

  • gl_Position: position of the vertex in screen space

  • Varyings usually prefixed with v_ are passed on to the fragment shader

    Fragment shaders are used to control the actual color of the pixels drawn on screen. Their only output is gl_FragColor.

    Both shaders can take uniforms or attributes as input. Attributes are explained later. Uniforms are common, read-only values that can be changed at every frame and can be of type float, arrays of float or images.

    Shaders must be compiled and assembled into a program like so:

    // here we simply create two shaders and assemble them in a program which is then used
    // for subsequent rendering calls
    const vertexShader = new WebGLVertex(VERTEX_SHADER);
    const fragmentShader = new WebGLFragment(FRAGMENT_SHADER);
    const program = this.context.getProgram(fragmentShader, vertexShader);
    helper.useProgram(this.program);

    Uniforms are defined using the uniforms option and can either be explicit values or callbacks taking the frame state as argument. You can also change their value along the way like so:

    helper.setUniformFloatValue('u_value', valueAsNumber);

Defining post processing passes

Post processing describes the act of rendering primitives to a texture, and then rendering this texture to the final canvas while applying special effects in screen space. Typical uses are: blurring, color manipulation, depth of field, filtering...

The WebGLHelper class offers the possibility to define post processes at creation time using the postProcesses option. A post process step accepts the following options:

  • fragmentShader and vertexShader: text literals in GLSL language that will be compiled and used in the post processing step.

  • uniforms: uniforms can be defined for the post processing steps just like for the main render.

  • scaleRatio: allows using an intermediate texture smaller or higher than the final canvas in the post processing step. This is typically used in blur steps to reduce the performance overhead by using an already downsampled texture as input.

    The module:ol/webgl/PostProcessingPass~WebGLPostProcessingPass class is used internally, refer to its documentation for more info.

Binding WebGL buffers and flushing data into them

Data that must be passed to the GPU has to be transferred using module:ol/webgl/Buffer~WebGLArrayBuffer objects. A buffer has to be created only once, but must be bound every time the buffer content will be used for rendering. This is done using bindBuffer. When the buffer's array content has changed, the new data has to be flushed to the GPU memory; this is done using flushBufferData. Note: this operation is expensive and should be done as infrequently as possible.

When binding an array buffer, a target parameter must be given: it should be either module:ol/webgl.ARRAY_BUFFER (if the buffer contains vertices data) or module:ol/webgl.ELEMENT_ARRAY_BUFFER (if the buffer contains indices data).

Examples below:

  // at initialization phase
  const verticesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
  const indicesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);

  // when array values have changed
  helper.flushBufferData(ARRAY_BUFFER, this.verticesBuffer);
  helper.flushBufferData(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);

  // at rendering phase
  helper.bindBuffer(ARRAY_BUFFER, this.verticesBuffer);
  helper.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);

Specifying attributes

The GPU only receives the data as arrays of numbers. These numbers must be handled differently depending on what it describes (position, texture coordinate...). Attributes are used to specify these uses. Use enableAttributeArray_ and either the default attribute names in module:ol/webgl/Helper.DefaultAttrib or custom ones.

Please note that you will have to specify the type and offset of the attributes in the data array. You can refer to the documentation of WebGLRenderingContext.vertexAttribPointer for more explanation.

  // here we indicate that the data array has the following structure:
  // [posX, posY, offsetX, offsetY, texCoordU, texCoordV, posX, posY, ...]
  helper.enableAttributes([
    {
       name: 'a_position',
       size: 2
    },
    {
      name: 'a_offset',
      size: 2
    },
    {
      name: 'a_texCoord',
      size: 2
    }
  ])

Rendering primitives

Once all the steps above have been achieved, rendering primitives to the screen is done using prepareDraw, drawElements and finalizeDraw.

  // frame preparation step
  helper.prepareDraw(frameState);

  // call this for every data array that has to be rendered on screen
  helper.drawElements(0, this.indicesBuffer.getArray().length);

  // finalize the rendering by applying post processes
  helper.finalizeDraw(frameState);

For an example usage of this class, refer to module:ol/renderer/webgl/PointsLayer~WebGLPointsLayerRenderer.

new WebGLHelper(opt_options)

webgl/Helper.js, line 237
Name Type Description
options

Options.

Name Type Description
uniforms Object.<string, module:ol/webgl/Helper~UniformValue>

Uniform definitions; property names must match the uniform names in the provided or default shaders.

postProcesses Array.<module:ol/webgl/Helper~PostProcessesOptions>

Post-processes definitions

Extends

  • module:ol/Disposable~Disposable

Methods

bindBuffer(buffer)

webgl/Helper.js, line 364

Just bind the buffer if it's in the cache. Otherwise create the WebGL buffer, bind it, populate it, and add an entry to the cache.

Name Type Description
buffer module:ol/webgl/Buffer~WebGLArrayBuffer

Buffer.

createTexture(size, opt_data, opt_texture){WebGLTexture}

webgl/Helper.js, line 810

Will create or reuse a given webgl texture and apply the given size. If no image data specified, the texture will be empty, otherwise image data will be used and the size parameter will be ignored. Note: wrap parameters are set to clamp to edge, min filter is set to linear.

Name Type Description
size Array.<number>

Expected size of the texture

data ImageData | HTMLImageElement | HTMLCanvasElement

Image data/object to bind to the texture

texture WebGLTexture

Existing texture to reuse

Returns:
The generated texture

drawElements(start, end)

webgl/Helper.js, line 480

Execute a draw call based on the currently bound program, texture, buffers, attributes.

Name Type Description
start number

Start index.

end number

End index.

enableAttributes(attributes)

webgl/Helper.js, line 773

Will enable the following attributes to be read from the currently bound buffer, i.e. tell the GPU where to read the different attributes in the buffer. An error in the size/type/order of attributes will most likely break the rendering and throw a WebGL exception.

Name Type Description
attributes Array.<module:ol/webgl/Helper~AttributeDescription>

Ordered list of attributes to read from the buffer

finalizeDraw(frameState)

webgl/Helper.js, line 495

Apply the successive post process passes which will eventually render to the actual canvas.

Name Type Description
frameState

current frame state

Name Type Description
pixelRatio number

The pixel ratio of the frame.

time number

The time when rendering of the frame was requested.

viewState module:ol/View~State

The state of the current view.

animate boolean
coordinateToPixelTransform module:ol/transform~Transform
extent null | module:ol/extent~Extent
declutterItems Array.<module:ol/PluggableMap~DeclutterItems>
index number
layerStatesArray Array.<module:ol/layer/Layer~State>
layerIndex number
pixelToCoordinateTransform module:ol/transform~Transform
postRenderFunctions Array.<module:ol/PluggableMap~PostRenderFunction>
size module:ol/size~Size
tileQueue module:ol/TileQueue~TileQueue
usedTiles Object.<string, Object.<string, boolean>>
viewHints Array.<number>
wantedTiles Object.<string, Object.<string, boolean>>

flushBufferData(buffer)

webgl/Helper.js, line 385

Update the data contained in the buffer array; this is required for the new data to be rendered

Name Type Description
buffer module:ol/webgl/Buffer~WebGLArrayBuffer

Buffer.

getAttributeLocation(name){number}

webgl/Helper.js, line 694

Will get the location from the shader or the cache

Name Type Description
name string

Attribute name

Returns:
attribLocation

getCanvas(){HTMLCanvasElement}

webgl/Helper.js, line 506
Returns:
Canvas.

getGL(){WebGLRenderingContext}

webgl/Helper.js, line 515

Get the WebGL rendering context

Returns:
The rendering context.

getProgram(fragmentShaderSource, vertexShaderSource){WebGLProgram}

webgl/Helper.js, line 643

Create a program for a vertex and fragment shader. The shaders compilation may have failed: use WebGLHelper.getShaderCompileErrors()to have details if any.

Name Type Description
fragmentShaderSource string

Fragment shader source.

vertexShaderSource string

Vertex shader source.

Returns:
Program

getShaderCompileErrors(){string|null}

webgl/Helper.js, line 671

Will return the last shader compilation errors. If no error happened, will return null;

Returns:
Errors description, or null if last compilation was successful

getUniformLocation(name){WebGLUniformLocation}

webgl/Helper.js, line 681

Will get the location from the shader or the cache

Name Type Description
name string

Uniform name

Returns:
uniformLocation

makeProjectionTransform(frameState, transform){module:ol/transform~Transform}

webgl/Helper.js, line 709

Modifies the given transform to apply the rotation/translation/scaling of the given frame state. The resulting transform can be used to convert world space coordinates to view coordinates.

Name Type Description
frameState module:ol/PluggableMap~FrameState

Frame state.

transform module:ol/transform~Transform

Transform to update.

frameState.pixelRatio number

The pixel ratio of the frame.

frameState.time number

The time when rendering of the frame was requested.

frameState.viewState module:ol/View~State

The state of the current view.

frameState.animate boolean
frameState.coordinateToPixelTransform module:ol/transform~Transform
frameState.extent null | module:ol/extent~Extent
frameState.declutterItems Array.<module:ol/PluggableMap~DeclutterItems>
frameState.index number
frameState.layerStatesArray Array.<module:ol/layer/Layer~State>
frameState.layerIndex number
frameState.pixelToCoordinateTransform module:ol/transform~Transform
frameState.postRenderFunctions Array.<module:ol/PluggableMap~PostRenderFunction>
frameState.size module:ol/size~Size
frameState.tileQueue module:ol/TileQueue~TileQueue
frameState.usedTiles Object.<string, Object.<string, boolean>>
frameState.viewHints Array.<number>
frameState.wantedTiles Object.<string, Object.<string, boolean>>
Returns:
The updated transform object.

prepareDraw(frameState)

webgl/Helper.js, line 419

Clear the buffer & set the viewport to draw. Post process passes will be initialized here, the first one being bound as a render target for subsequent draw calls.

Name Type Description
frameState

current frame state

Name Type Description
pixelRatio number

The pixel ratio of the frame.

time number

The time when rendering of the frame was requested.

viewState module:ol/View~State

The state of the current view.

animate boolean
coordinateToPixelTransform module:ol/transform~Transform
extent null | module:ol/extent~Extent
declutterItems Array.<module:ol/PluggableMap~DeclutterItems>
index number
layerStatesArray Array.<module:ol/layer/Layer~State>
layerIndex number
pixelToCoordinateTransform module:ol/transform~Transform
postRenderFunctions Array.<module:ol/PluggableMap~PostRenderFunction>
size module:ol/size~Size
tileQueue module:ol/TileQueue~TileQueue
usedTiles Object.<string, Object.<string, boolean>>
viewHints Array.<number>
wantedTiles Object.<string, Object.<string, boolean>>

setUniformFloatValue(uniform, value)

webgl/Helper.js, line 731

Give a value for a standard float uniform

Name Type Description
uniform string

Uniform name

value number

Value

setUniformMatrixValue(uniform, value)

webgl/Helper.js, line 741

Give a value for a standard matrix4 uniform

Name Type Description
uniform string

Uniform name

value Array.<number>

Matrix value

useProgram(program){boolean}

webgl/Helper.js, line 605

Use a program. If the program is already in use, this will return false.

Name Type Description
program WebGLProgram

Program.

Returns:
Changed.