topical media & game development

talk show tell print

graphic-webgl-scenejs-examples-custom-shaders-fog-custom-shaders-fog.js / js



  /*
   Custom fog 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 defines a fog effect.
       *
       * The shader binds two custom functions into the fragment shader that
       * is automatically generated by SceneJS; one function collects the
       * view-space fragment position, while the other function intercepts
       * the outgoing fragment colour and applies the fog effect to it, which is
       * computed from the fragment position's Z-depth.
       *
       * 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: "fogShader",
  
            shaders: [
  
              /*----------------------------------------------------------------------
               * Custom fog fragment shader
               *--------------------------------------------------------------------*/
  
              {
                stage: "fragment",
  
                code: [
  
                  /* Parameter uniforms
                   */
                  "uniform float fogMode;",
                  "uniform float fogDensity;",
                  "uniform float fogStart;",
                  "uniform float fogEnd;",
                  "uniform vec3  fogColor;",
  
                  /* Collected view-space fragment position
                   */
                  "vec4 _viewPos;",
  
                  /* Collects view-space fragment position
                   */
                  "void fogViewPosFunc(vec4 viewPos) {",
                  "  _viewPos = viewPos;",
                  "}",
  
                  /* Modifies fragment colour
                   */
                  "vec4 fogPixelColorFunc(vec4 color) {",
                  "  if (fogMode != 0.0) {",     // not "disabled"
                  "    float fogFactor = (1.0 - fogDensity);",
                  "    if (fogMode != 4.0) {",   // not "constant"
                  "      if (fogMode == 1.0) {", // "linear"
                  "        fogFactor *= clamp(pow(max((fogEnd - length(- _viewPos.xyz)) / " +
                  "          (fogEnd - fogStart), 0.0), 2.0), 0.0, 1.0);",
                  "      } else {",        // "exp" or "exp2"
                  "        fogFactor *= clamp((fogEnd - length(- _viewPos.xyz)) / (fogEnd - fogStart), 0.0, 1.0);",
                  "      }",
                  "    }",
                  "    return color * (fogFactor + vec4(fogColor, 1.0)) * (1.0 - fogFactor);",
                  "  }",
                  "  return color;",
                  "}"
                ],
  
                /* Bind our functions to hooks
                 */
                hooks: {
                  viewPos:  "fogViewPosFunc",
                  pixelColor: "fogPixelColorFunc"
                }
              }
            ],
  
            /* Declare parameters and set default values
             */
            params: {
              fogMode: 0.0,      // 0.0 disabled, 1.0 linear, 2.0 exponential, 3.0 quadratic, 4.0 constant
              fogDensity: 1.0,        // Fog density in range of [0.0..1.0]
              fogStart: 0.0,         // Nearest point of fog in view space (receeding Z-axis is positive)
              fogEnd: 1000.0,         // Furthest point of fog in view space
              fogColor: [0.0, 0.0, 0.0, 1.0] // Colour of fog - the colour that objects blend into
            }
          }
        ]
      },
  
      /*----------------------------------------------------------------------
       * 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.3, g: 0.3, b: 1.0 },
                        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.
                           *--------------------------------------------------------------------*/
  
                          /*----------------------------------------------------------------------
                           * First teapot, wrapped in an instance of the shader, which is
                           * parameterised to make the teapot red
                           *--------------------------------------------------------------------*/
  
                          // Instance the custom shader
                          {
                            type: "shader",
                            coreId: "fogShader",
  
                            nodes: [
  
                              // Set the shader's params
                              {
                                type: "shaderParams",
  
                                params: {
                                  fogMode: 3.0,
                                  fogDensity: 0.5,
                                  fogStart: 20.0,
                                  fogEnd: 30.0,
                                  fogColor: [0.0, 0.0, 0.0]
                                },
  
                                nodes: [
                                  {
                                    type: "translate",
                                    x: -7.0,
  
                                    nodes: [
                                      {
                                        type : "teapot"
                                      }
                                    ]
                                  },
                                  {
                                    type: "translate",
                                    x: 0.0,
  
                                    nodes: [
                                      {
                                        type : "teapot"
                                      }
                                    ]
                                  },
                                  {
                                    type: "translate",
                                    x: 7.0,
  
                                    nodes: [
                                      {
                                        type : "teapot"
                                      }
                                    ]
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  });
  
  /*----------------------------------------------------------------------
   * 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 touchStart(event) {
    lastX = event.targetTouches[0].clientX;
    lastY = event.targetTouches[0].clientY;
    dragging = true;
  }
  
  function mouseUp() {
    dragging = false;
  }
  
  function touchEnd() {
    dragging = false;
  }
  
  function mouseMove(event) {
    var posX = event.clientX;
    var posY = event.clientY;
    actionMove(posX,posY);
  }
  
  function touchMove(event) {
    var posX = event.targetTouches[0].clientX;
    var posY = event.targetTouches[0].clientY;
    actionMove(posX,posY);
  }
  
  /* On a mouse/touch drag, we'll re-render the scene, passing in
   * incremented angles in each time.
   */
  function actionMove(posX, posY) {
    if (dragging) {
      yaw += (posX - lastX) * 0.5;
      pitch += (posY - lastY) * 0.5;
  
      yawRotate.set("angle", yaw);
      pitchRotate.set("angle", pitch);
  
      lastX = posX;
      lastY = posY;
    }
  }
  
  canvas.addEventListener('mousedown', mouseDown, true);
  canvas.addEventListener('mousemove', mouseMove, true);
  canvas.addEventListener('mouseup', mouseUp, true);
  canvas.addEventListener('touchstart', touchStart, true);
  canvas.addEventListener('touchmove', touchMove, true);
  canvas.addEventListener('touchend', touchEnd, 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.