The WebGL API is for high performance rendering. Definitely read about how WebGL works and look at some examples before trying to do too much with just the documentation provided here.
Mesh forms geometry from the specified vertices. Each vertex contains a bunch of attributes, defined as a custom record type, e.g.:
type alias Attributes =
{ position : Vec3
, color : Vec3
}
The supported types in attributes are: Int
, Float
, Texture
and Vec2
, Vec3
, Vec4
, Mat4
from the
linear-algebra
package.
Do not generate meshes in view
, read more about this here.
triangles : List ( attributes, attributes, attributes ) -> Mesh attributes
Triangles are the basic building blocks of a mesh. You can put them together to form any shape.
So when you create triangles
you are really providing three sets of attributes
that describe the corners of each triangle.
Shaders are programs for running many computations on the GPU in parallel. They are written in a language called GLSL. Read more about shaders here.
Normally you specify a shader with a [glsl| |]
block. Elm compiler will parse
the shader code block and derive the type signature for your shader.
attributes
define vertices in the mesh;uniforms
allow you to pass scene parameters like
transformation matrix, texture, screen size, etc.;varyings
define the output from the vertex shader.attributes
, uniforms
and varyings
are records with the fields of the
following types: Int
, Float
, Texture
and Vec2
, Vec3
, Vec4
,
Mat4
from the
linear-algebra
package.
Conceptually, an encapsulation of the instructions to render something.
entity : Shader attributes uniforms varyings -> Shader {} uniforms varyings -> Mesh attributes -> uniforms -> Entity
Packages a vertex shader, a fragment shader, a mesh, and uniforms
as an Entity
. This specifies a full rendering pipeline to be run
on the GPU. You can read more about the pipeline
here.
The vertex shader receives attributes
and uniforms
and returns varyings
and gl_Position
—the position of the vertex on the screen, defined as
vec4(x, y, z, w)
, that means (x/w, y/w, z/w)
in the clip space coordinates:
-- (-1,1,1) +================+ (1,1,1)
-- /| /|
-- / | | / |
--(-1,1,-1)+================+ (1,1,-1)
-- | | | / | |
-- | | |/ | |
-- | | +-------|->|
-- (-1,-1,1|) +--(0,0,0)----|--+ (1,-1,1)
-- | / | /
-- |/ |/
-- +================+
-- (-1,-1,-1) (1,-1,-1)
The fragment shader is called for each pixel inside the clip space with
varyings
and uniforms
and returns gl_FragColor
—the color of
the pixel, defined as vec4(r, g, b, a)
where each color component is a float
from 0 to 1.
Shaders and a mesh are cached so that they do not get resent to the GPU. It should be relatively cheap to create new entities out of existing values.
By default, depth test is enabled for you.
If you need more settings, like
blending or stencil test,
then use entityWith
.
entity =
entityWith [ DepthTest.default ]
toHtml : List (Html.Attribute msg) -> List Entity -> Html msg
Render a WebGL scene with the given html attributes, and entities.
width
and height
html attributes resize the drawing buffer, while
the corresponding css properties scale the canvas element.
To prevent blurriness on retina screens, you may want the drawing buffer to be twice the size of the canvas element.
To remove an extra whitespace around the canvas, set display: block
.
By default, alpha channel with premultiplied alpha, antialias and depth buffer
are enabled. Use toHtmlWith
for custom options.
toHtml =
toHtmlWith [ alpha True, antialias, depth 1 ]
entityWith : List Settings.Setting -> Shader attributes uniforms varyings -> Shader {} uniforms varyings -> Mesh attributes -> uniforms -> Entity
The same as entity
, but allows to configure an entity with
settings.
toHtmlWith : List Option -> List (Html.Attribute msg) -> List Entity -> Html msg
Render a WebGL scene with the given options, html attributes, and entities.
Due to browser limitations, options will be applied only once, when the canvas is created for the first time.
Internal.Option
Provides a way to enable features and change the scene behavior
in toHtmlWith
.
alpha : Basics.Bool -> Option
Enable alpha channel in the drawing buffer. If the argument is True
, then
the page compositor will assume the drawing buffer contains colors with
premultiplied alpha (r * a, g * a, b * a, a)
.
depth : Basics.Float -> Option
Enable the depth buffer, and prefill it with given value each time before the scene is rendered. The value is clamped between 0 and 1.
stencil : Basics.Int -> Option
Enable the stencil buffer, specifying the index used to fill the stencil buffer before we render the scene. The index is masked with 2^m - 1, where m >= 8 is the number of bits in the stencil buffer. The default is 0.
antialias : Option
Enable multisample antialiasing of the drawing buffer, if supported by the platform. Useful when you need to have smooth lines and smooth edges of triangles at a lower cost than supersampling (rendering to larger dimensions and then scaling down with CSS transform).
clearColor : Basics.Float -> Basics.Float -> Basics.Float -> Basics.Float -> Option
Set the red, green, blue and alpha channels, that will be used to fill the drawing buffer every time before drawing the scene. The values are clamped between 0 and 1. The default is all 0's.
preserveDrawingBuffer : Option
By default, WebGL canvas swaps the drawing and display buffers. This option forces it to copy the drawing buffer into the display buffer.
Even though this slows down the rendering, it allows you to extract an image
from the canvas element using canvas.toBlob()
in JavaScript without having
to worry about synchronization between frames.
indexedTriangles : List attributes -> List ( Basics.Int, Basics.Int, Basics.Int ) -> Mesh attributes
Create triangles from vertices and indices, grouped in sets of three to define each triangle by refering the vertices. This helps to avoid duplicated vertices whenever two triangles share an edge.
-- v2 +---+ v1
-- |\ |
-- | \ |
-- | \|
-- v3 +---+ v0
For example, if you want to define a rectangle using
triangles
, v0
and v2
will have to be duplicated:
rectangle =
triangles [ ( v0, v1, v2 ), ( v2, v3, v0 ) ]
This will use two vertices less:
rectangle =
indexedTriangles [ v0, v1, v2, v3 ] [ ( 0, 1, 2 ), ( 2, 3, 0 ) ]
lines : List ( attributes, attributes ) -> Mesh attributes
Connects each pair of vertices with a line.
lineStrip : List attributes -> Mesh attributes
Connects each two subsequent vertices with a line.
lineLoop : List attributes -> Mesh attributes
Similar to lineStrip
, but connects the last vertex back to
the first.
points : List attributes -> Mesh attributes
Draws a single dot per vertex.
triangleFan : List attributes -> Mesh attributes
Similar to triangleStrip
, but creates a fan shaped
output.
triangleStrip : List attributes -> Mesh attributes
Creates a strip of triangles where each additional vertex creates an additional triangle once the first three vertices have been drawn.