chickadee » hypergiant » Shader

Shaderconstant

Uniforms

   ((inverse-transpose-model #:mat4)
    (camera-position #:vec3)
    (ambient #:vec3)
    (n-lights #:int)
    (light-positions (#:array #:vec3 N-LIGHTS))
    (light-colors (#:array #:vec3 N-LIGHTS))
    (light-intensities (#:array #:float N-LIGHTS))
    (material #:vec4))

Note that all of these uniforms (except material) are automatically provided by add-node, although they depend on Hyperscene’s lighting extension to be activated. E.g. (activate-extension SCENE (lighting)

The function make-material can be used to create a vector suitable for passing as the material uniform value.

Exports

   (light (SURFACE-COLOR #:vec4) (POSITION #:vec3) (NORMAL #:vec3)) -> #:vec4

This shader is designed to provided per-fragment multiple-light Phong lighting, in combination with Hyperscene’s lighting extension. It provides a single function used for calculating the fragment colour: light. Given a base, SURFACE-COLOR the resulting colour after lighting is calculated given the fragments’ POSITION and NORMAL (and the uniforms listed above).

When using this shader, make sure it is defined with the proper number of lights, N-LIGHTS, that will be used by the lighting extension with the shader. This defaults to 8, but can be set with set-max-lights!.

Here is an example of a simple pipeline using this shader:

    
(define-pipeline phong-pipeline 
  ((#:vertex input: ((position #:vec3) (normal #:vec3) (tex-coord #:vec2))
             uniform: ((mvp #:mat4) (model #:mat4))
             output: ((p #:vec3) (n #:vec3) (t #:vec2)))
   (define (main) #:void
     (set! gl:position (* mvp (vec4 position 1.0)))
     (set! p (vec3 (* model (vec4 position 1))))
     (set! t tex-coord)
     (set! n normal)))
  ((#:fragment input: ((n #:vec3) (p #:vec3) (t #:vec2))
               use: (phong-lighting)
               uniform: ((tex #:sampler-2d)
                         (camera-position #:vec3)
                         (inverse-transpose-model #:mat4)
                         (ambient #:vec3)
                         (n-lights #:int)
                         (light-positions (#:array #:vec3 8))
                         (light-colors (#:array #:vec3 8))
                         (light-intensities (#:array #:float 8))
                         (material #:vec4))
               output: ((frag-color #:vec4)))
   (define (main) #:void
     (set! frag-color (light (texture tex t) p n)))))

[procedure] (set-max-lights! N)

This function replaces set-max-lights!, from Hyperscene. It should be used in the same way. The only difference is that this function selects an appropriate phong-lighting shader based on the number of lights set. The phong-lighting shaders differ in the array size of the uniforms, and an appropriate N value should be used in the uniforms of any pipeline using phong-lighting: the size of each uniform array should be greater than or equal to N and a power of 2 from 8 to 64.