GLSL Example Effect (COLLADA 1.4.1)

From COLLADA Public Wiki
Jump to: navigation, search

An example of a Profile GLSL effect

This document describes a simple example of the COLLADA profile_GLSL. The full listing can be found in the APPENDIX of this document. It is a complete example in that it includes geometry, textures, a scene, and a profile_GLSL effect. When rendered, the example should look like the following image.

Example.jpg

Figure 1: The example when rendered using the COLLADA OpenGL Effects Viewer.

OpenGL Effect Viewer

The following example uses the common COLLADA libraries, such as library_effects, library_materials, library_geometry, and library_images. Information on these libraries can be found elsewhere, this document focuses on the profile_GLSL only.

Structure of the GLSL Profile

The start of the profile_GLSL is indicated within the <effect> element using the <profile_GLSL> element.

<library_effects>
   <effect id="Textured_Bump_E0_MP_FX">
     <profile_GLSL>

The GLSL profile consists of the following main blocks:

  • Code for the vertex and fragment shaders is contained within the element
  • Values for the shader parameters are defined using <newparams>
  • A Technique that defines an effect specific to a target platform (defined in <technique>)
  • A List of passes (one or more) defined in the <pass> element
  • Shader descriptions (<shader>)

The <code> element

The following is a typical GLSL <code> element containing GLSL shader code (marked in green). There are usually two <code> elements, one for the vertex shader and one for the fragment shader. The GLSL shading language is not described here.

<code sid="Vertex_Program_E0_P0_VP">
  uniform vec4 fvSpecular;
  uniform vec4 fvDiffuse;
  uniform float fSpecularPower;
  uniform sampler2D baseMap;
  uniform sampler2D bumpMap;
  varying vec2 Texcoord;
  varying vec3 ViewDirection;
  varying vec3 LightDirection;
  void main( void )
  {
  vec3 fvLightDirection = normalize( LightDirection );
  vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * 2.0 ) - 1.0 );
  float fNDotL = dot( fvNormal, fvLightDirection ); 
  vec3 fvReflection = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); 
  vec3 fvViewDirection = normalize( ViewDirection );
  float fRDotV = max( 0.0, dot( fvReflection, fvViewDirection ) );
  vec4 fvBaseColor = texture2D( baseMap, Texcoord );
  vec4 fvTotalAmbient = fvAmbient * fvBaseColor; 
  vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor; 
  vec4 fvTotalSpecular = fvSpecular * ( pow( fRDotV, fSpecularPower ) );
  gl_FragColor = ( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular );
  }
</code>

The <newparam> element

Newparams are used to define data that needs to be bound to the uniforms in the shader code. In the following examples we can see that newparams for specular power, sampler data and surface data are set. Please note that these values can be overridden at the <material> level by using <setparam>‘s.

       <newparam sid="fSpecularPower_E0_P0">
         <float>25</float>
       </newparam>
       <newparam sid="baseMap_Sampler">
         <sampler2D>
           <source>baseMap_Surface</source>
           <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>
           <magfilter>LINEAR</magfilter>
         </sampler2D>
       </newparam>
       <newparam sid="baseMap_Surface">
         <surface type="2D">
           <init_from>base_E0</init_from>
           <format>A8R8G8B8</format>
         </surface>
       </newparam>

The <technique> element

Techniques are a another layer of hierarchy inside profiles, each of which describes the same effect for a gradation of GPU hardware, API, or slight variations of the same effect e.g. different types of skin (cow, alligator, ostrich etc).

<technique sid="Textured_Bump_E0_MP_TECH">

The <pass> and <shader> elements

At the core of an effect description are the <pass> elements. Each pass element specifies the target compiler, references to the vertex or fragment shader programs (with code entry points), and a set of input bindings for the shader parameters.

In the following example we show a pass element with the two shader stages (vertex and fragment). Each shader stage binds the params to the uniforms within tha shader code. Notice that the params do not actually define any data - just the reference to a previously defined newparam.

         <pass sid="Pass_0">
           <shader stage="VERTEXPROGRAM">
             <compiler_target>110</compiler_target>
             <name source="Vertex_Program_E0_P0_VP">main</name>
             <bind symbol="fvEyePosition">
               <param ref="fvEyePosition_E0_P0"></param>
             </bind>
             <bind symbol="fvLightPosition">
               <param ref="fvLightPosition_E0_P0"></param>
             </bind>
           </shader>
           <shader stage="FRAGMENTPROGRAM">
             <compiler_target>110</compiler_target>
             <name source="Fragment_Program_E0_P0_FP">main</name>
             <bind symbol="fSpecularPower">
               <param ref="fSpecularPower_E0_P0"></param>
             </bind>
             <bind symbol="fvAmbient">
               <param ref="fvAmbient_E0_P0"></param>
             </bind>
             <bind symbol="fvDiffuse">
               <param ref="fvDiffuse_E0_P0"></param>
             </bind>
             <bind symbol="fvSpecular">
               <param ref="fvSpecular_E0_P0"></param>
             </bind>
             <bind symbol="baseMap">
               <param ref="baseMap_Sampler"></param>
             </bind>
             <bind symbol="bumpMap">
               <param ref="bumpMap_Sampler"></param>
             </bind>
           </shader>
         </pass>
       </technique>
     </profile_GLSL>
   </effect>

