Phong Shader Material

From KitwarePublic
Revision as of 02:43, 29 November 2006 by Kmorel (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Back to VTKShaders

<?xml version="1.0" encoding="UTF-8"?>

<!--
     This shader implements Phong shading.  Phong shading is equivalent to
     the Gouraud implemented by the standard OpenGL pipeline except that
     instead of doing lighting caluclations on vertices and interpolating
     colors, normals are interpolated and lighting is performed per fragment.
     This can result in a much smoother surface.

 Copyright 2006 Sandia Corporation.
 Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 license for use of this work by or on behalf of the
 U.S. Government. Redistribution and use in source and binary forms, with
 or without modification, are permitted provided that this Notice and any
 statement of authorship are reproduced on all copies.
-->


<Material name="Phong"
          number_of_properties="0"
          number_of_vertex_shaders="1"
          number_of_fragment_shaders="1">

  <Shader scope="Vertex"
          name="PhongVert"
          location="Inline"
          language="GLSL"
          entry="main">
/* This is a vertex program for phong shading.  Since the lighting is done
 * in the fragment shader, it basically just transforms the vertices and
 * passes the lighting parameters.
 */

/*
 * Copyright 2006 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

varying vec3 Normal;
varying vec4 EyePosition;

void main(void)
{
  gl_Position = ftransform();

  /* Compute the position in eye coordinates. */
  EyePosition = gl_ModelViewMatrix*gl_Vertex;

  /* Transform the normal. */
  Normal = normalize(gl_NormalMatrix*gl_Normal);

  /* Pass lighting and coloring parameters. */
  gl_FrontColor = gl_Color;
  gl_BackColor = gl_Color;
  gl_TexCoord[0] = gl_MultiTexCoord0;
}

  </Shader>

  <Shader scope="Fragment"
          name="PhongFrag"
          location="Inline"
          language="GLSL"
          entry="main">
    <LightUniform name="NumLights" value="NumberOfLights"/>
/* This is a fragment program for phong shading.
 *
 * This shader performs 2 sided lighting, but assumes that all lights are
 * directional (changing that would be pretty easy to fix).
 *
 * This shader supports up to 5 lights.  The number 5 was picked because that is
 * how many lights are created by light kit.
 *
 * This shader does not support mapping scalars to colors.  You need to make
 * custom variations of the shader to either do texture lookups or to
 * replace the diffuse term with gl_Color.
 */

/*
 * Copyright 2006 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

varying vec3 Normal;
varying vec4 EyePosition;

uniform int NumLights;

/* Compute the contribution from a particular light source.  This basically
 * comes straight out of the OpenGL orange book. */
void DirectionalLight(in int lightIndex,
                      in vec3 normal,
                      inout vec4 ambient,
                      inout vec4 diffuse,
                      inout vec4 specular)
{
  /**** Compute ambient term. ****/
  ambient += gl_LightSource[lightIndex].ambient;

  /**** Compute diffuse term. ****/
  /* normal dot light direction.  Assume the light direction vector is already
     normalized.*/
  float nDotL = max(0.0, dot(normal,
                             normalize(vec3(gl_LightSource[lightIndex].position))));
  diffuse += gl_LightSource[lightIndex].diffuse * nDotL;

  /**** Compute specular term. ****/
  /* normal dot halfway vector */
  float nDotH = max(0.0, dot(normal,
                             vec3(gl_LightSource[lightIndex].halfVector)));
  float pf;     /* Power factor. */
  if (nDotH <= 0.0)
    {
    pf = 0.0;
    }
  else
    {
    pf = pow(nDotH, gl_FrontMaterial.shininess);
    }
  specular += gl_LightSource[lightIndex].specular * pf;
}

void AllLights(in vec3 normal,
               inout vec4 ambient,
               inout vec4 diffuse,
               inout vec4 specular)
{
  DirectionalLight(0, normal, ambient, diffuse, specular);
  if (NumLights > 1)
    {
    DirectionalLight(1, normal, ambient, diffuse, specular);
    if (NumLights > 2)
      {
      DirectionalLight(2, normal, ambient, diffuse, specular);
      if (NumLights > 3)
        {
        DirectionalLight(3, normal, ambient, diffuse, specular);
        if (NumLights > 4)
          {
          DirectionalLight(4, normal, ambient, diffuse, specular);
          }
        }
      }
    }
}

void main(void)
{
  /* If lighting the back of a polygon, flip normal.*/
  vec3 normal = normalize(Normal);

  /* Compute light contributions. */
  vec4 ambient = vec4(0.0);
  vec4 diffuse = vec4(0.0);
  vec4 specular = vec4(0.0);
  AllLights(normal, ambient, diffuse, specular);

  gl_FragColor = (  ambient*gl_FrontMaterial.ambient
                  + diffuse*gl_FrontMaterial.diffuse
                  + specular*gl_FrontMaterial.specular);
}

  </Shader>
</Material>

Back to VTKShaders