figureone
    Preparing search index...

    DiagramElementPrimitive with low level WegGL drawing object.

    A number of WebGL specific properties can be defined.

    WebGL specific properties are glPrimitive, vertexShader, fragmentShader attributes, uniforms and an optional texture. The nomencalture for these properties is directly from WebGL.

    Properties vertices, colors, dimension, light and normals provide shortcuts for defining the shaders, attributes and uniforms when shaders are not customized.

    Shaders are programs that run in the GPU and are written in a C-like language. Shaders operate on each vertex of a shape in parallel. The vertex shader transforms each vertex to some specific position, and performs color and lighting related calculations for scenarios when color and/or lighting are vertex specific. The fragment shader computes the final color of each pixel (fragment) between the vertices that make up a glPrimitive.

    Data can be passed from the CPU (JavaScript) to the GPU with attributes and uniforms.

    Attributes are arrays of numbers that represent data specific for each vertex in a shape. At a minimum, an attribute that defines the (x, y) or (x, y, z) coordinates of each vertex is needed. Other attributes might be color if all verticies do not have the same color, texture coordinates to map vertex color to a 2D image texture, and normal vectors for defining how light reflects from and thus brightens a surface. Each attribute must define data for every vertex in a shape. Attributes are typically defined and loaded into GPU buffers once. On each animation frame, the GPU will pass the buffered attributes to the shaders. Attributes are only passed to the vertex shader.

    Uniforms are small amounts of data (vectors or square matrices with a maximum dimension/rank of 4) that are passed from the CPU to the GPU on each frame. A uniform value can be passed to both the vertex and fragment shader and is thus available to all vertices and fragments. A uniform is like a global variable whose value can change on each animation frame. Example uniforms are:

    • transform matrix that transforms all vertices in space the same way
    • color value that colors all vertices the same (instead of having to define a color for each vertex)
    • light source properties like position, direction, and amplitude

    Data can be passed from the vertex shader to the fragment shader in variables called varyings. Example varyings include color attributes (color that is defined for each vertex) and lighting information if the lighting is vertex dependent.

    Shaders source code can be defined as a string, or composed automatically from options including dimension, color and light. Shader source code contains attribute and uniform variables, and these attributes and uniforms need to be defined with attributes and uniforms.

    If using automated shader composition, then only attributes need to be defined. The uniforms will be passed to the shader from the information in the color property of the FigureElementPrimitive and the scene used to draw the primitive. See OBJ_VertexShader and OBJ_FragmentShader for names of attributes and uniforms used in the shaders, and when they are used.

    // Default options are 2D, uniform color, TRIANGLES.
    // Create two red triangles (6 vertices, 12 values)
    figure.add({
    make: 'gl',
    vertices: [0, 0, 0.5, 0, 0, 0.5, 0.5, 0, 1, 0, 0.5, 0.5],
    color: [1, 0, 0, 1],
    });
    // Simple rotatable element with a custom position
    figure.add({
    make: 'gl',
    vertices: [0, 0, 0.5, 0, 0, 0.5, 0.5, 0, 1, 0, 0.5, 0.5],
    color: [1, 0, 0, 1],
    position: [-0.4, -0.4, 0],
    move: { type: 'rotation' },
    });
    // Assign a color to each vertex
    figure.add({
    make: 'gl',
    vertices: [0, 0, 0.5, 0, 0, 0.5, 0.5, 0, 1, 0, 0.5, 0.5],
    colors: [
    0, 0, 1, 1,
    1, 0, 0, 1,
    0, 0, 1, 1,
    1, 0, 0, 1,
    0, 0, 1, 1,
    1, 0, 0, 1,
    ],
    });
    // Assign a color to each vertex, using just 3 numbers per color (no alpha)
    figure.add({
    make: 'gl',
    vertices: [0, 0, 0.5, 0, 0, 0.5, 0.5, 0, 1, 0, 0.5, 0.5],
    colors: {
    data: [
    0, 0, 1,
    1, 0, 0,
    0, 0, 1,
    1, 0, 0,
    0, 0, 1,
    1, 0, 0,
    ],
    size: 3,
    },
    });
    // Texture filled square
    figure.add({
    make: 'gl',
    vertices: [-0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5],
    numVertices: 6,
    texture: {
    src: './flower.jpeg',
    coords: [0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1],
    loadColor: [0, 0, 0, 0],
    },
    });
    // Make a 3D cube using composed shaders
    const { toNumbers } = Fig;
    const [cubeVertices, cubeNormals] = Fig.cube({ side: 0.5 });
    figure.scene.setProjection({ style: 'orthographic' });
    figure.scene.setCamera({ position: [2, 1, 2] });
    figure.scene.setLight({ directional: [0.7, 0.5, 1] });

    figure.add({
    make: 'gl',
    light: 'directional',
    dimension: 3,
    vertices: toNumbers(cubeVertices),
    normals: toNumbers(cubeNormals),
    color: [1, 0, 0, 1],
    });
    // Custom shaders
    // Make a shader with a custom attribute aVertex and custom uniform uColor,
    // which are then defined in the options.
    // Note, the `u_worldViewProjectionMatrix` uniform does not need to be defined
    // as this will be passed by FigureOne using the Scene information of the
    // figure (or element if an element has a custom scene attached to it).
    figure.add({
    make: 'gl',
    vertexShader: {
    src: `
    uniform mat4 u_worldViewProjectionMatrix;
    attribute vec4 aVertex;
    void main() {
    gl_Position = u_worldViewProjectionMatrix * aVertex;
    }`,
    vars: ['aVertex', 'u_worldViewProjectionMatrix'],
    },
    fragmentShader: {
    src: `
    precision mediump float;
    uniform vec4 uColor;
    void main() {
    gl_FragColor = uColor;
    gl_FragColor.rgb *= gl_FragColor.a;
    }`,
    vars: ['uColor'],
    },
    attributes: [
    {
    name: 'aVertex',
    size: 3,
    data: [0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 1, 0, 0, 0.5, 0.5, 0],
    },
    ],
    uniforms: [
    {
    name: 'uColor',
    length: 4,
    value: [1, 0, 0, 1],
    },
    ],
    });
    @interface