APPENDIX I: A complete profile_GLSL example

<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
 <asset>
   <contributor>
     <author></author>
     <authoring_tool>RenderMonkey</authoring_tool>
     <comments>Output from RenderMonkey COLLADA Exporter</comments>
     <copyright></copyright>
     <source_data></source_data>
   </contributor>
   <created>2007-12-11T14:24:00Z</created>
   <modified>2007-12-11T14:24:00Z</modified>
   <unit meter="0.01" name="centimeter"></unit>
   <up_axis>Y_UP</up_axis>
 </asset>
 <library_visual_scenes>
   <visual_scene id="VisualSceneNode" name="untitled">
     <node id="Model_E0_MESH_0_REF_1" name="Model_E0_MESH_0_REF_1">
       <instance_geometry url="#Model_E0_MESH_0_REF_1_lib">
         <bind_material>
           <technique_common>
             <instance_material symbol="Textured_Bump_E0_MP_MAT" target="#Textured_Bump_E0_MP_MAT">
               <bind_vertex_input semantic="rm_Binormal" input_semantic="BINORMAL" input_set="2"></bind_vertex_input>
               <bind_vertex_input semantic="rm_Tangent" input_semantic="TANGENT" input_set="1"></bind_vertex_input>
             </instance_material>
           </technique_common>
         </bind_material>
       </instance_geometry>
     </node>
   </visual_scene>
 </library_visual_scenes>
 <library_materials>
   <material id="Textured_Bump_E0_MP_MAT" name="Textured_Bump_E0_MP_MAT">
     <instance_effect url="#Textured_Bump_E0_MP_FX">
       <technique_hint platform="PC-OGL" profile="GLSL" ref="Textured_Bump_E0_MP_TECH"></technique_hint>
       <setparam ref="fSpecularPower_E0_P0">
         <float>25</float>
       </setparam>
       <setparam ref="fvAmbient_E0_P0">
         <float4>0.368627 0.368421 0.368421 1</float4>
       </setparam>
       <setparam ref="fvDiffuse_E0_P0">
         <float4>0.886275 0.885003 0.885003 1</float4>
       </setparam>
       <setparam ref="fvEyePosition_E0_P0">
         <float3>0 0 100</float3>
       </setparam>
       <setparam ref="fvLightPosition_E0_P0">
         <float3>-100 100 100</float3>
       </setparam>
       <setparam ref="fvSpecular_E0_P0">
         <float4>0.490196 0.488722 0.488722 1</float4>
       </setparam>
       <setparam ref="baseMap_Sampler">
         <sampler2D>
           <source>baseMap_Surface</source>
           <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>
           <magfilter>LINEAR</magfilter>
         </sampler2D>
       </setparam>
       <setparam ref="baseMap_Surface">
         <surface type="2D">
           <init_from>base_E0</init_from>
           <format>A8R8G8B8</format>
         </surface>
       </setparam>
       <setparam ref="bumpMap_Sampler">
         <sampler2D>
           <source>bumpMap_Surface</source>
           <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>
           <magfilter>LINEAR</magfilter>
         </sampler2D>
       </setparam>
       <setparam ref="bumpMap_Surface">
         <surface type="2D">
           <init_from>bump_E0</init_from>
           <format>A8R8G8B8</format>
         </surface>
       </setparam>
     </instance_effect>
   </material>
 </library_materials>
 <library_effects>
   <effect id="Textured_Bump_E0_MP_FX">
     <profile_GLSL>
       <code sid="Vertex_Program_E0_P0_VP">
         uniform vec3 fvLightPosition;
         uniform vec3 fvEyePosition;
         varying vec2 Texcoord;
         varying vec3 ViewDirection;
         varying vec3 LightDirection;
         attribute vec3 rm_Binormal;
         attribute vec3 rm_Tangent;
         void main( void )
         {
          gl_Position = ftransform();
          Texcoord = gl_MultiTexCoord0.xy;
          vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
          vec3 fvViewDirection = fvEyePosition - fvObjectPosition.xyz;
          vec3 fvLightDirection = fvLightPosition - fvObjectPosition.xyz;
          vec3 fvNormal = gl_NormalMatrix * gl_Normal;
          vec3 fvBinormal = gl_NormalMatrix * rm_Binormal;
          vec3 fvTangent = gl_NormalMatrix * rm_Tangent;
          ViewDirection.x = dot( fvTangent, fvViewDirection );
          ViewDirection.y = dot( fvBinormal, fvViewDirection );
          ViewDirection.z = dot( fvNormal, fvViewDirection );
          LightDirection.x = dot( fvTangent, fvLightDirection.xyz );
          LightDirection.y = dot( fvBinormal, fvLightDirection.xyz );
          LightDirection.z = dot( fvNormal, fvLightDirection.xyz );
          }
       </code>
       <code sid="Fragment_Program_E0_P0_FP">
         uniform vec4 fvAmbient;
         uniform vec4 fvSpecular;
         uniform vec4 fvDiffuse;
         uniform float fSpecularPower;
         uniform sampler2D baseMap;
         uniform sampler2D bumpMap;
         varying vec2 Texcoord;
         varying vec3 ViewDirection;
         varying vec3 LightDirection;
         void main( void )
         {
           vec3 fvLightDirection = normalize( LightDirection );
           vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * 2.0 ) - 1.0 );
           float fNDotL = dot( fvNormal, fvLightDirection ); 
           vec3 fvReflection = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); 
           vec3 fvViewDirection = normalize( ViewDirection );
           float fRDotV = max( 0.0, dot( fvReflection, fvViewDirection ) );
           vec4 fvBaseColor = texture2D( baseMap, Texcoord );
           vec4 fvTotalAmbient = fvAmbient * fvBaseColor; 
           vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor; 
           vec4 fvTotalSpecular = fvSpecular * ( pow( fRDotV, fSpecularPower ) );
           gl_FragColor = ( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular );
         }
       </code>
       <newparam sid="fSpecularPower_E0_P0">
         <float>25</float>
       </newparam>
       <newparam sid="fvAmbient_E0_P0">
         <float4>0.368627 0.368421 0.368421 1</float4>
       </newparam>
       <newparam sid="fvDiffuse_E0_P0">
         <float4>0.886275 0.885003 0.885003 1</float4>
       </newparam>
       <newparam sid="fvEyePosition_E0_P0">
         <float3>0 0 100</float3>
       </newparam>
       <newparam sid="fvLightPosition_E0_P0">
         <float3>-100 100 100</float3>
       </newparam>
       <newparam sid="fvSpecular_E0_P0">
         <float4>0.490196 0.488722 0.488722 1</float4>
       </newparam>
       <newparam sid="baseMap_Sampler">
         <sampler2D>
           <source>baseMap_Surface</source>
           <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>
           <magfilter>LINEAR</magfilter>
         </sampler2D>
       </newparam>
       <newparam sid="baseMap_Surface">
         <surface type="2D">
           <init_from>base_E0</init_from>
           <format>A8R8G8B8</format>
         </surface>
       </newparam>
       <newparam sid="bumpMap_Sampler">
         <sampler2D>
           <source>bumpMap_Surface</source>
           <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>
           <magfilter>LINEAR</magfilter>
         </sampler2D>
       </newparam>
       <newparam sid="bumpMap_Surface">
         <surface type="2D">
           <init_from>bump_E0</init_from>
           <format>A8R8G8B8</format>
         </surface>
       </newparam>
       <technique sid="Textured_Bump_E0_MP_TECH">
         <pass sid="Pass_0">
           <shader stage="VERTEXPROGRAM">
             <compiler_target>110</compiler_target>
             <name source="Vertex_Program_E0_P0_VP">main</name>
             <bind symbol="fvEyePosition">
               <param ref="fvEyePosition_E0_P0"></param>
             </bind>
             <bind symbol="fvLightPosition">
               <param ref="fvLightPosition_E0_P0"></param>
             </bind>
           </shader>
           <shader stage="FRAGMENTPROGRAM">
             <compiler_target>110</compiler_target>
             <name source="Fragment_Program_E0_P0_FP">main</name>
             <bind symbol="fSpecularPower">
               <param ref="fSpecularPower_E0_P0"></param>
             </bind>
             <bind symbol="fvAmbient">
               <param ref="fvAmbient_E0_P0"></param>
             </bind>
             <bind symbol="fvDiffuse">
               <param ref="fvDiffuse_E0_P0"></param>
             </bind>
             <bind symbol="fvSpecular">
               <param ref="fvSpecular_E0_P0"></param>
             </bind>
             <bind symbol="baseMap">
               <param ref="baseMap_Sampler"></param>
             </bind>
             <bind symbol="bumpMap">
               <param ref="bumpMap_Sampler"></param>
             </bind>
           </shader>
         </pass>
       </technique>
     </profile_GLSL>
   </effect>
 </library_effects>
 <library_images>
   <image id="base_E0" name="base_E0">
     <init_from>./Textured_Bump/Fieldstone.tga</init_from>
   </image>
   <image id="bump_E0" name="bump_E0">
     <init_from>./Textured_Bump/FieldstoneBumpDOT3.tga</init_from>
   </image>
 </library_images>
 <library_geometries>
   <geometry id="Model_E0_MESH_0_REF_1_lib" name="Model_E0_MESH_0_REF_1">
     <mesh>
       <source id="Model_E0_MESH_0_REF_1_lib_positions" name="position">
         <float_array id="Model_E0_MESH_0_REF_1_lib_positions_array" count="9">-50 -50 0 50 -50 0 0 50 0</float_array>
         <technique_common>
           <accessor count="3" source="#Model_E0_MESH_0_REF_1_lib_positions_array" stride="3">
             <param name="X" type="float"></param>
             <param name="Y" type="float"></param>
             <param name="Z" type="float"></param>
           </accessor>
         </technique_common>
       </source>
       <source id="Model_E0_MESH_0_REF_1_lib_normals" name="normal">
         <float_array id="Model_E0_MESH_0_REF_1_lib_normals_array" count="9">0 0 -1 0 0 -1 0 0 -1</float_array>
         <technique_common>
           <accessor count="3" source="#Model_E0_MESH_0_REF_1_lib_normals_array" stride="3">
             <param name="X" type="float"></param>
             <param name="Y" type="float"></param>
             <param name="Z" type="float"></param>
           </accessor>
         </technique_common>
       </source>
       <source id="Model_E0_MESH_0_REF_1_lib_texcoords" name="texcoords">
         <float_array id="Model_E0_MESH_0_REF_1_lib_texcoords_array" count="6">0 0 1 0 0.5 1</float_array>
         <technique_common>
           <accessor count="3" source="#Model_E0_MESH_0_REF_1_lib_texcoords_array" stride="2">
             <param name="X" type="float"></param>
             <param name="Y" type="float"></param>
           </accessor>
         </technique_common>
       </source>
       <source id="Model_E0_MESH_0_REF_1_lib_tangents" name="tangent">
         <float_array id="Model_E0_MESH_0_REF_1_lib_tangents_array" count="9">1 0 0 1 0 0 1 0 0</float_array>
         <technique_common>
           <accessor count="3" source="#Model_E0_MESH_0_REF_1_lib_tangents_array" stride="3">
             <param name="X" type="float"></param>
             <param name="Y" type="float"></param>
             <param name="Z" type="float"></param>
           </accessor>
         </technique_common>
       </source>
       <source id="Model_E0_MESH_0_REF_1_lib_binormals" name="binormal">
         <float_array id="Model_E0_MESH_0_REF_1_lib_binormals_array" count="9">0 1 0 0 0 0 0 1 0</float_array>
         <technique_common>
           <accessor count="3" source="#Model_E0_MESH_0_REF_1_lib_binormals_array" stride="3">
             <param name="X" type="float"></param>
             <param name="Y" type="float"></param>
             <param name="Z" type="float"></param>
           </accessor>
         </technique_common>
       </source>
       <vertices id="Model_E0_MESH_0_REF_1_lib_vertices">
         <input semantic="POSITION" source="#Model_E0_MESH_0_REF_1_lib_positions"></input>
         <input semantic="NORMAL" source="#Model_E0_MESH_0_REF_1_lib_normals"></input>
         <input semantic="TEXCOORD" source="#Model_E0_MESH_0_REF_1_lib_texcoords"></input>
       </vertices>
       <triangles count="1" material="Textured_Bump_E0_MP_MAT">
         <input offset="0" semantic="VERTEX" source="#Model_E0_MESH_0_REF_1_lib_vertices"></input>
         <input offset="0" semantic="TANGENT" source="#Model_E0_MESH_0_REF_1_lib_tangents"></input>
         <input offset="0" semantic="BINORMAL" source="#Model_E0_MESH_0_REF_1_lib_binormals"></input>
          <p>0 1 2</p>
       </triangles>
     </mesh>
   </geometry>
 </library_geometries>
 <scene>
   <instance_visual_scene url="#VisualSceneNode"></instance_visual_scene>
 </scene>
</COLLADA>