Vizard 7 » Reference » Shaders » Shaders basics
7.7

Shaders basics

Vizard uses the OpenGL Shading Language (GLSL) for shaders. Using vertex and fragment shaders for rendering real-time graphics has many benefits. Most notably, it moves graphics related operations from the CPU to the GPU. This allows programmers to use the graphics hardware directly to render a wider range of effects and realistic materials.

 

This section describes how to manually create and apply shader objects. In addition to manually creating shaders, Vizard provides a high-level shader effect framework that simplifies the process of creating and combining shader effects. The effect framework also supports automatically generating effects from models created by the OpenSceneGraph 3ds Max exporter. Vizard also provides a library for applying post-process shader effects to the output image of rendered scene.

 

Note: This section of the documentation assumes you are already familiar with GLSL. There are many books and tutorials online that go into great detail about GLSL. You can visit the official OpenGL website for links to various GLSL resources.

Creating shaders

To create a shader object in Vizard, simply use the <viz>.addShader command. You can specify the file or code for the vertex, geometry, and fragment shader when using this command. The following sample defines the code for a fragment shader directly in the script and creates a shader object using the code:

fragCode = """
void main()
{
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
"""

shader = viz.addShader(frag=fragCode)

The above shader will simply set the color of the object to red. Once the shader is created you can apply it to any node3d object using the <node3d>.apply command. The code below will create a quad and apply our shader to it:

quad = viz.addTexQuad(pos=(0,1.8,2))
quad.apply(shader)

Creating uniforms

GLSL allows passing values to shaders through the use of uniforms. To create a uniform in Vizard you can use <viz>.addUniformBool, <viz>.addUniformFloat, or <viz>.addUniformInt depending on the type of data the uniform needs to hold. Once the uniform is created, use the <node3d>.apply command to apply the uniform to any node3d object. The following code shows how to create a uniform:

colorUniform = viz.addUniformFloat('color',viz.RED)

Notice how the name and initial value must be specified when creating the uniform. Let's modify the above shader so that the color is specified through a uniform, instead of being hard coded.

fragCode = """
uniform vec3 color;
void main()
{
    gl_FragColor = vec4(color,1.0);
}
"""

shader = viz.addShader(frag=fragCode)

# Apply shader to a quad
quad = viz.addTexQuad(pos=(0,1.8,2))
quad.apply(shader)

# Apply color uniform to quad
colorUniform = viz.addUniformFloat('color',viz.RED)
quad.apply(colorUniform)

Once you have created a uniform, you can change the value associated with it using the <uniform>.set command. You must pass the same number of values to the <uniform>.set command as you used when creating the uniform. Try adding the following code to the previous example in order to change the color of the uniform when the spacebar is pressed:

import vizact
vizact.onkeydown(' ',colorUniform.set,viz.BLUE)

Built-in uniforms

The following list of uniforms are available to all shaders used with Vizard.

Uniform Name

GLSL Type

Description

viz_ScreenSize

ivec2

The width/height of the graphics window

osg_FrameNumber

int

Incrementing frame number

osg_FrameTime

float

Incrementing frame time (seconds)

osg_DeltaFrameTime

float

Elapsed time since last frame (seconds)

osg_ViewMatrix

mat4

Viewpoint matrix for current frame

osg_ViewMatrixInverse

mat4

Inverse viewpoint matrix for current frame

Here is an example shader that uses the built-in osg_FrameTime uniform to animate the color of a quad:

fragCode = """
uniform float osg_FrameTime;
void main()
{
    float r = (sin(osg_FrameTime) + 1.0) * 0.5 * gl_TexCoord[0].s;
    float g = (cos(osg_FrameTime) + 1.0) * 0.5 * gl_TexCoord[0].t;
    float b = (sin(osg_FrameTime) * cos(osg_FrameTime) + 1.0) * 0.5;
    gl_FragColor = vec4(r,g,b,1.0);
}
"""

shader = viz.addShader(frag=fragCode)

# Apply shader to a quad
quad = viz.addTexQuad(pos=(0,1.8,2))
quad.apply(shader)

See also

Effects

Post-Process Effects

 

<viz>.addShader

<viz>.addUniformBool

<viz>.addUniformFloat

<viz>.addUniformInt

<viz>.addUniformMatrix

 

<shader>.attach

<shader>.detach

<shader>.loadFragment

<shader>.loadGeometry

<shader>.loadVertex

<shader>.remove

<shader>.unapply

 

<uniform>.get

<uniform>.getName

<uniform>.remove

<uniform>.set

<uniform>.unapply

 

<node3d>.apply

<node3d>.setUniformBool

<node3d>.setUniformFloat

<node3d>.setUniformInt