topical media & game development

talk show tell print

graphic-webgl-scenejs-examples-custom-shaders-colorTrans-custom-shaders-colortrans.js / js



  /*
   Custom fragment color transform shader example
  
   Demonstrates the parameterised reuse of a custom shader via a shared node core.
  
   More info on custom shaders:
  
   http://scenejs.wikispaces.com/shader
   http://scenejs.wikispaces.com/shaderParams
  
   */
  
  SceneJS.createScene({
  
    type: "scene",
    id: "theScene",
    canvasId: "theCanvas",
    loggingElementId: "theLoggingDiv",
  
    nodes: [
  
      /*----------------------------------------------------------------------
       * Library section containing a shader node which transforms outgoing
       * fragment colour.
       *
       * The shader binds a custom functions into the SceneJS fragment shader
       * to apply saturation, scale and addition operations to the outgoing
       * fragment colour.
       *
       * The fog effect is configured by a set of uniforms, which the shader
       * node exposes as parameters with default values.
       *
       * The shader is "instantiated" later in the scene by another shader
       * which shares its node core.
       *--------------------------------------------------------------------*/
  
      {
        type: "library",
        nodes: [
          {
            type: "shader",
            coreId: "colorTransShader",
  
            shaders: [
  
              /*----------------------------------------------------------------------
               * Custom colour transform fragment shader
               *--------------------------------------------------------------------*/
  
              {
                stage: "fragment",
  
                code: [
  
                  /* Parameter uniforms
                   */
                  "uniform bool  colorTransEnabled;",
                  "uniform float colorTransSaturation;",
                  "uniform vec4  colorTransScale;",
                  "uniform vec4  colorTransAdd;",
  
                  /* Modifies fragment colour
                   */
                  "vec4 colorTransPixelColorFunc(vec4 color) {",
                  "  if (colorTransEnabled) {",
                  "    if (colorTransSaturation < 0.0) {",
                  "      float intensity = 0.3 * color.r + 0.59 * color.g + 0.11 * color.b;",
                  "      color = vec4((intensity * -colorTransSaturation) + color.rgb * (1.0 + colorTransSaturation), 1.0);",
                  "    }",
                  "    color = (color * colorTransScale) + colorTransAdd;",
                  "  }",
                  "  return color;",
                  "}"
                ],
  
                /* Bind our functions to hooks
                 */
                hooks: {
                  pixelColor: "colorTransPixelColorFunc"
                }
              }
            ],
  
            /* Declare parameters and set default values
             */
            params: {
              colorTransEnabled: false,        // Shader enabled/disabled
              colorTransSaturation: 1.0,       // Saturation in range of [0.0..1.0]
              colorTransScale: [1.0, 1.0, 1.0, 1.0], // Scale factor [0.0..1.0] for each colour component
              colorTransAdd: [0.0, 0.0, 0.0, 0.0]   // Addition offset [-1.0..1.0] for each colour component
            }
          }
        ]
      },
  
      /*----------------------------------------------------------------------
       * View and projection transforms
       *--------------------------------------------------------------------*/
  
      {
        type: "lookAt",
        eye : { x: 0.0, y: 10.0, z: 25 },
        look : { y:1.0 },
        up : { y: 1.0 },
  
        nodes: [
          {
            type: "camera",
            optics: {
              type: "perspective",
              fovy : 25.0,
              aspect : 1.47,
              near : 0.10,
              far : 300.0
            },
  
            nodes: [
  
              /*----------------------------------------------------------------------
               * Lighting
               *--------------------------------------------------------------------*/
  
              {
                type: "light",
                mode:          "dir",
                color:         { r: 1.0, g: 1.0, b: 1.0 },
                diffuse:        true,
                specular:        true,
                dir:          { x: 1.0, y: -0.5, z: -1.0 }
              },
  
              {
                type: "light",
                mode:          "dir",
                color:         { r: 1.0, g: 1.0, b: 0.8 },
                diffuse:        true,
                specular:        false,
                dir:          { x: 0.0, y: -0.5, z: -1.0 }
              },
  
              /*----------------------------------------------------------------------
               * Modelling transforms
               *--------------------------------------------------------------------*/
  
              {
                type: "rotate",
                id: "pitch",
                angle: 0.0,
                x : 1.0,
  
                nodes: [
                  {
                    type: "rotate",
                    id: "yaw",
                    angle: 0.0,
                    y : 1.0,
  
                    nodes: [
  
                      /*----------------------------------------------------------------------
                       * Material properties
                       *--------------------------------------------------------------------*/
  
                      {
                        type: "material",
                        emit: 0,
                        baseColor:   { r: 0.5, g: 0.5, b: 0.5 },
                        specularColor: { r: 0.9, g: 0.9, b: 0.9 },
                        specular:    0.7,
                        shine:     10.0,
                        alpha:     0.9,
  
                        nodes: [
  
                          /*----------------------------------------------------------------------
                           * Three teapots share the shader by instancing its node core, wrapping
                           * each teapot in a shaderParams node to set different parameters for
                           * the uniforms that are exposed by the shader as parameters.
                           *--------------------------------------------------------------------*/
  
                          // Instance the custom shader
                          {
                            type: "shader",
                            coreId: "colorTransShader",
  
                            nodes: [
  
                              // Set the shader's params
                              {
                                type: "shaderParams",
  
                                params: {
                                  colorTransEnabled: true,        // Shader enabled
                                  colorTransSaturation: 1.0,
                                  colorTransScale: [0.0, 1.0, 1.0, 1.0], // Cyan
                                  colorTransAdd: [0.0, 0.0, 0.0, 0.0]
                                },
  
                                nodes: [
                                  {
                                    type: "translate",
                                    x: -7.0,
  
                                    nodes: [
                                      {
                                        type : "teapot"
                                      }
                                    ]
                                  }
                                ]
                              }
                            ]
                          },
  
                          /*----------------------------------------------------------------------
                           * Second teapot, wrapped in an instance of the shader, which is
                           * parameterised to make the teapot green
                           *--------------------------------------------------------------------*/
  
                          // Instance the custom shader
                          {
                            type: "shader",
                            coreId: "colorTransShader",
  
                            nodes: [
  
                              // Set the shader's params
                              {
                                type: "shaderParams",
  
                                params: {
                                  colorTransEnabled: true,        // Shader enabled
                                  colorTransSaturation: 1.0,
                                  colorTransScale: [1.0, 0.0, 1.0, 1.0], // Purple
                                  colorTransAdd: [0.0, 0.0, 0.0, 0.0]
                                },
  
                                nodes: [
                                  {
                                    type: "translate",
                                    x: 0.0,
  
                                    nodes: [
                                      {
                                        type : "teapot"
                                      }
                                    ]
                                  }
                                ]
                              }
                            ]
                          },
  
                          /*----------------------------------------------------------------------
                           * First teapot, wrapped in an instance of the shader, which is
                           * parameterised to make the teapot blue
                           *--------------------------------------------------------------------*/
  
                          // Instance the custom shader
                          {
                            type: "shader",
                            coreId: "colorTransShader",
  
                            nodes: [
  
                              // Set the shader's params
                              {
                                type: "shaderParams",
  
                                params: {
                                  colorTransEnabled: true,        // Shader enabled
                                  colorTransSaturation: 1.0,
                                  colorTransScale: [1.0, 1.0, 0.0, 1.0], // Yellow
                                  colorTransAdd: [0.0, 0.0, 0.0, 0.0]
                                },
  
                                nodes: [
                                  {
                                    type: "translate",
                                    x: 7.0,
  
                                    nodes: [
                                      {
                                        type : "teapot"
                                      }
                                    ]
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  });
  
  SceneJS.setDebugConfigs({
    shading : {
      logScripts : false,
      validate: true
    }
  });
  
  /*----------------------------------------------------------------------
   * Scene rendering loop and mouse handler stuff follows
   *---------------------------------------------------------------------*/
  
  var scene = SceneJS.scene("theScene");
  var pitchRotate = scene.findNode("pitch");
  var yawRotate = scene.findNode("yaw");
  
  var yaw = 0;
  var pitch = 0;
  var lastX;
  var lastY;
  var dragging = false;
  
  var canvas = document.getElementById("theCanvas");
  
  function mouseDown(event) {
    lastX = event.clientX;
    lastY = event.clientY;
    dragging = true;
  }
  
  function mouseUp() {
    dragging = false;
  }
  
  /* On a mouse drag, we'll re-render the scene, passing in
   * incremented angles in each time.
   */
  function mouseMove(event) {
    if (dragging) {
      yaw += (event.clientX - lastX) * 0.5;
      pitch += (event.clientY - lastY) * 0.5;
  
      yawRotate("yaw").set("angle", yaw);
      pitchRotate.set("angle", pitch);
  
      lastX = event.clientX;
      lastY = event.clientY;
    }
  }
  
  canvas.addEventListener('mousedown', mouseDown, true);
  canvas.addEventListener('mousemove', mouseMove, true);
  canvas.addEventListener('mouseup', mouseUp, true);
  
  scene.start();
  
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.