Shaders are programs that the GPU can evaluate that allow the
programmer to completely customized the final output of a GPU draw
call. The (chickadee render shader)
module provides an API for
building custom shaders.
Shaders are written in the OpenGL Shading Language, or GLSL for short. Chickadee aspires to provide a domain specific language for writing shaders in Scheme, but we are not there yet.
Shader programs consist of two components: A vertex shader and a fragment shader. A vertex shader receives vertex data (position coordinates, texture coordinates, normals, etc.) and transforms them as desired, whereas a fragment shader controls the color of each pixel.
Sample vertex shader:
#version 130 in vec2 position; in vec2 tex; out vec2 fragTex; uniform mat4 mvp; void main(void) { fragTex = tex; gl_Position = mvp * vec4(position.xy, 0.0, 1.0); }
Sample fragment shader:
#version 130 in vec2 fragTex; uniform sampler2D colorTexture; void main (void) { gl_FragColor = texture2D(colorTexture, fragTex); }
This manual will not cover GLSL features and syntax as there is lots of information already available about this topic.
One way to think about rendering with shaders, and the metaphor Chickadee uses, is to think about it as a function call: The shader is a function, and it is applied to some “attributes” (positional arguments), and some “uniforms” (keyword arguments).
(define my-shader (load-shader "vert.glsl" "frag.glsl")) (define vertices (make-vertex-array …)) (gpu-apply my-shader vertices #:color red)
See Rendering Engine for more details about the gpu-apply
procedure.
Shaders are incredibly powerful tools, and there’s more information about them than we could ever fit into this manual, so we highly recommend searching the web for more information and examples. What we can say, though, is how to use our API:
Compile vertex-source, the GLSL code for the vertex shader, and fragment-source, the GLSL code for the fragment shader, into a GPU shader program.
Compile the GLSL source code within vertex-source-file and fragment-source-file into a GPU shader program.
Read GLSL source from vertex-port and fragment-port and compile them into a GPU shader program.
Return #t
if obj is a shader.
Represents the absence shader program.
Return the metadata for the uniform name in shader.
Return a hash table of uniforms for shader.
Return a hash table of attributes for shader.
Return #t
if obj is a uniform.
Return the variable name of uniform.
Return the data type of uniform.
Return the current value of uniform.
Return the default value of uniform.
Return #t
if obj is an attribute.
Return the variable name of attribute.
Return the binding location of attribute.
Return the data type of attribute.