Index: /data/branches/Shader_HS18/programs/Example/Cg/ASCIIFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/ASCIIFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/ASCIIFP.cg	(revision 12083)
@@ -0,0 +1,32 @@
+sampler2D RT : register(s0);
+sampler3D pattern : register(s1);
+
+float4 ASCII_ps( float4 pos : POSITION,
+      float2 TexCoord : TEXCOORD0,
+			uniform float2 numTiles,
+			uniform float2 iNumTiles,
+			uniform float2 iNumTiles2,
+			uniform float4 lum,
+			uniform float charBias) : COLOR
+{
+    float3 local;
+
+	//sample RT
+	local.xy = fmod(TexCoord, iNumTiles);
+	float2 middle = TexCoord - local.xy;
+	local.xy = local.xy * numTiles;
+	
+	//iNumTiles2 = iNumTiles / 2
+	middle = middle + iNumTiles2;
+	float4 c = tex2D(RT, middle );
+	
+	//multiply luminance by charbias , beacause not all slices of the ascii
+	//volume texture are used
+	local.z = dot(c , lum)*charBias;
+	
+	//fix to brighten the dark pixels with small characters
+	//c *= lerp(2.0,1.0, local.z);
+	
+	c *= tex3D(pattern,local);
+	return c;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Combine_fp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Combine_fp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Combine_fp.cg	(revision 12083)
@@ -0,0 +1,15 @@
+float4 Combine_fp
+(
+    in float2 texCoord: TEXCOORD0,
+    
+    uniform sampler2D RT : register(s0),
+    uniform sampler2D Sum : register(s1),
+
+    uniform float blur
+) : COLOR
+{
+   float4 render = tex2D(RT, texCoord);
+   float4 sum = tex2D(Sum, texCoord);
+
+   return lerp(render, sum, blur);
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Common.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Common.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Common.cg	(revision 12083)
@@ -0,0 +1,81 @@
+struct outPixel
+{
+  float4 colour  : COLOR0;
+};
+
+// General functions
+
+// Expand a range-compressed vector
+half4 expand(half4 v)
+{
+    return v * 2 - 1;
+}
+half3 expand(half3 v)
+{
+    return v * 2 - 1;
+}
+half2 expand(half2 v)
+{
+    return v * 2 - 1;
+}
+half1 expand(half1 v)
+{
+    return v * 2 - 1;
+}
+
+// Returns light direction from light position and vertex position
+half3 getLightDirection(float4 lightPosition, float4 position)
+{
+    // calculate tangent space light vector
+    // Get object space light direction
+    // Non-normalised since we'll do that in the fragment program anyway
+    return lightPosition.xyz -  (position.xyz * lightPosition.w);
+}
+
+// Returns eye direction from eye position and vertex position
+half3 getEyeDirection(float3 eyePosition, float4 position)
+{
+    return eyePosition - position.xyz;
+}
+
+// Returns a Tangent Binormal Normal matrix
+half3x3 getTBNMatrix(float3 tangent, float3 normal)
+{
+    // Calculate the binormal (NB we assume both normal and tangent are
+    // already normalised)
+    // NB looks like nvidia cross params are BACKWARDS to what you'd expect
+    // this equates to NxT, not TxN
+    float3 binormal = cross(tangent, normal);
+	
+    // Form a rotation matrix out of the vectors
+    return half3x3(tangent, binormal, normal);
+}
+
+// Returns expanded normal vector from texture map
+half3 getNormalMapVector(sampler2D normalMap, float2 uv)
+{
+    // get bump map vector, again expand from range-compressed
+    return expand(tex2D(normalMap, uv).xyz);
+}
+
+// Returns displacement vector from normalmaps alpha channel
+half getDisplacement(sampler2D normalMap, float2 uv, half scale, half bias)
+{
+    // get the height using the tex coords
+    half height = tex2D(normalMap, uv).a;
+
+    // calculate displacement	
+    return (height * scale) + bias;
+}
+
+// Returns a specular component from normal vector, specular colour and specular power
+half3 getSpecularComponent(float3 normal, float3 halfAngle, float3 specularcolour, float specularPower)
+{
+    return pow(saturate(dot(normal, halfAngle)), specularPower) * specularcolour;
+}
+
+// Returns a per-pixel lighted component from normal vector, lightdir and colour
+half3 getLightingComponent(float3 normal, float3 lightDir, float3 colour)
+{
+    return saturate(dot(normal, lightDir)) * colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/DOF_ps.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/DOF_ps.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/DOF_ps.cg	(revision 12083)
@@ -0,0 +1,47 @@
+// Simple blur filter
+
+const float2 samples[8] = {
+    {-1, 1},
+    {-1, 0},
+    {-1, -1},
+    {0, -1},
+    {1, -1},
+    {1, 0},
+    {1, 1},
+    {0, 1}
+};
+
+float4 blur(
+
+    in float2 texCoord: TEXCOORD0,
+    uniform float sampleDistance: register(c0),
+    uniform sampler Blur0: register(s0)
+
+) : COLOR
+{
+   float4 sum = tex2D(Blur0, texCoord);
+   for (int i = 0; i < 8; ++i){
+      sum += tex2D(Blur0, texCoord + sampleDistance * samples[i]);
+   }
+   return sum / 9;
+}
+
+
+
+float4 blend
+(
+    in float2 texCoord: TEXCOORD0,
+
+    uniform sampler Blur0 : register(s0),
+    uniform sampler Blur1 : register(s1),
+
+    uniform float focus: register(c0),
+    uniform float range: register(c1)
+) : COLOR
+{
+   float4 sharp = tex2D(Blur0, texCoord);
+   float4 blur  = tex2D(Blur1, texCoord);
+
+   // alpha channel of sharp RT has depth info
+   return lerp(sharp, blur, saturate(range * abs(focus - sharp.a)));
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/DitherFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/DitherFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/DitherFP.cg	(revision 12083)
@@ -0,0 +1,18 @@
+sampler2D RT : register(s0);
+sampler2D pattern : register(s1);
+
+half4 Dither_ps(float4 pos : POSITION, float2 TexCoord : TEXCOORD0) : COLOR
+{	
+	half c = dot(tex2D(RT, TexCoord),half4(0.30,0.11,0.59,0.00));
+	half n = tex2D(pattern, TexCoord).r*2 - 1.0;
+	c += n;
+	if (c > 0.5)
+	{
+		c = 0.0;
+	}
+	else
+	{
+		c = 1.0;
+	}   
+	return half4(c,c,c,1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/DualQuaternion.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/DualQuaternion.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/DualQuaternion.cg	(revision 12083)
@@ -0,0 +1,159 @@
+#include "DualQuaternion_Common.cg"
+
+//Dual quaternion skinning with per-vertex antipodality handling (this is the most robust, but not the most efficient way):
+void dualQuaternionHardwareSkinningTwoWeights_vp(	
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float2x4 worldDualQuaternion2x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient,
+	uniform float4   diffuse)
+{		
+	float2x4 blendDQ = blendTwoWeightsAntipod(blendWgt, blendIdx, worldDualQuaternion2x4Array);
+
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	float3 blendPosition = calculateBlendPosition(position.xyz, blendDQ);
+
+	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
+	float3 blendNormal = calculateBlendNormal(normal, blendDQ);
+	
+	oPosition = mul(viewProjectionMatrix, float4(blendPosition, 1.0));
+	
+	// Lighting - support point and directional
+	float3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition.xyz * lightPos[0].w));
+	float3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition.xyz * lightPos[1].w));
+
+	oUv = uv;
+
+	colour = diffuse * (ambient + (saturate(dot(lightDir0, blendNormal)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, blendNormal)) * lightDiffuseColour[1]));		
+}
+
+
+//Shadow caster pass
+void dualQuaternionHardwareSkinningTwoWeightsCaster_vp(
+	float4 position : POSITION,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float2x4 worldDualQuaternion2x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	float2x4 blendDQ = blendTwoWeightsAntipod(blendWgt, blendIdx, worldDualQuaternion2x4Array);
+
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	float3 blendPosition = calculateBlendPosition(position.xyz, blendDQ);
+
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, float4(blendPosition, 1.0));
+	
+	colour = ambient;
+}
+
+//Two-phase skinning: dual quaternion skinning with scale and shear transformations
+void dualQuaternionHardwareSkinningTwoWeightsTwoPhase_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float2x4 worldDualQuaternion2x4Array[24],
+	uniform float3x4 scaleM[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient,
+	uniform float4   diffuse)
+{
+	//First phase - applies scaling and shearing:
+	float3x4 blendS = blendWgt.x*scaleM[blendIdx.x];
+	blendS += blendWgt.y*scaleM[blendIdx.y];	
+		
+	float3 pass1_position = mul(blendS, position);
+	float3x3 blendSrotAT = adjointTransposeMatrix(float3x3(blendS));
+	float3 pass1_normal = normalize(mul(blendSrotAT, normal.xyz));
+
+	//Second phase
+	float2x4 blendDQ = blendTwoWeightsAntipod(blendWgt, blendIdx, worldDualQuaternion2x4Array);
+	
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	float3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
+
+	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
+	float3 blendNormal = calculateBlendNormal(pass1_normal, blendDQ);
+
+	oPosition = mul(viewProjectionMatrix, float4(blendPosition, 1.0));
+
+	// Lighting - support point and directional
+	float3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition.xyz * lightPos[0].w));
+	float3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition.xyz * lightPos[1].w));
+
+	oUv = uv;
+	colour = diffuse * (ambient + (saturate(dot(lightDir0, blendNormal)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, blendNormal)) * lightDiffuseColour[1]));
+}
+
+//Two-phase skinning shadow caster pass
+void dualQuaternionHardwareSkinningTwoWeightsTwoPhaseCaster_vp(
+	float4 position : POSITION,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float2x4 worldDualQuaternion2x4Array[24],
+	uniform float3x4 scaleM[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	//First phase - applies scaling and shearing:
+	float3x4 blendS = blendWgt.x*scaleM[blendIdx.x];
+	blendS += blendWgt.y*scaleM[blendIdx.y];	
+		
+	float3 pass1_position = mul(blendS, position);
+
+	//Second phase
+	float2x4 blendDQ = blendTwoWeightsAntipod(blendWgt, blendIdx, worldDualQuaternion2x4Array);
+	
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	float3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
+
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, float4(blendPosition, 1.0));
+	
+	colour = ambient;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/DualQuaternion_Common.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/DualQuaternion_Common.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/DualQuaternion_Common.cg	(revision 12083)
@@ -0,0 +1,85 @@
+//All of these functions are based on dqs.cg from http://isg.cs.tcd.ie/kavanl/dq/
+/* dqs.cg
+
+  Dual quaternion skinning vertex shaders (no shading computations)
+
+  Version 1.0.3, November 1st, 2007
+
+  Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights 
+  Reserved
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author(s) be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Author: Ladislav Kavan, kavanl@cs.tcd.ie
+
+*/
+
+float2x4 blendTwoWeights(float4 blendWgt, float4 blendIdx, float2x4 dualQuaternions[24])
+{
+	float2x4 blendDQ = blendWgt.x*dualQuaternions[blendIdx.x];
+	blendDQ += blendWgt.y*dualQuaternions[blendIdx.y];
+
+	return blendDQ;
+}
+
+float2x4 blendTwoWeightsAntipod(float4 blendWgt, float4 blendIdx, float2x4 dualQuaternions[24])
+{
+	float2x4 dq0 = dualQuaternions[blendIdx.x];
+	float2x4 dq1 = dualQuaternions[blendIdx.y];
+
+	//Accurate antipodality handling. For speed increase, remove the following line, 
+	//though, the results will only be valid for rotations less than 180 degrees.
+	if (dot(dq0[0], dq1[0]) < 0.0) dq1 *= -1.0;
+	
+	float2x4 blendDQ = blendWgt.x*dq0;
+	blendDQ += blendWgt.y*dq1;
+
+	return blendDQ;
+}
+
+float3 calculateBlendPosition(float3 position, float2x4 blendDQ)
+{
+	float3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position.xyz) + blendDQ[0].x*position);
+	float3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+float3 calculateBlendNormal(float3 normal, float2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+float3x3 adjointTransposeMatrix(float3x3 M)
+{
+	float3x3 atM;
+	atM._m00 = M._m22 * M._m11 - M._m12 * M._m21;
+	atM._m01 = M._m12 * M._m20 - M._m10 * M._m22;
+	atM._m02 = M._m10 * M._m21 - M._m20 * M._m11;
+
+	atM._m10 = M._m02 * M._m21 - M._m22 * M._m01;
+	atM._m11 = M._m22 * M._m00 - M._m02 * M._m20;
+	atM._m12 = M._m20 * M._m01 - M._m00 * M._m21;
+
+	atM._m20 = M._m12 * M._m01 - M._m02 * M._m11;
+	atM._m21 = M._m10 * M._m02 - M._m12 * M._m00;
+	atM._m22 = M._m00 * M._m11 - M._m10 * M._m01;
+
+	return atM;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/Dyn-Text.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Dyn-Text.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Dyn-Text.cg	(revision 12083)
@@ -0,0 +1,23 @@
+void main_vs(float4 position : POSITION,
+			 float3 uv		  : TEXCOORD0,
+			 out float4 oPosition : POSITION,
+			 out float3 oUv	   : TEXCOORD0,
+			 uniform float4x4 worldViewProj)
+{
+	position.w = 1.0f;
+	oPosition = mul(worldViewProj, position);
+	oUv = uv;
+}
+
+void main_fp(float4 position          : POSITION, 
+			 float2 uv                : TEXCOORD0,
+			 out float4 colour        : COLOR,
+			 uniform sampler2D Image : register(s0),
+			 uniform sampler2D Thaw : register(s1))
+{
+	float4 l_color0 = tex2D(Image,uv);
+	float4 l_color1 = tex2D(Thaw,uv);
+	 	
+	colour = l_color0 * l_color1;
+	//colour = l_color1;	
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_Basic.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_Basic.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_Basic.cg	(revision 12083)
@@ -0,0 +1,400 @@
+/*
+  Basic ambient lighting vertex program
+*/
+void ambientOneTexture_vp(float4 position : POSITION,
+						  float2 uv		  : TEXCOORD0,
+						  
+						  out float4 oPosition : POSITION,
+						  out float2 oUv	   : TEXCOORD0,
+						  out float4 colour    : COLOR,
+
+						  uniform float4x4 worldViewProj,
+						  uniform float4 ambient)
+{
+	oPosition = mul(worldViewProj, position);
+	oUv = uv;
+	colour = ambient;
+}
+
+/*
+  Basic fragment program using texture and diffuse colour.
+*/
+void diffuseOneTexture_fp(float4 position          : POSITION, 
+						  float2 uv                : TEXCOORD0,
+						  float4 diffuse           : COLOR,
+						  out float4 colour        : COLOR,
+						  uniform sampler2D texMap : register(s0))
+{
+	colour = tex2D(texMap,uv) * diffuse;
+}
+			  
+/*
+  Single-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningOneWeight_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = mul((float3x3)worldMatrix3x4Array[blendIdx], normal);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}	
+
+/*
+  Single-weight-per-vertex hardware skinning, shadow-caster pass
+*/
+void hardwareSkinningOneWeightCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+	colour = ambient;
+	
+}	
+
+/*
+  Two-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningTwoWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient,
+	uniform float4   diffuse)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 2; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = diffuse * (ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]));
+	
+}
+
+/*
+  Two-weight-per-vertex hardware skinning, shadow caster pass
+*/
+void hardwareSkinningTwoWeightsCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+
+	colour = ambient;
+}
+
+
+/*
+  Four-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningFourWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 4; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 4; ++i)
+	{
+		float3x3 d = (float3x3)worldMatrix3x4Array[blendIdx[i]];
+		norm += mul(d, normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}
+
+// hardware morph animation (no normals)
+void hardwareMorphAnimation(float3 pos1 : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pos2	  : TEXCOORD1,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
+// hardware pose animation (no normals)
+void hardwarePoseAnimation(float3 pos : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pose1	  : TEXCOORD1,
+			  float3 pose2	  : TEXCOORD2,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos + anim_t.x*pose1 + anim_t.y*pose2, 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
+// hardware morph animation (with normals)
+void hardwareMorphAnimationWithNormals(float3 pos1 : POSITION,
+			  float3 normal1  : NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pos2	  : TEXCOORD1,
+			  float3 normal2  : TEXCOORD2,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 objSpaceLightPos,
+			  uniform float4 ambient,
+			  uniform float4 anim_t)
+{
+	// interpolate position
+	float4 posinterp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
+
+	// nlerp normal
+	float3 ninterp = normal1 + anim_t.x*(normal2 - normal1);
+	ninterp = normalize(ninterp);
+	
+	oPosition = mul(worldViewProj, posinterp);
+	oUv = uv;
+	
+	float3 lightDir = normalize(
+		objSpaceLightPos.xyz -  (posinterp.xyz * objSpaceLightPos.w));
+
+	// Colour it red to make it easy to identify
+	float lit = saturate(dot(lightDir, ninterp));
+	colour = float4((ambient.rgb + float3(lit,lit,lit)) * float3(1,0,0), 1);
+}
+
+// hardware pose animation (with normals)
+void hardwarePoseAnimationWithNormals(float3 pos : POSITION,
+			  float3 normal	   : NORMAL,
+			  float2 uv		   : TEXCOORD0,
+			  float3 pose1pos  : TEXCOORD1,
+			  float3 pose1norm : TEXCOORD2,
+			  float3 pose2pos  : TEXCOORD3,
+			  float3 pose2norm : TEXCOORD4,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 objSpaceLightPos,
+			  uniform float4 ambient,
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 posinterp = float4(pos + anim_t.x*pose1pos + anim_t.y*pose2pos, 1.0f);
+	
+	// nlerp normal
+	// First apply the pose normals (these are actual normals, not offsets)
+	float3 ninterp = anim_t.x*pose1norm + anim_t.y*pose2norm;
+
+	// Now add back any influence of the original normal
+	// This depends on what the cumulative weighting left the normal at, if it's lacking or cancelled out
+	//float remainder = 1.0 - min(anim_t.x + anim_t.y, 1.0);
+	float remainder = 1.0 - min(length(ninterp), 1.0);
+	ninterp = ninterp + (normal * remainder);
+	ninterp = normalize(ninterp);
+
+	oPosition = mul(worldViewProj, posinterp);
+	oUv = uv;
+	
+	float3 lightDir = normalize(
+		objSpaceLightPos.xyz -  (posinterp.xyz * objSpaceLightPos.w));
+
+	// Colour it red to make it easy to identify
+	float lit = saturate(dot(lightDir, ninterp));
+	colour = float4((ambient.rgb + float3(lit,lit,lit)) * float3(1,0,0), 1);
+}
+
+void basicPassthroughTangent_v(float4 position : POSITION,
+						float3 tangent       : TANGENT,
+						  
+						  out float4 oPosition : POSITION,
+						  out float3 oTangent  : TEXCOORD0,
+
+						  uniform float4x4 worldViewProj)
+{
+	oPosition = mul(worldViewProj, position);
+	oTangent = tangent;
+}
+void basicPassthroughNormal_v(float4 position : POSITION,
+						float3 normal       : NORMAL,
+						  
+						  out float4 oPosition : POSITION,
+						  out float3 oNormal  : TEXCOORD0,
+
+						  uniform float4x4 worldViewProj)
+{
+	oPosition = mul(worldViewProj, position);
+	oNormal = normal;
+}
+// Basic fragment program to display UV
+float4 showuv_p (float4 position : POSITION, float2 uv : TEXCOORD0) : COLOR
+{
+	// wrap values using frac
+	return float4(frac(uv.x), frac(uv.y), 0, 1);
+}
+// Basic fragment program to display 3d uv
+float4 showuvdir3d_p (float4 position : POSITION, float3 uv : TEXCOORD0) : COLOR
+{
+	float3 n = normalize(uv);
+	return float4(n.x, n.y, n.z, 1);
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_Basic_sm4.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_Basic_sm4.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_Basic_sm4.cg	(revision 12083)
@@ -0,0 +1,404 @@
+/*
+  Basic ambient lighting vertex program
+*/
+void ambientOneTexture_vp(float4 position    : POSITION,
+						  float3   normal    : NORMAL,
+						  float2   uv        : TEXCOORD0,
+						  float3   tangent   : TANGENT,						  
+
+						  
+						  out float4 oPosition : SV_POSITION,
+						  out float2 oUv	   : TEXCOORD0,
+						  out float4 colour    : COLOR,
+
+						  uniform float4x4 worldViewProj,
+						  uniform float4 ambient)
+{
+	oPosition = mul(worldViewProj, position);
+	oUv = uv;
+	colour = ambient;
+}
+
+/*
+  Basic fragment program using texture and diffuse colour.
+*/
+void diffuseOneTexture_fp(float4 position          : SV_POSITION, 
+						  float2 uv                : TEXCOORD0,
+						  float4 diffuse           : COLOR,
+						  out float4 colour        : COLOR,
+						  uniform sampler2D texMap : register(s0))
+{
+	colour = tex2D(texMap,uv) * diffuse;
+}
+			  
+/*
+  Single-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningOneWeight_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : SV_POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = mul((float3x3)worldMatrix3x4Array[blendIdx], normal);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}	
+
+/*
+  Single-weight-per-vertex hardware skinning, shadow-caster pass
+*/
+void hardwareSkinningOneWeightCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : SV_POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+	colour = ambient;
+	
+}	
+
+/*
+  Two-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningTwoWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : SV_POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient,
+	uniform float4   diffuse)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 2; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = diffuse * (ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]));
+	
+}
+
+/*
+  Two-weight-per-vertex hardware skinning, shadow caster pass
+*/
+void hardwareSkinningTwoWeightsCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : SV_POSITION,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+
+	colour = ambient;
+}
+
+
+/*
+  Four-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningFourWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : SV_POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 4; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 4; ++i)
+	{
+		float3x3 d = (float3x3)worldMatrix3x4Array[blendIdx[i]];
+		norm += mul(d, normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}
+
+// hardware morph animation (no normals)
+void hardwareMorphAnimation(float3 pos1 : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pos2	  : TEXCOORD1,
+						  
+			  out float4 oPosition : SV_POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
+// hardware pose animation (no normals)
+void hardwarePoseAnimation(float3 pos : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pose1	  : TEXCOORD1,
+			  float3 pose2	  : TEXCOORD2,
+						  
+			  out float4 oPosition : SV_POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos + anim_t.x*pose1 + anim_t.y*pose2, 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
+// hardware morph animation (with normals)
+void hardwareMorphAnimationWithNormals(float3 pos1 : POSITION,
+			  float3 normal1  : NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pos2	  : TEXCOORD1,
+			  float3 normal2  : TEXCOORD2,
+						  
+			  out float4 oPosition : SV_POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 objSpaceLightPos,
+			  uniform float4 ambient,
+			  uniform float4 anim_t)
+{
+	// interpolate position
+	float4 posinterp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
+
+	// nlerp normal
+	float3 ninterp = normal1 + anim_t.x*(normal2 - normal1);
+	ninterp = normalize(ninterp);
+	
+	oPosition = mul(worldViewProj, posinterp);
+	oUv = uv;
+	
+	float3 lightDir = normalize(
+		objSpaceLightPos.xyz -  (posinterp.xyz * objSpaceLightPos.w));
+
+	// Colour it red to make it easy to identify
+	float lit = saturate(dot(lightDir, ninterp));
+	colour = float4((ambient.rgb + float3(lit,lit,lit)) * float3(1,0,0), 1);
+}
+
+// hardware pose animation (with normals)
+void hardwarePoseAnimationWithNormals(float3 pos : POSITION,
+			  float3 normal	   : NORMAL,
+			  float2 uv		   : TEXCOORD0,
+			  float3 pose1pos  : TEXCOORD1,
+			  float3 pose1norm : TEXCOORD2,
+			  float3 pose2pos  : TEXCOORD3,
+			  float3 pose2norm : TEXCOORD4,
+						  
+			  out float4 oPosition : SV_POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 objSpaceLightPos,
+			  uniform float4 ambient,
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 posinterp = float4(pos + anim_t.x*pose1pos + anim_t.y*pose2pos, 1.0f);
+	
+	// nlerp normal
+	// First apply the pose normals (these are actual normals, not offsets)
+	float3 ninterp = anim_t.x*pose1norm + anim_t.y*pose2norm;
+
+	// Now add back any influence of the original normal
+	// This depends on what the cumulative weighting left the normal at, if it's lacking or cancelled out
+	//float remainder = 1.0 - min(anim_t.x + anim_t.y, 1.0);
+	float remainder = 1.0 - min(length(ninterp), 1.0);
+	ninterp = ninterp + (normal * remainder);
+	ninterp = normalize(ninterp);
+
+	oPosition = mul(worldViewProj, posinterp);
+	oUv = uv;
+	
+	float3 lightDir = normalize(
+		objSpaceLightPos.xyz -  (posinterp.xyz * objSpaceLightPos.w));
+
+	// Colour it red to make it easy to identify
+	float lit = saturate(dot(lightDir, ninterp));
+	colour = float4((ambient.rgb + float3(lit,lit,lit)) * float3(1,0,0), 1);
+}
+
+void basicPassthroughTangent_v( float4   position  : POSITION,
+								float3   normal    : NORMAL,
+								float2	 texcord   : TEXCOORD0,
+								float3   tangent   : TANGENT,						  
+				   			out float4   oPosition : SV_POSITION,
+							out float3   oTangent  : TEXCOORD0,
+
+						uniform float4x4 worldViewProj)
+{
+	oPosition = mul(worldViewProj, position);
+	oTangent = tangent;
+}
+void basicPassthroughNormal_v(float4   position  : POSITION,
+  							  float3   normal    : NORMAL,
+							  float2   texcord   : TEXCOORD0,
+							  float3   tangent   : TANGENT,						  
+						  out float4   oPosition : SV_POSITION,
+						  out float3   oNormal  : TEXCOORD0,
+				      uniform float4x4 worldViewProj)
+{
+	oPosition = mul(worldViewProj, position);
+	oNormal = normal;
+}
+// Basic fragment program to display UV
+float4 showuv_p (float4 position : SV_POSITION, float2 uv : TEXCOORD0, float4 colour    : COLOR) : COLOR
+{
+	// wrap values using frac
+	return float4(frac(uv.x), frac(uv.y), 0, 1);
+}
+// Basic fragment program to display 3d uv
+float4 showuvdir3d_p (float4 position : SV_POSITION, float3 uv : TEXCOORD0) : COLOR
+{
+	float3 n = normalize(uv);
+	return float4(n.x, n.y, n.z, 1);
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_BumpMapping.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_BumpMapping.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_BumpMapping.cg	(revision 12083)
@@ -0,0 +1,235 @@
+// General functions
+
+// Expand a range-compressed vector
+float3 expand(float3 v)
+{
+	return (v - 0.5) * 2;
+}
+
+
+/* Bump mapping vertex program
+   In this program, we want to calculate the tangent space light vector
+   on a per-vertex level which will get passed to the fragment program,
+   or to the fixed function dot3 operation, to produce the per-pixel
+   lighting effect. 
+*/
+void main_vp(float4 position	: POSITION,
+			 float3 normal		: NORMAL,
+			 float2 uv			: TEXCOORD0,
+			 float4 tangent     : TANGENT,
+			 // outputs
+			 out float4 oPosition    : POSITION,
+			 out float2 oUv			 : TEXCOORD0,
+			 out float3 oTSLightDir	 : TEXCOORD1,
+			 // parameters
+			 uniform float4 lightPosition, // object space
+			 uniform float4x4 worldViewProj)
+{
+	// calculate output position
+	oPosition = mul(worldViewProj, position);
+
+	// pass the main uvs straight through unchanged
+	oUv = uv;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	// Non-normalised since we'll do that in the fragment program anyway
+	float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
+	// this equates to NxT, not TxN
+
+#if TANGENTS_HAVE_PARITY
+	float3 binormal = cross(tangent.xyz, normal) * tangent.www;
+#else
+	// fixed handedness
+	float3 binormal = cross(tangent.xyz, normal);
+#endif
+	
+	// Form a rotation matrix out of the vectors
+	float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = mul(rotation, lightDir);
+	
+	
+}
+
+/* Bump mapping vertex program for shadow receiving
+   In this program, we want to calculate the tangent space light vector
+   on a per-vertex level which will get passed to the fragment program,
+   or to the fixed function dot3 operation, to produce the per-pixel
+   lighting effect. 
+*/
+void main_shadowreceiver_vp(float4 position	: POSITION,
+			 float3 normal		: NORMAL,
+			 float2 uv			: TEXCOORD0,
+			 float3 tangent     : TANGENT,
+			 
+			 // outputs
+			 out float4 oPosition    : POSITION,
+			 out float4 uvproj		 : TEXCOORD0,
+			 out float2 oUv	 		 : TEXCOORD1,
+			 out float3 oTSLightDir  : TEXCOORD2,
+			 
+			 // parameters
+			 uniform float4 lightPosition, // object space
+			 uniform float4x4 worldViewProj,
+			 uniform float4x4 worldMatrix,
+			 uniform float4x4 texViewProj)
+{
+	// calculate output position
+	oPosition = mul(worldViewProj, position);
+
+	// pass the main uvs straight through unchanged
+	oUv = uv;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	// Non-normalised since we'll do that in the fragment program anyway
+	float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
+	// this equates to NxT, not TxN
+	float3 binormal = cross(tangent, normal);
+	
+	// Form a rotation matrix out of the vectors
+	float3x3 rotation = float3x3(tangent.xyz, binormal, normal);
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = mul(rotation, lightDir);
+
+	// Projection
+    uvproj = mul(worldMatrix, position);
+	uvproj = mul(texViewProj, uvproj);
+	
+}
+
+
+void main_fp( float4 position	: POSITION, 
+        float2 uv			: TEXCOORD0,
+			  float3 TSlightDir : TEXCOORD1,
+
+			  out float4 colour	: COLOR,
+
+			  uniform float4 lightDiffuse,
+			  uniform sampler2D   normalMap : register(s0))
+{
+	// retrieve normalised light vector, expand from range-compressed
+	float3 lightVec = normalize(TSlightDir).xyz;
+
+	// get bump map vector, again expand from range-compressed
+	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
+
+	// Calculate dot product
+	colour = lightDiffuse * dot(bumpVec, lightVec);
+	
+}
+
+void main_shadowreceiver_fp( float4 position	: POSITION,
+			  float4 uvproj		: TEXCOORD0,
+			  float2 uv			: TEXCOORD1,
+			  float3 TSlightDir : TEXCOORD2,
+
+			  out float4 colour	: COLOR,
+
+			  uniform float4 lightDiffuse,
+			  uniform sampler2D   shadowMap : register(s0),
+			  uniform sampler2D   normalMap : register(s1))
+{
+
+
+	// retrieve normalised light vector, expand from range-compressed
+	float3 lightVec = expand(normalize(TSlightDir).xyz);
+
+	// get bump map vector, again expand from range-compressed
+	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
+
+	// get shadow value
+	float3 shadow = tex2Dproj(shadowMap, uvproj).xyz;
+
+	// Calculate dot product
+	colour = float4(shadow * lightDiffuse * dot(bumpVec, lightVec), 1.0f);
+	
+}
+
+/* Vertex program which includes specular component */
+void specular_vp(float4 position	: POSITION,
+			 	 float3 normal		: NORMAL,
+			 	 float2 uv			: TEXCOORD0,
+			 	 float3 tangent     : TANGENT,
+			 	 // outputs
+			 	 out float4 oPosition    : POSITION,
+			 	 out float2 oUv			 : TEXCOORD0,
+			 	 out float3 oTSLightDir	 : TEXCOORD1,
+				 out float3 oTSHalfAngle : TEXCOORD2,
+			 	 // parameters
+				 uniform float4 lightPosition, // object space
+			 	 uniform float3 eyePosition,   // object space
+			 	 uniform float4x4 worldViewProj)
+{
+	// calculate output position
+	oPosition = mul(worldViewProj, position);
+
+	// pass the main uvs straight through unchanged
+	oUv = uv;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
+	// this equates to NxT, not TxN
+	float3 binormal = cross(tangent, normal);
+	
+	// Form a rotation matrix out of the vectors
+	float3x3 rotation = float3x3(tangent, binormal, normal);
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = mul(rotation, lightDir);
+
+	// Calculate half-angle in tangent space
+	float3 eyeDir = normalize(eyePosition - position.xyz);
+	float3 halfAngle = normalize(eyeDir + lightDir);
+	oTSHalfAngle = mul(rotation, halfAngle);
+	
+	
+}
+
+/* Fragment program which supports specular component */
+void specular_fp( float4 position	: POSITION, 
+        float2 uv			: TEXCOORD0,
+			  float3 TSlightDir : TEXCOORD1,
+			  float3 TShalfAngle: TEXCOORD2,
+
+			  out float4 colour	: COLOR,
+
+			  uniform float4 lightDiffuse,
+			  uniform float4 lightSpecular,
+			  uniform sampler2D   normalMap : register(s0)) 
+{
+	// retrieve normalised light vector
+	float3 lightVec = normalize(TSlightDir);
+
+	// retrieve half angle and normalise
+	float3 halfAngle = normalize(TShalfAngle);
+
+	// get bump map vector, again expand from range-compressed
+	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
+
+	// Pre-raise the specular exponent to the eight power
+	float specFactor = pow(saturate(dot(bumpVec, halfAngle)), 4);
+	
+
+	// Calculate dot product for diffuse
+	colour = (lightDiffuse * saturate(dot(bumpVec, lightVec))) + 
+			(lightSpecular * specFactor);
+	
+}
+			 
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_CelShading.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_CelShading.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_CelShading.cg	(revision 12083)
@@ -0,0 +1,64 @@
+
+/* Cel shading vertex program for single-pass rendering
+   In this program, we want to calculate the diffuse and specular
+   ramp components, and the edge factor (for doing simple outlining)
+   For the outlining to look good, we need a pretty well curved model.
+*/
+void main_vp(float4 position	: POSITION,
+			 float3 normal		: NORMAL,
+			 // outputs
+			 out float4 oPosition : POSITION,
+			 out float  diffuse		 : TEXCOORD0,
+			 out float  specular	 : TEXCOORD1,
+			 out float  edge		 : TEXCOORD2,
+			 // parameters
+			 uniform float3 lightPosition, // object space
+			 uniform float3 eyePosition,   // object space
+			 uniform float4  shininess,
+			 uniform float4x4 worldViewProj)
+{
+	// calculate output position
+	oPosition = mul(worldViewProj, position);
+
+	// calculate light vector
+	float3 N = normalize(normal);
+	float3 L = normalize(lightPosition - position.xyz);
+	
+	// Calculate diffuse component
+	diffuse = max(dot(N, L) , 0);
+
+	// Calculate specular component
+	float3 E = normalize(eyePosition - position.xyz);
+	float3 H = normalize(L + E);
+	specular = pow(max(dot(N, H), 0), shininess);
+	// Mask off specular if diffuse is 0
+	if (diffuse == 0) specular = 0;
+
+	// Edge detection, dot eye and normal vectors
+	edge = max(dot(N, E), 0);
+}
+
+void main_fp( float4 position	: POSITION,
+       float diffuseIn 	: TEXCOORD0,
+			 float specularIn	: TEXCOORD1,
+			 float edge		: TEXCOORD2,
+			 
+			 out float4 colour	: COLOR,
+			 
+			 uniform float4 diffuse,
+			 uniform float4 specular,
+			 
+			 uniform sampler1D diffuseRamp,
+			 uniform sampler1D specularRamp,
+			 uniform sampler1D edgeRamp)
+{
+	// Step functions from textures
+	diffuseIn = tex1D(diffuseRamp, diffuseIn).x;
+	specularIn = tex1D(specularRamp, specularIn).x;
+	edge = tex1D(edgeRamp, edge).x;
+
+	colour = edge * ((diffuse * diffuseIn) + 
+					(specular * specularIn));
+}
+			 
+			 
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_Fresnel.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_Fresnel.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_Fresnel.cg	(revision 12083)
@@ -0,0 +1,116 @@
+// Vertex program for fresnel reflections / refractions
+void main_vp(
+		float4 pos			: POSITION,
+		float4 normal		: NORMAL,
+		float2 tex			: TEXCOORD0,
+		
+		out float4 oPos		: POSITION,
+		out float3 noiseCoord : TEXCOORD0,
+		out float4 projectionCoord : TEXCOORD1,
+		out float3 oEyeDir : TEXCOORD2, 
+		out float3 oNormal : TEXCOORD3, 
+
+		uniform float4x4 worldViewProjMatrix,
+		uniform float3 eyePosition, // object space
+		uniform float timeVal,
+		uniform float scale,  // the amount to scale the noise texture by
+		uniform float scroll, // the amount by which to scroll the noise
+		uniform float noise  // the noise perturb as a factor of the  time
+		)
+{
+	oPos = mul(worldViewProjMatrix, pos);
+	// Projective texture coordinates, adjust for mapping
+	float4x4 scalemat = float4x4(0.5,   0,   0, 0.5, 
+	                               0,-0.5,   0, 0.5,
+								   0,   0, 0.5, 0.5,
+								   0,   0,   0,   1);
+	projectionCoord = mul(scalemat, oPos);
+	// Noise map coords
+	noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
+	noiseCoord.z = noise * timeVal;
+
+	oEyeDir = normalize(pos.xyz - eyePosition); 
+	oNormal = normal.rgb; 
+	
+}
+
+// Fragment program for distorting a texture using a 3D noise texture
+void main_fp(
+		float4 pos			: POSITION,
+    float3 noiseCoord			: TEXCOORD0,
+		float4 projectionCoord		: TEXCOORD1,
+		float3 eyeDir				: TEXCOORD2,
+		float3 normal				: TEXCOORD3,
+		
+		out float4 col		: COLOR,
+		
+		uniform float4 tintColour,
+		uniform float noiseScale, 
+		uniform float fresnelBias,
+		uniform float fresnelScale,
+		uniform float fresnelPower,
+		uniform sampler2D noiseMap : register(s0),
+		uniform sampler2D reflectMap : register(s1),
+		uniform sampler2D refractMap : register(s2)
+		)
+{
+	// Do the tex projection manually so we can distort _after_
+	float2 final = projectionCoord.xy / projectionCoord.w;
+
+	// Noise
+	float3 noiseNormal = (tex2D(noiseMap, (noiseCoord.xy / 5)).rgb - 0.5).rbg * noiseScale;
+	final += noiseNormal.xz;
+
+	// Fresnel
+	//normal = normalize(normal + noiseNormal.xz);
+	float fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
+
+	// Reflection / refraction
+	float4 reflectionColour = tex2D(reflectMap, final);
+	float4 refractionColour = tex2D(refractMap, final) + tintColour;
+
+	// Final colour
+	col = lerp(refractionColour, reflectionColour, fresnel);
+
+
+}
+
+
+// Old version to match ATI PS 1.3 implementation
+void main_vp_old(
+		float4 pos			: POSITION,
+		float4 normal		: NORMAL,
+		float2 tex			: TEXCOORD0,
+		
+		out float4 oPos		: POSITION,
+		out float fresnel   : COLOR,
+		out float3 noiseCoord : TEXCOORD0,
+		out float4 projectionCoord : TEXCOORD1,
+
+		uniform float4x4 worldViewProjMatrix,
+		uniform float3 eyePosition, // object space
+		uniform float fresnelBias,
+		uniform float fresnelScale,
+		uniform float fresnelPower,
+		uniform float timeVal,
+		uniform float scale,  // the amount to scale the noise texture by
+		uniform float scroll, // the amount by which to scroll the noise
+		uniform float noise  // the noise perturb as a factor of the  time
+		)
+{
+	oPos = mul(worldViewProjMatrix, pos);
+	// Projective texture coordinates, adjust for mapping
+	float4x4 scalemat = float4x4(0.5,   0,   0, 0.5, 
+	                               0,-0.5,   0, 0.5,
+								   0,   0, 0.5, 0.5,
+								   0,   0,   0,   1);
+	projectionCoord = mul(scalemat, oPos);
+	// Noise map coords
+	noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
+	noiseCoord.z = noise * timeVal;
+
+	// calc fresnel factor (reflection coefficient)
+	float3 eyeDir = normalize(pos.xyz - eyePosition);
+	fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
+	
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_Projection.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_Projection.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_Projection.cg	(revision 12083)
@@ -0,0 +1,28 @@
+
+void generalPurposeProjection_vp(
+		float4 pos			: POSITION,
+		
+		out float4 oPos		: POSITION,
+		out float4 texCoord : TEXCOORD0,
+
+		uniform float4x4 worldViewProjMatrix,
+		uniform float4x4 worldMatrix,
+		uniform float4x4 texViewProjMatrix)
+{
+	oPos = mul(worldViewProjMatrix, pos);
+	// multiply position by world matrix, then by projective view/proj
+	float4 newpos = mul(worldMatrix, pos);
+	texCoord = mul(texViewProjMatrix, newpos);
+	
+}
+
+void generalPurposeProjection_fp(
+		float4 texCoord		: TEXCOORD0,
+		out float4 col		: COLOR,
+		uniform sampler2D texMap)
+{
+	col = tex2Dproj(texMap, texCoord);
+
+}
+		
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/Example_TextureArrayVS.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Example_TextureArrayVS.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Example_TextureArrayVS.cg	(revision 12083)
@@ -0,0 +1,14 @@
+
+
+void textureArray_v(float4 position : POSITION,
+						  float3 uv		  : TEXCOORD0,
+						  
+						  out float4 oPosition : POSITION,
+						  out float3 oUv	   : TEXCOORD0,
+
+						  uniform float4x4 worldViewProj)
+{
+	oPosition = mul(worldViewProj, position);
+	oUv = uv;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/GlassFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/GlassFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/GlassFP.cg	(revision 12083)
@@ -0,0 +1,9 @@
+sampler2D RT : register(s0);
+sampler2D NormalMap : register(s1);
+
+float4 main_ps(float4 pos : POSITION, float2 iTexCoord : TEXCOORD0) : COLOR
+{
+	float4 normal = 2 * (tex2D(NormalMap, iTexCoord * 2.5) - 0.5);
+
+	return tex2D(RT, iTexCoord + normal.xy * 0.05);
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Grass.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Grass.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Grass.cg	(revision 12083)
@@ -0,0 +1,283 @@
+////////////////////////////// MOVING GRASS
+// Vertex program to wave some grass about
+// Assumes UV texture coords of v==0 indicates the top of the grass
+void grass_vp(float4 position : POSITION,
+			  float3 normal   : NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 oColour    : COLOR,
+
+			  uniform float4x4 worldViewProj,
+			  //uniform float4 camObjPos,
+			  uniform float4 ambient,
+			  uniform float4 objSpaceLight,
+			  uniform float4 lightColour,
+			  uniform float4 offset)
+{
+	float4 mypos = position;
+	//offset = float4(0.5, 0, 0, 0);
+	float4 factor = float4(1,1,1,1) - uv.yyyy;
+	mypos = mypos + offset * factor;
+	oPosition = mul(worldViewProj, mypos);
+
+	oUv = uv;
+    // Color    
+	// get vertex light direction (support directional and point)
+	float3 light = normalize(objSpaceLight.xyz -  (mypos.xyz * objSpaceLight.w));
+	// grass is just 2D quads, so if light passes underneath we need to invert the normal
+	// abs() will have the same effect
+    float diffuseFactor = abs(dot(normal.xyz, light));
+	oColour = ambient + diffuseFactor * lightColour;    
+    
+}
+
+void grass_fp( float4 position : POSITION,
+               float2 uv	         : TEXCOORD0,
+               float4 colour         : COLOR,  
+               
+               out float4 oColour    : COLOR,
+              
+              uniform sampler2D diffuseMap
+              )
+{	
+    float4 texColor = tex2D(diffuseMap, uv.xy);
+    oColour = float4(texColor.rgb * colour.rgb, texColor.a); 
+    if(oColour.a < 0.58)
+      discard; 
+}
+
+
+void grassTex_vp(
+        float4 position : POSITION,
+			  float4 normal   : NORMAL,
+			  float2 uv		  : TEXCOORD0,
+              
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  //out float4 oNormal   : NORMAL,
+
+			  uniform float4x4 worldViewProj,
+              
+			  uniform float4 ambient,
+			  uniform float4 objSpaceLight,
+			  uniform float4 lightColour,
+              
+			  uniform float4 offset)
+{	    
+     // Position
+	float4 mypos = position;
+	float4 factor = float4(1,1,1,1) - uv.yyyy;
+	mypos = mypos + offset * factor;
+	oPosition = mul(worldViewProj, mypos);
+    // Texture Coord
+	oUv.xy = uv.xy;      
+}
+
+/// grass_vp ambient
+void grassAmbient_vp(
+              float4 position : POSITION,
+			  float4 normal   : NORMAL,
+			  float2 uv		  : TEXCOORD0,
+              
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 oColour    : COLOR,
+			  //out float4 oNormal   : NORMAL,
+
+              //uniform float4 camObjPos,
+			  uniform float4x4 worldViewProj,              
+			  uniform float4 ambient,
+			  uniform float4 offset)
+{	
+     // Position
+	float4 mypos = position;
+	float4 factor = float4(1,1,1,1) - uv.yyyy;
+	mypos = mypos + offset * factor;
+  	oPosition = mul(worldViewProj, mypos);
+    // Texture Coord
+	oUv.xy = uv.xy;      
+    /*
+    // Normal
+    // Make vec from vertex to camera
+    float4 EyeVec = camObjPos - mypos;
+    // Dot the v to eye and the normal to see if they point
+    //  in the same direction or opposite
+    float aligned = dot(normal, EyeVec); // -1..1
+    // If aligned is negative, we need to flip the normal
+    if (aligned < 0)  
+        normal = -normal;  
+    //oNormal = normal; 
+    */
+    // Color    
+	oColour = ambient; 
+}
+
+
+void grassAmbient_fp( 
+               float4 position : POSITION,
+               float2 uv	         : TEXCOORD0,
+               float4 colour         : COLOR,  
+               
+               out float4 oColour    : COLOR,
+              
+              uniform sampler2D diffuseMap
+              )
+{	
+    float4 texColor = tex2D(diffuseMap, uv.xy);
+    oColour = float4(colour.rgb, texColor.a); 
+}
+
+//////////////////////// GRASS SHADOW CASTER
+// Shadow caster vertex program.
+void grasscaster_vp(float4 position : POSITION,
+			        float2 uv	    : TEXCOORD0,
+              
+    			  out float4 oPosition  : POSITION,
+    			  out float2 oUv	    : TEXCOORD0,
+                  out float2 oDepth	    : TEXCOORD1,
+
+    			  uniform float4x4 worldViewProj,
+    			  uniform float4 offset,
+                  uniform float4 texelOffsets)
+{
+	float4 mypos = position;
+	float4 factor = float4(1,1,1,1) - uv.yyyy;
+	mypos = mypos + offset * factor;
+	oPosition = mul(worldViewProj, mypos);
+
+	// fix pixel / texel alignment
+	oPosition.xy += texelOffsets.zw * oPosition.w;
+    
+	oDepth.x = oPosition.z;
+	oDepth.y = oPosition.w;
+  
+  	oUv = uv;
+    
+}
+
+
+void grasscaster_fp(
+                    float4 position : POSITION,
+                    float2 uv	        : TEXCOORD0,
+                    float2 depth		: TEXCOORD1,
+                         
+                    out float4 result : COLOR,
+              
+                    uniform sampler2D diffuseMap
+                    )
+{	
+	float alpha = tex2D(diffuseMap, uv).a;
+	if (alpha > 0.001)
+    {
+       result = float4(1.0f, 1.0f, 1.0f, 0.0f);
+    }
+    else
+    {
+        float finalDepth = depth.x / depth.y;
+        // just smear across all components 
+        // therefore this one needs high individual channel precision
+        result = float4(finalDepth.xxx, 1.0f);
+    }
+}
+
+
+//////////////////////// GRASS SHADOW RECEIVER
+void grassreceiver_vp(
+                float4 position : POSITION,
+        			  float4 normal   : NORMAL,
+        			  float2 uv		  : TEXCOORD0,
+              
+			  out float4 oPosition    : POSITION,
+			  out float4 oShadowUV    : TEXCOORD0,
+			  out float3 oUv	      : TEXCOORD1,
+			  out float4 oColour      : COLOR,
+        	  //out float4 oNormal      : NORMAL,
+
+              uniform float4x4        world,
+			  uniform float4x4        worldViewProj,
+              uniform float4x4        texViewProj,
+              
+              uniform float4 camObjPos,
+              
+			  uniform float4 objSpaceLight,
+			  uniform float4 lightColour,
+              
+			  uniform float4 offset)
+{	    
+	float4 mypos = position;
+	float4 factor = float4(1,1,1,1) - uv.yyyy;
+	mypos = mypos + offset * factor;
+	oPosition = mul(worldViewProj, mypos);
+	oUv.xy = uv.xy;    
+    // Transform position to world space
+	float4 worldPos = mul(world, mypos);    
+	// calculate shadow map coords
+	oShadowUV = mul(texViewProj, worldPos);  
+       
+    // Make vec from vertex to camera
+    float4 EyeVec = camObjPos - mypos;
+    // Dot the v to eye and the normal to see if they point
+    // in the same direction or opposite
+    float alignedEye = dot(normal, EyeVec); // -1..1
+    // If aligned is negative, we need to flip the normal
+    if (alignedEye < 0)  
+        normal = -normal;        
+    //oNormal = normal;
+    
+  	// get vertex light direction (support directional and point)
+	float3 lightVec = normalize(objSpaceLight.xyz -  (mypos.xyz * objSpaceLight.w));
+    // Dot the v to light and the normal to see if they point
+    // in the same direction or opposite
+    float alignedLight = dot(normal.xyz, lightVec); // -1..1
+    // If aligned is negative, shadowing/lighting is not possible.
+    oUv.z = (alignedLight < 0)? 0 : 1 ;
+         
+    float diffuseFactor = max(alignedLight, 0);
+	//oColour = diffuseFactor * lightColour;    
+	oColour = lightColour;    
+}
+  	
+  	
+void grassreceiver_fp( 
+                         float4 position : POSITION
+                       , float4 shadowUV    : TEXCOORD0
+                       , float3 uv	        : TEXCOORD1
+                       , float4 vertexLight : COLOR     
+                      
+                       , out float4 oColour : COLOR
+              
+                       , uniform sampler2D shadowMap : register(s0)
+                       , uniform sampler2D diffuseMap : register(s1)
+                      
+                      //, uniform float inverseShadowmapSize
+                      , uniform float fixedDepthBias
+                      , uniform float gradientClamp
+                      , uniform float gradientScaleBias
+              )
+{		
+    if (shadowUV.z > 0)
+    {
+       float4 diffuse = tex2D(diffuseMap, uv.xy);
+       if (diffuse.a > 0.001)
+       {
+            oColour = float4(0.0f, 0.0f, 0.0f, 0.0f);
+  }
+       else
+       {
+            // point on shadowmap (no gradient as cg1.4 compiler is unable to handle that complexity)
+            shadowUV = shadowUV / shadowUV.w;
+            float4 shadowDepths = tex2D(shadowMap, shadowUV.xy);        
+            
+            float gradientFactor = gradientClamp * gradientScaleBias;
+            float depthAdjust = gradientFactor + fixedDepthBias * shadowDepths.x;
+            float centerdepth = shadowDepths.x + depthAdjust;
+  
+            oColour = (centerdepth > shadowUV.z) ? float4(vertexLight.rgb, diffuse.a) : float4(0, 0, 0, diffuse.a);
+       }
+    }
+    else
+    {
+        oColour = float4(0.0f, 0.0f, 0.0f, 0.0f);
+    }
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/GrayScale.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/GrayScale.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/GrayScale.cg	(revision 12083)
@@ -0,0 +1,20 @@
+sampler2D RT : register(s0);
+
+float4 GrayScale_ps( float4 pos : POSITION,
+                     float2 iTexCoord : TEXCOORD0) : COLOR
+{
+    float3 greyscale = dot(tex2D(RT, iTexCoord).rgb, float3(0.3, 0.59, 0.11));
+	return float4(greyscale, 1.0);
+}
+
+float4 Embossed_ps( float4 pos : POSITION,
+                    float2 iTexCoord : TEXCOORD0) : COLOR
+{
+    float4 Color;
+    Color.a = 1.0f;
+    Color.rgb = 0.5f;
+    Color -= tex2D( RT, iTexCoord - 0.001)*2.0f;
+    Color += tex2D( RT, iTexCoord + 0.001)*2.0f;
+    Color.rgb = (Color.r+Color.g+Color.b)/3.0f;
+    return Color;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/HWBasicInstancing.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/HWBasicInstancing.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/HWBasicInstancing.cg	(revision 12083)
@@ -0,0 +1,69 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+//---------------------------------------------
+//Vertex Shader Input
+//---------------------------------------------
+struct VS_INPUT
+{
+	float4 Position	:	POSITION;
+	float3 Normal	:	NORMAL;
+	float3 Tangent	:	TANGENT;
+	float2 uv0		:	TEXCOORD0;
+
+	float4 mat14	:	TEXCOORD1;
+	float4 mat24	:	TEXCOORD2;
+	float4 mat34	:	TEXCOORD3;
+};
+
+#include "InstancingVertexInterpolators.cg"
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+VS_OUTPUT main_vs( in VS_INPUT input,
+				   uniform float4x4 viewProjMatrix
+
+#if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER )
+				,  uniform float4 depthRange
+#endif
+#ifdef DEPTH_SHADOWRECEIVER
+				,  uniform float4x4 texViewProjMatrix
+#endif
+				)
+{
+	VS_OUTPUT output;
+
+	float3x4 worldMatrix;
+	worldMatrix[0] = input.mat14;
+	worldMatrix[1] = input.mat24;
+	worldMatrix[2] = input.mat34;
+
+	float4 worldPos = float4( mul( worldMatrix, input.Position ).xyz, 1.0f );
+	float3 worldNorm= mul( (float3x3)(worldMatrix), input.Normal );
+
+	//Transform the position
+	output.Position		= mul( viewProjMatrix, worldPos );
+
+#ifdef DEPTH_SHADOWCASTER
+	output.ps.unused	= float3( 0 );
+	output.ps.depth		= (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w;
+#else
+	output.ps.uv0		= input.uv0;
+
+	//Pass Normal and position for Blinn Phong lighting
+	output.ps.Normal	= normalize(worldNorm);
+	output.ps.vPos		= worldPos.xyz;
+	
+	#ifdef DEPTH_SHADOWRECEIVER
+		// Calculate the position of vertex in light space to do shadows
+		output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos );
+		// make linear
+		output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+
+	return output;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/HW_VTFInstancing.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/HW_VTFInstancing.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/HW_VTFInstancing.cg	(revision 12083)
@@ -0,0 +1,124 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+//---------------------------------------------
+//Vertex Shader Input
+//---------------------------------------------
+struct VS_INPUT
+{
+	float4 Position	:	POSITION;
+	float3 Normal	:	NORMAL;
+	float3 Tangent	:	TANGENT;
+#ifdef BONE_TWO_WEIGHTS
+	float4 weights		: 	BLENDWEIGHT;
+#endif
+	float2 uv0		:	TEXCOORD0;
+	float4 m03		:	TEXCOORD1; //m03.w is always 0
+
+	float2 mOffset		:	TEXCOORD2;
+	
+#ifdef BONE_MATRIX_LUT
+	float4 worldMatrix0	:	TEXCOORD3;
+	float4 worldMatrix1	:	TEXCOORD4;
+	float4 worldMatrix2	:	TEXCOORD5;
+#endif
+};
+
+#include "InstancingVertexInterpolators.cg"
+#ifdef ST_DUAL_QUATERNION
+#include "DualQuaternion_Common.cg"
+#endif
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+VS_OUTPUT main_vs( in VS_INPUT input,
+				   uniform float4x4 viewProjMatrix,
+				   
+#ifdef DEPTH_SHADOWCASTER
+				   uniform sampler2D matrixTexture : register(s0)
+#else
+				   uniform sampler2D matrixTexture : register(s2)
+#endif
+
+#if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER )
+				,  uniform float4 depthRange
+#endif
+#ifdef DEPTH_SHADOWRECEIVER
+				,  uniform float4x4 texViewProjMatrix
+#endif
+				)
+{
+	VS_OUTPUT output;
+	float4 worldPos;
+	float3 worldNorm;
+
+
+#ifdef ST_DUAL_QUATERNION
+	float2x4 blendDQ;	
+	blendDQ[0] = tex2D( matrixTexture, float2(input.m03.x, 0.0) + input.mOffset );
+	blendDQ[1] = tex2D( matrixTexture, float2(input.m03.y, 0.0) + input.mOffset );
+#ifdef BONE_TWO_WEIGHTS
+	float2x4 blendDQ2;
+	//Use the empty parts of m03, z and w, for the second dual quaternion
+	blendDQ2[0] = tex2D( matrixTexture, float2(input.m03.z, 0.0) + input.mOffset );
+	blendDQ2[1] = tex2D( matrixTexture, float2(input.m03.w, 0.0) + input.mOffset );
+	
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= input.weights.x;
+	blendDQ += input.weights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = float4(calculateBlendPosition(input.Position.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(input.Normal, blendDQ);
+#else
+	float3x4 worldMatrix;
+	worldMatrix[0] = tex2D( matrixTexture, input.m03.xw + input.mOffset );
+	worldMatrix[1] = tex2D( matrixTexture, input.m03.yw + input.mOffset );
+	worldMatrix[2] = tex2D( matrixTexture, input.m03.zw + input.mOffset );
+
+	worldPos = float4( mul( worldMatrix, input.Position ).xyz, 1.0f );
+	worldNorm= mul( (float3x3)(worldMatrix), input.Normal );
+#endif
+
+#ifdef BONE_MATRIX_LUT
+	float3x4 worldCompMatrix;
+	worldCompMatrix[0] = input.worldMatrix0;
+	worldCompMatrix[1] = input.worldMatrix1;
+	worldCompMatrix[2] = input.worldMatrix2;
+	
+	worldPos =  float4( mul( worldCompMatrix, worldPos ).xyz, 1.0f );
+	worldNorm = mul( (float3x3)(worldCompMatrix), worldNorm );
+	
+#endif
+
+
+	//Transform the position
+	output.Position		= mul( viewProjMatrix, worldPos );
+
+#ifdef DEPTH_SHADOWCASTER
+	output.ps.unused	= float3( 0 );
+	output.ps.depth		= (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w;
+#else
+	output.ps.uv0		= input.uv0;
+
+	//Pass Normal and position for Blinn Phong lighting
+	output.ps.Normal	= normalize(worldNorm);
+	output.ps.vPos		= worldPos.xyz;
+	
+	#ifdef DEPTH_SHADOWRECEIVER
+		// Calculate the position of vertex in light space to do shadows
+		output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos );
+		// make linear
+		output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+
+	return output;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/HalftoneFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/HalftoneFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/HalftoneFP.cg	(revision 12083)
@@ -0,0 +1,19 @@
+sampler2D RT : register(s0);
+sampler3D pattern : register(s1);
+
+float4 Halftone_ps(	float4 pos : POSITION,
+      float2 TexCoord : TEXCOORD0,
+			uniform float2 numTiles,
+			uniform float2 iNumTiles,
+			uniform float2 iNumTiles2,
+			uniform float4 lum) : COLOR
+{	
+	float3 local;
+	local.xy = fmod(TexCoord, iNumTiles);
+	float2 middle = TexCoord - local.xy;
+	local.xy = local.xy * numTiles;
+	middle +=  iNumTiles2;
+	local.z = dot(tex2D(RT, middle ) , lum);
+	float4 c = tex3D(pattern,local).r;
+	return c;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/HeatVision.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/HeatVision.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/HeatVision.cg	(revision 12083)
@@ -0,0 +1,230 @@
+//////////////////////////////////////////////
+//				 CASTER PASS				//
+//				    HEAT					//
+//////////////////////////////////////////////
+
+// vs_1_1
+void HeatCaster_vp(
+              // in
+              float4 vPos: POSITION,
+              float4 vNormal: NORMAL,
+              
+              // out
+              out float4 oPos: POSITION,
+              out float2 oNDotV: TEXCOORD0,
+              
+              // parameters
+              uniform float4x4 worldViewProj,
+              uniform float3 eyePosition        // object space
+            )
+{
+   float4 eyeDir = float4(eyePosition - vPos.xyz, 0);
+   eyeDir = normalize(eyeDir);
+   oPos   = mul( worldViewProj, vPos );
+   oNDotV = clamp( dot( vNormal, eyeDir ), 0, 1 );
+}
+
+// ps_2_0
+float4 HeatCaster_fp(
+                        // input from vp
+                        float2 iNDotV: TEXCOORD0
+                     ) : COLOR0
+{
+   return iNDotV.x;
+}
+
+
+//////////////////////////////////////////////
+//				 CASTER PASS				//
+//				    COLD					//
+//////////////////////////////////////////////
+
+// vs_1_1
+void ColdCaster_vp(
+              // in
+              float4 vPos: POSITION,
+              float4 vNormal: NORMAL,
+              
+              // out
+              out float4 oPos: POSITION,
+              out float2 oNDotV: TEXCOORD0,
+              
+              // parameters
+              uniform float4x4 worldViewProj,
+              uniform float3 eyePosition        // object space
+            )
+{
+   float4 eyeDir = float4(eyePosition - vPos.xyz, 0);
+   eyeDir = normalize(eyeDir);
+   oPos   = mul( worldViewProj, vPos );
+   oNDotV = clamp( dot( vNormal, eyeDir ), 0, 1 );
+}
+
+// ps_2_0
+float4 ColdCaster_fp(
+                        // input from vp
+                        float2 iNDotV: TEXCOORD0
+                     ) : COLOR0
+{
+   return iNDotV.x / 2;
+}
+
+
+//////////////////////////////////////////////
+//	   PASS 1 - Light to heat conversion	//
+//////////////////////////////////////////////
+
+// vs_1_1
+void LightToHeat_vp(
+                    // in
+                    float4 inPos: POSITION,
+                    
+                    uniform float flipping,
+
+                    // out
+                    out float4 Pos: POSITION,
+                    out float2 uv0: TEXCOORD0
+                   )
+{
+    Pos = float4(inPos.x, flipping * inPos.y, 0.0f, 1.0f);
+    inPos.xy = sign(inPos.xy);
+    uv0  = (float2(inPos.x, -inPos.y) + 1.0f)/2.0f;
+}
+
+
+// ps_2_0
+void LightToHeat_fp(
+                        // input from vp
+                        float4 inDiffuse: COLOR0,
+                        float2 inUV0: TEXCOORD0,
+                        
+                        // out
+                        out float4 outColor: COLOR0,
+                        
+                        // params
+                        uniform float4 random_fractions,
+                        uniform float4 heatBiasScale,
+                        uniform float4 depth_modulator,
+
+                        uniform sampler2D Input,         // output of HeatVisionCaster_fp (NdotV)
+                        uniform sampler2D NoiseMap,
+                        uniform sampler2D HeatLookup
+                     )
+{
+   float  depth, heat, interference;
+
+   //  Output constant color:
+   depth = tex2D( Input, inUV0 );
+   depth *= (depth * depth_modulator);
+
+   heat  = (depth * heatBiasScale.y);
+
+//   if (depth > 0)
+   {
+		interference = -0.5 + tex2D( NoiseMap, inUV0 + float2( random_fractions.x, random_fractions.y ) );
+		interference *= interference;
+		interference *= 1 - heat;
+		heat += interference;//+ heatBiasScale.x;
+   }
+
+/*
+	heatBias isn't used for now
+   if (heat > 0)
+       heat += heatBiasScale.x;
+*/
+
+   // Clamp UVs
+   heat  = max( 0.005, min( 0.995, heat ) );
+   outColor = tex2D( HeatLookup, float2( heat, 0.f ) );
+}
+
+
+//////////////////////////////////////////////
+// PASS 2 - add simple blur (final pass)	//
+//////////////////////////////////////////////
+
+// vs_1_1
+void Blur_vp(
+                    // in
+                    float4 inPos: POSITION,
+                    
+                    uniform float flipping,
+
+                    // out
+                    out float4 Pos: POSITION,
+                    out float2 uv0: TEXCOORD0
+                   )
+{
+    Pos = float4(inPos.x, flipping * inPos.y, 0.0f, 1.0f);
+    inPos.xy = sign(inPos.xy);
+    uv0  = (float2(inPos.x, -inPos.y) + 1.0f)/2.0f;
+}
+
+// ps_2_0
+void Blur_fp(
+                    // input from vp
+                    float4 inDiffuse: COLOR0,
+                    float2 inUV0: TEXCOORD0,
+                    
+                    // out
+                    out float4 outColor: COLOR0,
+                    
+                    // parameters
+                    uniform sampler2D Input,             // output of HeatVision_fp1 (HeatRenderTexture)
+                    uniform float4 blurAmount
+                    )
+{
+   int i;
+   float4 tmpOutColor;
+   float  diffuseGlowFactor;
+   const float2 offsets[4] = 
+   {
+/*
+		// hazy blur
+		-1.8, -1.8,
+		-1.8, 1.8,
+		1.8, -1.8,
+		1.8, 1.8
+*/
+/*
+		// less-hazy blur
+	  -1.0,  2.0,
+	  -1.0, -1.0,
+	   1.0, -1.0,
+	   1.0,  1.0
+*/
+/*
+      -0.326212, -0.405805,
+      -0.840144, -0.073580,
+      -0.695914,  0.457137,
+      -0.203345,  0.620716
+*/
+
+	  -0.3,  0.4,
+	  -0.3, -0.4,
+	   0.3, -0.4,
+	   0.3,  0.4
+
+   };
+
+   tmpOutColor = tex2D( Input, inUV0 );	// UV coords are in image space
+
+   // calculate glow amount
+   diffuseGlowFactor = 0.0113f * (2.0 - max( tmpOutColor.r, tmpOutColor.g ));
+
+   // basic blur filter
+   for (i = 0; i < 4; i++) {
+      tmpOutColor += tex2D( Input, inUV0 + blurAmount.x * diffuseGlowFactor * offsets[i] );
+   }
+
+   tmpOutColor *= 0.25;
+
+   // TIPS (old-skool strikes again!)
+   // Pay attention here! If you use the "out float4 outColor" directly
+   // in your steps while creating the output color (like you remove
+   // the "tmpOutColor" var and just use the "outColor" directly)
+   // your pixel-color output IS CHANGING EACH TIME YOU DO AN ASSIGNMENT TOO!
+   // A temporary variable, instead, acts like a per-pixel double buffer, and
+   // best of all, lead to better performance.
+   outColor = tmpOutColor;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/InstancingMisc.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/InstancingMisc.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/InstancingMisc.cg	(revision 12083)
@@ -0,0 +1,63 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+//This shader is not instancing related, but is used in the Instancing tests for lighting
+//consistency (i.e. the ground)
+
+//---------------------------------------------
+//Vertex Shader Input
+//---------------------------------------------
+struct VS_INPUT
+{
+	float4 Position	:	POSITION;
+	float3 Normal	:	NORMAL;
+	float2 uv0		:	TEXCOORD0;
+};
+
+#include "InstancingVertexInterpolators.cg"
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+VS_OUTPUT main_vs( in VS_INPUT input,
+				   uniform float4x4 viewProjMatrix,
+				   uniform float4x4 worldMatrix
+
+#if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER )
+				,  uniform float4 depthRange
+#endif
+#ifdef DEPTH_SHADOWRECEIVER
+				,  uniform float4x4 texViewProjMatrix
+#endif
+				   )
+{
+	VS_OUTPUT output;
+	
+	float4 worldPos  = mul( worldMatrix, input.Position );
+	float3 worldNorm = mul( (float3x3)(worldMatrix), input.Normal );
+
+	//Transform the position
+	output.Position		= mul( viewProjMatrix, worldPos );
+	
+#ifdef DEPTH_SHADOWCASTER
+	output.ps.unused	= float3( 0 );
+	output.ps.depth		= (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w;
+#else
+	output.ps.uv0		= input.uv0;
+	
+	//Pass Normal and position for Blinn Phong lighting
+	output.ps.Normal	= worldNorm;
+	output.ps.vPos		= worldPos.xyz;
+
+	#ifdef DEPTH_SHADOWRECEIVER
+		// Calculate the position of vertex in light space to do shadows
+		output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos );
+		// make linear
+		output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+
+	return output;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/InstancingVertexInterpolators.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/InstancingVertexInterpolators.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/InstancingVertexInterpolators.cg	(revision 12083)
@@ -0,0 +1,34 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+//---------------------------------------------
+//Pixel Shader Input
+//---------------------------------------------
+struct PS_INPUT
+{
+#ifdef DEPTH_SHADOWCASTER
+	float3 unused	:	TEXCOORD0;
+	float depth		:	TEXCOORD1;
+#else
+	float2 uv0		:	TEXCOORD0;
+	float3 Normal	:	TEXCOORD1;
+	float3 vPos		:	TEXCOORD2;
+	
+	#ifdef DEPTH_SHADOWRECEIVER
+		float4 lightSpacePos	:	TEXCOORD3;
+	#endif
+#endif
+};
+
+#define SHADOW_BIAS 0
+
+//---------------------------------------------
+//Vertex Shader Output
+//---------------------------------------------
+struct VS_OUTPUT
+{
+	float4 Position	:	POSITION;
+	PS_INPUT	ps;
+};
Index: /data/branches/Shader_HS18/programs/Example/Cg/Instancing_ps.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Instancing_ps.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Instancing_ps.cg	(revision 12083)
@@ -0,0 +1,57 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+#include "InstancingVertexInterpolators.cg"
+
+#include "shadows.cg"
+
+//---------------------------------------------
+//Main Pixel Shader
+//---------------------------------------------
+half4 main_ps( PS_INPUT input ,
+				uniform float4	lightPosition,
+				uniform float3	cameraPosition,
+				uniform half3 	lightAmbient,
+				uniform half3	lightDiffuse,
+				uniform half3	lightSpecular,
+				uniform half4	lightAttenuation,
+				uniform half	lightGloss,
+
+				//Textures
+				uniform sampler2D diffuseMap : register(s0)
+
+#ifdef DEPTH_SHADOWRECEIVER
+			,	uniform float invShadowMapSize,
+				uniform sampler2D shadowMap : register(s1)
+#endif
+			) : COLOR0
+{
+	float fShadow = 1.0f;
+#ifdef DEPTH_SHADOWRECEIVER
+	fShadow = calcDepthShadow( shadowMap, input.lightSpacePos, invShadowMapSize );
+#endif
+
+	const half4 baseColour = tex2D( diffuseMap, input.uv0 );
+	
+	//Blinn-Phong lighting
+	const half3 normal		= normalize( input.Normal );
+	half3 lightDir			= lightPosition.xyz - input.vPos * lightPosition.w;
+	half3 eyeDir			= normalize( cameraPosition - input.vPos  );
+
+	const half fLength		= length( lightDir );
+	lightDir				= normalize( lightDir );
+
+	const half NdotL = max( 0.0f, dot( normal, lightDir ) );
+	half3 halfVector = normalize(lightDir + eyeDir);
+	const half HdotN = max( 0.0f, dot( halfVector, normal ) );
+	
+	const half3 ambient  = lightAmbient * baseColour.xyz;
+	const half3 diffuse  = lightDiffuse * NdotL * baseColour.xyz;
+	const half3 specular = lightSpecular * pow( HdotN, lightGloss );
+	
+	const half3 directLighting = (diffuse + specular) * fShadow;
+	
+	return half4( directLighting + ambient, baseColour.a );
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/InvertFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/InvertFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/InvertFP.cg	(revision 12083)
@@ -0,0 +1,6 @@
+sampler2D RT : register(s0);
+
+float4 Invert_ps (float4 pos : POSITION, float2 iTexCoord : TEXCOORD0) : COLOR
+{
+	return 1 - tex2D(RT, iTexCoord);
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/LaplaceFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/LaplaceFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/LaplaceFP.cg	(revision 12083)
@@ -0,0 +1,37 @@
+sampler2D Image : register(s0);
+
+// The Laplace filter approximates the second order derivate,
+// that is, the rate of change of slope in the image. It can be
+// used for edge detection. The Laplace filter gives negative
+// response on the higher side of the edge and positive response
+// on the lower side.
+
+// This is the filter kernel:
+// 0  1  0
+// 1 -4  1
+// 0  1  0
+
+
+
+float4 Laplace_ps ( float4 pos : POSITION,
+      float2 texCoord: TEXCOORD0,
+			uniform float scale,
+			uniform float pixelSize) : COLOR
+{
+
+    float2 samples[4] = {
+        0, -1,
+       -1,  0,
+        1,  0,
+        0,  1
+    };
+   float4 laplace = -4 * tex2D(Image, texCoord);
+
+   // Sample the neighbor pixels
+   for (int i = 0; i < 4; i++){
+      laplace += tex2D(Image, texCoord + pixelSize * samples[i]);
+   }
+
+   return (0.5 + scale * laplace);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/NightVisionFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/NightVisionFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/NightVisionFP.cg	(revision 12083)
@@ -0,0 +1,27 @@
+sampler2D RT : register(s0);
+sampler3D noiseVol : register(s1);
+
+float4 NightVision_ps(	float4 pos : POSITION,
+      float2 TexCoord : TEXCOORD0,
+			uniform float4 lum,
+			uniform float time) : COLOR
+{	
+	float4 oC;
+	oC = tex2D(RT, TexCoord);
+	
+	//obtain luminence value
+	oC = dot(oC,lum);
+	
+	//add some random noise
+	oC += 0.2 *(tex3D(noiseVol, float3(TexCoord*5,time)))- 0.05;
+	
+	//add lens circle effect
+	//(could be optimised by using texture)
+	float dist = distance(TexCoord, float2(0.5,0.5));
+	oC *= smoothstep(0.5,0.45,dist);
+	
+	//add rb to the brightest pixels
+	oC.rb = max (oC.r - 0.75, 0)*4;
+	
+	return oC ;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Ocean2HLSL_Cg.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Ocean2HLSL_Cg.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Ocean2HLSL_Cg.frag	(revision 12083)
@@ -0,0 +1,85 @@
+/*********************************************************************NVMH3****
+Copyright NVIDIA Corporation 2003
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+	Simple ocean shader with animated bump map and geometric waves
+	Based partly on "Effective Water Simulation From Physical Models", GPU Gems
+
+11 Aug 05: heavily modified by Jeff Doyle (nfz) for Ogre
+
+******************************************************************************/
+
+
+
+struct v2f {
+	float4 Position  : POSITION;  // in clip space
+	float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform from tangent to obj space
+	float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform from tangent to obj space
+	float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform from tangent to obj space
+
+	float2 bumpCoord0 : TEXCOORD3;
+	float2 bumpCoord1 : TEXCOORD4;
+	float2 bumpCoord2 : TEXCOORD5;
+
+	float3 eyeVector  : TEXCOORD6;
+};
+
+
+float4 main(v2f IN,
+			uniform sampler2D NormalMap,
+			uniform samplerCUBE EnvironmentMap,
+			uniform float4 deepColor,
+			uniform float4 shallowColor,
+			uniform float4 reflectionColor,
+			uniform float reflectionAmount,
+			uniform float reflectionBlur,
+			uniform float waterAmount,
+			uniform float fresnelPower,
+			uniform float fresnelBias,
+			uniform float hdrMultiplier
+			) : COLOR
+{
+	// sum normal maps
+	// sample from 3 different points so no texture repetition is noticeable
+    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
+    float4 t1 = tex2D(NormalMap, IN.bumpCoord1) * 2.0 - 1.0;
+    float4 t2 = tex2D(NormalMap, IN.bumpCoord2) * 2.0 - 1.0;
+    float3 N = t0.xyz + t1.xyz + t2.xyz;
+
+    float3x3 m; // tangent to world matrix
+    m[0] = IN.rotMatrix1;
+    m[1] = IN.rotMatrix2;
+    m[2] = IN.rotMatrix3;
+
+    N = normalize( mul( N, m ) );
+
+	// reflection
+    float3 E = normalize(IN.eyeVector);
+    float4 R;
+    R.xyz = reflect(E, N);
+    // Ogre conversion for cube map lookup
+    R.z = -R.z;
+    R.w = reflectionBlur;
+    float4 reflection = texCUBEbias(EnvironmentMap, R);
+    // cheap hdr effect
+    reflection.rgb *= (reflection.r + reflection.g + reflection.b) * hdrMultiplier;
+
+	// fresnel
+    float facing = 1.0 - max(dot(-E, N), 0);
+    float fresnel = saturate(fresnelBias + pow(facing, fresnelPower));
+
+    float4 waterColor = lerp(shallowColor, deepColor, facing) * waterAmount;
+
+    reflection = lerp(waterColor,  reflection * reflectionColor, fresnel) * reflectionAmount;
+    return waterColor + reflection;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Ocean2HLSL_Cg.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Ocean2HLSL_Cg.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Ocean2HLSL_Cg.vert	(revision 12083)
@@ -0,0 +1,108 @@
+/*********************************************************************NVMH3****
+Copyright NVIDIA Corporation 2003
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+	Simple ocean shader with animated bump map and geometric waves
+	Based partly on "Effective Water Simulation From Physical Models", GPU Gems
+
+11 Aug 05: heavily modified by Jeff Doyle (nfz) for Ogre
+
+******************************************************************************/
+
+struct a2v {
+	float4 Position : POSITION;   // in object space
+	float2 TexCoord : TEXCOORD0;
+};
+
+struct v2f {
+	float4 Position  : POSITION;  // in clip space
+	float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform from tangent to obj space
+	float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform from tangent to obj space
+	float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform from tangent to obj space
+
+	float2 bumpCoord0 : TEXCOORD3;
+	float2 bumpCoord1 : TEXCOORD4;
+	float2 bumpCoord2 : TEXCOORD5;
+
+	float3 eyeVector  : TEXCOORD6;
+};
+
+// wave functions
+
+struct Wave {
+  float freq;  // 2*PI / wavelength
+  float amp;   // amplitude
+  float phase; // speed * 2*PI / wavelength
+  float2 dir;
+};
+
+v2f main(a2v IN,
+		uniform float4x4 WorldViewProj,
+		uniform float3 eyePosition,
+		uniform float BumpScale,
+		uniform float2 textureScale,
+		uniform float2 bumpSpeed,
+		uniform float time,
+		uniform float waveFreq,
+		uniform float waveAmp
+        )
+{
+	v2f OUT;
+
+	#define NWAVES 2
+	Wave wave[NWAVES] = {
+		{ 1.0, 1.0, 0.5, float2(-1, 0) },
+		{ 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
+	};
+
+    wave[0].freq = waveFreq;
+    wave[0].amp = waveAmp;
+
+    wave[1].freq = waveFreq * 3.0;
+    wave[1].amp = waveAmp * 0.33;
+
+    float4 P = IN.Position;
+
+	// sum waves
+	float ddx = 0.0, ddy = 0.0;
+	float deriv;
+	float angle;
+
+	// wave synthesis using two sine waves at different frequencies and phase shift
+	for(int i = 0; i<NWAVES; ++i)
+	{
+		angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
+		P.y += wave[i].amp * sin( angle );
+		// calculate derivate of wave function
+		deriv = wave[i].freq * wave[i].amp * cos(angle);
+		ddx -= deriv * wave[i].dir.x;
+		ddy -= deriv * wave[i].dir.y;
+	}
+
+	// compute the 3x3 transform from tangent space to object space
+	// first rows are the tangent and binormal scaled by the bump scale
+
+	OUT.rotMatrix1.xyz = BumpScale * normalize(float3(1, ddy, 0)); // Binormal
+	OUT.rotMatrix2.xyz = BumpScale * normalize(float3(0, ddx, 1)); // Tangent
+	OUT.rotMatrix3.xyz = normalize(float3(ddx, 1, ddy)); // Normal
+
+	OUT.Position = mul(WorldViewProj, P);
+
+	// calculate texture coordinates for normal map lookup
+	OUT.bumpCoord0.xy = IN.TexCoord*textureScale + time * bumpSpeed;
+	OUT.bumpCoord1.xy = IN.TexCoord*textureScale * 2.0 + time * bumpSpeed * 4.0;
+	OUT.bumpCoord2.xy = IN.TexCoord*textureScale * 4.0 + time * bumpSpeed * 8.0;
+
+	OUT.eyeVector = P.xyz - eyePosition; // eye position in vertex space
+	return OUT;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/OffsetMapping.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/OffsetMapping.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/OffsetMapping.cg	(revision 12083)
@@ -0,0 +1,84 @@
+/* Bump mapping with Parallax offset vertex program 
+   In this program, we want to calculate the tangent space light end eye vectors 
+   which will get passed to the fragment program to produce the per-pixel bump map 
+   with parallax offset effect. 
+*/
+
+#include "Common.cg"
+
+float4 lightPosition;
+float3 eyePosition;
+float4x4 worldViewProj;
+
+float3 lightDiffuse;
+float3 lightSpecular;
+float4 scaleBias;
+sampler2D normalHeightMap;
+sampler2D diffuseMap;
+
+struct app2vertOffsetMapping
+{
+    float4 position	: POSITION;
+    float3 normal	: NORMAL;
+    float2 uv		: TEXCOORD0;
+    float3 tangent      : TANGENT;
+};
+
+struct vert2fragOffsetMapping
+{
+    float4 position     : POSITION;
+    float2 uv		: TEXCOORD0;
+    float3 lightDir     : TEXCOORD1;
+    float3 eyeDir       : TEXCOORD2;
+    float3 halfAngle    : TEXCOORD3;
+};
+
+/* Vertex program that moves light and eye vectors into texture tangent space at vertex */ 
+
+vert2fragOffsetMapping main_vp(app2vertOffsetMapping IN) 
+{
+    vert2fragOffsetMapping OUT;
+
+    // calculate output position 
+    OUT.position = mul(worldViewProj, IN.position); 
+
+    // pass the main uvs straight through unchanged 
+    OUT.uv = IN.uv; 
+
+    half3 lightDir = getLightDirection(lightPosition, IN.position);
+    half3 eyeDir = getEyeDirection(eyePosition, IN.position);
+    
+    // Form a rotation matrix out of the vectors 
+    half3x3 TBN = getTBNMatrix(IN.tangent, IN.normal); 
+    
+    // Transform the light vector according to this matrix 
+    OUT.lightDir = normalize(mul(TBN, lightDir)); 
+    OUT.eyeDir = normalize(mul(TBN, eyeDir)); 
+
+    OUT.halfAngle = normalize(OUT.eyeDir + OUT.lightDir);
+
+    return OUT;
+}
+
+outPixel main_fp(vert2fragOffsetMapping IN)
+{
+    outPixel OUT;
+
+    half displacement = getDisplacement(normalHeightMap, IN.uv, scaleBias.x, scaleBias.y);
+	
+    float3 uv2 = float3(IN.uv, 1);
+	
+    // calculate the new tex coord to use for normal and diffuse
+    float2 newTexCoord = ((IN.eyeDir * displacement) + uv2).xy;
+	
+    // get the new normal and diffuse values
+    half3 normal = getNormalMapVector(normalHeightMap, newTexCoord);
+    half3 diffuse = tex2D(diffuseMap, newTexCoord).xyz;
+	
+    half3 specular = getSpecularComponent(normal, IN.halfAngle, lightSpecular, 32);
+    half3 col = diffuse * getLightingComponent(normal, IN.lightDir, lightDiffuse) + specular;
+		
+    OUT.colour = float4(col, 1);
+
+    return OUT;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/OldMovieFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/OldMovieFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/OldMovieFP.cg	(revision 12083)
@@ -0,0 +1,55 @@
+sampler2D RT : register(s0);
+sampler2D SplotchesTx : register(s1);
+sampler1D Texture2 : register(s2);
+sampler1D SepiaTx : register(s3);
+
+float2 calcSpriteAddr(float2 texCoord, float DirtFrequency1, float period)
+{
+   return texCoord + tex1D(Texture2, period  * DirtFrequency1).xy;
+}
+
+float4 getSplotches(float2 spriteAddr)
+{
+   // get sprite address into paged texture coords space
+   spriteAddr = spriteAddr / 6.3f;
+   //spriteAddr = spriteAddr - frac(spriteAddr);
+   spriteAddr = spriteAddr - (spriteAddr /33.3f);
+
+   return float4(1,1,1,1) * tex2D(SplotchesTx, spriteAddr).r;
+}
+
+float4 OldMovie_ps (float4 pos : POSITION, 
+        float2 texCoord  : TEXCOORD0,
+				uniform float time_cycle_period,
+				uniform float flicker,
+				uniform float DirtFrequency,
+				uniform float3 luminance,
+				uniform float frameJitter,
+				uniform float lumiShift
+				) : COLOR
+{
+
+   // get sprite address
+   float2 spriteAddr = calcSpriteAddr(texCoord, DirtFrequency, time_cycle_period);
+
+    // add some dark and light splotches to the film
+   float4 splotches = getSplotches(spriteAddr);
+   float4 specs = 1.0f - getSplotches(spriteAddr / 3.0f);
+
+   // convert color to base luminance
+   float4 base = tex2D(RT, texCoord + float2(0, spriteAddr.y * frameJitter));
+   float lumi = dot(base.rgb, luminance);
+   // randomly shift luminance
+   lumi -= spriteAddr.x * lumiShift;
+   // tone map luminance
+   base.rgb = tex1D(SepiaTx, lumi ).rgb;
+
+   // calc flicker speed
+   float darken = frac(flicker * time_cycle_period);
+
+   // we want darken to cycle between 0.6 and 1.0
+   darken = abs(darken - 0.5f) * 0.4f + 0.6f;
+   // composite dirt onto film
+   return base * splotches * darken + specs;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/OldTV.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/OldTV.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/OldTV.cg	(revision 12083)
@@ -0,0 +1,43 @@
+sampler2D Image: register(s0);
+sampler3D Rand: register(s1);
+sampler3D Noise: register(s2);
+
+float4 OldTV_ps(float4 posIn: POSITION, float2 img: TEXCOORD0,
+    uniform float distortionFreq: register(c3),
+    uniform float distortionScale: register(c4),
+    uniform float distortionRoll: register(c5),
+    uniform float interference: register(c7),
+    uniform float frameLimit: register(c8),
+    uniform float frameShape: register(c0),
+    uniform float frameSharpness: register(c1),
+    uniform float time_0_X: register(c2),
+    uniform float sin_time_0_X: register(c6)
+
+) : COLOR {
+   // Define a frame shape
+   float2 pos = abs((img - 0.5) * 2.0);
+   float f = (1 - pos.x * pos.x) * (1 - pos.y * pos.y);
+   float frame = saturate(frameSharpness * (pow(f, frameShape) - frameLimit));
+
+   // Interference ... just a texture filled with rand()
+   float4 rand = tex3D(Rand, float3(1.5 * pos, time_0_X));
+   rand -= float4(0.2,0.2,0.2,0.2);
+
+   // Some signed noise for the distortion effect
+   float4 noisy = tex3D(Noise, float3(0, 0.5 * pos.y, 0.1 * time_0_X));
+   noisy -= float4(0.5,0.5,0.5,0.5);
+
+   // Repeat a 1 - x^2 (0 < x < 1) curve and roll it with sinus.
+   float dst = frac(pos.y * distortionFreq + distortionRoll * sin_time_0_X);
+   dst *= (1 - dst);
+   // Make sure distortion is highest in the center of the image
+   dst /= 1 + distortionScale * abs(pos.y);
+
+   // ... and finally distort
+   img.x += distortionScale * noisy.x * dst;
+   float4 image = tex2D(Image, img);
+
+   // Combine frame, distorted image and interference
+   return frame * (interference * rand.x + image);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/ParticleGS.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/ParticleGS.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/ParticleGS.cg	(revision 12083)
@@ -0,0 +1,324 @@
+//
+// Explanation of different particle types
+//
+#define PT_LAUNCHER 0 //Firework Launcher - launches a PT_SHELL every so many seconds
+#define PT_SHELL    1 //Unexploded shell - flies from the origin and explodes into many PT_EMBERXs
+#define PT_EMBER1   2 //basic particle - after it's emitted from the shell, it dies
+#define PT_EMBER2   3 //after it's emitted, it explodes again into many PT_EMBER1s
+#define PT_EMBER3   4 //just a differently colored ember1
+#define P_SHELLLIFE 3.0
+#define P_EMBER1LIFE 2.5
+#define P_EMBER2LIFE 1.5
+#define P_EMBER3LIFE 2.0
+
+//These two were originally shader params, but they caused runtime errors
+#define NUM_EMBER_1S 30
+#define NUM_EMBER_2S 15
+#define NUM_EMBER_3S 10
+//This one was originally a variant, but this also causes runtime errors
+//#define MAX_EMBER_2S 15.0
+
+//
+// Generic particle motion handler
+//
+
+void GSGenericHandler( float3 Pos, float3 Vel, float Timer, float Type,
+						float elapsedTime, 
+						float3 frameGravity)
+{
+    Pos += Vel * elapsedTime;
+    Vel += frameGravity;
+    Timer -= elapsedTime;
+	if (Pos.y > -100)
+	{
+		emitVertex( Pos : POSITION, Vel : TEXCOORD2, Timer : TEXCOORD0, Type : TEXCOORD1);
+	}
+}
+
+//
+// Sample a random direction from our random texture
+//
+float3 RandomDir(float fOffset, float globalTime, sampler1D randomTex)
+{
+    float tCoord = (globalTime + fOffset) / 300.0;
+    return tex1D(randomTex, tCoord).rgb;
+}
+
+//
+// Launcher type particle handler
+//
+void GSLauncherHandler( float3 Pos, float3 Vel, float Timer, float Type, 
+						float elapsedTime, 
+						float globalTime, 
+						sampler1D randomTex,
+						float secondsPerFirework)
+{
+    if(Timer <= 0)
+    {
+        float3 vRandom = normalize( RandomDir( Type, globalTime, randomTex) );
+		//Give it more of an up bias
+        vRandom = normalize(vRandom + float3(0,2.5,0)); 
+		
+		//time to emit a new SHELL
+        float3 outputPos = Pos + Vel*elapsedTime;
+        float3 outputVel = Vel + vRandom*35.0;
+        float  outputTimer = P_SHELLLIFE + vRandom.y*0.5;
+        float outputType = PT_SHELL;
+        emitVertex(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
+        
+        //reset our timer
+        Timer = secondsPerFirework + vRandom.x*0.4;
+    }
+    else
+    {
+        Timer -= elapsedTime;
+    }
+    
+    //emit ourselves to keep us alive
+    emitVertex( Pos : POSITION, Vel : TEXCOORD2, Timer : TEXCOORD0, Type : TEXCOORD1);
+}
+
+//
+// Shell type particle handler
+//	
+void GSShellHandler( float3 Pos, float3 Vel, float Timer, float Type,
+					float elapsedTime, 
+					float globalTime, 
+					sampler1D randomTex,
+					float3 frameGravity)
+{
+    if(Timer <= 0)
+    {
+        float3 outputPos;
+		float3 outputVel;
+		float outputTimer;
+		float outputType;
+		
+        float3 vRandom = float3(0,0,0);
+        
+        //time to emit a series of new Ember1s  
+        for(int i=0; i<NUM_EMBER_1S; i++)
+        {
+            vRandom = normalize( RandomDir( Type+i, globalTime, randomTex ) );
+            outputPos = Pos + Vel*elapsedTime;
+            outputVel = Vel + vRandom*15.0;
+            outputTimer = P_EMBER1LIFE;
+            outputType = PT_EMBER1;
+            emitVertex(outputPos : POSITION, outputTimer : TEXCOORD0, outputType : TEXCOORD1, outputVel : TEXCOORD2);
+        }
+        
+        //find out how many Ember2s to emit
+		//Not doing this because it causes a runtime error
+		//int numEmber2s = abs(vRandom.x)*MAX_EMBER_2S;
+        for(int i=0; i<NUM_EMBER_2S; i++)
+        {
+            vRandom = normalize( RandomDir( Type, globalTime, randomTex) );
+            outputPos = Pos + Vel*elapsedTime;
+            outputVel = Vel + vRandom*10.0;
+            outputTimer = P_EMBER2LIFE + 0.4*vRandom.x;
+            outputType = PT_EMBER2;
+            emitVertex(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
+        }
+        
+    }
+    else
+    {
+        GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
+    }
+}
+
+//
+// Ember1 and Ember3 type particle handler
+//
+void GSEmber1Handler( float3 Pos, float3 Vel, float Timer, float Type,
+						float elapsedTime, 
+						float3 frameGravity)
+{
+    if(Timer > 0)
+    {
+        GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
+    }
+}
+
+//
+// Ember2 type particle handler
+//
+void GSEmber2Handler( float3 Pos, float3 Vel, float Timer, float Type,
+						float elapsedTime, 
+						float globalTime, 
+						sampler1D randomTex,
+						float3 frameGravity)
+{
+    if(Timer <= 0)
+    {
+		float3 outputPos;
+		float3 outputVel;
+		float outputTimer;
+		float outputType;
+    
+        //time to emit a series of new Ember3s  
+        for(int i=0; i<NUM_EMBER_3S; i++)
+        {
+            outputPos = Pos + Vel*elapsedTime;
+            outputVel = Vel + normalize( RandomDir( Type + i, globalTime, randomTex ) )*10.0;
+            outputTimer = P_EMBER3LIFE;
+            outputType = PT_EMBER3;
+            emitVertex(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
+        }
+    }
+    else
+    {
+         GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
+    }
+}
+
+struct FireworkData
+{
+	float4 	Pos 	: POSITION;
+	float 	Timer 	: TEXCOORD0;
+    float 	Type 	: TEXCOORD1;
+	float3	Velocity : TEXCOORD2;
+};
+
+//The vertex shader that prepares the fireworks for display
+FireworkData GenerateParticles_VS(
+    in float4 		inPos : POSITION,	
+	in float 		inTimer : TEXCOORD0,
+	in float 		inType : TEXCOORD1,
+	in float3 		inVelocity : TEXCOORD2
+	)
+{
+	FireworkData output;
+	output.Pos = inPos;
+	output.Timer = inTimer;
+	output.Type = inType;
+	output.Velocity = inVelocity;
+	
+	return output;
+}
+
+POINT
+POINT_OUT
+void GenerateParticles_GS(
+	AttribArray<float3> Pos : POSITION,
+	AttribArray<float> Timer : TEXCOORD0,
+	AttribArray<float> Type : TEXCOORD1,
+	AttribArray<float3> Vel : TEXCOORD2,
+	
+	uniform sampler1D randomTex : TEXUNIT0,
+	uniform float3 frameGravity,
+	uniform float globalTime,
+	uniform float elapsedTime,
+	uniform float secondsPerFirework
+	)
+{
+	if( Type[0] == PT_LAUNCHER )
+        GSLauncherHandler( Pos[0], Vel[0], Timer[0], Type[0], 
+							elapsedTime, globalTime, randomTex, secondsPerFirework);
+	else if ( Type[0] == PT_SHELL )
+        GSShellHandler( Pos[0], Vel[0], Timer[0], Type[0], 
+							elapsedTime, globalTime, randomTex, frameGravity);
+	else if ( Type[0] == PT_EMBER1 ||
+              Type[0] == PT_EMBER3 )
+       GSEmber1Handler( Pos[0], Vel[0], Timer[0], Type[0], 
+							elapsedTime, frameGravity);
+    else if( Type[0] == PT_EMBER2 )
+        GSEmber2Handler( Pos[0], Vel[0], Timer[0], Type[0], 
+							elapsedTime, globalTime, randomTex, frameGravity);
+}
+
+struct ColoredFirework
+{
+	float3 	pos : POSITION;
+    float4 	color : COLOR;
+	float	radius : TEXCOORD0;
+};
+
+//The vertex shader that prepares the fireworks for display
+ColoredFirework DisplayParticles_VS
+(
+    in float3 		inPos : POSITION,
+	in float 		inTimer : TEXCOORD0,
+	in float 		inType : TEXCOORD1,
+	in float3 		inVelocity : TEXCOORD2
+	
+
+    //uniform float4x4 worldViewProj
+)
+{
+	ColoredFirework output;
+    //
+    // Pass the point through
+    //
+    output.pos = inPos; //Multiply by world matrix?
+    output.radius = 1.5;
+    
+    //  
+    // calculate the color
+    //
+    if( inType == PT_LAUNCHER )
+    {
+        output.color = float4(1,0.1,0.1,1);
+        output.radius = 1.0;
+    }
+    else if( inType == PT_SHELL )
+    {
+        output.color = float4(0.1,1,1,1);
+        output.radius = 1.0;
+    }
+    else if( inType == PT_EMBER1 )
+    {
+        output.color = float4(1,1,0.1,1);
+        output.color *= (inTimer / P_EMBER1LIFE );
+    }
+    else if( inType == PT_EMBER2 )
+    {
+        output.color = float4(1,0.1,1,1);
+    }
+    else if( inType == PT_EMBER3 )
+    {
+        output.color = float4(1,0.1,0.1,1);
+        output.color *= (inTimer / P_EMBER3LIFE );
+    }
+    
+    return output;
+}
+
+//The geometry shader that prepares the fireworks for display
+POINT 
+TRIANGLE_OUT 
+void DisplayParticles_GS( AttribArray<float3> Pos : POSITION,
+							AttribArray<float4> Color : COLOR,
+							AttribArray<float> Radius : TEXCOORD0,
+							
+							uniform float4x4 inverseView,
+							uniform float4x4 worldViewProj)
+{
+	//float3 g_positions[4] = { float3( -1, 1, 0 ), float3( 1, 1, 0 ), float3( -1, -1, 0 ), float3( 1, -1, 0 ) };
+	float3 g_positions[4] = { float3( -1, 1, 0 ), float3( -1, -1, 0 ), float3( 1, 1, 0 ), float3( 1, -1, 0 ) };
+    float2 g_texcoords[4] = { float2(0,1), float2(1,1), float2(0,0), float2(1,0) };
+	
+	
+	//
+    // Emit two new triangles
+    //
+    for(int i=0; i<4; i++)
+    {
+		float3 position = -g_positions[i]*Radius[0];
+        position = mul( (float3x3)inverseView, position ) + Pos[0];
+        float4 outPos = mul( worldViewProj, float4(position,1.0) );
+        
+        emitVertex(outPos : POSITION, Color[0] : COLOR0, g_texcoords[i] : TEXCOORD0);
+    }
+    restartStrip();
+}
+
+//The pixels shaders that colors the fireworks
+float4 DisplayParticles_PS(	float2 iTexCoord : TEXCOORD0,
+							float4 iColor : COLOR0,
+							uniform sampler diffuseTex : register(s0)) : COLOR
+{
+	return tex2D(diffuseTex, iTexCoord) * iColor;
+	//return float4(iTexCoord.x, iTexCoord.y, 0, 1) + iColor * 0.01;
+	//return float4(iTexCoord.xy, 0, 1) * 0.3 + tex2D(diffuseTex, iTexCoord) * 0.7 + iColor * 0.01;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/PassthroughFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/PassthroughFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/PassthroughFP.cg	(revision 12083)
@@ -0,0 +1,14 @@
+float4 main (float4 pos : POSITION, uniform float4 colour) : COLOR
+{
+	return colour;
+}
+
+float4 mainCg (float4 colour0 : COLOR) : COLOR
+{
+    return colour0;
+}
+
+float4 mainForAmbientOneTexture (float4 pos : POSITION, float2 oUv : TEXCOORD0, float4 colour0 : COLOR, uniform float4 colour) : COLOR
+{
+	return colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/PassthroughFP_sm4.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/PassthroughFP_sm4.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/PassthroughFP_sm4.cg	(revision 12083)
@@ -0,0 +1,16 @@
+float4 main (float4 pos			: SV_POSITION, 
+			 float2 oUv			: TEXCOORD0,
+			 float4 colour		: COLOR) : COLOR
+{
+	return colour;
+}
+
+float4 mainCg (float4 pos : SV_POSITION, float4 colour0 : COLOR) : COLOR
+{
+    return colour0;
+}
+
+float4 mainForAmbientOneTexture (float4 pos : SV_POSITION, float2 oUv : TEXCOORD0, float4 colour0 : COLOR, uniform float4 colour) : COLOR
+{
+	return colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/PosterizeFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/PosterizeFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/PosterizeFP.cg	(revision 12083)
@@ -0,0 +1,17 @@
+sampler2D RT : register(s0);
+
+float4 Posterize_ps (float4 pos : POSITION, float2 iTexCoord : TEXCOORD0) : COLOR
+{
+
+	float nColors = 8;
+	float gamma = 0.6;
+
+	float4 texCol = tex2D(RT, iTexCoord);
+	float3 tc = texCol.xyz;
+	tc = pow(tc, gamma);
+	tc = tc * nColors;
+	tc = floor(tc);
+	tc = tc / nColors;
+	tc = pow(tc,1.0/gamma);
+	return float4(tc,texCol.w);
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Radial_Blur_FP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Radial_Blur_FP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Radial_Blur_FP.cg	(revision 12083)
@@ -0,0 +1,58 @@
+//------------------------------------------------------
+//Radial_Blur_FP.cg
+//  Implements radial blur to be used with the compositor
+//  It's very dependent on screen resolution
+//------------------------------------------------------
+
+uniform sampler2D tex: register(s0);
+
+static const float samples[10] =
+{
+-0.08,
+-0.05,
+-0.03,
+-0.02,
+-0.01,
+0.01,
+0.02,
+0.03,
+0.05,
+0.08
+};
+
+float4 main(float4 Pos : POSITION,
+            float2 texCoord: TEXCOORD0,
+            uniform float sampleDist,
+            uniform float sampleStrength
+           ) : COLOR
+{
+   //Vector from pixel to the center of the screen
+   float2 dir = 0.5 - texCoord;
+
+   //Distance from pixel to the center (distant pixels have stronger effect)
+   //float dist = distance( float2( 0.5, 0.5 ), texCoord );
+   float dist = sqrt( dir.x*dir.x + dir.y*dir.y );
+
+
+   //Now that we have dist, we can normlize vector
+   dir = normalize( dir );
+
+   //Save the color to be used later
+   float4 color = tex2D( tex, texCoord );
+   //Average the pixels going along the vector
+   float4 sum = color;
+   for (int i = 0; i < 10; i++)
+   {
+      float4 res=tex2D( tex, texCoord + dir * samples[i] * sampleDist );
+      sum += res;
+   }
+   sum /= 11;
+
+   //Calculate amount of blur based on
+   //distance and a strength parameter
+   float t = dist * sampleStrength;
+   t = saturate( t );//We need 0 <= t <= 1
+
+   //Blend the original color with the averaged pixels
+   return lerp( color, sum, t );
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/ShaderInstancing.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/ShaderInstancing.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/ShaderInstancing.cg	(revision 12083)
@@ -0,0 +1,101 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+//---------------------------------------------
+//Vertex Shader Input
+//---------------------------------------------
+struct VS_INPUT
+{
+	float4 Position	:	POSITION;
+	float3 Normal	:	NORMAL;
+	float3 Tangent	:	TANGENT;
+	float2 uv0	:	TEXCOORD0;
+
+	float4 BlendIdx	:	BLENDINDICES;
+	float4 BlendWgt	:	BLENDWEIGHT;
+};
+
+#include "InstancingVertexInterpolators.cg"
+#ifdef ST_DUAL_QUATERNION
+#include "DualQuaternion_Common.cg"
+#endif
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+VS_OUTPUT main_vs( in VS_INPUT input,
+				   uniform float4x4 viewProjMatrix,
+#ifdef ST_DUAL_QUATERNION
+				   uniform float2x4 worldDualQuaternion2x4Array[120]
+#else
+				   uniform float3x4 worldMatrix3x4Array[80]
+#endif
+#if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER )
+				,  uniform float4 depthRange
+#endif
+#ifdef DEPTH_SHADOWRECEIVER
+				,  uniform float4x4 texViewProjMatrix
+#endif
+				   )
+{
+	VS_OUTPUT output;
+
+	float4 worldPos	 = 0;
+	float3 worldNorm = 0;
+
+	int idx = int(input.BlendIdx[0]);
+#ifdef ST_DUAL_QUATERNION
+	//Only dealing with one weight so normalization of the dual quaternion and weighting are unnecessary
+	float2x4 blendDQ = worldDualQuaternion2x4Array[idx];
+#ifdef BONE_TWO_WEIGHTS
+	float2x4 blendDQ2 = worldDualQuaternion2x4Array[int(input.BlendIdx[1])];
+	
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= input.BlendWgt.x;
+	blendDQ += input.BlendWgt.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = float4(calculateBlendPosition(input.Position.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(input.Normal, blendDQ);
+#else
+	worldPos  = float4( mul( worldMatrix3x4Array[idx], input.Position ).xyz, 1.0f );
+	worldNorm = mul( (float3x3)(worldMatrix3x4Array[idx]), input.Normal );
+#endif
+
+	/*int i;
+	for( i=0; i<4; i++ )
+	{
+		int idx = int(input.BlendIdx[0]);
+		worldPos += float4( mul( worldMatrix3x4Array[idx], input.Position ).xyz, 1.0f ) * input.BlendWgt[i];
+		worldNorm += mul( (float3x3)(worldMatrix3x4Array[idx]), input.Normal ) * input.BlendWgt[i];
+	}*/
+
+	//Transform the position
+	output.Position		= mul( viewProjMatrix, worldPos );
+	
+#ifdef DEPTH_SHADOWCASTER
+	output.ps.unused	= float3( 0 );
+	output.ps.depth		= (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w;
+#else
+	output.ps.uv0		= input.uv0;
+	
+	//Pass Normal and position for Blinn Phong lighting
+	output.ps.Normal	= normalize(worldNorm);
+	output.ps.vPos		= worldPos.xyz;
+
+	#ifdef DEPTH_SHADOWRECEIVER
+		// Calculate the position of vertex in light space to do shadows
+		output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos );
+		// make linear
+		output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+
+	return output;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/SharpenEdgesFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/SharpenEdgesFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/SharpenEdgesFP.cg	(revision 12083)
@@ -0,0 +1,23 @@
+sampler2D RT: register(s0);
+
+float4 sharpenEdges_fp( float4 pos : POSITION, float2 iTexCoord: TEXCOORD0, uniform float2 vTexelSize) : COLOR
+{
+
+	float2 usedTexelED[8] = {
+		-1, -1,
+		 0, -1,
+		 1, -1,
+		-1,  0,
+		 1,  0,
+		-1,  1,
+		 0,  1,
+	     1,  1,
+	};
+
+	float4 cAvgColor= 9 * tex2D (RT, iTexCoord);
+
+	for(int t=0; t<8; t++)
+		cAvgColor -= tex2D(RT, iTexCoord + vTexelSize * usedTexelED[t]);
+
+	return cAvgColor;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/StdQuad_vp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/StdQuad_vp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/StdQuad_vp.cg	(revision 12083)
@@ -0,0 +1,113 @@
+void StdQuad_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+}
+
+void StdQuad_Tex2_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = uv0;
+}
+
+void StdQuad_Tex2a_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = inPos.xy;
+}
+
+void StdQuad_Tex3_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+    out float2 uv2 : TEXCOORD2,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = uv0;
+    uv2 = uv0;
+}
+
+void StdQuad_Tex4_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+    out float2 uv2 : TEXCOORD2,
+    out float2 uv3 : TEXCOORD3,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = uv0;
+    uv2 = uv0;
+    uv3 = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/Swizzle.gp
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/Swizzle.gp	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/Swizzle.gp	(revision 12083)
@@ -0,0 +1,39 @@
+!!NVgp4.0
+PRIMITIVE_IN TRIANGLES;
+PRIMITIVE_OUT TRIANGLE_STRIP;
+VERTICES_OUT 6;
+# cgc version 2.0.0015, build date May 15 2008
+# command line args: -profile gpu_gp
+# source file: gs_simple.cg
+#vendor NVIDIA Corporation
+#version 2.0.0.15
+#profile gpu_gp
+#program geometry_swizzle
+#semantic geometry_swizzle.position : POSITION
+#var float4 position.__data[0] : $vin.VERTEX[0].POSITION : HPOS[0][32] : 0 : 1
+#var float4 position.__data[1] : $vin.VERTEX[1].POSITION : HPOS[1][32] : 0 : 1
+#var float4 position.__data[2] : $vin.VERTEX[2].POSITION : HPOS[2][32] : 0 : 1
+ATTRIB vertex_position = vertex.position;
+TEMP RC, HC;
+MOV.F result.position, vertex[0].position;
+MOV.F result.color, {1, 0}.xyyx;
+EMIT;
+MOV.F result.position, vertex[1].position;
+MOV.F result.color, {1, 0}.xyyx;
+EMIT;
+MOV.F result.position, vertex[2].position;
+MOV.F result.color, {1, 0}.xyyx;
+EMIT;
+ENDPRIM;
+MOV.F result.position, vertex[0].position.yxzw;
+MOV.F result.color, {0, 1}.xxyy;
+EMIT;
+MOV.F result.position, vertex[1].position.yxzw;
+MOV.F result.color, {0, 1}.xxyy;
+EMIT;
+MOV.F result.position, vertex[2].position.yxzw;
+MOV.F result.color, {0, 1}.xxyy;
+EMIT;
+ENDPRIM;
+END
+# 20 instructions, 0 R-regs
Index: /data/branches/Shader_HS18/programs/Example/Cg/SwizzleGP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/SwizzleGP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/SwizzleGP.cg	(revision 12083)
@@ -0,0 +1,14 @@
+// Geometry pass-through program for colored triangles
+TRIANGLE void gs_swizzle(AttribArray<float4> position : POSITION)
+{
+  for (int i=0; i<position.length; i++) {
+    emitVertex(position[i], float4(1,0.9,0.8,0.7):COLOR0);
+  }
+  restartStrip();
+  for (int i=0; i<position.length; i++) {
+    float4 newPosition = position[i].yxzw;
+	newPosition.z += 20;
+	emitVertex(newPosition:POSITION, float4(0.3,0.4,0.5,0.6):COLOR0);
+  }
+  restartStrip();
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/TilingFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/TilingFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/TilingFP.cg	(revision 12083)
@@ -0,0 +1,33 @@
+sampler2D RT : register(s0);
+
+float4 Tiling_ps(float4 inPos : POSITION,
+				float2 iTexCoord : TEXCOORD0,
+				uniform half NumTiles,
+				uniform half Threshold) : COLOR
+{
+
+
+	half3 EdgeColor = {0.7, 0.7, 0.7};
+
+    half size = 1.0/NumTiles;
+    half2 Pbase = iTexCoord - fmod(iTexCoord, size.xx);
+    half2 PCenter = Pbase + (size/2.0).xx;
+    half2 st = (iTexCoord - Pbase)/size;
+    half4 c1 = (half4)0;
+    half4 c2 = (half4)0;
+    half4 invOff = half4((1-EdgeColor),1);
+    if (st.x > st.y) { c1 = invOff; }
+    half threshholdB =  1.0 - Threshold;
+    if (st.x > threshholdB) { c2 = c1; }
+    if (st.y > threshholdB) { c2 = c1; }
+    half4 cBottom = c2;
+    c1 = (half4)0;
+    c2 = (half4)0;
+    if (st.x > st.y) { c1 = invOff; }
+    if (st.x < Threshold) { c2 = c1; }
+    if (st.y < Threshold) { c2 = c1; }
+    half4 cTop = c2;
+    half4 tileColor = tex2D(RT, PCenter);
+    half4 result = tileColor + cTop - cBottom;
+    return result;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/VTFInstancing.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/VTFInstancing.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/VTFInstancing.cg	(revision 12083)
@@ -0,0 +1,107 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+//---------------------------------------------
+//Vertex Shader Input
+//---------------------------------------------
+struct VS_INPUT
+{
+	float4 Position	:	POSITION;
+	float3 Normal	:	NORMAL;
+	float3 Tangent	:	TANGENT;
+#ifdef BONE_TWO_WEIGHTS
+	float4 weights		: 	BLENDWEIGHT;
+#endif
+	float2 uv0		:	TEXCOORD0;
+
+	float4 m01		:	TEXCOORD1;
+	float4 m23		:	TEXCOORD2;
+};
+
+#include "InstancingVertexInterpolators.cg"
+#ifdef ST_DUAL_QUATERNION
+#include "DualQuaternion_Common.cg"
+#endif
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+VS_OUTPUT main_vs( in VS_INPUT input,
+				   uniform float4x4 viewProjMatrix,
+				   
+#ifdef DEPTH_SHADOWCASTER
+				   uniform sampler2D matrixTexture : register(s0)
+#else
+				   uniform sampler2D matrixTexture : register(s2)
+#endif
+
+#if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER )
+				,  uniform float4 depthRange
+#endif
+#ifdef DEPTH_SHADOWRECEIVER
+				,  uniform float4x4 texViewProjMatrix
+#endif
+				)
+{
+	VS_OUTPUT output;
+
+	float4 worldPos	 = 0;
+	float3 worldNorm = 0;
+
+#ifdef ST_DUAL_QUATERNION
+	float2x4 blendDQ;	
+	blendDQ[0] = tex2D( matrixTexture, input.m01.xy );
+	blendDQ[1] = tex2D( matrixTexture, input.m01.zw );
+#ifdef BONE_TWO_WEIGHTS
+	float2x4 blendDQ2;
+	//Use the empty parts of m03, z and w, for the second dual quaternion
+	blendDQ2[0] = tex2D( matrixTexture, input.m23.xy );
+	blendDQ2[1] = tex2D( matrixTexture, input.m23.zw );
+	
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= input.weights.x;
+	blendDQ += input.weights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	//Only dealing with one weight so normalization of the dual quaternion and weighting are unnecessary
+	worldPos = float4(calculateBlendPosition(input.Position.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(input.Normal.xyz, blendDQ);
+#else
+	float3x4 worldMatrix;
+	worldMatrix[0] = tex2D( matrixTexture, input.m01.xy );
+	worldMatrix[1] = tex2D( matrixTexture, input.m01.zw );
+	worldMatrix[2] = tex2D( matrixTexture, input.m23.xy );
+
+	worldPos = float4( mul( worldMatrix, input.Position ).xyz, 1.0f );
+	worldNorm= mul( (float3x3)(worldMatrix), input.Normal );
+#endif
+
+	//Transform the position
+	output.Position		= mul( viewProjMatrix, worldPos );
+
+#ifdef DEPTH_SHADOWCASTER
+	output.ps.unused	= float3( 0 );
+	output.ps.depth		= (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w;
+#else
+	output.ps.uv0		= input.uv0;
+
+	//Pass Normal and position for Blinn Phong lighting
+	output.ps.Normal	= normalize(worldNorm);
+	output.ps.vPos		= worldPos.xyz;
+	
+	#ifdef DEPTH_SHADOWRECEIVER
+		// Calculate the position of vertex in light space to do shadows
+		output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos );
+		// make linear
+		output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+
+	return output;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/depthshadowobject.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/depthshadowobject.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/depthshadowobject.cg	(revision 12083)
@@ -0,0 +1,185 @@
+/* Copyright Torus Knot Software Ltd 2000-2013
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#include "shadows.cg"
+
+#define BIAS 0
+
+struct VS_OUT
+{
+    float4  pos			  : POSITION;   
+    float3  diffuseUV     : TEXCOORD0;  // xy = UV, z = fog/depth
+#if !SHADOWCASTER
+	float3	col			  : COLOR;
+#endif
+#if DEPTH_SHADOWCASTER
+	float	depth		  : TEXCOORD1;
+#endif
+#if DEPTH_SHADOWRECEIVER
+	float4 lightSpacePos0	: TEXCOORD2;
+	float4 lightSpacePos1	: TEXCOORD3;
+	float4 lightSpacePos2	: TEXCOORD4;
+#endif
+};
+
+VS_OUT main_vp(
+	float4   pos	: POSITION,     
+    float3   normal	: NORMAL,    
+    float4   uv0	: TEXCOORD0,
+
+   	uniform float4x4 worldViewProj,
+	uniform float4 lightPosition,
+	uniform float3 lightDiffuse
+#if FOG
+	, uniform float2 fogParams		// x = fog start, y = fog distance
+#endif
+#if DEPTH_SHADOWCASTER
+	, uniform float4 depthRange // x = min, y = max, z = range, w = 1/range
+#elif DEPTH_SHADOWRECEIVER
+	, uniform float4 depthRange0 // x = min, y = max, z = range, w = 1/range
+	, uniform float4 depthRange1 // x = min, y = max, z = range, w = 1/range
+	, uniform float4 depthRange2 // x = min, y = max, z = range, w = 1/range
+#endif
+#if DEPTH_SHADOWRECEIVER
+	, uniform float4x4 texWorldViewProjMatrix0
+	, uniform float4x4 texWorldViewProjMatrix1
+	, uniform float4x4 texWorldViewProjMatrix2
+#endif
+
+	)
+{
+    VS_OUT outp;
+
+    // project position to the screen
+    outp.pos = mul(worldViewProj, pos);
+
+#if !SHADOWCASTER
+	// Get object space light direction
+	float3 lightDir = normalize(lightPosition.xyz - (pos.xyz * lightPosition.w).xyz);
+	outp.col = lightDiffuse.xyz * max(dot(lightDir, normal.xyz), 0.0);
+#  if FOG
+    outp.diffuseUV.z = linearFog(outp.pos.z, fogParams.x, fogParams.y);
+#  endif
+
+#endif
+
+    // pass through other texcoords exactly as they were received
+    outp.diffuseUV.xy = uv0.xy;
+    
+
+#if DEPTH_SHADOWCASTER
+	outp.depth = (BIAS + outp.pos.z - depthRange.x) * depthRange.w;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+	// Calculate the position of vertex in light space
+	outp.lightSpacePos0 = mul(texWorldViewProjMatrix0, pos);
+	outp.lightSpacePos1 = mul(texWorldViewProjMatrix1, pos);
+	outp.lightSpacePos2 = mul(texWorldViewProjMatrix2, pos);
+
+	// make linear
+	outp.lightSpacePos0.z = (outp.lightSpacePos0.z - depthRange0.x) * depthRange0.w;
+	outp.lightSpacePos1.z = (outp.lightSpacePos1.z - depthRange1.x) * depthRange1.w;
+	outp.lightSpacePos2.z = (outp.lightSpacePos2.z - depthRange2.x) * depthRange2.w;
+
+	// pass cam depth
+	outp.diffuseUV.z = outp.pos.z;
+
+#endif
+
+    return outp;
+}
+
+
+float4 main_fp(
+	VS_OUT In,
+
+	uniform sampler2D diffuseMap	: register(s0),
+#if DEPTH_SHADOWRECEIVER
+	uniform sampler2D shadowMap0 : register(s1),
+	uniform sampler2D shadowMap1 : register(s2),
+	uniform sampler2D shadowMap2 : register(s3),
+#endif
+
+	uniform float3 materialAmbient
+	
+#if SHADOWCASTER
+	, uniform float3 shadowColour
+#endif
+#if FOG
+	, uniform float3 fogColour
+#endif
+#if DEPTH_SHADOWRECEIVER
+	, uniform float inverseShadowmapSize0
+	, uniform float inverseShadowmapSize1
+	, uniform float inverseShadowmapSize2
+	, uniform float4 pssmSplitPoints
+#endif
+
+	) : COLOR
+{
+
+    // look up the diffuse map layer
+    float4 texDiffuse = tex2D(diffuseMap, In.diffuseUV.xy);
+    
+#if SHADOWCASTER
+#  if DEPTH_SHADOWCASTER
+	// early-out with depth (we still include alpha for those cards that support it)
+	return float4(In.depth.xxx, 1);
+#  else
+	return float4(shadowColour.xyz, texDiffuse.a);
+#  endif
+
+#else
+    // compute the ambient contribution (pulled from the diffuse map)
+    float3 vAmbient = texDiffuse.xyz * materialAmbient.xyz;
+    float3 vColor3 = texDiffuse.rgb * In.col.rgb;
+
+#  if DEPTH_SHADOWRECEIVER
+	float camDepth = In.diffuseUV.z;
+	float shadow = calcPSSMDepthShadow(shadowMap0, shadowMap1, shadowMap2, 
+		In.lightSpacePos0, In.lightSpacePos1, In.lightSpacePos2,
+		inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2,
+		pssmSplitPoints, camDepth);
+	vColor3 *= shadow;
+	/*
+	vAmbient = float3(0,0,0);
+	vColor3 = calcPSSMDebugShadow(shadowMap0, shadowMap1, shadowMap2, 
+		In.lightSpacePos0, In.lightSpacePos1, In.lightSpacePos2,
+		inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2,
+		pssmSplitPoints, camDepth);
+	*/
+#  endif    
+
+	float4 vColor;
+    vColor = float4(vColor3 + vAmbient, texDiffuse.a);
+    
+#  if FOG
+    // if fog is active, interpolate between the unfogged color and the fog color
+    // based on vertex shader fog value
+    vColor.rgb = lerp(vColor.rgb, fogColour, In.diffuseUV.z).rgb;
+#  endif
+
+    return vColor;
+#endif
+
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/hdr.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/hdr.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/hdr.cg	(revision 12083)
@@ -0,0 +1,25 @@
+void morningskybox_fp (
+	float2 uv : TEXCOORD0,
+	out float4 colour : COLOR,
+
+	uniform sampler2D tex : register(s0) )
+{
+	colour = tex2D(tex, uv);
+
+	// blow out the light a bit
+	colour *= 1.7;
+}
+void morningcubemap_fp (
+	float3 uv : TEXCOORD0,
+	out float4 colour : COLOR,
+
+	uniform samplerCUBE tex : register(s0) )
+{
+	colour = texCUBE(tex, uv);
+
+	// blow out the light a bit
+	colour *= 1.7;
+}
+
+
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/instancing.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/instancing.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/instancing.cg	(revision 12083)
@@ -0,0 +1,125 @@
+
+
+void instancing_vp(uniform float3x4   worldMatrix3x4Array[80], float4 position : POSITION,
+						float3 normal : NORMAL,
+						float2 uv : TEXCOORD0,
+						float index : TEXCOORD1,
+						uniform float4x4 viewProjectionMatrix,
+						uniform float4 lightPos,
+						uniform float4 ambient,
+						uniform float4 lightDiffuseColour,
+						out float4 oPosition : POSITION,
+						out float2 oUv : TEXCOORD0,
+						out float4 Color : COLOR )
+{
+	// transform by indexed matrix
+	float4 transformedPos = float4(mul(worldMatrix3x4Array[index], position).xyz, 1.0);
+	
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, transformedPos);
+	oUv = uv;
+
+	float3 norm = mul((float3x3)worldMatrix3x4Array[index], normal);
+	
+	float3 lightDir = 	normalize(
+		lightPos.xyz -  (transformedPos.xyz * lightPos.w));
+
+	Color = ambient + saturate(dot(lightDir, norm)) * lightDiffuseColour;
+	
+	
+}
+
+/*
+  Instancing shadow-caster pass
+*/
+void instancingCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float index     : TEXCOORD1,
+
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 80 bones of float3x4
+	uniform float3x4   worldMatrix3x4Array[80],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 transformedPos = float4(mul(worldMatrix3x4Array[index], position).xyz, 1.0);
+
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, transformedPos);
+	
+	colour = ambient;
+	
+}
+void crowd_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4  blendIdx : BLENDINDICES,
+	float4	blendWgt : BLENDWEIGHT,
+	float   index : TEXCOORD1,
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 20 bones of float3x4
+	// vs_2_0 only supports 256 params so more than this is not feasible
+	uniform float4x4 viewProjectionMatrix,
+	uniform float numBones,
+	uniform float3x4   worldMatrix3x4Array[80],
+	uniform float4 lightDiffuseColour,
+	uniform float4 ambient,
+	uniform float4 lightPos)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 4; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[index*numBones+blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	oUv = uv;
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 4; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[index*numBones+blendIdx[i]], normal)* blendWgt[i];
+	}
+	float3 lightDir = 	normalize(
+		lightPos.xyz -  (blendPos.xyz * lightPos.w));
+
+	colour = ambient + saturate(dot(lightDir, norm)) * lightDiffuseColour;
+
+	
+}
+
+/*
+  Single-weight-per-vertex hardware skinning, shadow-caster pass
+*/
+void crowdCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float  blendIdx : BLENDINDICES,
+	float index     : TEXCOORD1,
+
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[80],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float numBones,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[index*numBones+blendIdx], position).xyz, 1.0);
+
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+	colour = ambient;
+	
+}	
Index: /data/branches/Shader_HS18/programs/Example/Cg/isosurf.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/isosurf.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/isosurf.cg	(revision 12083)
@@ -0,0 +1,155 @@
+// Ogre port of Nvidia's IsoSurf.cg file
+// Modified code follows. See http://developer.download.nvidia.com/SDK/10/opengl/samples.html for original
+//
+// Cg port of Yury Uralsky's metaball FX shader
+//
+// Authors: Simon Green and Yury Urlasky
+// Email: sdkfeedback@nvidia.com
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct SampleData
+{
+	float4 Pos   : POSITION;
+	float3 N     : TEXCOORD0;
+	float2 Field : TEXCOORD1;
+	float4 Color : COLOR0;
+};
+
+struct SurfaceVertex
+{
+	float4 Pos	: POSITION;
+	float3 N	: TEXCOORD0;
+};
+
+uniform int Num_Metaballs = 2;
+uniform float4 Metaballs[] = {
+	{ -0.5, 0, 0, 0.2 },
+	{ 0.6, 0, 0, 0.4 },
+};
+
+// Size of the sampling grid
+uniform int3 SizeMask = { 63, 63, 63 };
+uniform int3 SizeShift = { 0, 6, 12 };
+
+uniform float IsoValue = 1.0;
+
+// Metaball function
+// Returns metaball function value in .w and its gradient in .xyz
+
+float4 Metaball(float3 Pos, float3 Center, float RadiusSq)
+{
+	float epsilon = 0.001;
+
+	float3 Dist = Pos - Center;
+	float InvDistSq = 1 / (dot(Dist, Dist) + epsilon);
+
+	float4 o;
+	o.xyz = -2 * RadiusSq * InvDistSq * InvDistSq * Dist;
+	o.w = RadiusSq * InvDistSq;
+	return o;
+}
+
+// Vertex shader
+SampleData mainVS(float4 pos : POSITION,
+						uniform float4x4 WorldViewProj,
+						uniform float4x4 origWorldViewIT)
+{
+	SampleData o;
+	
+	// Sum up contributions from all metaballs
+	float4 Field = 0;
+	for (int i = 0; i<2; i++) 
+	{
+		Field += Metaball(pos.xyz, Metaballs[i].xyz, Metaballs[i].w);
+	}
+	
+	float3x3 WorldViewIT = { origWorldViewIT[0].xyz, origWorldViewIT[1].xyz, origWorldViewIT[2].xyz };
+	
+	// Transform position and normals
+	o.Pos = mul(WorldViewProj, pos);
+	o.N = mul(WorldViewIT, Field.xyz);	// we want normals in world space
+	o.Field.x = Field.w;
+	
+	// Generate in-out flags
+	o.Field.y = (Field.w < IsoValue) ? 1 : 0;
+
+	o.Color = (Field*0.5+0.5) * (Field.w / 10.0);
+	return o;
+}
+
+
+
+// Estimate where isosurface intersects grid edge with endpoints v0, v1
+void CalcIntersection(float4 Pos0,
+					  float3 N0,
+					  float2 Field0,
+					  float4 Pos1,
+					  float3 N1,
+					  float2 Field1)
+{
+	float t = (IsoValue - Field0.x) / (Field1.x - Field0.x);
+	if ((Field0.x < IsoValue) && (Field1.x > Field0.x))
+	{
+		if (t > 0 && t < 1)
+		{
+			float4 Pos = lerp(Pos0, Pos1, t);
+			float3 N = lerp(N0, N1, t);
+			emitVertex(Pos : POSITION, N : TEXCOORD0);
+		}
+	}
+}
+	
+// Geometry shader
+// input: line with adjacency (tetrahedron)
+// outputs: zero, one or two triangles depending if isosurface intersects tetrahedron
+LINE_ADJ
+TRIANGLE_OUT
+void mainGS(
+	AttribArray<float4> Pos : POSITION,
+	AttribArray<float3> N : TEXCOORD0,
+	AttribArray<float2> Field : TEXCOORD1
+	)
+{
+	// construct index for this tetrahedron
+	unsigned int index = (int(Field[0].y) << 3) |
+				(int(Field[1].y) << 2) |
+				(int(Field[2].y) << 1) |
+				 int(Field[3].y);
+	
+	// don't bother if all vertices out or all vertices inside isosurface
+	if (index > 0 && index < 15)
+	{
+		//Uber-compressed version of the edge table.
+		unsigned int edgeListHex[] = 
+			{0x0001cde0, 0x98b08c9d, 0x674046ce, 0x487bc480, 
+			0x21301d2e, 0x139bd910, 0x26376e20, 0x3b700000};
+		
+		unsigned int edgeValFull = edgeListHex[index/2];
+		unsigned int edgeVal = (index % 2 == 1) ? (edgeValFull & 0xFFFF) : ((edgeValFull >> 16) & 0xFFFF);
+		int4 e0 = int4((edgeVal >> 14) & 0x3, (edgeVal >> 12) & 0x3, (edgeVal >> 10) & 0x3, (edgeVal >> 8) & 0x3);
+		int4 e1 = int4((edgeVal >> 6) & 0x3, (edgeVal >> 4) & 0x3, (edgeVal >> 2) & 0x3, (edgeVal >> 0) & 0x3);
+		
+		CalcIntersection(Pos[e0.x], N[e0.x], Field[e0.x], Pos[e0.y], N[e0.y], Field[e0.y]);
+		CalcIntersection(Pos[e0.z], N[e0.z], Field[e0.z], Pos[e0.w], N[e0.w], Field[e0.w]);
+		CalcIntersection(Pos[e1.x], N[e1.x], Field[e1.x], Pos[e1.y], N[e1.y], Field[e1.y]);
+
+		// Emit additional triangle, if necessary
+		if (e1.z != -1) {
+			CalcIntersection(Pos[e1.z], N[e1.z], Field[e1.z], Pos[e1.w], N[e1.w], Field[e1.w]);
+		}
+	}
+}
+
+// Pixel shader
+float4 mainPS(float3 N : TEXCOORD0) : COLOR
+{
+	//Sanitize input
+	N = normalize(N);
+	float3 L = float3(0, 0, 1);
+	//return float4(N*0.5+0.5, 1);
+	float3 materials[2] = { float3(1, 1, 1), float3(0, 0, 0.5)};
+    float nDotL = dot( N, L);
+	return float4(abs(nDotL) * materials[nDotL < 0.0], 0.1);
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/oceanHLSL_Cg.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/oceanHLSL_Cg.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/oceanHLSL_Cg.frag	(revision 12083)
@@ -0,0 +1,45 @@
+// oceanHLSL_Cg.frag
+// fragment program for Ocean water simulation
+// 04 Aug 2005
+// adapted for Ogre by nfz
+// original shader source from Render Monkey 1.6 Reflections Refractions.rfx
+// can be used in both Cg and HLSL compilers
+
+// 06 Aug 2005: moved uvw calculation from fragment program into vertex program 
+
+float4 main(  float4 Pos:    POSITION,
+  float3 uvw: TEXCOORD0, float3 normal: TEXCOORD1, float3 vVec: TEXCOORD2,
+	uniform float fadeBias,
+	uniform float fadeExp,
+	uniform float4 waterColor,
+	uniform sampler3D Noise,
+	uniform samplerCUBE skyBox
+
+) : COLOR
+{
+
+   float3 noisy = tex3D(Noise, uvw).xyz;
+
+   // convert to Signed noise 
+   float3 bump = 2 * noisy - 1;
+   bump.xz *= 0.15;
+   // Make sure the normal always points upwards
+   // note that Ogres y axis is vertical (RM Z axis is vertical)
+   bump.y = 0.8 * abs(bump.y) + 0.2;
+   // Offset the surface normal with the bump
+   bump = normalize(normal + bump);
+
+   // Find the reflection vector
+   float3 normView = normalize(vVec);
+   float3 reflVec = reflect(normView, bump);
+   // Ogre has z flipped for cubemaps
+   reflVec.z = -reflVec.z;
+   float4 refl = texCUBE(skyBox, reflVec);
+
+   // set up for fresnel calc
+   float lrp = 1 - dot(-normView, bump);
+   
+   // Interpolate between the water color and reflection for fresnel effect
+   return lerp(waterColor, refl, saturate(fadeBias + pow(lrp, fadeExp)));
+
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/oceanHLSL_Cg.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/oceanHLSL_Cg.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/oceanHLSL_Cg.vert	(revision 12083)
@@ -0,0 +1,41 @@
+// oceanHLSL_Cg.vert
+// vertex program for Ocean water simulation
+// 04 Aug 2005
+// adapted for Ogre by nfz
+// original shader source from Render Monkey 1.6 Reflections Refractions.rfx
+// can be used in both Cg and HLSL compilers
+
+// 06 Aug 2005: moved uvw calculation from fragment program into vertex program 
+
+struct VS_OUTPUT {
+   float4 Pos:    POSITION;
+   float3 uvw:    TEXCOORD0;
+   float3 normal: TEXCOORD1;
+   float3 vVec:   TEXCOORD2;
+};
+
+VS_OUTPUT main(float4 Pos: POSITION, float3 normal: NORMAL,
+	uniform float4x4 worldViewProj_matrix,
+	uniform float3 scale,
+	uniform float2 waveSpeed,
+	uniform float noiseSpeed,
+	uniform float time_0_X,
+	uniform float3 eyePosition
+
+)
+{
+   VS_OUTPUT Out;
+
+   Out.Pos = mul(worldViewProj_matrix, Pos);
+   
+   // uvw is the calculated uvw coordinates based on vertex position
+   Out.uvw = Pos.xyz * scale;
+   Out.uvw.xz += waveSpeed * time_0_X;
+   Out.uvw.y += Out.uvw.z + noiseSpeed * time_0_X;
+   
+   //  the view vector needs to be in vertex space
+   Out.vVec = Pos.xyz - eyePosition;
+   Out.normal = normal;
+
+   return Out;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/pssm.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/pssm.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/pssm.cg	(revision 12083)
@@ -0,0 +1,164 @@
+void shadow_caster_vs(
+	float4 position			: POSITION,
+
+	out float4 oPosition	: POSITION,
+	out float2 oDepth		: TEXCOORD0,
+
+	uniform float4x4 wvpMat)
+{
+	// this is the view space position
+	oPosition = mul(wvpMat, position);
+
+	// depth info for the fragment.
+	oDepth.x = oPosition.z;
+	oDepth.y = oPosition.w;
+
+	// clamp z to zero. seem to do the trick. :-/
+	//oPosition.z = max(oPosition.z, 0);
+}
+
+void shadow_caster_ps(
+	float2 depth		: TEXCOORD0,
+
+	out float4 oColour	: COLOR,
+
+	uniform float4 pssmSplitPoints)
+{
+	float finalDepth = depth.x / depth.y;
+	oColour = float4(finalDepth, finalDepth, finalDepth, 1);
+}
+
+
+
+void shadow_receiver_vs(
+	float4 position				: POSITION,
+	float3 normal				: NORMAL,
+	float2 uv					: TEXCOORD0,
+
+	out float4 oPosition		: POSITION,
+	out float3 oUv				: TEXCOORD0,
+	out float3 oLightDir		: TEXCOORD1,
+	out float3 oHalfAngle		: TEXCOORD2,
+	out float4 oLightPosition0	: TEXCOORD3,
+	out float4 oLightPosition1	: TEXCOORD4,
+	out float4 oLightPosition2	: TEXCOORD5,
+	out float3 oNormal			: TEXCOORD6,
+
+	uniform float4 lightPosition,				// object space
+	uniform float3 eyePosition,					// object space
+	uniform float4x4 worldViewProjMatrix,
+	uniform float4x4 texWorldViewProjMatrix0,
+	uniform float4x4 texWorldViewProjMatrix1,
+	uniform float4x4 texWorldViewProjMatrix2)
+{
+	// calculate output position
+	oPosition = mul(worldViewProjMatrix, position);
+
+	// pass the main uvs straight through unchanged
+	oUv.xy = uv;
+	oUv.z = oPosition.z;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	oLightDir = normalize(lightPosition.xyz - (position * lightPosition.w).xyz);
+
+	// Calculate half-angle in tangent space
+	float3 eyeDir = normalize(eyePosition - position.xyz);
+	oHalfAngle = normalize(eyeDir + oLightDir);	
+
+	// Calculate the position of vertex in light space
+	oLightPosition0 = mul(texWorldViewProjMatrix0, position);
+	oLightPosition1 = mul(texWorldViewProjMatrix1, position);
+	oLightPosition2 = mul(texWorldViewProjMatrix2, position);
+
+	oNormal = normal;
+}
+
+float shadowPCF(sampler2D shadowMap, float4 shadowMapPos, float2 offset)
+{
+	shadowMapPos = shadowMapPos / shadowMapPos.w;
+	float2 uv = shadowMapPos.xy;
+	float3 o = float3(offset, -offset.x) * 0.3f;
+
+	// Note: We using 2x2 PCF. Good enough and is alot faster.
+	float c =	(shadowMapPos.z <= tex2D(shadowMap, uv.xy - o.xy).r) ? 1 : 0; // top left
+	c +=		(shadowMapPos.z <= tex2D(shadowMap, uv.xy + o.xy).r) ? 1 : 0; // bottom right
+	c +=		(shadowMapPos.z <= tex2D(shadowMap, uv.xy + o.zy).r) ? 1 : 0; // bottom left
+	c +=		(shadowMapPos.z <= tex2D(shadowMap, uv.xy - o.zy).r) ? 1 : 0; // top right
+	//float c =	(shadowMapPos.z <= tex2Dlod(shadowMap, uv.xyyy - o.xyyy).r) ? 1 : 0; // top left
+	//c +=		(shadowMapPos.z <= tex2Dlod(shadowMap, uv.xyyy + o.xyyy).r) ? 1 : 0; // bottom right
+	//c +=		(shadowMapPos.z <= tex2Dlod(shadowMap, uv.xyyy + o.zyyy).r) ? 1 : 0; // bottom left
+	//c +=		(shadowMapPos.z <= tex2Dlod(shadowMap, uv.xyyy - o.zyyy).r) ? 1 : 0; // top right
+	return c / 4;
+}
+
+// to put it simply, this does 100% per pixel diffuse lighting
+void shadow_receiver_ps(
+	float3 uv				: TEXCOORD0,
+	float3 OSlightDir			: TEXCOORD1,
+	float3 OShalfAngle		: TEXCOORD2,
+	float4 LightPosition0	: TEXCOORD3,
+	float4 LightPosition1	: TEXCOORD4,
+	float4 LightPosition2	: TEXCOORD5,
+	float3 normal			: TEXCOORD6,
+
+	out float4 oColour		: COLOR,
+
+	uniform float4 invShadowMapSize0,
+	uniform float4 invShadowMapSize1,
+	uniform float4 invShadowMapSize2,
+	uniform float4 pssmSplitPoints,
+	uniform sampler2D diffuse,
+	uniform sampler2D specular,
+	uniform sampler2D normalMap,
+	uniform sampler2D shadowMap0,
+	uniform sampler2D shadowMap1,
+	uniform sampler2D shadowMap2,
+	uniform float4 lightDiffuse,
+	uniform float4 lightSpecular,
+	uniform float4 ambient
+	)
+{
+	// calculate shadow
+	float shadowing = 1.0f;
+	float4 splitColour;
+	if (uv.z <= pssmSplitPoints.y)
+	{
+		splitColour = float4(0.1, 0, 0, 1);
+		shadowing = shadowPCF(shadowMap0, LightPosition0, invShadowMapSize0.xy);
+	}
+	else if (uv.z <= pssmSplitPoints.z)
+	{
+		splitColour = float4(0, 0.1, 0, 1);
+		shadowing = shadowPCF(shadowMap1, LightPosition1, invShadowMapSize1.xy);
+	}
+	else
+	{
+		splitColour = float4(0.1, 0.1, 0, 1);
+		shadowing = shadowPCF(shadowMap2, LightPosition2, invShadowMapSize2.xy);
+	}
+
+	// retrieve normalised light vector, expand from range-compressed
+	float3 lightVec = normalize(OSlightDir);
+
+	// retrieve half angle and normalise through cube map
+	float3 halfAngle = normalize(OShalfAngle);
+
+	// get diffuse colour
+	float4 diffuseColour = tex2D(diffuse, uv.xy);
+
+	// specular
+	float4 specularColour = tex2D(specular, uv.xy);
+	float shininess = specularColour.w;
+	specularColour.w = 1;
+
+	// calculate lit value.
+	float4 lighting = lit(dot(normal, lightVec), dot(normal, halfAngle), shininess * 128) * shadowing;
+
+	// final lighting with diffuse and spec
+	oColour = (diffuseColour * clamp(ambient + lightDiffuse * lighting.y, 0, 1)) + (lightSpecular * specularColour * lighting.z);
+	oColour.w = diffuseColour.w;
+
+	//oColour += splitColour;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/Cg/shadows.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/shadows.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/shadows.cg	(revision 12083)
@@ -0,0 +1,144 @@
+/* Copyright Torus Knot Software Ltd 2000-2013
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+// Simple PCF 
+// Number of samples in one dimension (square for total samples)
+#define NUM_SHADOW_SAMPLES_1D 2.0
+#define SHADOW_FILTER_SCALE 1
+
+#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D
+
+float4 offsetSample(float4 uv, float2 offset, float invMapSize)
+{
+	return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w);
+}
+
+float calcDepthShadow(sampler2D shadowMap, float4 uv, float invShadowMapSize)
+{
+	// 4-sample PCF
+	
+	float shadow = 0.0;
+	float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE;
+	for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE)
+		for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE)
+		{
+			float depth = tex2Dproj(shadowMap, offsetSample(uv, float2(x, y), invShadowMapSize)).x;
+			if (depth >= 1 || depth >= uv.z)
+				shadow += 1.0;
+		}
+
+	shadow /= SHADOW_SAMPLES;
+
+	return shadow;
+}
+
+
+float calcSimpleShadow(sampler2D shadowMap, float4 shadowMapPos)
+{
+	return tex2Dproj(shadowMap, shadowMapPos).x;
+}
+
+float calcPSSMDepthShadow(sampler2D shadowMap0, sampler2D shadowMap1, sampler2D shadowMap2, 
+						   float4 lsPos0, float4 lsPos1, float4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   float4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	float4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = float4(0.3, 0.0, 0, 0);
+		shadow = calcDepthShadow(shadowMap0, lsPos0, invShadowmapSize0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = float4(0, 0.3, 0, 0);
+		shadow = calcDepthShadow(shadowMap1, lsPos1, invShadowmapSize1);
+	}
+	else
+	{
+		splitColour = float4(0.0, 0.0, 0.3, 0);
+		shadow = calcDepthShadow(shadowMap2, lsPos2, invShadowmapSize2);
+	}
+
+	return shadow;
+}
+
+float calcPSSMSimpleShadow(sampler2D shadowMap0, sampler2D shadowMap1, sampler2D shadowMap2, 
+						   float4 lsPos0, float4 lsPos1, float4 lsPos2,
+						   float4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	float4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = float4(0.3, 0.0, 0, 0);
+		shadow = calcSimpleShadow(shadowMap0, lsPos0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = float4(0, 0.3, 0, 0);
+		shadow = calcSimpleShadow(shadowMap1, lsPos1);
+	}
+	else
+	{
+		splitColour = float4(0.0, 0.0, 0.3, 0);
+		shadow = calcSimpleShadow(shadowMap2, lsPos2);
+	}
+
+	return shadow;
+}
+
+
+
+float3 calcPSSMDebugShadow(sampler2D shadowMap0, sampler2D shadowMap1, sampler2D shadowMap2, 
+						   float4 lsPos0, float4 lsPos1, float4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   float4 pssmSplitPoints, float camDepth)
+{
+
+	float4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		//splitColour = float4(0.3, 0.0, 0, 0);
+		//splitColour = lsPos0 / lsPos0.w;
+		splitColour.rgb = tex2Dproj(shadowMap0, lsPos0).x;
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		//splitColour = float4(0, 0.3, 0, 0);
+		//splitColour = lsPos1 / lsPos1.w;
+		splitColour.rgb = tex2Dproj(shadowMap1, lsPos1).x;
+	}
+	else
+	{
+		//splitColour = float4(0.0, 0.0, 0.3, 0);
+		//splitColour = lsPos2 / lsPos2.w;
+		splitColour.rgb = tex2Dproj(shadowMap2, lsPos2).x;
+	}
+
+	return splitColour.rgb;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowcasterfp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowcasterfp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowcasterfp.cg	(revision 12083)
@@ -0,0 +1,65 @@
+/////////////////////////////////////////////////////////////////////////////////
+//
+// shadowcasterfp.cg
+//
+// Hamilton Chong
+// (c) 2006
+//
+// This is an example fragment shader for shadow caster objects.  
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+// Define outputs from vertex shader.
+struct VertexOut
+{
+  float4 position   : POSITION;     // can't rely on access to this
+  float4 pos  	    : TEXCOORD0;    // position of fragment (in homogeneous coordinates)
+  float4 normal     : TEXCOORD1;    // un-normalized normal in object space
+  float4 modelPos   : TEXCOORD2;    // coordinates of model in object space at this point
+};
+
+struct FragmentOut
+{
+    float4 color  : COLOR0;
+};
+
+FragmentOut main( VertexOut        In,                     // fragment to process
+                  uniform float    uDepthOffset,           // offset amount (constant in eye space)
+                  uniform float4x4 uProjection             // projection matrix
+              )
+{
+    FragmentOut Out;
+
+    // compute the "normalized device coordinates" (no viewport applied yet)
+    float4 postproj = In.pos / In.pos.w;
+
+    // get the normalized normal of the geometry seen at this point
+    float4 normal = normalize(In.normal);
+
+
+    // -- Computing Depth Bias Quantities -----------------------------
+
+    // We now compute the change in z that would signify a push in the z direction
+    // by 1 unit in eye space.  Note that eye space z is related in a nonlinear way to
+    // screen space z, so this is not just a constant.  
+    // ddepth below is how much screen space z at this point would change for that push.
+    // NOTE: computation of ddepth likely differs from OpenGL's glPolygonOffset "unit"
+    //  computation, which is allowed to be vendor specific.
+    float4 dpwdz = mul(uProjection, float4(0.0, 0.0, 1.0, 0.0));
+    float4 dpdz = (dpwdz - (postproj * dpwdz.w)) / In.pos.w;
+    float  ddepth = abs(dpdz.z);
+
+    // -- End depth bias helper section --------------------------------   
+
+    // We now compute the depth of the fragment.  This is the actual depth value plus
+    // our depth bias.  The depth bias depends on how uncertain we are about the z value
+    // plus some constant push in the z direction.  The exact coefficients to use are
+    // up to you, but at least it should be somewhat intuitive now what the tradeoffs are.
+    float depthval = postproj.z /* + (0.5 * dzlen)*/ + (uDepthOffset * ddepth);
+    depthval = (0.5 * depthval) + 0.5; // put into [0,1] range instead of [-1,1] 
+
+    
+    Out.color = float4(depthval, depthval * depthval, depthval, 0.0);
+    return Out;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowcastervp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowcastervp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowcastervp.cg	(revision 12083)
@@ -0,0 +1,44 @@
+/////////////////////////////////////////////////////////////////////////////////
+//
+// shadowcastervp.cg
+//
+// Hamilton Chong
+// (c) 2006
+//
+// This is an example vertex shader for shadow caster objects.  
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+// Define inputs from application.
+struct VertexIn
+{
+  float4 position : POSITION;       // vertex position in object space
+  float4 normal   : NORMAL;         // vertex normal in object space
+};
+
+// Define outputs from vertex shader.
+struct VertexOut
+{
+  float4 position   : POSITION;     // post projection position coordinates
+  float4 pos  	    : TEXCOORD0;    // ditto. Not all hardware allows access values bound to POSITION in fp.
+  float4 normal     : TEXCOORD1;    // normal in object space (to be interpolated)
+  float4 modelPos   : TEXCOORD2;    // position in object space (to be interpolated) 
+};
+
+VertexOut main( VertexIn         In,                   // vertex to process
+                uniform float4x4 uModelViewProjection  // model-view-projection matrix
+              )
+{
+    VertexOut Out;   // output data
+    
+    // Transform vertex position into post projective (homogenous screen) space.
+    Out.position = mul(uModelViewProjection, In.position);
+    Out.pos      = mul(uModelViewProjection, In.position);
+
+    // copy over data to interpolate using perspective correct interpolation
+    Out.normal = float4(In.normal.x, In.normal.y, In.normal.z, 0.0);
+    Out.modelPos = In.position;
+
+    return Out;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowreceiverfp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowreceiverfp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowreceiverfp.cg	(revision 12083)
@@ -0,0 +1,107 @@
+/////////////////////////////////////////////////////////////////////////////////
+//
+// shadowreceiverfp.cg
+//
+// Hamilton Chong
+// (c) 2006
+//
+// This is an example fragment shader for shadow receiver objects.  
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+sampler2D ShadowMap : TEXUNIT0;
+
+// Define outputs from vertex shader.
+struct Vertex
+{
+  float4 position       : POSITION;     // fragment position in post projective space
+  float4 shadowCoord    : TEXCOORD0;    // fragment position in shadow map coordinates
+  float  diffuse        : TEXCOORD1;    // diffuse shading value
+};
+
+struct Fragment
+{
+    float4 color  : COLOR0;
+};
+
+Fragment main(Vertex        In, 
+              uniform float uSTexWidth,
+              uniform float uSTexHeight)
+{
+    Fragment Out;
+
+    // compute the shadow coordinates for texture lookup
+    // NOTE: texture_viewproj_matrix maps z into [0,1] range, not [-1,1], so
+    //  have to make sure shadow caster stores depth values with same convention.
+    float4 scoord = In.shadowCoord / In.shadowCoord.w;
+
+
+    // -- Bilinear Filtering of Sample -------------------------------------------- 
+
+    // One could use scoord.xy to look up the shadow map for depth testing, but
+    // we'll be implementing a simple "percentage closest filtering" algorithm instead.
+    // This mimics the behavior of turning on bilinear filtering on NVIDIA hardware
+    // when also performing shadow comparisons.  This causes bilinear filtering of
+    // depth tests.  Note that this is NOT the same as bilinear filtering the depth
+    // values and then doing the depth comparison.  The two operations are not 
+    // commutative.  PCF is explicitly about filtering the test values since
+    // testing filtered z values is often meaningless.  
+
+    // Real percentage closest filtering should sample from the entire footprint
+    // on the shadow map, not just seek the closest four sample points.  Such 
+    // an improvement is for future work.
+
+    
+    // NOTE: Assuming OpenGL convention for texture lookups with integers in centers.
+    //  DX convention is to have integers mark sample corners
+    float2 tcoord;
+    tcoord.x = (scoord.x * uSTexWidth) - 0.5;
+    tcoord.y = (scoord.y * uSTexHeight) - 0.5;
+    float x0 = floor(tcoord.x);
+    float x1 = ceil(tcoord.x);
+    float fracx = frac(tcoord.x);
+    float y0 = floor(tcoord.y);
+    float y1 = ceil(tcoord.y);
+    float fracy = frac(tcoord.y);
+    
+    // sample coordinates in [0,1]^2 domain
+    float2 t00, t01, t10, t11;
+    float invWidth  = 1.0 / uSTexWidth;
+    float invHeight = 1.0 / uSTexHeight;
+    t00 = float2((x0+0.5) * invWidth, (y0+0.5) * invHeight);
+    t10 = float2((x1+0.5) * invWidth, (y0+0.5) * invHeight);
+    t01 = float2((x0+0.5) * invWidth, (y1+0.5) * invHeight);
+    t11 = float2((x1+0.5) * invWidth, (y1+0.5) * invHeight);
+    
+    // grab the samples
+    float2 z00 = tex2D(ShadowMap, t00).xy;
+    float2 z01 = tex2D(ShadowMap, t01).xy;
+    float2 z10 = tex2D(ShadowMap, t10).xy;
+    float2 z11 = tex2D(ShadowMap, t11).xy;
+
+    // bilinear filter the sample data
+    float2 d0 = ((1.0 - fracx) * z00) + (fracx * z10);
+    float2 d1 = ((1.0 - fracx) * z01) + (fracx * z11);
+    float2 datum = ((1.0 - fracy) * d0) + (fracy * d1);
+
+    // -- Variance Shadow Mapping ---------------------------------------------------
+
+    float zVariance = datum.y - (datum.x * datum.x);
+    float zDeviation = scoord.z - datum.x;
+    zDeviation = (zDeviation < 0.0) ? 0.0 : zDeviation;
+    float visibility = zVariance / (zVariance + (zDeviation * zDeviation));
+    float ztest = (scoord.z < datum.x) ? 1.0:0.0;  // filtering depth ok, because used only for small variance
+    visibility = (zVariance > 0.0) ? visibility : ztest; // if variance too small, we get garbage
+    //0.0000001
+
+    // determine that all geometry within pixel border of shadow map (and outside) is lit
+    float filterBorder = max(invWidth, invHeight);
+    visibility = (all(abs(scoord.xy-0.5)<=0.5-filterBorder)) ? visibility : 1.0;
+
+    // ------------------------------------------------------------------------------
+
+    visibility *= In.diffuse;
+    Out.color = float4(visibility, visibility, visibility, 0.0);
+    return Out;
+}
Index: /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowreceivervp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowreceivervp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/Cg/varianceshadowreceivervp.cg	(revision 12083)
@@ -0,0 +1,47 @@
+/////////////////////////////////////////////////////////////////////////////////
+//
+// shadowreceivervp.cg
+//
+// Hamilton Chong
+// (c) 2006
+//
+// This is an example vertex shader for shadow receiver objects.  
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+// Define inputs from application.
+struct VertexIn
+{
+  float4 position       : POSITION;     // vertex position in object space
+  float4 normal         : NORMAL;       // vertex normal in object space
+};
+
+// Define outputs from vertex shader.
+struct Vertex
+{
+  float4 position       : POSITION;     // vertex position in post projective space
+  float4 shadowCoord    : TEXCOORD0;    // vertex position in shadow map coordinates
+  float  diffuse        : TEXCOORD1;    // diffuse shading value
+};
+
+Vertex main(VertexIn         In,
+            uniform float4x4 uModelViewProjection,   // model-view-projection matrix
+            uniform float4   uLightPosition,         // light position in object space
+            uniform float4x4 uModel,                 // model matrix
+            uniform float4x4 uTextureViewProjection  // shadow map's view projection matrix
+            )
+{
+    Vertex Out;
+
+    // compute diffuse shading
+    float3 lightDirection = normalize(uLightPosition.xyz - In.position.xyz);
+    Out.diffuse = dot(In.normal.xyz, lightDirection);
+
+    // compute shadow map lookup coordinates
+    Out.shadowCoord = mul(uTextureViewProjection, mul(uModel, In.position));
+
+    // compute vertex's homogenous screen-space coordinates
+    Out.position = mul(uModelViewProjection, In.position);
+
+    return Out;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/AmbientOneTexture.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/AmbientOneTexture.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/AmbientOneTexture.glsl	(revision 12083)
@@ -0,0 +1,13 @@
+uniform vec4 ambient;
+
+/*
+  Basic ambient lighting vertex program
+*/
+void main()
+{
+	gl_Position = ftransform();
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+	gl_FrontColor = ambient;
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Bloom2_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Bloom2_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Bloom2_ps20.glsl	(revision 12083)
@@ -0,0 +1,27 @@
+//-------------------------------
+//Bloom_ps20.glsl
+// Blends using weights the blurred image with the sharp one
+// Params:
+//   OriginalImageWeight
+//   BlurWeight
+//-------------------------------
+
+uniform sampler2D RT;
+uniform sampler2D Blur1;
+
+uniform float OriginalImageWeight;
+uniform float BlurWeight;
+
+void main()
+{
+    vec4 sharp;
+    vec4 blur;
+    
+    vec2 texCoord = vec2( gl_TexCoord[0] );
+
+    sharp = texture2D( RT, texCoord);
+    blur = texture2D( Blur1, texCoord);
+    
+    gl_FragColor = ( (blur * BlurWeight) + (sharp * OriginalImageWeight) );
+    //gl_FragColor = vec4(0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Blur0_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Blur0_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Blur0_vs.glsl	(revision 12083)
@@ -0,0 +1,16 @@
+varying vec2 texCoord[5];
+uniform mat4 worldViewProj;
+attribute vec2 uv0;
+
+void main()                    
+{
+	gl_Position = worlViewProj * gl_Vertex;
+	
+	texCoord[0]  = uv0;
+	
+	const float size = 0.01;
+	texCoord[1] = texCoord[0] + vec2(1.0, 0.0)*size;
+	texCoord[2] = texCoord[0] + vec2(2.0, 0.0)*size;
+	texCoord[3] = texCoord[0] + vec2(-1.0, 0.0)*size;
+	texCoord[4] = texCoord[0] + vec2(-2.0, 0.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Blur1_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Blur1_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Blur1_vs.glsl	(revision 12083)
@@ -0,0 +1,16 @@
+varying vec2 texCoord[5];
+attribute vec2 uv0;
+uniform mat4 worldViewProj;
+
+void main()                    
+{
+	gl_Position = worldViewProj * gl_Vertex;
+	
+	texCoord[0]  = uv0;
+	
+	const float size = 0.01;
+	texCoord[1] = texCoord[0] + vec2(0.0, 1.0)*size;
+	texCoord[2] = texCoord[0] + vec2(0.0, 2.0)*size;
+	texCoord[3] = texCoord[0] + vec2(0.0, -1.0)*size;
+	texCoord[4] = texCoord[0] + vec2(0.0, -2.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/BlurH_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/BlurH_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/BlurH_ps20.glsl	(revision 12083)
@@ -0,0 +1,57 @@
+//-------------------------------
+//BlurH_ps20.glsl
+// Horizontal Gaussian-Blur pass
+//-------------------------------
+#version 120
+
+uniform sampler2D Blur0;
+vec2 pos[11] = vec2[11]
+(
+	vec2( -5, 0),
+	vec2( -4, 0),
+	vec2( -3, 0),
+	vec2( -2, 0),
+	vec2( -1, 0),
+	vec2( 0, 0),
+	vec2( 1, 0),
+	vec2( 2, 0),
+	vec2( 3, 0),
+	vec2( 4, 0),
+	vec2( 5, 0)
+);
+
+//We use the Normal-gauss distribution formula
+//f(x) being the formula, we used f(0.5)-f(-0.5); f(1.5)-f(0.5)...
+float samples[11] = float[11]
+(//stddev=2.0
+0.01222447,
+0.02783468,
+0.06559061,
+0.12097757,
+0.17466632,
+
+0.19741265,
+
+0.17466632,
+0.12097757,
+0.06559061,
+0.02783468,
+0.01222447
+);
+
+void main()
+{
+    vec4 retVal;
+    
+    vec4 sum;
+    vec2 texcoord = vec2( gl_TexCoord[0] );
+    int i = 0;
+
+    sum = vec4( 0 );
+    for( i=0;i < 11; i++ )
+    {
+        sum += texture2D( Blur0, texcoord + (pos[i] * 0.0100000) ) * samples[i];
+    }
+
+    gl_FragColor = sum;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/BlurV_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/BlurV_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/BlurV_ps20.glsl	(revision 12083)
@@ -0,0 +1,61 @@
+// Note, this won't work on ATI which is why it's not used
+// the issue is with the array initializers
+// no card supports GL_3DL_array_objects but it does work on nvidia, not on ATI
+//#extension GL_3DL_array_objects : enable
+#version 120
+
+//-------------------------------
+//BlurV_ps20.glsl
+// Vertical Gaussian-Blur pass
+//-------------------------------
+
+uniform sampler2D Blur0;
+vec2 pos[11]  = vec2[11](
+	vec2(0.0, -5.0),
+	vec2(0.0, -4.0),
+	vec2(0.0, -3.0),
+	vec2(0.0, -2.0),
+	vec2(0.0, -1.0),
+	vec2(0.0, 0.0),
+	vec2(0.0, 1.0),
+	vec2(0.0, 2.0),
+	vec2(0.0, 3.0),
+	vec2(0.0, 4.0),
+	vec2(0.0, 5.0)
+);
+
+//We use the Normal-gauss distribution formula
+//f(x) being the formula, we used f(0.5)-f(-0.5); f(1.5)-f(0.5)...
+float samples[11] = float[11] 
+(//stddev=2.0
+0.01222447,
+0.02783468,
+0.06559061,
+0.12097757,
+0.17466632,
+
+0.19741265,
+
+0.17466632,
+0.12097757,
+0.06559061,
+0.02783468,
+0.01222447
+);
+
+void main()
+{
+    vec4 retVal;
+    
+    vec4 sum;
+    vec2 texcoord = vec2(gl_TexCoord[0]);
+    int i = 0;
+
+    sum = vec4( 0 );
+    for( ;i < 11; i++ )
+    {
+        sum += texture2D( Blur0, texcoord + (pos[i] * 0.0100000) ) * samples[i];
+    }
+
+    gl_FragColor = sum;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Blur_ps.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Blur_ps.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Blur_ps.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+uniform sampler2D tex0;
+
+varying vec2 texCoord[5];
+
+void main()
+{
+	vec4 sum = texture2D(tex0, texCoord[0]) + 
+			   texture2D(tex0, texCoord[1]) +
+			   texture2D(tex0, texCoord[2]) + 
+			   texture2D(tex0, texCoord[3]) +
+			   texture2D(tex0, texCoord[4]);
+	gl_FragColor = sum / 5.0;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Blur_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Blur_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Blur_vs.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+uniform mat4 worldViewProj;
+attribute vec2 uv0;
+
+void main()                    
+{
+	gl_Position = worldViewProj * gl_Vertex;
+
+	gl_TexCoord[0]  = vec4( uv0, 0, 0 );
+	
+	const float size = 0.01;
+	gl_TexCoord[1] = vec4( uv0 + vec2(0.0, 1.0)*size, 0, 0);
+	gl_TexCoord[2] = vec4( uv0  + vec2(0.0, 2.0)*size, 0, 0);
+	gl_TexCoord[3] = vec4( uv0  + vec2(0.0, -1.0)*size, 0, 0);
+	gl_TexCoord[4] = vec4( uv0  + vec2(0.0, -2.0)*size, 0, 0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/BrightBloom2_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/BrightBloom2_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/BrightBloom2_ps20.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+//-------------------------------
+//BrightBloom_ps20.glsl
+// High-pass filter for obtaining lumminance
+// We use an aproximation formula that is pretty fast:
+//   f(x) = ( -3 * ( x - 1 )^2 + 1 ) * 2
+//   Color += Grayscale( f(Color) ) + 0.6
+//
+// Special thanks to ATI for their great HLSL2GLSL utility
+//     http://sourceforge.net/projects/hlsl2glsl
+//-------------------------------
+
+uniform sampler2D RT;
+
+void main()
+{
+    vec4 tex;
+    vec4 bright4;
+    float bright;
+    
+    vec2 texCoord = vec2( gl_TexCoord[0] );
+
+    tex = texture2D( RT, texCoord);
+    tex -= 1.00000;
+    bright4 = -6.00000 * tex * tex + 2.00000;
+    bright = dot( bright4, vec4( 0.333333, 0.333333, 0.333333, 0.000000) );
+    tex += (bright + 0.600000);
+
+    gl_FragColor = tex;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapCasterFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapCasterFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapCasterFp.glsl	(revision 12083)
@@ -0,0 +1,13 @@
+#version 120
+
+varying vec2 depth;
+
+void main()
+{
+	float finalDepth = depth.x / depth.y;
+
+	// just smear across all components 
+	// therefore this one needs high individual channel precision
+	gl_FragColor = vec4(finalDepth, finalDepth, finalDepth, 1.0);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapCasterVp.glsl	(revision 12083)
@@ -0,0 +1,18 @@
+#version 120
+
+uniform mat4 worldViewProj;
+uniform vec4 texelOffsets;
+
+attribute vec4 vertex;
+
+varying vec2 depth;
+
+void main()
+{
+	vec4 outPos = worldViewProj * vertex;
+	outPos.xy += texelOffsets.zw * outPos.w;
+	// fix pixel / texel alignment
+	depth = outPos.zw;
+	gl_Position = outPos;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapNormalMapReceiverFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapNormalMapReceiverFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapNormalMapReceiverFp.glsl	(revision 12083)
@@ -0,0 +1,70 @@
+#version 120
+
+uniform float inverseShadowmapSize;
+uniform float fixedDepthBias;
+uniform float gradientClamp;
+uniform float gradientScaleBias;
+uniform vec4 lightColour;
+
+uniform sampler2D shadowMap;
+uniform sampler2D normalMap;
+
+varying vec3 tangentLightDir;
+varying	vec4 oUv;
+varying	vec2 oUv2;
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+void main()
+{
+
+	// get the new normal and diffuse values
+	vec3 normal = normalize(expand(texture2D(normalMap, oUv2).xyz));
+	
+	vec4 vertexColour = clamp(dot(normal, tangentLightDir),0.0,1.0) * lightColour;
+
+
+	vec4 shadowUV = oUv;
+	// point on shadowmap
+	shadowUV.xy = shadowUV.xy / shadowUV.w;
+	float centerdepth = texture2D(shadowMap, shadowUV.xy).x;
+    
+    // gradient calculation
+  	float pixeloffset = inverseShadowmapSize;
+    vec4 depths = vec4(
+    	texture2D(shadowMap, shadowUV.xy + vec2(-pixeloffset, 0)).x,
+    	texture2D(shadowMap, shadowUV.xy + vec2(+pixeloffset, 0)).x,
+    	texture2D(shadowMap, shadowUV.xy + vec2(0, -pixeloffset)).x,
+    	texture2D(shadowMap, shadowUV.xy + vec2(0, +pixeloffset)).x);
+
+	vec2 differences = abs( depths.yw - depths.xz );
+	float gradient = min(gradientClamp, max(differences.x, differences.y));
+	float gradientFactor = gradient * gradientScaleBias;
+
+	// visibility function
+	float depthAdjust = gradientFactor + (fixedDepthBias * centerdepth);
+	float finalCenterDepth = centerdepth + depthAdjust;
+
+	// shadowUV.z contains lightspace position of current object
+#if PCF
+	// use depths from prev, calculate diff
+	depths += depthAdjust;
+	float final = (finalCenterDepth > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.x > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.y > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.z > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.w > shadowUV.z) ? 1.0 : 0.0;
+	
+	final *= 0.2;
+
+	gl_FragColor = vec4(vertexColour.xyz * final, 1);
+	
+#else
+	gl_FragColor = (finalCenterDepth > shadowUV.z) ? vertexColour : vec4(0,0,0,1);
+#endif
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapNormalMapReceiverVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapNormalMapReceiverVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapNormalMapReceiverVp.glsl	(revision 12083)
@@ -0,0 +1,42 @@
+#version 120
+
+uniform mat4 world;
+uniform mat4 worldViewProj;
+uniform mat4 texViewProj;
+uniform vec4 lightPosition; // object space
+
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec3 tangent;
+attribute vec4 uv0;
+
+varying vec3 tangentLightDir;
+varying	vec4 oUv;
+varying	vec2 oUv2;
+
+void main()
+{
+	vec4 worldPos = world * vertex;
+
+	// Get object space light direction 
+    vec3 lightDir = normalize(lightPosition.xyz -  (vertex.xyz * lightPosition.w));
+
+	// calculate shadow map coords
+	oUv = texViewProj * worldPos;
+
+	// pass the main uvs straight through unchanged 
+	oUv2 = uv0.xy;
+
+	// Calculate the binormal (NB we assume both normal and tangent are 
+	// already normalised) 
+	vec3 binormal = cross(normal, tangent); 
+
+	// Form a rotation matrix out of the vectors 
+	mat3 rotation = mat3(tangent, binormal, normal); 
+    
+	// Transform the light vector according to this matrix 
+	tangentLightDir = normalize(rotation * lightDir); 
+	
+	gl_Position = worldViewProj * vertex;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapReceiverFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapReceiverFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapReceiverFp.glsl	(revision 12083)
@@ -0,0 +1,54 @@
+#version 120
+
+uniform float inverseShadowmapSize;
+uniform float fixedDepthBias;
+uniform float gradientClamp;
+uniform float gradientScaleBias;
+
+uniform sampler2D shadowMap;
+
+varying	vec4 oUv;
+varying	vec4 outColor;
+
+void main()
+{
+	vec4 shadowUV = oUv;
+	// point on shadowmap
+	shadowUV.xy = shadowUV.xy / shadowUV.w;
+	float centerdepth = texture2D(shadowMap, shadowUV.xy).x;
+    
+    // gradient calculation
+  	float pixeloffset = inverseShadowmapSize;
+    vec4 depths = vec4(
+    	texture2D(shadowMap, shadowUV.xy + vec2(-pixeloffset, 0)).x,
+    	texture2D(shadowMap, shadowUV.xy + vec2(+pixeloffset, 0)).x,
+    	texture2D(shadowMap, shadowUV.xy + vec2(0, -pixeloffset)).x,
+    	texture2D(shadowMap, shadowUV.xy + vec2(0, +pixeloffset)).x);
+
+	vec2 differences = abs( depths.yw - depths.xz );
+	float gradient = min(gradientClamp, max(differences.x, differences.y));
+	float gradientFactor = gradient * gradientScaleBias;
+
+	// visibility function
+	float depthAdjust = gradientFactor + (fixedDepthBias * centerdepth);
+	float finalCenterDepth = centerdepth + depthAdjust;
+
+	// shadowUV.z contains lightspace position of current object
+#if PCF
+	// use depths from prev, calculate diff
+	depths += depthAdjust;
+	float final = (finalCenterDepth > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.x > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.y > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.z > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.w > shadowUV.z) ? 1.0 : 0.0;
+	
+	final *= 0.2;
+
+	gl_FragColor = vec4(outColor.xyz * final, 1);
+	
+#else
+	gl_FragColor = (centerdepth > shadowUV.z) ? vec4(outColor.xyz,1) : vec4(0,0,0,1);
+#endif
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapReceiverVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapReceiverVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DepthShadowmapReceiverVp.glsl	(revision 12083)
@@ -0,0 +1,33 @@
+#version 120
+
+uniform mat4 world;
+uniform mat4 worldIT;
+uniform mat4 worldViewProj;
+uniform mat4 texViewProj;
+uniform vec4 lightPosition;
+uniform vec4 lightColour;
+
+attribute vec4 vertex;
+attribute vec3 normal;
+
+varying	vec4 oUv;
+varying	vec4 outColor;
+
+void main()
+{
+	gl_Position = worldViewProj * vertex;
+	
+	vec4 worldPos = world * vertex;
+
+	vec3 worldNorm = (worldIT * vec4(normal, 1.0)).xyz;
+
+	// calculate lighting (simple vertex lighting)
+	vec3 lightDir = normalize(
+		lightPosition.xyz - (worldPos.xyz * lightPosition.w));
+
+	outColor = lightColour * max(dot(lightDir, worldNorm), 0.0);
+
+	// calculate shadow map coords
+	oUv = texViewProj * worldPos;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DiffuseOneTexture.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DiffuseOneTexture.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DiffuseOneTexture.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 120
+
+uniform sampler2D texMap;
+
+varying vec4 colour;
+varying vec4 uv;
+
+/*
+  Basic fragment program using texture and diffuse colour.
+*/
+void main()
+{
+	gl_FragColor = texture2D(texMap, uv.xy) * colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion.glsl	(revision 12083)
@@ -0,0 +1,42 @@
+#version 120
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ);
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform mat4 viewProjectionMatrix;
+uniform vec4   lightPos[2];
+uniform vec4   lightDiffuseColour[2];
+uniform vec4   ambient;
+
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+attribute vec4 uv0;
+
+void main()
+{	
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	vec3 blendPosition = calculateBlendPosition(vertex.xyz, blendDQ);
+		
+	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
+	vec3 blendNormal = calculateBlendNormal(normal, blendDQ);
+	
+	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
+	
+	// Lighting - support point and directional
+	vec3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition * lightPos[0].w));
+	vec3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition * lightPos[1].w));
+
+	gl_TexCoord[0] = uv0;
+
+	gl_FrontColor = gl_FrontMaterial.diffuse * (ambient + (clamp(dot(lightDir0, blendNormal), 0.0, 1.0) * lightDiffuseColour[0]) + 
+		(clamp(dot(lightDir1, blendNormal), 0.0, 1.0) * lightDiffuseColour[1]));			
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_Common.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_Common.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_Common.glsl	(revision 12083)
@@ -0,0 +1,70 @@
+#version 120
+
+//All of these functions are based on dqs.cg from http://isg.cs.tcd.ie/kavanl/dq/
+/* dqs.cg
+
+  Dual quaternion skinning vertex shaders (no shading computations)
+
+  Version 1.0.3, November 1st, 2007
+
+  Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights 
+  Reserved
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author(s) be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Author: Ladislav Kavan, kavanl@cs.tcd.ie
+
+*/
+
+mat2x4 blendTwoWeights(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24])
+{
+	mat2x4 blendDQ = blendWgt.x*mat2x4(dualQuaternions[int(blendIdx.x) * 2], dualQuaternions[int(blendIdx.x) * 2 + 1]);
+	blendDQ += blendWgt.y*mat2x4(dualQuaternions[int(blendIdx.y) * 2], dualQuaternions[int(blendIdx.y) * 2 + 1]);
+
+	return blendDQ;
+}
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24])
+{
+	mat2x4 dq0 = mat2x4(dualQuaternions[int(blendIdx.x) * 2], dualQuaternions[int(blendIdx.x) * 2 + 1]);
+	mat2x4 dq1 = mat2x4(dualQuaternions[int(blendIdx.y) * 2], dualQuaternions[int(blendIdx.y) * 2 + 1]);
+
+	//Accurate antipodality handling. For speed increase, remove the following line, 
+	//though, the results will only be valid for rotations less than 180 degrees.
+	if (dot(dq0[0], dq1[0]) < 0.0) dq1 *= -1.0;
+	
+	mat2x4 blendDQ = blendWgt.x*dq0;
+	blendDQ += blendWgt.y*dq1;
+
+	return blendDQ;
+}
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_ShadowCaster.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_ShadowCaster.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_ShadowCaster.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+#version 120
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform mat4 viewProjectionMatrix;
+uniform vec4   ambient;
+
+attribute vec4 vertex;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+//Shadow caster pass
+void main()
+{
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	vec3 blendPosition = calculateBlendPosition(vertex.xyz, blendDQ);
+
+	// view / projection
+	gl_Position = viewProjectionMatrix * vec4(blendPosition, 1.0);
+	
+	gl_FrontColor = ambient;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_TwoPhase.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_TwoPhase.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_TwoPhase.glsl	(revision 12083)
@@ -0,0 +1,77 @@
+#version 120
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ);
+
+mat3 adjointTransposeMatrix(mat3 M)
+{
+	mat3 atM;
+	atM[0][0] = M[2][2] * M[1][1] - M[2][1] * M[1][2];
+	atM[1][0] = M[2][1] * M[0][2] - M[0][1] * M[2][2];
+	atM[2][0] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
+
+	atM[0][1] = M[2][0] * M[1][2] - M[2][2] * M[1][0];
+	atM[1][1] = M[2][2] * M[0][0] - M[2][0] * M[0][2];
+	atM[2][1] = M[0][2] * M[1][0] - M[0][0] * M[1][2];
+
+	atM[0][2] = M[2][1] * M[1][0] - M[2][0] * M[1][1];
+	atM[1][2] = M[0][1] * M[2][0] - M[2][1] * M[0][0];
+	atM[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
+
+	return atM;
+}
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform vec4 scaleM[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4   lightPos[2];
+uniform vec4   lightDiffuseColour[2];
+uniform vec4   ambient;
+
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+attribute vec4 uv0;
+
+void main()
+{	
+	//First phase - applies scaling and shearing:
+	int blendIndicesX = int(blendIndices.x) * 3;
+	int blendIndicesY = int(blendIndices.y) * 3;
+	
+	mat3x4 blendS = blendWeights.x*mat3x4(scaleM[blendIndicesX], 
+		scaleM[blendIndicesX + 1], scaleM[blendIndicesX + 2]);
+	
+	blendS += blendWeights.y*mat3x4(scaleM[blendIndicesY], 						scaleM[blendIndicesY + 1], scaleM[blendIndicesY + 2]);
+
+	mat4x3 blendF = transpose(blendS);
+
+	vec3 pass1_position = blendF * vertex;
+
+	mat3x3 blendSrotAT = adjointTransposeMatrix(mat3x3(blendF));
+	vec3 pass1_normal = normalize(blendSrotAT * normal);
+
+	//Second phase
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	blendDQ /= length(blendDQ[0]);
+
+	vec3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
+
+	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
+	vec3 blendNormal = calculateBlendNormal(pass1_normal, blendDQ);
+	
+	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
+
+	// Lighting - support point and directional
+	vec3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition * lightPos[0].w));
+	vec3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition * lightPos[1].w));
+
+	gl_TexCoord[0] = uv0;
+
+	gl_FrontColor = gl_FrontMaterial.diffuse * (ambient + (clamp(dot(lightDir0, blendNormal), 0.0, 1.0) * lightDiffuseColour[0]) + 
+		(clamp(dot(lightDir1, blendNormal), 0.0, 1.0) * lightDiffuseColour[1]));			
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_TwoPhaseShadowCaster.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_TwoPhaseShadowCaster.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/DualQuaternion_TwoPhaseShadowCaster.glsl	(revision 12083)
@@ -0,0 +1,44 @@
+#version 120
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform vec4 scaleM[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4   ambient;
+
+attribute vec4 vertex;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+varying vec4 colour;
+
+//Shadow caster pass
+void main()
+{	
+	//First phase - applies scaling and shearing:
+	int blendIndicesX = int(blendIndices.x) * 3;
+	int blendIndicesY = int(blendIndices.y) * 3;
+	
+	mat3x4 blendS = blendWeights.x*mat3x4(scaleM[blendIndicesX], 
+		scaleM[blendIndicesX + 1], scaleM[blendIndicesX + 2]);
+	
+	blendS += blendWeights.y*mat3x4(scaleM[blendIndicesY], 						scaleM[blendIndicesY + 1], scaleM[blendIndicesY + 2]);
+
+	mat4x3 blendF = transpose(blendS);
+
+	vec3 pass1_position = blendF * vertex;
+
+	//Second phase
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	blendDQ /= length(blendDQ[0]);
+
+	vec3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
+	
+	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
+
+	colour = ambient;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Example_TextureArrayPS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Example_TextureArrayPS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Example_TextureArrayPS.glsl	(revision 12083)
@@ -0,0 +1,17 @@
+#version 120
+#extension GL_EXT_texture_array : enable
+
+uniform sampler2DArray TextureArrayTex;
+varying vec3 oUv;
+
+void main(void)
+{
+	vec3 texcoord;
+	texcoord = oUv;
+	texcoord.z = floor(texcoord.z);
+    vec4 c0 = texture2DArray(TextureArrayTex, texcoord);
+	texcoord.z += 1.0;
+    vec4 c1 = texture2DArray(TextureArrayTex, texcoord);
+
+	gl_FragColor = mix(c0, c1, fract(oUv.z));
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Example_TextureArrayVS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Example_TextureArrayVS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Example_TextureArrayVS.glsl	(revision 12083)
@@ -0,0 +1,11 @@
+#version 120
+
+varying vec3 oUv;
+
+uniform mat4 worldViewProj;
+
+void main(void)
+{
+	gl_Position = worldViewProj * gl_Vertex;
+	oUv = gl_MultiTexCoord0.xyz;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/HWBasicInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/HWBasicInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/HWBasicInstancing.vert	(revision 12083)
@@ -0,0 +1,69 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 120
+
+//Vertex input
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec4 uv0;
+attribute vec4 uv1;
+attribute vec4 uv2;
+attribute vec4 uv3;
+attribute vec3 tangent;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	varying vec2 depth;
+#else
+	varying vec2 _uv0;
+	varying vec3 oNormal;
+	varying vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		varying vec4 oLightSpacePos;
+	#endif
+#endif
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	mat4 worldMatrix;
+	worldMatrix[0] = uv1;
+	worldMatrix[1] = uv2;
+	worldMatrix[2] = uv3;
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	vec4 worldPos		= vertex * worldMatrix;
+	vec3 worldNorm		= normal * mat3(worldMatrix);
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/HW_VTFInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/HW_VTFInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/HW_VTFInstancing.vert	(revision 12083)
@@ -0,0 +1,131 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 120
+
+//Vertex input
+attribute vec4 vertex;
+attribute vec3 normal;
+
+#ifdef BONE_TWO_WEIGHTS
+	attribute vec4 blendWeights;
+#endif
+
+attribute vec4 uv0;
+attribute vec4 uv1;
+attribute vec4 uv2;
+	
+#if BONE_MATRIX_LUT
+	attribute vec4 uv3;
+	attribute vec4 uv4;
+	attribute vec4 uv5;
+#endif
+
+attribute vec3 tangent;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+uniform sampler2D matrixTexture;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	varying vec2 depth;
+#else
+	varying vec2 _uv0;
+	varying vec3 oNormal;
+	varying vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		varying vec4 oLightSpacePos;
+	#endif
+#endif
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 worldPos;
+	vec3 worldNorm;
+
+#ifdef ST_DUAL_QUATERNION
+	mat2x4 blendDQ;	
+	blendDQ[0] = texture2D( matrixTexture, vec2(uv1.x, 0.0) + uv2.xy );
+	blendDQ[1] = texture2D( matrixTexture, vec2(uv1.y, 0.0) + uv2.xy );
+#ifdef BONE_TWO_WEIGHTS
+	mat2x4 blendDQ2;
+	blendDQ2[0] = texture2D( matrixTexture, vec2(uv1.z, 0.0) + uv2.xy );
+	blendDQ2[1] = texture2D( matrixTexture, vec2(uv1.w, 0.0) + uv2.xy );
+
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= blendWeights.x;
+	blendDQ += blendWeights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(normal, blendDQ);
+#else
+	mat4 worldMatrix;
+	worldMatrix[0] = texture2D( matrixTexture, uv1.xw + uv2.xy );
+	worldMatrix[1] = texture2D( matrixTexture, uv1.yw + uv2.xy );
+	worldMatrix[2] = texture2D( matrixTexture, uv1.zw + uv2.xy );
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	worldPos		= vertex * worldMatrix;
+	worldNorm		= normal * mat3(worldMatrix);
+#endif
+
+#if BONE_MATRIX_LUT
+	mat4 worldCompMatrix;
+	worldCompMatrix[0] = uv3;
+	worldCompMatrix[1] = uv4;
+	worldCompMatrix[2] = uv5;
+	worldCompMatrix[3] = vec4( 0, 0, 0, 1 );
+	
+	worldPos =  worldPos * worldCompMatrix;
+	worldNorm = worldNorm * mat3(worldCompMatrix);
+#endif
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Instancing.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Instancing.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Instancing.frag	(revision 12083)
@@ -0,0 +1,66 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+uniform sampler2D diffuseMap;
+
+uniform vec4	lightPosition;
+uniform vec3	cameraPosition;
+uniform vec3 	lightAmbient;
+uniform vec3	lightDiffuse;
+uniform vec3	lightSpecular;
+uniform vec4	lightAttenuation;
+uniform float	lightGloss;
+
+#if DEPTH_SHADOWRECEIVER
+uniform float invShadowMapSize;
+uniform sampler2DShadow shadowMap;
+
+//declare external function
+//vec4 calcDepthShadow(in vec4 inColour, in float lum);
+float calcDepthShadow(sampler2DShadow shadowMap, vec4 uv, float invShadowMapSize);
+#endif
+
+varying vec2 _uv0;
+varying vec3 oNormal;
+varying vec3 oVPos;
+#if DEPTH_SHADOWRECEIVER
+	varying vec4 oLightSpacePos;
+#endif
+
+//---------------------------------------------
+//Main Pixel Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 color = texture2D( diffuseMap, _uv0 );
+
+	float fShadow = 1.0;
+#if DEPTH_SHADOWRECEIVER
+	fShadow = calcDepthShadow( shadowMap, oLightSpacePos, invShadowMapSize );
+#endif
+
+	vec4 baseColour = texture2D( diffuseMap, _uv0 );
+
+	//Blinn-Phong lighting
+	vec3 normal	= normalize( oNormal );
+	vec3 lightDir		= lightPosition.xyz - oVPos * lightPosition.w;
+	vec3 eyeDir			= normalize( cameraPosition - oVPos );
+
+	float fLength	= length( lightDir );
+	lightDir			= normalize( lightDir );
+
+	float NdotL	= max( 0.0, dot( normal, lightDir ) );
+	vec3 halfVector		= normalize(lightDir + eyeDir);
+	float HdotN	= max( 0.0, dot( halfVector, normal ) );
+	
+	vec3 ambient  = lightAmbient * baseColour.xyz;
+	vec3 diffuse  = lightDiffuse * NdotL * baseColour.xyz;
+	vec3 specular = lightSpecular * pow( HdotN, lightGloss );
+	
+	vec3 directLighting = (diffuse + specular) * fShadow;
+	
+	gl_FragColor = vec4( directLighting + ambient, baseColour.a );
+	//gl_FragColor = baseColour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/InstancingMisc.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/InstancingMisc.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/InstancingMisc.vert	(revision 12083)
@@ -0,0 +1,62 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 120
+
+//Vertex input
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec3 tangent;
+attribute vec4 uv0;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+uniform mat4 worldMatrix;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	varying vec2 depth;
+#else
+	varying vec2 _uv0;
+	varying vec3 oNormal;
+	varying vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		varying vec4 oLightSpacePos;
+	#endif
+#endif
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 worldPos		= vertex * worldMatrix;
+	vec3 worldNorm		= normal * mat3(worldMatrix);
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Ocean2GLSL.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Ocean2GLSL.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Ocean2GLSL.frag	(revision 12083)
@@ -0,0 +1,71 @@
+/*********************************************************************NVMH3****
+Copyright NVIDIA Corporation 2003
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+	Simple ocean shader with animated bump map and geometric waves
+	Based partly on "Effective Water Simulation From Physical Models", GPU Gems
+
+11 Aug 05: converted from HLSL to GLSL by Jeff Doyle (nfz) to work in Ogre
+
+******************************************************************************/
+
+
+uniform sampler2D NormalMap;
+uniform samplerCube EnvironmentMap;
+uniform vec4 deepColor;
+uniform vec4 shallowColor;
+uniform vec4 reflectionColor;
+uniform float reflectionAmount;
+uniform float reflectionBlur;
+uniform float waterAmount;
+uniform float fresnelPower;
+uniform float fresnelBias;
+uniform float hdrMultiplier;
+
+varying mat3 rotMatrix; // first row of the 3x3 transform from tangent to cube space
+varying vec2 bumpCoord0;
+varying vec2 bumpCoord1;
+varying vec2 bumpCoord2;
+varying vec3 eyeVector;
+
+
+void main(void)
+{
+	// sum normal maps
+	// sample from 3 different points so no texture repetition is noticeable
+    vec4 t0 = texture2D(NormalMap, bumpCoord0) * 2.0 - 1.0;
+    vec4 t1 = texture2D(NormalMap, bumpCoord1) * 2.0 - 1.0;
+    vec4 t2 = texture2D(NormalMap, bumpCoord2) * 2.0 - 1.0;
+    vec3 N = t0.xyz + t1.xyz + t2.xyz;
+
+    N = normalize(rotMatrix * N);
+
+	// reflection
+    vec3 E = normalize(eyeVector);
+    vec3 R = reflect(E, N);
+    // Ogre conversion for cube map lookup
+    R.z = -R.z;
+
+    vec4 reflection = textureCube(EnvironmentMap, R, reflectionBlur);
+    // cheap hdr effect
+    reflection.rgb *= (reflection.r + reflection.g + reflection.b) * hdrMultiplier;
+
+	// fresnel
+    float facing = 1.0 - dot(-E, N);
+    float fresnel = clamp(fresnelBias + pow(facing, fresnelPower), 0.0, 1.0);
+
+    vec4 waterColor = mix(shallowColor, deepColor, facing) * waterAmount;
+
+    reflection = mix(waterColor,  reflection * reflectionColor, fresnel) * reflectionAmount;
+    gl_FragColor = waterColor + reflection;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/Ocean2GLSL.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/Ocean2GLSL.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/Ocean2GLSL.vert	(revision 12083)
@@ -0,0 +1,92 @@
+/*********************************************************************NVMH3****
+Copyright NVIDIA Corporation 2003
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+	Simple ocean shader with animated bump map and geometric waves
+	Based partly on "Effective Water Simulation From Physical Models", GPU Gems
+
+11 Aug 05: converted from HLSL to GLSL by Jeff Doyle (nfz) to work in Ogre
+
+******************************************************************************/
+
+uniform vec3 eyePosition;
+uniform float BumpScale;
+uniform vec2 textureScale;
+uniform vec2 bumpSpeed;
+uniform float time;
+uniform float waveFreq;
+uniform float waveAmp;
+uniform mat4 worldViewProj;
+
+varying mat3 rotMatrix; //  transform from tangent to obj space
+varying vec2 bumpCoord0;
+varying vec2 bumpCoord1;
+varying vec2 bumpCoord2;
+varying vec3 eyeVector;
+
+// wave functions
+struct Wave {
+  float freq;  // 2*PI / wavelength
+  float amp;   // amplitude
+  float phase; // speed * 2*PI / wavelength
+  vec2 dir;
+};
+
+
+void main(void)
+{
+
+	#define NWAVES 2
+
+	Wave wave[NWAVES];
+
+	wave[0] = Wave( waveFreq, waveAmp, 0.5, vec2(-1, 0) );
+	wave[1] = Wave( 3.0 * waveFreq, 0.33 * waveAmp, 1.7, vec2(-0.7, 0.7) );
+
+
+    vec4 P = gl_Vertex;
+
+	// sum waves
+	float ddx = 0.0, ddy = 0.0;
+	float deriv;
+	float angle;
+
+	// wave synthesis using two sine waves at different frequencies and phase shift
+	for(int i = 0; i<NWAVES; ++i)
+	{
+		angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
+		P.y += wave[i].amp * sin( angle );
+		// calculate derivate of wave function
+		deriv = wave[i].freq * wave[i].amp * cos(angle);
+		ddx -= deriv * wave[i].dir.x;
+		ddy -= deriv * wave[i].dir.y;
+	}
+
+	// compute the 3x3 transform from tangent space to object space
+	// compute tangent basis
+    vec3 T = normalize(vec3(1.0, ddy, 0.0)) * BumpScale;
+    vec3 B = normalize(vec3(0.0, ddx, 1.0)) * BumpScale;
+    vec3 N = normalize(vec3(ddx, 1.0, ddy));
+
+	rotMatrix = mat3(T, B, N);
+
+	gl_Position = gl_ModelViewProjectionMatrix * P;
+
+	// calculate texture coordinates for normal map lookup
+	bumpCoord0.xy = gl_MultiTexCoord0.xy * textureScale + time * bumpSpeed;
+	bumpCoord1.xy = gl_MultiTexCoord0.xy * textureScale * 2.0 + time * bumpSpeed * 4.0;
+	bumpCoord2.xy = gl_MultiTexCoord0.xy * textureScale * 4.0 + time * bumpSpeed * 8.0;
+
+
+	eyeVector = P.xyz - eyePosition; // eye position in vertex space
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/OffsetMappingFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/OffsetMappingFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/OffsetMappingFp.glsl	(revision 12083)
@@ -0,0 +1,69 @@
+uniform vec4 lightDiffuse;
+uniform vec4 scaleBias;
+uniform vec4 spotParams;
+uniform vec4 lightDiffuse1;
+uniform vec4 spotParams1;
+
+uniform sampler2D normalHeightMap;
+uniform sampler2D diffuseMap;
+uniform sampler2D shadowMap1;
+uniform sampler2D shadowMap2;
+
+
+
+varying vec3 tangentEyeDir;
+varying vec3 tangentLightDir[2];
+varying vec3 tangentSpotDir[2];
+varying vec4 shadowUV[2];
+
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+
+void main()
+{
+	// get the height using the tex coords
+	float height = texture2D(normalHeightMap, gl_TexCoord[0].xy).a;
+	// scale and bias factors	
+	float scale = scaleBias.x;
+	float bias = scaleBias.y;
+
+	// calculate displacement	
+	float displacement = (height * scale) + bias;
+	//float displacement = (height * 0.04) - 0.02;
+	
+	vec3 scaledEyeDir = tangentEyeDir * displacement;
+	
+	// calculate the new tex coord to use for normal and diffuse
+	vec2 newTexCoord = (scaledEyeDir + gl_TexCoord[0].xyz).xy;
+	
+	// get the new normal and diffuse values
+	vec3 normal = expand(texture2D(normalHeightMap, newTexCoord).xyz);
+	vec4 diffuse = texture2D(diffuseMap, newTexCoord);
+	
+	vec4 col1 = diffuse * clamp(dot(normal, tangentLightDir[0]),0.0,1.0) * lightDiffuse;
+	// factor in spotlight angle
+	float rho = clamp(dot(tangentSpotDir[0], tangentLightDir[0]),0.0,1.0);
+	// factor = (rho - cos(outer/2) / cos(inner/2) - cos(outer/2)) ^ falloff
+	float spotFactor = pow(
+		clamp(rho - spotParams.y,0.0,1.0) / (spotParams.x - spotParams.y), spotParams.z);
+	col1 = col1 * spotFactor;
+	vec4 col2 = diffuse * clamp(dot(normal, tangentLightDir[1]),0.0,1.0) * lightDiffuse1;
+	// factor in spotlight angle
+	rho = clamp(dot(tangentSpotDir[1], tangentLightDir[1]),0.0,1.0);
+	// factor = (rho - cos(outer/2) / cos(inner/2) - cos(outer/2)) ^ falloff
+	spotFactor = pow(
+		clamp(rho - spotParams1.y,0.0,1.0) / (spotParams1.x - spotParams1.y), spotParams1.z);
+	col2 = col2 * spotFactor;
+
+	// shadow textures
+	col1 = col1 * texture2DProj(shadowMap1, shadowUV[0]);
+	col2 = col2 * texture2DProj(shadowMap2, shadowUV[1]);
+
+	gl_FragColor = col1 + col2;
+
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/OffsetMappingVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/OffsetMappingVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/OffsetMappingVp.glsl	(revision 12083)
@@ -0,0 +1,54 @@
+attribute vec3 tangent;
+
+uniform vec4 lightPosition; // object space 
+uniform vec4 lightPosition1; // object space 
+uniform vec4 eyePosition;   // object space 
+uniform vec4 spotDirection; // object space
+uniform vec4 spotDirection1; // object space
+uniform mat4 worldViewProj; // not actually used but here for compat with HLSL
+uniform mat4 worldMatrix;
+uniform mat4 texViewProj1;
+uniform mat4 texViewProj2;
+
+
+varying vec3 tangentEyeDir;
+varying vec3 tangentLightDir[2];
+varying vec3 tangentSpotDir[2];
+varying vec4 shadowUV[2];
+
+void main()
+{
+	gl_Position = ftransform();
+
+	vec4 worldPos = worldMatrix * gl_Vertex;
+
+	shadowUV[0] = texViewProj1 * worldPos;
+	shadowUV[1] = texViewProj2 * worldPos;
+
+	// pass the main uvs straight through unchanged 
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+
+	// calculate tangent space light vector 
+	// Get object space light direction 
+    vec3 lightDir = normalize(lightPosition.xyz -  (gl_Vertex.xyz * lightPosition.w));
+	vec3 lightDir1 = normalize(lightPosition1.xyz -  (gl_Vertex.xyz * lightPosition1.w));
+	
+	vec3 eyeDir = (eyePosition - gl_Vertex).xyz; 
+
+	// Calculate the binormal (NB we assume both normal and tangent are 
+	// already normalised) 
+	vec3 binormal = cross(gl_Normal, tangent); 
+
+	// Form a rotation matrix out of the vectors 
+	mat3 rotation = mat3(tangent, binormal, gl_Normal); 
+    
+	// Transform the light vector according to this matrix 
+	tangentLightDir[0] = normalize(rotation * lightDir); 
+	tangentLightDir[1] = normalize(rotation * lightDir1); 
+	// Invert the Y on the eye dir since we'll be using this to alter UVs and
+	// GL has Y inverted
+	tangentEyeDir = normalize(rotation * eyeDir) * vec3(1, -1, 1); 
+
+	tangentSpotDir[0] = normalize(rotation * -spotDirection.xyz);
+	tangentSpotDir[1] = normalize(rotation * -spotDirection1.xyz);	
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/PassthroughFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/PassthroughFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/PassthroughFP.glsl	(revision 12083)
@@ -0,0 +1,9 @@
+varying vec4 colour;
+
+/*
+  Basic ambient lighting fragment program for GLSL ES
+*/
+void main()
+{
+	gl_FragColor = colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/PassthroughVP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/PassthroughVP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/PassthroughVP.glsl	(revision 12083)
@@ -0,0 +1,5 @@
+void main()																					
+{																							
+	//Transform the vertex (ModelViewProj matrix)											
+	gl_Position = ftransform();																
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/ShaderInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/ShaderInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/ShaderInstancing.vert	(revision 12083)
@@ -0,0 +1,117 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 120
+
+//Vertex input
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec3 tangent;
+attribute vec4 uv0;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+//uniform mat4x3 worldMatrix3x4Array[80];
+#ifdef ST_DUAL_QUATERNION
+uniform vec4 worldDualQuaternion2x4Array[240];
+#else
+uniform vec4 worldMatrix3x4Array[240]; //240 = 80*3
+#endif
+
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	varying vec2 depth;
+#else
+	varying vec2 _uv0;
+	varying vec3 oNormal;
+	varying vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		varying vec4 oLightSpacePos;
+	#endif
+#endif
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+vec4 worldPos;
+vec3 worldNorm;
+
+#ifdef ST_DUAL_QUATERNION
+	int idx = int(blendIndices[0]) * 2;
+	mat2x4 blendDQ;
+	blendDQ[0] = worldDualQuaternion2x4Array[idx];
+	blendDQ[1] = worldDualQuaternion2x4Array[idx + 1];
+#ifdef BONE_TWO_WEIGHTS
+	int idx2 = int(blendIndices[1]) * 2;
+	mat2x4 blendDQ2;
+ 	blendDQ2[0] = worldDualQuaternion2x4Array[idx2];
+	blendDQ2[1] = worldDualQuaternion2x4Array[idx2 + 1];
+
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= blendWeights.x;
+	blendDQ += blendWeights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(normal, blendDQ);
+#else
+	mat4 worldMatrix;
+	int idx = int(blendIndices[0]) * 3;
+	worldMatrix[0] = worldMatrix3x4Array[idx];
+	worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+	worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	worldPos		= vertex * worldMatrix;
+	worldNorm		= normal * mat3(worldMatrix);
+#endif
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/StdQuad_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/StdQuad_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/StdQuad_vp.glsl	(revision 12083)
@@ -0,0 +1,11 @@
+varying vec2 uv;
+uniform mat4 worldViewProj;
+attribute vec2 uv0;
+
+void main()                    
+{
+	gl_Position = worldViewProj * gl_Vertex;
+	
+	uv = uv0;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/SwizzleGP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/SwizzleGP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/SwizzleGP.glsl	(revision 12083)
@@ -0,0 +1,40 @@
+#version 120																				
+#extension GL_EXT_geometry_shader4 : enable													
+
+uniform vec4 origColor;																		
+uniform vec4 cloneColor;																	
+
+void main(void)																				
+{																							
+
+	//increment variable																	
+	int i;																					
+
+	/////////////////////////////////////////////////////////////							
+	//This example has two parts															
+	//	step a) draw the primitive pushed down the pipeline									
+	//		 there are gl_Vertices # of vertices											
+	//		 put the vertex value into gl_Position											
+	//		 use EmitVertex => 'create' a new vertex										
+	// 		use EndPrimitive to signal that you are done creating a primitive!				
+	//	step b) create a new piece of geometry (I.E. WHY WE ARE USING A GEOMETRY SHADER!)	
+	//		I just do the same loop, but swizzle the x and y values							
+	//	result => the line we want to draw, and the same line, but along the other axis		
+
+	//Pass-thru!																			
+	for(i=0; i< gl_VerticesIn; i++){														
+		gl_Position = gl_PositionIn[i];														
+		gl_FrontColor = origColor;															
+		EmitVertex();																		
+	}																						
+	EndPrimitive();																			
+	//New piece of geometry!  We just swizzle the x and y terms								
+	for(i=0; i< gl_VerticesIn; i++){														
+		gl_Position = gl_PositionIn[i];														
+		gl_Position.xy = gl_Position.yx;													
+		gl_FrontColor = cloneColor;															
+		EmitVertex();																		
+	}																						
+	EndPrimitive();																			
+
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/VTFInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/VTFInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/VTFInstancing.vert	(revision 12083)
@@ -0,0 +1,113 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 120
+
+//Vertex input
+attribute vec4 vertex;
+attribute vec3 normal;
+
+#ifdef BONE_TWO_WEIGHTS
+	attribute vec4 blendWeights;
+#endif
+
+attribute vec4 uv0;
+attribute vec4 uv1;
+attribute vec4 uv2;
+attribute vec3 tangent;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+uniform sampler2D matrixTexture;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	varying vec2 depth;
+#else
+	varying vec2 _uv0;
+	varying vec3 oNormal;
+	varying vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		varying vec4 oLightSpacePos;
+	#endif
+#endif
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 worldPos;
+	vec3 worldNorm;
+
+#ifdef ST_DUAL_QUATERNION
+	mat2x4 blendDQ;	
+	blendDQ[0] = texture2D( matrixTexture, uv1.xy );
+	blendDQ[1] = texture2D( matrixTexture, uv1.zy );
+#ifdef BONE_TWO_WEIGHTS
+	mat2x4 blendDQ2;
+	blendDQ2[0] = texture2D( matrixTexture, uv2.xy );
+	blendDQ2[1] = texture2D( matrixTexture, uv2.zw );
+
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= blendWeights.x;
+	blendDQ += blendWeights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(normal, blendDQ);
+#else
+	mat4 worldMatrix;
+	worldMatrix[0] = texture2D( matrixTexture, uv1.xy );
+	worldMatrix[1] = texture2D( matrixTexture, uv1.zw );
+	worldMatrix[2] = texture2D( matrixTexture, uv2.xy );
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	worldPos		= vertex * worldMatrix;
+	worldNorm		= normal * mat3(worldMatrix);
+#endif
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/crowdVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/crowdVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/crowdVp.glsl	(revision 12083)
@@ -0,0 +1,62 @@
+uniform mat4 viewProjectionMatrix;
+uniform float numBones;
+uniform vec4 worldMatrix3x4Array[240];
+uniform vec4 lightDiffuseColour;
+uniform vec4 ambient;
+uniform vec4 lightPos;
+
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+
+void main()
+{
+	vec3 blendPos = vec3(0,0,0);
+	vec3 blendNorm = vec3(0,0,0);
+	
+	vec3 tmpPos = vec3(0,0,0);
+	vec3 tmpNorm = vec3(0,0,0);
+
+
+	int instanceOffset = int(gl_MultiTexCoord1.x) * 3 * int(numBones);
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+		for (int row = 0; row < 3; ++row)
+		{
+		    int idx = instanceOffset + int(blendIndices[bone]) * 3 + row;
+			vec4 blendMatrixRow = worldMatrix3x4Array[idx];
+			tmpPos[row] = dot(blendMatrixRow, gl_Vertex);
+#if SHADOW_CASTER
+#else
+			tmpNorm[row] = dot(blendMatrixRow.xyz, gl_Normal);
+#endif
+			
+		}
+		// now weight this into final 
+		blendPos += tmpPos * blendWeights[bone];
+#if SHADOW_CASTER
+#else
+		blendNorm += tmpNorm * blendWeights[bone];
+#endif
+	}
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1);
+
+	
+#if SHADOW_CASTER
+	gl_FrontColor = ambient;
+#else
+	// simple lighting model
+	vec3 lightDir = normalize(
+		lightPos.xyz -  (blendPos.xyz * lightPos.w));
+	gl_FrontColor = ambient 
+		+ clamp(dot(lightDir, blendNorm), 0.0, 1.0) * lightDiffuseColour;
+#endif
+    gl_FrontSecondaryColor = vec4(0);
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+
+	
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/hdr_bloom.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/hdr_bloom.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/hdr_bloom.glsl	(revision 12083)
@@ -0,0 +1,22 @@
+uniform sampler2D inRTT;
+
+uniform vec4 sampleOffsets[15];
+uniform vec4 sampleWeights[15];
+
+varying vec2 uv;
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 1.0);
+	vec2 sampleUV;
+    
+    for( int i = 0; i < 15; i++ )
+    {
+        // Sample from adjacent points, 7 each side and central
+        sampleUV = uv + sampleOffsets[i].xy;
+        accum += sampleWeights[i] * texture2D(inRTT, sampleUV);
+    }
+    
+    gl_FragColor = accum;
+	
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale2x2luminence.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale2x2luminence.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale2x2luminence.glsl	(revision 12083)
@@ -0,0 +1,24 @@
+uniform sampler2D inRTT;
+uniform vec2 texelSize;
+
+varying vec2 uv;
+
+void main(void)
+{
+	
+    vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+	vec4 LUMINENCE_FACTOR  = vec4(0.27, 0.67, 0.06, 0.0);
+
+    // Get colour from source
+    accum += texture2D(inRTT, uv + texelSize * vec2(-0.5, -0.5));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-0.5, 0.5));
+    accum += texture2D(inRTT, uv + texelSize * vec2(0.5, 0.5));
+    accum += texture2D(inRTT, uv + texelSize * vec2(0.5, -0.5));
+    
+	// Adjust the accumulated amount by lum factor
+	float lum = dot(accum, LUMINENCE_FACTOR);
+	// take average of 4 samples
+	lum *= 0.25;
+	gl_FragColor = vec4(lum, lum, lum, 1.0);
+
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale3x3.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale3x3.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale3x3.glsl	(revision 12083)
@@ -0,0 +1,26 @@
+uniform sampler2D inRTT;
+uniform vec2 texelSize;
+
+varying vec2 uv;
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+
+    // Get colour from source
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  1.0));
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+	gl_FragColor = accum;
+
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale3x3brightpass.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale3x3brightpass.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/hdr_downscale3x3brightpass.glsl	(revision 12083)
@@ -0,0 +1,37 @@
+uniform sampler2D inRTT;
+uniform sampler2D inLum;
+uniform vec2 texelSize;
+
+varying vec2 uv;
+const vec4 BRIGHT_LIMITER = vec4(0.6, 0.6, 0.6, 0.0);
+
+// declare external function
+vec4 toneMap(in vec4 inColour, in float lum);
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  1.0));
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+    // Reduce bright and clamp
+    accum = max(vec4(0.0, 0.0, 0.0, 1.0), accum - BRIGHT_LIMITER);
+
+	// Sample the luminence texture
+	vec4 lum = texture2D(inLum, vec2(0.5, 0.5));
+	
+	// Tone map result
+	gl_FragColor = toneMap(accum, lum.r);
+
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/hdr_finalToneMapping.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/hdr_finalToneMapping.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/hdr_finalToneMapping.glsl	(revision 12083)
@@ -0,0 +1,28 @@
+uniform sampler2D inRTT;
+uniform sampler2D inBloom;
+uniform sampler2D inLum;
+
+varying vec2 uv;
+
+// declare external function
+vec4 toneMap(in vec4 inColour, in float lum);
+
+void main(void)
+{
+	// Get main scene colour
+    vec4 sceneCol = texture2D(inRTT, uv);
+
+	// Get luminence value
+	vec4 lum = texture2D(inLum, vec2(0.5, 0.5));
+
+	// tone map this
+	vec4 toneMappedSceneCol = toneMap(sceneCol, lum.r);
+	
+	// Get bloom colour
+    vec4 bloom = texture2D(inBloom, uv);
+
+	// Add scene & bloom
+	gl_FragColor = vec4(toneMappedSceneCol.rgb + bloom.rgb, 1.0);
+    
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/hdr_tonemap_util.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/hdr_tonemap_util.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/hdr_tonemap_util.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+const float MIDDLE_GREY = 0.72;
+const float FUDGE = 0.001;
+const float L_WHITE = 1.5;
+
+/** Tone mapping function 
+@note Only affects rgb, not a
+@param inColour The HDR colour
+@param lum The scene lumninence 
+@returns Tone mapped colour
+*/
+vec4 toneMap(in vec4 inColour, in float lum)
+{
+	// From Reinhard et al
+	// "Photographic Tone Reproduction for Digital Images"
+	
+	// Initial luminence scaling (equation 2)
+    inColour.rgb *= MIDDLE_GREY / (FUDGE + lum);
+
+	// Control white out (equation 4 nom)
+    inColour.rgb *= (1.0 + inColour.rgb / L_WHITE);
+
+	// Final mapping (equation 4 denom)
+	inColour.rgb /= (1.0 + inColour.rgb);
+	
+	return inColour;
+
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/instancingVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/instancingVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/instancingVp.glsl	(revision 12083)
@@ -0,0 +1,39 @@
+uniform vec4 worldMatrix3x4Array[240];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 lightPos;
+uniform vec4 ambient;
+uniform vec4 lightDiffuseColour;
+
+void main()
+{
+
+	// transform by indexed matrix
+	// perform matrix multiplication manually since no 3x4 matrices
+	vec3 transformedPos;
+	vec3 transformedNorm;
+	int instanceOffset = int(gl_MultiTexCoord1.x) * 3;
+	for (int row = 0; row < 3; ++row)
+	{
+		vec4 matrixRow = worldMatrix3x4Array[instanceOffset + row];
+		transformedPos[row] = dot(matrixRow, gl_Vertex);
+#if SHADOW_CASTER
+#else
+		transformedNorm[row] = dot(matrixRow.xyz, gl_Normal);
+#endif
+		
+	}
+	
+	// view / projection
+	gl_Position = viewProjectionMatrix * vec4(transformedPos,1);
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+    gl_FrontSecondaryColor = vec4(0);
+	
+#if SHADOW_CASTER
+	gl_FrontColor = ambient;
+#else
+	vec3 lightDir = normalize(
+		lightPos.xyz -  (transformedPos.xyz * lightPos.w));
+	gl_FrontColor = ambient + clamp(dot(lightDir, transformedNorm),0.0,1.0) * lightDiffuseColour;
+#endif
+	
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/mrttestfp_quad.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/mrttestfp_quad.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/mrttestfp_quad.glsl	(revision 12083)
@@ -0,0 +1,17 @@
+uniform sampler2D rt0;
+uniform sampler2D rt1;
+uniform sampler2D rt2;
+uniform sampler2D rt3;
+
+varying vec2 uv;
+
+void main(void)
+{
+    
+    //gl_FragColor = texture2D(rt0, uv);
+    gl_FragColor = texture2D(rt1, uv);
+    //gl_FragColor = texture2D(rt2, uv);
+    //gl_FragColor = texture2D(rt3, uv);
+	
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/mrttestfp_scene.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/mrttestfp_scene.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/mrttestfp_scene.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+// Need to enable the draw buffers extension
+#extension GL_ARB_draw_buffers : enable
+
+uniform sampler2D tex0;
+
+void main()                    
+{
+	vec4 baseColour = texture2D(tex0, gl_TexCoord[0].xy);
+
+	gl_FragData[0] = baseColour;
+
+	gl_FragData[1] = baseColour * vec4(1, 0, 0, 1);
+
+	float abs = (baseColour.r + baseColour.g + baseColour.b) * 0.333;
+	gl_FragData[2] = vec4(abs, abs, abs, 1);
+	
+	float invabs = 1.0 - abs;
+	gl_FragData[3] = vec4(invabs, invabs, invabs, 1);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL/oceanGLSL.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/oceanGLSL.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/oceanGLSL.frag	(revision 12083)
@@ -0,0 +1,45 @@
+// oceanGLSL.frag
+// fragment program for Ocean water simulation
+// 05 Aug 2005
+// adapted for Ogre by nfz
+// converted from HLSL to GLSL
+// original shader source from Render Monkey 1.6 Reflections Refractions.rfx
+
+// 06 Aug 2005: moved uvw calculation from fragment program into vertex program 
+
+uniform float fadeBias;
+uniform float fadeExp;
+uniform vec4 waterColor;
+uniform sampler3D Noise;
+uniform samplerCube skyBox;
+
+varying vec3 uvw;
+varying vec3 normal;
+varying vec3 vVec;
+
+void main(void)
+{
+   vec3 noisy = texture3D(Noise, uvw).xyz;
+   
+   // convert to signed noise
+   vec3 bump = 2.0 * noisy - 1.0;
+   bump.xz *= 0.15;
+   // Make sure the normal always points upwards
+   // note that Ogres y axis is vertical (RM Z axis is vertical)
+   bump.y = 0.8 * abs(bump.y) + 0.2;
+   // Offset the surface normal with the bump
+   bump = normalize(normal + bump);
+
+   // Find the reflection vector
+   vec3 normView = normalize(vVec);
+   vec3 reflVec = reflect(normView, bump);
+   // Ogre has z flipped for cubemaps
+   reflVec.z = -reflVec.z;
+   vec4 refl = textureCube(skyBox, reflVec);
+
+   // set up for fresnel calc
+   float lrp = 1.0 - dot(-normView, bump);
+   
+   // Interpolate between the water color and reflection for fresnel effect
+   gl_FragColor = mix(waterColor, refl, clamp(fadeBias + pow(lrp, fadeExp), 0.0, 1.0) );
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/oceanGLSL.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/oceanGLSL.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/oceanGLSL.vert	(revision 12083)
@@ -0,0 +1,33 @@
+// oceanGLSL.vert
+// vertex program for Ocean water simulation
+// 05 Aug 2005
+// adapted for Ogre by nfz
+// converted from HLSL to GLSL
+// original shader source from Render Monkey 1.6 Reflections Refractions.rfx
+
+// 06 Aug 2005: moved uvw calculation from fragment program into vertex program 
+
+uniform vec3 scale;
+uniform vec3 eyePosition;
+uniform vec2 waveSpeed;
+uniform float noiseSpeed;
+uniform float time_0_X;
+uniform mat4 worldViewProj;
+
+varying vec3 uvw;
+varying vec3 normal;
+varying vec3 vVec;
+
+void main(void)
+{
+   gl_Position = worldViewProj * gl_Vertex;
+   
+   //  the view vector needs to be in vertex space
+   vVec = gl_Vertex.xyz - eyePosition;
+   normal = gl_Normal;
+   // uvw is the calculated uvw coordinates based on vertex position
+   uvw = gl_Vertex.xyz * scale.xyz;
+   uvw.xz += waveSpeed * time_0_X;
+   uvw.y += uvw.z + noiseSpeed * time_0_X;
+   
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/shadows.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/shadows.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/shadows.glsl	(revision 12083)
@@ -0,0 +1,146 @@
+/* Copyright Torus Knot Software Ltd 2012-2013
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Adapted by Matias N. Goldberg (Dark Sylinc) to GLSL based on the Cg file shadows.cg
+*/
+
+// Simple PCF 
+// Number of samples in one dimension (square for total samples)
+#define NUM_SHADOW_SAMPLES_1D 2.0
+#define SHADOW_FILTER_SCALE 1.0
+
+#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D
+
+vec4 offsetSample(vec4 uv, vec2 offset, float invMapSize)
+{
+	return vec4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w);
+}
+
+float calcDepthShadow(sampler2DShadow shadowMap, vec4 uv, float invShadowMapSize)
+{
+	// 4-sample PCF
+	
+	float shadow = 0.0;
+	float offset = (NUM_SHADOW_SAMPLES_1D/2.0 - 0.5) * SHADOW_FILTER_SCALE;
+	for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE)
+		for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE)
+		{
+			float depth = shadow2DProj(shadowMap, offsetSample(uv, vec2(x, y), invShadowMapSize)).x;
+			if (depth >= 1.0 || depth >= uv.z)
+				shadow += 1.0;
+		}
+
+	shadow /= SHADOW_SAMPLES;
+
+	return shadow;
+}
+
+
+float calcSimpleShadow(sampler2DShadow shadowMap, vec4 shadowMapPos)
+{
+	return shadow2DProj(shadowMap, shadowMapPos).x;
+}
+
+float calcPSSMDepthShadow(sampler2DShadow shadowMap0, sampler2DShadow shadowMap1, sampler2DShadow shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = vec4(0.3, 0.0, 0, 0);
+		shadow = calcDepthShadow(shadowMap0, lsPos0, invShadowmapSize0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = vec4(0, 0.3, 0, 0);
+		shadow = calcDepthShadow(shadowMap1, lsPos1, invShadowmapSize1);
+	}
+	else
+	{
+		splitColour = vec4(0.0, 0.0, 0.3, 0);
+		shadow = calcDepthShadow(shadowMap2, lsPos2, invShadowmapSize2);
+	}
+
+	return shadow;
+}
+
+float calcPSSMSimpleShadow(sampler2DShadow shadowMap0, sampler2DShadow shadowMap1, sampler2DShadow shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = vec4(0.3, 0.0, 0, 0);
+		shadow = calcSimpleShadow(shadowMap0, lsPos0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = vec4(0, 0.3, 0, 0);
+		shadow = calcSimpleShadow(shadowMap1, lsPos1);
+	}
+	else
+	{
+		splitColour = vec4(0.0, 0.0, 0.3, 0);
+		shadow = calcSimpleShadow(shadowMap2, lsPos2);
+	}
+
+	return shadow;
+}
+
+
+
+vec3 calcPSSMDebugShadow(sampler2DShadow shadowMap0, sampler2DShadow shadowMap1, sampler2DShadow shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		//splitColour = vec4(0.3, 0.0, 0, 0);
+		//splitColour = lsPos0 / lsPos0.w;
+		splitColour.rgb = shadow2DProj(shadowMap0, lsPos0).xxx;
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		//splitColour = vec4(0, 0.3, 0, 0);
+		//splitColour = lsPos1 / lsPos1.w;
+		splitColour.rgb = shadow2DProj(shadowMap1, lsPos1).xxx;
+	}
+	else
+	{
+		//splitColour = vec4(0.0, 0.0, 0.3, 0);
+		//splitColour = lsPos2 / lsPos2.w;
+		splitColour.rgb = shadow2DProj(shadowMap2, lsPos2).xxx;
+	}
+
+	return splitColour.rgb;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/skinningTwoWeightsShadowCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/skinningTwoWeightsShadowCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/skinningTwoWeightsShadowCasterVp.glsl	(revision 12083)
@@ -0,0 +1,42 @@
+// Example GLSL program for skinning with two bone weights per vertex
+
+attribute vec4 vertex;
+attribute vec4 uv0;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+// 3x4 matrix, passed as vec4's for compatibility with GL 2.0
+// GL 2.0 supports 3x4 matrices
+// Support 24 bones ie 24*3, but use 72 since our parser can pick that out for sizing
+uniform vec4 worldMatrix3x4Array[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 ambient;
+
+void main()
+{
+	vec3 blendPos = vec3(0,0,0);
+
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+        // ATI GLSL compiler can't handle indexing an array within an array so calculate the inner index first
+	    int idx = int(blendIndices[bone]) * 3;
+        // ATI GLSL compiler can't handle unrolling the loop so do it manually
+        // ATI GLSL has better performance when mat4 is used rather than using individual dot product
+        // There is a bug in ATI mat4 constructor (Cat 7.2) when indexed uniform array elements are used as vec4 parameter so manually assign
+		mat4 worldMatrix;
+		worldMatrix[0] = worldMatrix3x4Array[idx];
+		worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+		worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+		worldMatrix[3] = vec4(0);
+		// now weight this into final 
+		blendPos += (vertex * worldMatrix).xyz * blendWeights[bone];
+	}
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1);
+	
+	gl_FrontSecondaryColor = vec4(0,0,0,0);
+	gl_FrontColor = ambient;
+	gl_TexCoord[0] = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL/skinningTwoWeightsVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL/skinningTwoWeightsVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL/skinningTwoWeightsVp.glsl	(revision 12083)
@@ -0,0 +1,63 @@
+// Example GLSL program for skinning with two bone weights per vertex
+
+attribute vec4 vertex;
+attribute vec3 normal;
+attribute vec4 uv0;
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+// 3x4 matrix, passed as vec4's for compatibility with GL 2.0
+// GL 2.0 supports 3x4 matrices
+// Support 24 bones ie 24*3, but use 72 since our parser can pick that out for sizing
+uniform vec4 worldMatrix3x4Array[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 lightPos[2];
+uniform vec4 lightDiffuseColour[2];
+uniform vec4 ambient;
+uniform vec4 diffuse;
+
+varying vec4 colour;
+varying vec4 uv;
+
+void main()
+{
+	vec3 blendPos = vec3(0.0, 0.0, 0.0);
+	vec3 blendNorm = vec3(0.0, 0.0, 0.0);
+
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+        // ATI GLSL compiler can't handle indexing an array within an array so calculate the inner index first
+		int idx = int(blendIndices[bone]) * 3;
+        // ATI GLSL compiler can't handle unrolling the loop so do it manually
+        // ATI GLSL has better performance when mat4 is used rather than using individual dot product
+        // There is a bug in ATI mat4 constructor (Cat 7.2) when indexed uniform array elements are used as vec4 parameter so manually assign
+		mat4 worldMatrix;
+		worldMatrix[0] = worldMatrix3x4Array[idx];
+		worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+		worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+		worldMatrix[3] = vec4(0);
+		// now weight this into final
+		float weight = blendWeights[bone];
+		blendPos += (vertex * worldMatrix).xyz * weight;
+
+		mat3 worldRotMatrix = mat3(worldMatrix[0].xyz, worldMatrix[1].xyz, worldMatrix[2].xyz);
+		blendNorm += (normal * worldRotMatrix) * weight;
+	}
+
+	blendNorm = normalize(blendNorm);
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1.0);
+
+	// simple vertex lighting model
+	vec3 lightDir0 = normalize(
+		lightPos[0].xyz -  (blendPos * lightPos[0].w));
+	vec3 lightDir1 = normalize(
+		lightPos[1].xyz -  (blendPos * lightPos[1].w));
+
+	colour = diffuse * (ambient + (clamp(dot(lightDir0, blendNorm), 0.0, 1.0) * lightDiffuseColour[0]) +
+		(clamp(dot(lightDir1, blendNorm), 0.0, 1.0) * lightDiffuseColour[1]));
+
+	uv = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ASCIIFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ASCIIFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ASCIIFP.glsl	(revision 12083)
@@ -0,0 +1,37 @@
+#version 150
+
+in vec4 pos;
+in vec2 oUv0;
+out vec4 fragColour;
+
+uniform sampler2D RT;
+uniform sampler3D chars;
+uniform vec2 numTiles;
+uniform vec2 iNumTiles;
+uniform vec2 iNumTiles2;
+uniform vec4 lum;
+uniform float charBias;
+
+void main()
+{
+    vec3 local;
+
+	//sample RT
+	local.xy = mod(oUv0, iNumTiles);
+	vec2 middle = oUv0 - local.xy;
+	local.xy = local.xy * numTiles;
+	
+	//iNumTiles2 = iNumTiles / 2
+	middle = middle + iNumTiles2;
+	vec4 c = texture(RT, middle);
+	
+	//multiply luminance by charbias , beacause not all slices of the ascii
+	//volume texture are used
+	local.z = dot(c , lum)*charBias;
+	
+	//fix to brighten the dark pixels with small characters
+	//c *= lerp(2.0,1.0, local.z);
+	
+	c *= texture(chars, local);
+	fragColour = c;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/AmbientOneTexture.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/AmbientOneTexture.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/AmbientOneTexture.glsl	(revision 12083)
@@ -0,0 +1,17 @@
+#version 150
+
+uniform vec4 ambient;
+uniform mat4 worldViewProj;
+
+in vec4 position;
+
+out vec4 colour;
+
+/*
+  Basic ambient lighting vertex program for GLSL
+*/
+void main()
+{
+	gl_Position = worldViewProj * position;
+	colour = ambient;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/AmbientOneTextureWithUV.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/AmbientOneTextureWithUV.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/AmbientOneTextureWithUV.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+#version 150
+
+uniform vec4 ambient;
+uniform mat4 worldViewProj;
+
+in vec4 position;
+in vec4 uv0;
+
+out vec4 ambColour;
+out vec4 ambientUV;
+
+/*
+  Basic ambient lighting vertex program for GLSL
+*/
+void main()
+{
+	gl_Position = worldViewProj * position;
+	ambColour = ambient;
+	ambientUV = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Bloom2_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Bloom2_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Bloom2_ps20.glsl	(revision 12083)
@@ -0,0 +1,31 @@
+#version 150
+
+//-------------------------------
+//Bloom_ps20.glsl
+// Blends using weights the blurred image with the sharp one
+// Params:
+//   OriginalImageWeight
+//   BlurWeight
+//-------------------------------
+
+uniform sampler2D RT;
+uniform sampler2D Blur1;
+
+uniform float OriginalImageWeight;
+uniform float BlurWeight;
+
+out vec4 fragColour;
+in vec2 texCoord[5];
+
+void main()
+{
+    vec4 sharp;
+    vec4 blur;
+    
+
+    sharp = texture(RT, texCoord[0]);
+    blur = texture(Blur1, texCoord[0]);
+    
+    fragColour = ( (blur * BlurWeight) + (sharp * OriginalImageWeight) );
+    //fragColour = vec4(0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Blur0_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Blur0_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Blur0_vs.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+#version 150
+
+out vec2 texCoord[5];
+in vec4 vertex;
+
+uniform mat4 worldViewProj;
+in vec2 uv0;
+
+void main()                    
+{
+	gl_Position = worldViewProj * vertex;
+	
+	texCoord[0]  = uv0;
+	
+	const float size = 0.01;
+	texCoord[1] = texCoord[0] + vec2(1.0, 0.0)*size;
+	texCoord[2] = texCoord[0] + vec2(2.0, 0.0)*size;
+	texCoord[3] = texCoord[0] + vec2(-1.0, 0.0)*size;
+	texCoord[4] = texCoord[0] + vec2(-2.0, 0.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Blur1_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Blur1_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Blur1_vs.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+#version 150
+
+uniform mat4 worldViewProj;
+
+out vec2 texCoord[5];
+in vec4 vertex;
+in vec2 uv0;
+
+void main()
+{
+	gl_Position = worldViewProj * vertex;
+	
+	texCoord[0]  = uv0;
+	
+	const float size = 0.01;
+	texCoord[1] = texCoord[0] + vec2(0.0, 1.0)*size;
+	texCoord[2] = texCoord[0] + vec2(0.0, 2.0)*size;
+	texCoord[3] = texCoord[0] + vec2(0.0, -1.0)*size;
+	texCoord[4] = texCoord[0] + vec2(0.0, -2.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/BlurH_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/BlurH_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/BlurH_ps20.glsl	(revision 12083)
@@ -0,0 +1,58 @@
+#version 150
+
+//-------------------------------
+//BlurH_ps20.glsl
+// Horizontal Gaussian-Blur pass
+//-------------------------------
+
+uniform sampler2D Blur0;
+out vec4 fragColour;
+in vec2 texCoord[5];
+
+vec2 pos[11] = vec2[11]
+(
+	vec2( -5, 0),
+	vec2( -4, 0),
+	vec2( -3, 0),
+	vec2( -2, 0),
+	vec2( -1, 0),
+	vec2( 0, 0),
+	vec2( 1, 0),
+	vec2( 2, 0),
+	vec2( 3, 0),
+	vec2( 4, 0),
+	vec2( 5, 0)
+);
+
+//We use the Normal-gauss distribution formula
+//f(x) being the formula, we used f(0.5)-f(-0.5); f(1.5)-f(0.5)...
+float samples[11] = float[11]
+(//stddev=2.0
+0.01222447,
+0.02783468,
+0.06559061,
+0.12097757,
+0.17466632,
+
+0.19741265,
+
+0.17466632,
+0.12097757,
+0.06559061,
+0.02783468,
+0.01222447
+);
+
+void main()
+{
+    vec4 retVal;
+    
+    vec4 sum = vec4( 0 );
+
+    for( int i=0;i < 11; i++ )
+    {
+        sum += texture( Blur0, texCoord[0] + (pos[i] * 0.0100000) ) * samples[i];
+    }
+
+    fragColour = sum;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/BlurV_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/BlurV_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/BlurV_ps20.glsl	(revision 12083)
@@ -0,0 +1,64 @@
+#version 150
+
+// Note, this won't work on ATI which is why it's not used
+// the issue is with the array initializers
+// no card supports GL_3DL_array_objects but it does work on nvidia, not on ATI
+//#extension GL_3DL_array_objects : enable
+
+//-------------------------------
+//BlurV_ps20.glsl
+// Vertical Gaussian-Blur pass
+//-------------------------------
+
+uniform sampler2D Blur0;
+out vec4 fragColour;
+in vec2 texCoord[5];
+
+vec2 pos[11]  = vec2[11](
+	vec2(0.0, -5.0),
+	vec2(0.0, -4.0),
+	vec2(0.0, -3.0),
+	vec2(0.0, -2.0),
+	vec2(0.0, -1.0),
+	vec2(0.0, 0.0),
+	vec2(0.0, 1.0),
+	vec2(0.0, 2.0),
+	vec2(0.0, 3.0),
+	vec2(0.0, 4.0),
+	vec2(0.0, 5.0)
+);
+
+//We use the Normal-gauss distribution formula
+//f(x) being the formula, we used f(0.5)-f(-0.5); f(1.5)-f(0.5)...
+float samples[11] = float[11] 
+(//stddev=2.0
+0.01222447,
+0.02783468,
+0.06559061,
+0.12097757,
+0.17466632,
+
+0.19741265,
+
+0.17466632,
+0.12097757,
+0.06559061,
+0.02783468,
+0.01222447
+);
+
+void main()
+{
+    vec4 retVal;
+    
+    vec4 sum;
+    int i = 0;
+
+    sum = vec4( 0 );
+    for( ;i < 11; i++ )
+    {
+        sum += texture( Blur0, texCoord[0] + (pos[i] * 0.0100000) ) * samples[i];
+    }
+
+    fragColour = sum;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Blur_ps.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Blur_ps.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Blur_ps.glsl	(revision 12083)
@@ -0,0 +1,18 @@
+#version 150
+
+uniform sampler2D tex0;
+
+in vec2 texCoord[5];
+
+out vec4 fragColour;
+
+void main()
+{
+	vec4 sum = texture(tex0, texCoord[0]) + 
+			   texture(tex0, texCoord[1]) +
+			   texture(tex0, texCoord[2]) + 
+			   texture(tex0, texCoord[3]) +
+			   texture(tex0, texCoord[4]);
+	fragColour = sum / 5.0;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Blur_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Blur_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Blur_vs.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+#version 150
+
+in vec4 vertex;
+out vec2 texCoord[5];
+
+uniform mat4 worldViewProj;
+in vec2 uv0;
+
+void main()
+{
+	gl_Position = worldViewProj * vertex;
+
+	texCoord[0] = uv0;
+	
+	const float size = 0.01;
+	texCoord[1] = uv0 + vec2(0.0, 1.0)*size;
+	texCoord[2] = uv0 + vec2(0.0, 2.0)*size;
+	texCoord[3] = uv0 + vec2(0.0, -1.0)*size;
+	texCoord[4] = uv0 + vec2(0.0, -2.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/BrightBloom2_ps20.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/BrightBloom2_ps20.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/BrightBloom2_ps20.glsl	(revision 12083)
@@ -0,0 +1,33 @@
+#version 150
+
+//-------------------------------
+//BrightBloom_ps20.glsl
+// High-pass filter for obtaining lumminance
+// We use an aproximation formula that is pretty fast:
+//   f(x) = ( -3 * ( x - 1 )^2 + 1 ) * 2
+//   Color += Grayscale( f(Color) ) + 0.6
+//
+// Special thanks to ATI for their great HLSL2GLSL utility
+//     http://sourceforge.net/projects/hlsl2glsl
+//-------------------------------
+
+uniform sampler2D RT;
+out vec4 fragColour;
+in vec2 oUv0;
+
+void main()
+{
+    vec4 tex;
+    vec4 bright4;
+    float bright;
+    
+    vec2 texCoord = oUv0.xy;
+
+    tex = texture( RT, texCoord);
+    tex -= 1.00000;
+    bright4 = -6.00000 * tex * tex + 2.00000;
+    bright = dot( bright4, vec4( 0.333333, 0.333333, 0.333333, 0.000000) );
+    tex += (bright + 0.600000);
+
+    fragColour = tex;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/BumpMapVPTangentParity.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/BumpMapVPTangentParity.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/BumpMapVPTangentParity.glsl	(revision 12083)
@@ -0,0 +1,51 @@
+#version 150
+
+/* Bump mapping vertex program
+   In this program, we want to calculate the tangent space light vector
+   on a per-vertex level which will get passed to the fragment program,
+   or to the fixed function dot3 operation, to produce the per-pixel
+   lighting effect. 
+*/
+// parameters
+uniform vec4 lightPosition; // object space
+uniform mat4 worldViewProj;
+uniform vec4 lightDiffuse;
+
+in vec4 vertex;
+in vec3 normal;
+in vec4 tangent;
+in vec2 uv0;
+
+out vec2 oUv0;
+out vec3 oTSLightDir;
+out vec4 colour;
+
+void main()
+{
+	// Calculate output position
+	gl_Position = worldViewProj * vertex;
+
+	// Pass the main uvs straight through unchanged
+	oUv0 = uv0;
+
+	// Calculate tangent space light vector
+	// Get object space light direction
+	// Non-normalised since we'll do that in the fragment program anyway
+	vec3 lightDir = lightPosition.xyz - (vertex * lightPosition.w).xyz;
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+
+	// Fixed handedness
+	vec3 binormal = cross(normal, tangent.xyz) * tangent.www;
+
+	// Form a rotation matrix out of the vectors, column major for glsl es 
+	mat3 rotation = mat3(tangent.xyz,binormal,normal);
+//	mat3 rotation = mat3(vec3(tangent[0], binormal[0], normal[0]),
+//						vec3(tangent[1], binormal[1], normal[1]),
+//						vec3(tangent[2], binormal[2], normal[2]));
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = rotation * lightDir;
+	colour = lightDiffuse;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ColdCasterFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ColdCasterFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ColdCasterFp.glsl	(revision 12083)
@@ -0,0 +1,9 @@
+#version 150
+
+in vec2 NDotV;
+out vec4 fragColour;
+
+void main()
+{
+   fragColour = vec4(NDotV.x / 2.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ColdCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ColdCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ColdCasterVp.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+#version 150
+
+uniform mat4 worldViewProj;
+uniform vec3 eyePosition;
+in vec4 position;
+in vec4 normal;
+out vec2 NDotV;
+
+void main()
+{
+   vec4 eyeDir = vec4(eyePosition - position.xyz, 0.0);
+   eyeDir = normalize(eyeDir);
+   gl_Position = worldViewProj * position;
+   NDotV = vec2(clamp( dot( normal, eyeDir ), 0.0, 1.0 ));
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Combine_fp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Combine_fp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Combine_fp.glsl	(revision 12083)
@@ -0,0 +1,16 @@
+#version 150
+
+uniform sampler2D RT;
+uniform sampler2D Sum;
+uniform float blur;
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+   vec4 render = texture(RT, oUv0);
+   vec4 sum = texture(Sum, oUv0);
+
+   fragColour = mix(render, sum, blur);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowObjectFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowObjectFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowObjectFp.glsl	(revision 12083)
@@ -0,0 +1,150 @@
+#version 150
+/* Copyright Torus Knot Software Ltd 2000-2013
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+in vec3 diffuseUV;
+uniform sampler2D diffuseMap;
+uniform vec3 materialAmbient;
+
+#if !SHADOWCASTER
+in vec3 col;
+#endif
+#if DEPTH_SHADOWCASTER
+in float depth;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+in vec4 lightSpacePos0;
+in vec4 lightSpacePos1;
+in vec4 lightSpacePos2;
+uniform sampler2D shadowMap0;
+uniform sampler2D shadowMap1;
+uniform sampler2D shadowMap2;
+uniform float inverseShadowmapSize0;
+uniform float inverseShadowmapSize1;
+uniform float inverseShadowmapSize2;
+uniform vec4 pssmSplitPoints;
+#endif
+	
+#if SHADOWCASTER
+uniform vec3 shadowColour;
+#endif
+#if FOG
+uniform vec3 fogColour;
+#endif
+
+out vec4 fragColour;
+
+// Number of samples in one dimension (square for total samples)
+#define NUM_SHADOW_SAMPLES_1D 2.0
+#define SHADOW_FILTER_SCALE 1
+
+#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D
+
+vec4 offsetSample(vec4 uv, vec2 offset, float invMapSize)
+{
+	return vec4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w);
+}
+
+float calcDepthShadow(sampler2D shadowMap, vec4 uv, float invShadowMapSize)
+{
+	// 4-sample PCF
+	
+	float shadow = 0.0;
+	float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE;
+	for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE)
+		for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE)
+		{
+			float depth = textureProj(shadowMap, offsetSample(uv, vec2(x, y), invShadowMapSize)).x;
+			if (depth >= 1 || depth >= uv.z)
+				shadow += 1.0;
+		}
+
+	shadow /= SHADOW_SAMPLES;
+
+	return shadow;
+}
+
+float calcPSSMDepthShadow(sampler2D shadowMap0, sampler2D shadowMap1, sampler2D shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = vec4(0.3, 0.0, 0, 0);
+		shadow = calcDepthShadow(shadowMap0, lsPos0, invShadowmapSize0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = vec4(0, 0.3, 0, 0);
+		shadow = calcDepthShadow(shadowMap1, lsPos1, invShadowmapSize1);
+	}
+	else
+	{
+		splitColour = vec4(0.0, 0.0, 0.3, 0);
+		shadow = calcDepthShadow(shadowMap2, lsPos2, invShadowmapSize2);
+	}
+
+	return shadow;
+}
+
+void main()
+{
+    // look up the diffuse map layer
+    vec4 texDiffuse = texture(diffuseMap, diffuseUV.xy);
+    
+#if SHADOWCASTER
+#  if DEPTH_SHADOWCASTER
+	// early-out with depth (we still include alpha for those cards that support it)
+	fragColour = vec4(depth, depth, depth, 1);
+#  else
+	fragColour = vec4(shadowColour.xyz, texDiffuse.a);
+#  endif
+
+#else
+    // compute the ambient contribution (pulled from the diffuse map)
+    vec3 vAmbient = texDiffuse.xyz * materialAmbient.xyz;
+    vec3 vColor3 = texDiffuse.rgb * col.rgb;
+
+#  if DEPTH_SHADOWRECEIVER
+	float camDepth = diffuseUV.z;
+	float shadow = calcPSSMDepthShadow(shadowMap0, shadowMap1, shadowMap2, 
+		lightSpacePos0, lightSpacePos1, lightSpacePos2,
+		inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2,
+		pssmSplitPoints, camDepth);
+	vColor3 *= shadow;
+#  endif
+
+    fragColour = vec4(vColor3 + vAmbient, texDiffuse.a);
+    
+#  if FOG
+    // if fog is active, interpolate between the unfogged color and the fog color
+    // based on vertex shader fog value
+    fragColour.rgb = mix(vColor.rgb, fogColour, diffuseUV.z).rgb;
+#  endif
+
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowObjectVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowObjectVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowObjectVp.glsl	(revision 12083)
@@ -0,0 +1,95 @@
+#version 150
+/* Copyright Torus Knot Software Ltd 2000-2013
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#define BIAS 0
+
+in vec4 position;
+in vec3 normal;
+in vec4 uv0;
+
+uniform mat4 worldViewProj;
+uniform vec4 lightPosition;
+uniform vec3 lightDiffuse;
+#if FOG
+uniform vec2 fogParams;		// x = fog start, y = fog distance
+#endif
+
+#if DEPTH_SHADOWCASTER
+uniform vec4 depthRange; // x = min, y = max, z = range, w = 1/range
+out float depth;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform vec4 depthRange0; // x = min, y = max, z = range, w = 1/range
+uniform vec4 depthRange1; // x = min, y = max, z = range, w = 1/range
+uniform vec4 depthRange2; // x = min, y = max, z = range, w = 1/range
+uniform mat4 texWorldViewProjMatrix0;
+uniform mat4 texWorldViewProjMatrix1;
+uniform mat4 texWorldViewProjMatrix2;
+out vec4 lightSpacePos0;
+out vec4 lightSpacePos1;
+out vec4 lightSpacePos2;
+#endif
+
+#if !SHADOWCASTER
+out vec3 col;
+#endif
+
+out vec3 diffuseUV;
+
+void main()
+{
+    // project position to the screen
+    gl_Position = worldViewProj * position;
+
+#if !SHADOWCASTER
+	// Get object space light direction
+	vec3 lightDir = normalize(lightPosition.xyz - (position.xyz * lightPosition.w).xyz);
+	col = lightDiffuse.xyz * max(dot(lightDir, normal.xyz), 0.0);
+#  if FOG
+    diffuseUV.z = linearFog(gl_Position.z, fogParams.x, fogParams.y);
+#  endif
+
+#endif
+
+    // pass through other texcoords exactly as they were received
+    diffuseUV.xy = uv0.xy;
+
+#if DEPTH_SHADOWCASTER
+	depth = (BIAS + gl_Position.z - depthRange.x) * depthRange.w;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+	// Calculate the position of vertex in light space
+	lightSpacePos0 = texWorldViewProjMatrix0 * position;
+	lightSpacePos1 = texWorldViewProjMatrix1 * position;
+	lightSpacePos2 = texWorldViewProjMatrix2 * position;
+
+	// make linear
+	lightSpacePos0.z = (lightSpacePos0.z - depthRange0.x) * depthRange0.w;
+	lightSpacePos1.z = (lightSpacePos1.z - depthRange1.x) * depthRange1.w;
+	lightSpacePos2.z = (lightSpacePos2.z - depthRange2.x) * depthRange2.w;
+
+	// pass cam depth
+	diffuseUV.z = gl_Position.z;
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapCasterFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapCasterFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapCasterFp.glsl	(revision 12083)
@@ -0,0 +1,18 @@
+#version 150
+
+in vec2 depth;
+//out vec4 fragColour;
+
+void main()
+{
+#if LINEAR_RANGE
+	float finalDepth = depth.x;
+#else
+	float finalDepth = depth.x;// / depth.y;
+#endif
+	// just smear across all components 
+	// therefore this one needs high individual channel precision
+//	fragColour = vec4(finalDepth, finalDepth, finalDepth, 1);
+	gl_FragDepth = finalDepth;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapCasterVp.glsl	(revision 12083)
@@ -0,0 +1,25 @@
+#version 150
+
+uniform mat4 worldViewProj;
+uniform vec4 texelOffsets;
+uniform vec4 depthRange;
+
+in vec4 vertex;
+out vec2 depth;
+
+void main()
+{
+	gl_Position = worldViewProj * vertex;
+
+	// fix pixel / texel alignment
+	gl_Position.xy += texelOffsets.zw * gl_Position.w;
+	// linear depth storage
+	// offset / scale range output
+#if LINEAR_RANGE
+	depth.x = (gl_Position.z - depthRange.x) * depthRange.w;
+#else
+	depth.x = gl_Position.z;
+#endif
+	depth.y = gl_Position.w;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapNormalMapReceiverFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapNormalMapReceiverFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapNormalMapReceiverFp.glsl	(revision 12083)
@@ -0,0 +1,82 @@
+#version 150
+
+uniform float inverseShadowmapSize;
+uniform float fixedDepthBias;
+uniform float gradientClamp;
+uniform float gradientScaleBias;
+uniform float shadowFuzzyWidth;
+uniform vec4 lightColour;
+
+uniform sampler2D shadowMap;
+uniform sampler2D normalMap;
+
+in vec3 tangentLightDir;
+in vec4 oUv0;
+in vec4 oUv1;
+out vec4 fragColour;
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+void main()
+{
+	// get the new normal and diffuse values
+	vec3 normal = normalize(expand(texture(normalMap, oUv1.xy).xyz));
+	
+	vec4 vertexColour = clamp(dot(normal, tangentLightDir),0.0,1.0) * lightColour;
+
+	vec4 shadowUV = oUv0;
+	// point on shadowmap
+#if LINEAR_RANGE
+	shadowUV.xy = shadowUV.xy / shadowUV.w;
+#else
+	shadowUV = shadowUV / shadowUV.w;
+#endif
+	float centerdepth = texture(shadowMap, shadowUV.xy).x;
+    
+    // gradient calculation
+  	float pixeloffset = inverseShadowmapSize;
+    vec4 depths = vec4(
+    	texture(shadowMap, shadowUV.xy + vec2(-pixeloffset, 0)).x,
+    	texture(shadowMap, shadowUV.xy + vec2(+pixeloffset, 0)).x,
+    	texture(shadowMap, shadowUV.xy + vec2(0, -pixeloffset)).x,
+    	texture(shadowMap, shadowUV.xy + vec2(0, +pixeloffset)).x);
+
+	vec2 differences = abs( depths.yw - depths.xz );
+	float gradient = min(gradientClamp, max(differences.x, differences.y));
+	float gradientFactor = gradient * gradientScaleBias;
+
+	// visibility function
+	float depthAdjust = gradientFactor + (fixedDepthBias * centerdepth);
+	float finalCenterDepth = centerdepth + depthAdjust;
+
+	// shadowUV.z contains lightspace position of current object
+
+#if FUZZY_TEST
+	// fuzzy test - introduces some ghosting in result and doesn't appear to be needed?
+	//float visibility = saturate(1 + delta_z / (gradient * shadowFuzzyWidth));
+	float visibility = saturate(1 + (finalCenterDepth - shadowUV.z) * shadowFuzzyWidth * shadowUV.w);
+
+	fragColour = vertexColour * visibility;
+#else
+	// hard test
+#if PCF
+	// use depths from prev, calculate diff
+	depths += depthAdjust;
+	float final = (finalCenterDepth > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.x > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.y > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.z > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.w > shadowUV.z) ? 1.0 : 0.0;
+	
+	final *= 0.2;
+
+	fragColour = vec4(vertexColour.xyz * final, 1);
+#else
+	fragColour = (finalCenterDepth > shadowUV.z) ? vertexColour : vec4(0,0,0,1);
+#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapNormalMapReceiverVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapNormalMapReceiverVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapNormalMapReceiverVp.glsl	(revision 12083)
@@ -0,0 +1,50 @@
+#version 150
+
+in vec3 tangent;
+in vec3 normal;
+in vec4 vertex;
+in vec4 uv1;
+
+uniform mat4 world;
+uniform mat4 worldViewProj;
+uniform mat4 texViewProj;
+uniform vec4 lightPosition; // object space
+uniform vec4 shadowDepthRange;
+
+out vec3 tangentLightDir;
+out vec4 oUv0;
+out vec4 oUv1;
+
+void main()
+{
+	gl_Position = worldViewProj * vertex;
+	
+	vec4 worldPos = world * vertex;
+
+	// Get object space light direction 
+    vec3 lightDir = normalize(lightPosition.xyz - (vertex.xyz * lightPosition.w));
+
+	// calculate shadow map coords
+	oUv0 = texViewProj * worldPos;
+#if LINEAR_RANGE
+	// adjust by fixed depth bias, rescale into range
+	oUv0.z = (oUv0.z - shadowDepthRange.x) * shadowDepthRange.w;
+#endif
+
+	// pass the main uvs straight through unchanged 
+	oUv1 = uv1;
+
+	// Calculate the binormal (NB we assume both normal and tangent are 
+	// already normalised) 
+	vec3 binormal = cross(normal, tangent); 
+
+	// Form a rotation matrix out of the vectors 
+	mat3 rotation = mat3(tangent, binormal, normal); 
+//	mat3 rotation = mat3(vec3(tangent[0], binormal[0], normal[0]),
+//						vec3(tangent[1], binormal[1], normal[1]),
+//						vec3(tangent[2], binormal[2], normal[2]));
+
+	// Transform the light vector according to this matrix 
+	tangentLightDir = normalize(rotation * lightDir); 
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapReceiverFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapReceiverFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapReceiverFp.glsl	(revision 12083)
@@ -0,0 +1,64 @@
+#version 150
+
+uniform float inverseShadowmapSize;
+uniform float fixedDepthBias;
+uniform float gradientClamp;
+uniform float gradientScaleBias;
+uniform float shadowFuzzyWidth;
+
+uniform sampler2D shadowMap;
+out vec4 fragColour;
+in vec4 shadowUV;
+in vec4 oColour;
+
+void main()
+{
+	float centerdepth = texture(shadowMap, shadowUV.xy).x;
+    
+    // gradient calculation
+  	float pixeloffset = inverseShadowmapSize;
+    vec4 depths = vec4(
+    	texture(shadowMap, shadowUV.xy + vec2(-pixeloffset, 0)).x,
+    	texture(shadowMap, shadowUV.xy + vec2(+pixeloffset, 0)).x,
+    	texture(shadowMap, shadowUV.xy + vec2(0, -pixeloffset)).x,
+    	texture(shadowMap, shadowUV.xy + vec2(0, +pixeloffset)).x);
+
+	vec2 differences = abs( depths.yw - depths.xz );
+	float gradient = min(gradientClamp, max(differences.x, differences.y));
+	float gradientFactor = gradient * gradientScaleBias;
+
+	// visibility function
+	float depthAdjust = gradientFactor + (fixedDepthBias * centerdepth);
+	float finalCenterDepth = centerdepth + depthAdjust;
+
+	// shadowUV.z contains lightspace position of current object
+
+#if FUZZY_TEST
+	// fuzzy test - introduces some ghosting in result and doesn't appear to be needed?
+	//float visibility = saturate(1 + delta_z / (gradient * shadowFuzzyWidth));
+	float visibility = saturate(1 + (finalCenterDepth - shadowUV.z) * shadowFuzzyWidth * shadowUV.w);
+
+	fragColour = vertexColour * visibility;
+#else
+	// hard test
+#if PCF
+	// use depths from prev, calculate diff
+	depths += depthAdjust;
+	float final = (finalCenterDepth > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.x > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.y > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.z > shadowUV.z) ? 1.0 : 0.0;
+	final += (depths.w > shadowUV.z) ? 1.0 : 0.0;
+	
+	final *= 0.2;
+
+	fragColour = vec4(oColour.xyz * final, 1);
+	
+#else
+	fragColour = (finalCenterDepth > shadowUV.z) ? oColour : vec4(0.5,0,0,1);
+#endif
+
+#endif
+   
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapReceiverVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapReceiverVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DepthShadowmapReceiverVp.glsl	(revision 12083)
@@ -0,0 +1,39 @@
+#version 150
+
+uniform mat4 world;
+uniform mat4 worldIT;
+uniform mat4 worldViewProj;
+uniform mat4 texViewProj;
+uniform vec4 lightPosition;
+uniform vec4 lightColour;
+uniform vec4 shadowDepthRange;
+
+in vec4 position;
+in vec3 normal;
+in vec4 ambient;
+
+out vec4 shadowUV;
+out vec4 oColour;
+
+void main()
+{
+	gl_Position = worldViewProj * position;
+	vec4 worldPos = world * position;
+	vec3 worldNorm = (worldIT * vec4(normal, 1)).xyz;
+
+	// calculate lighting (simple vertex lighting)
+	vec3 lightDir = normalize(
+		lightPosition.xyz - (worldPos.xyz * lightPosition.w));
+
+	oColour = lightColour * max(dot(lightDir, worldNorm), 0.0);
+
+	// calculate shadow map coords
+	shadowUV = texViewProj * worldPos;
+#if LINEAR_RANGE
+	// adjust by fixed depth bias, rescale into range
+//	shadowUV.z = (shadowUV.z - shadowDepthRange.x) * shadowDepthRange.w;
+	shadowUV.xy = shadowUV.xy / shadowUV.w;
+#else
+	shadowUV = shadowUV / shadowUV.w;
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DiffuseOneTexture.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DiffuseOneTexture.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DiffuseOneTexture.glsl	(revision 12083)
@@ -0,0 +1,16 @@
+#version 150
+
+uniform sampler2D texMap;
+
+in vec4 colour;
+in vec4 uv;
+
+out vec4 fragColour;
+
+/*
+  Basic fragment program using texture and diffuse colour.
+*/
+void main()
+{
+	fragColour = texture(texMap, uv.xy) * colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DitherFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DitherFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DitherFP.glsl	(revision 12083)
@@ -0,0 +1,18 @@
+#version 150
+
+uniform sampler2D RT;
+uniform sampler2D noise;
+in vec2 oUv0;
+
+out vec4 fragColour;
+
+void main()
+{
+	float c = dot(texture(RT, oUv0), vec4(0.30, 0.11, 0.59, 0.00));
+	float n = texture(noise, oUv0).r * 2.0 - 1.0;
+	c += n;
+
+	c = step(c, 0.5);
+
+	fragColour = vec4(c,c,c,1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion.glsl	(revision 12083)
@@ -0,0 +1,45 @@
+#version 150
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ);
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform mat4 viewProjectionMatrix;
+uniform vec4   lightPos[2];
+uniform vec4   lightDiffuseColour[2];
+uniform vec4   ambient;
+
+in vec4 vertex;
+in vec3 normal;
+in vec4 blendIndices;
+in vec4 blendWeights;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec4 ambientColour;
+
+void main()
+{	
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	vec3 blendPosition = calculateBlendPosition(vertex.xyz, blendDQ);
+		
+	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
+	vec3 blendNormal = calculateBlendNormal(normal, blendDQ);
+	
+	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
+	
+	// Lighting - support point and directional
+	vec3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition * lightPos[0].w));
+	vec3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition * lightPos[1].w));
+
+	oUv0 = uv0;
+
+	ambientColour = /*gl_FrontMaterial.diffuse **/ (ambient + (clamp(dot(lightDir0, blendNormal), 0.0, 1.0) * lightDiffuseColour[0]) + 
+		(clamp(dot(lightDir1, blendNormal), 0.0, 1.0) * lightDiffuseColour[1]));			
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_Common.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_Common.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_Common.glsl	(revision 12083)
@@ -0,0 +1,68 @@
+//All of these functions are based on dqs.cg from http://isg.cs.tcd.ie/kavanl/dq/
+/* dqs.cg
+
+  Dual quaternion skinning vertex shaders (no shading computations)
+
+  Version 1.0.3, November 1st, 2007
+
+  Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights 
+  Reserved
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author(s) be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Author: Ladislav Kavan, kavanl@cs.tcd.ie
+
+*/
+
+#version 150
+
+mat2x4 blendTwoWeights(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24])
+{
+	mat2x4 blendDQ = blendWgt.x*mat2x4(dualQuaternions[int(blendIdx.x) * 2], dualQuaternions[int(blendIdx.x) * 2 + 1]);
+	blendDQ += blendWgt.y*mat2x4(dualQuaternions[int(blendIdx.y) * 2], dualQuaternions[int(blendIdx.y) * 2 + 1]);
+
+	return blendDQ;
+}
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, mat2x4 dualQuaternions[24])
+{
+	mat2x4 dq0 = dualQuaternions[int(blendIdx.x)];
+	mat2x4 dq1 = dualQuaternions[int(blendIdx.y)];
+
+	//Accurate antipodality handling. For speed increase, remove the following line, 
+	//though, the results will only be valid for rotations less than 180 degrees.
+	if (dot(dq0[0], dq1[0]) < 0.0) dq1 *= -1.0;
+	
+	mat2x4 blendDQ = blendWgt.x*dq0;
+	blendDQ += blendWgt.y*dq1;
+
+	return blendDQ;
+}
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_ShadowCaster.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_ShadowCaster.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_ShadowCaster.glsl	(revision 12083)
@@ -0,0 +1,31 @@
+#version 150
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform mat4x4 viewProjectionMatrix;
+uniform vec4 ambient;
+
+in vec4 vertex;
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+out vec4 ambientColour;
+
+//Shadow caster pass
+void main()
+{
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	float len = length(blendDQ[0]);
+	blendDQ /= len;
+
+	vec3 blendPosition = calculateBlendPosition(vertex.xyz, blendDQ);
+
+	// view / projection
+	gl_Position = viewProjectionMatrix * vec4(blendPosition, 1.0);
+	
+	ambientColour = ambient;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_TwoPhase.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_TwoPhase.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_TwoPhase.glsl	(revision 12083)
@@ -0,0 +1,81 @@
+#version 150
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, mat2x4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ);
+
+mat3 adjointTransposeMatrix(mat3 M)
+{
+	mat3 atM;
+	atM[0][0] = M[2][2] * M[1][1] - M[2][1] * M[1][2];
+	atM[1][0] = M[2][1] * M[0][2] - M[0][1] * M[2][2];
+	atM[2][0] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
+
+	atM[0][1] = M[2][0] * M[1][2] - M[2][2] * M[1][0];
+	atM[1][1] = M[2][2] * M[0][0] - M[2][0] * M[0][2];
+	atM[2][1] = M[0][2] * M[1][0] - M[0][0] * M[1][2];
+
+	atM[0][2] = M[2][1] * M[1][0] - M[2][0] * M[1][1];
+	atM[1][2] = M[0][1] * M[2][0] - M[2][1] * M[0][0];
+	atM[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
+
+	return atM;
+}
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform vec4 scaleM[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 lightPos[2];
+uniform vec4 lightDiffuseColour[2];
+uniform vec4 ambient;
+
+in vec4 vertex;
+in vec3 normal;
+in vec4 blendIndices;
+in vec4 blendWeights;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec4 ambientColour;
+
+void main()
+{	
+	//First phase - applies scaling and shearing:
+	int blendIndicesX = int(blendIndices.x) * 3;
+	int blendIndicesY = int(blendIndices.y) * 3;
+	
+	mat3x4 blendS = blendWeights.x*mat3x4(scaleM[blendIndicesX], 
+		scaleM[blendIndicesX + 1], scaleM[blendIndicesX + 2]);
+	
+	blendS += blendWeights.y*mat3x4(scaleM[blendIndicesY],
+	            scaleM[blendIndicesY + 1], scaleM[blendIndicesY + 2]);
+
+	mat4x3 blendF = transpose(blendS);
+
+	vec3 pass1_position = blendF * vertex;
+
+	mat3x3 blendSrotAT = adjointTransposeMatrix(mat3x3(blendF));
+	vec3 pass1_normal = normalize(blendSrotAT * normal);
+
+	//Second phase
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	blendDQ /= length(blendDQ[0]);
+
+	vec3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
+
+	//No need to normalize, the magnitude of the normal is preserved because only rotation is performed
+	vec3 blendNormal = calculateBlendNormal(pass1_normal, blendDQ);
+	
+	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
+
+	// Lighting - support point and directional
+	vec3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition * lightPos[0].w));
+	vec3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition * lightPos[1].w));
+
+	oUv0 = uv0;
+
+	ambientColour = /*gl_FrontMaterial.diffuse **/ (ambient + (clamp(dot(lightDir0, blendNormal), 0.0, 1.0) * lightDiffuseColour[0]) + 
+		(clamp(dot(lightDir1, blendNormal), 0.0, 1.0) * lightDiffuseColour[1]));			
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_TwoPhaseShadowCaster.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_TwoPhaseShadowCaster.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/DualQuaternion_TwoPhaseShadowCaster.glsl	(revision 12083)
@@ -0,0 +1,44 @@
+#version 150
+
+mat2x4 blendTwoWeightsAntipod(vec4 blendWgt, vec4 blendIdx, vec4 dualQuaternions[24]);
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ);
+
+uniform vec4 worldDualQuaternion2x4Array[24];
+uniform vec4 scaleM[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4   ambient;
+
+in vec4 vertex;
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+out vec4 ambientColour;
+
+void main()
+{	
+	//First phase - applies scaling and shearing:
+	int blendIndicesX = int(blendIndices.x) * 3;
+	int blendIndicesY = int(blendIndices.y) * 3;
+	
+	mat3x4 blendS = blendWeights.x*mat3x4(scaleM[blendIndicesX], 
+		scaleM[blendIndicesX + 1], scaleM[blendIndicesX + 2]);
+	
+	blendS += blendWeights.y*mat3x4(scaleM[blendIndicesY],
+	    scaleM[blendIndicesY + 1], scaleM[blendIndicesY + 2]);
+
+	mat4x3 blendF = transpose(blendS);
+
+	vec3 pass1_position = blendF * vertex;
+
+	//Second phase
+	mat2x4 blendDQ = blendTwoWeightsAntipod(blendWeights, blendIndices, worldDualQuaternion2x4Array);
+
+	blendDQ /= length(blendDQ[0]);
+
+	vec3 blendPosition = calculateBlendPosition(pass1_position, blendDQ);
+	
+	gl_Position =  viewProjectionMatrix * vec4(blendPosition, 1.0);
+
+	ambientColour = ambient;			
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Dyn-TextFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Dyn-TextFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Dyn-TextFP.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 150
+
+uniform sampler2D Image;
+uniform sampler2D Thaw;
+in vec4 oUv;
+out vec4 fragColour;
+
+void main(void)
+{
+    vec4 c0 = texture(Image, oUv.xy);
+    vec4 c1 = texture(Thaw, oUv.xy);
+
+	fragColour = c0 * c1;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Dyn-TextVP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Dyn-TextVP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Dyn-TextVP.glsl	(revision 12083)
@@ -0,0 +1,13 @@
+#version 150
+
+in vec4 uv0;
+in vec4 vertex;
+out vec4 oUv;
+
+uniform mat4 worldViewProj;
+
+void main(void)
+{
+	gl_Position = worldViewProj * vertex;
+	oUv = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/EmbossedFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/EmbossedFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/EmbossedFp.glsl	(revision 12083)
@@ -0,0 +1,16 @@
+#version 150
+
+uniform sampler2D RT;
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+    vec4 Color;
+    Color.a = 1.0;
+    Color.rgb = vec3(0.5);
+    Color -= texture( RT, oUv0 - 0.001)*2.0;
+    Color += texture( RT, oUv0 + 0.001)*2.0;
+    Color.rgb = vec3((Color.r+Color.g+Color.b)/3.0);
+    fragColour = Color;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingFp.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+#version 150
+
+uniform vec4 lightDiffuse;
+uniform sampler2D normalMap;
+
+in vec4 oUv0;
+in vec3 oTSLightDir;
+
+out vec4 fragColour;
+
+// General functions
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+void main()
+{
+	// Retrieve normalised light vector, expand from range-compressed
+	vec3 lightVec = normalize(oTSLightDir).xyz;
+
+	// Get bump map vector, again expand from range-compressed
+	vec3 bumpVec = expand(texture(normalMap, oUv0.xy).xyz);
+
+	// Calculate dot product
+	fragColour = lightDiffuse * dot(bumpVec, lightVec);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingShadowRcvFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingShadowRcvFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingShadowRcvFp.glsl	(revision 12083)
@@ -0,0 +1,34 @@
+#version 150
+
+// General functions
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+uniform sampler2D shadowMap;
+uniform sampler2D normalMap;
+uniform vec4 lightDiffuse;
+
+in vec4 uvproj;
+in vec4 oUv0;
+in vec3 oTSLightDir;
+
+out vec4 fragColour;
+
+void main()
+{
+	// retrieve normalised light vector, expand from range-compressed
+	vec3 lightVec = expand(normalize(oTSLightDir).xyz);
+
+	// get bump map vector, again expand from range-compressed
+	vec3 bumpVec = expand(texture(normalMap, oUv0.xy).xyz);
+
+	// get shadow value
+	vec3 shadow = textureProj(shadowMap, uvproj).xyz;
+
+	// Calculate dot product
+	fragColour = vec4(shadow * lightDiffuse.xyz * dot(bumpVec, lightVec), 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingShadowRcvVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingShadowRcvVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingShadowRcvVp.glsl	(revision 12083)
@@ -0,0 +1,52 @@
+#version 150
+
+/* Bump mapping vertex program for shadow receiving
+   In this program, we want to calculate the tangent space light vector
+   on a per-vertex level which will get passed to the fragment program,
+   or to the fixed function dot3 operation, to produce the per-pixel
+   lighting effect. 
+*/
+
+// parameters
+uniform vec4 lightPosition; // object space
+uniform mat4 worldViewProj;
+uniform mat4 worldMatrix;
+uniform mat4 texViewProj;
+
+in vec4 vertex;
+in vec3 normal;
+in vec3 tangent;
+in vec4 uv0;
+
+out vec4 uvproj;
+out vec4 oUv0;
+out vec3 oTSLightDir;
+
+void main()
+{
+	// Calculate output position
+	gl_Position = worldViewProj * vertex;
+
+	// Pass the main uvs straight through unchanged
+	oUv0 = uv0;
+
+	// Calculate tangent space light vector
+	// Get object space light direction
+	// Non-normalised since we'll do that in the fragment program anyway
+	vec3 lightDir = lightPosition.xyz - (vertex * lightPosition.w).xyz;
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	vec3 binormal = cross(normal, tangent);
+	
+	// Form a rotation matrix out of the vectors, column major for glsl es 
+	mat3 rotation = mat3(vec3(tangent[0], binormal[0], normal[0]),
+						vec3(tangent[1], binormal[1], normal[1]),
+						vec3(tangent[2], binormal[2], normal[2]));
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = rotation * lightDir;
+
+	// Projection
+	uvproj = texViewProj * (worldMatrix * vertex);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingSpecularFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingSpecularFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingSpecularFp.glsl	(revision 12083)
@@ -0,0 +1,41 @@
+#version 150
+
+// General functions
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+uniform vec4 lightDiffuse;
+uniform vec4 lightSpecular;
+uniform sampler2D normalMap;
+
+in vec4 oUv0;
+in vec3 oTSLightDir;
+in vec3 oTSHalfAngle;
+
+out vec4 fragColour;
+
+// NOTE: GLSL does not have the saturate function.  But it is equivalent to clamp(val, 0.0, 1.0)
+
+/* Fragment program which supports specular component */
+void main()
+{
+	// retrieve normalised light vector
+	vec3 lightVec = normalize(oTSLightDir);
+
+	// retrieve half angle and normalise
+	vec3 halfAngle = normalize(oTSHalfAngle);
+
+	// get bump map vector, again expand from range-compressed
+	vec3 bumpVec = expand(texture(normalMap, oUv0.xy).xyz);
+
+	// Pre-raise the specular exponent to the eight power
+	float specFactor = pow(clamp(dot(bumpVec, halfAngle), 0.0, 1.0), 4.0);
+
+	// Calculate dot product for diffuse
+	fragColour = (lightDiffuse * clamp(dot(bumpVec, lightVec), 0.0, 1.0)) + 
+			(lightSpecular * specFactor);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingSpecularVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingSpecularVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingSpecularVp.glsl	(revision 12083)
@@ -0,0 +1,47 @@
+#version 150
+
+// General functions
+// parameters
+uniform vec4 lightPosition; // object space
+uniform vec3 eyePosition;   // object space
+uniform mat4 worldViewProj;
+
+in vec4 vertex;
+in vec3 normal;
+in vec3 tangent;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec3 oTSLightDir;
+out vec3 oTSHalfAngle;
+
+/* Vertex program which includes specular component */
+void main()
+{
+	// calculate output position
+	gl_Position = worldViewProj * vertex;
+
+	// pass the main uvs straight through unchanged
+	oUv0 = uv0;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	vec3 lightDir = normalize(lightPosition.xyz - (vertex * lightPosition.w).xyz);
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	vec3 binormal = cross(normal, tangent);
+	
+	// Form a rotation matrix out of the vectors
+	mat3 rotation = mat3(vec3(tangent[0], binormal[0], normal[0]),
+						vec3(tangent[1], binormal[1], normal[1]),
+						vec3(tangent[2], binormal[2], normal[2]));
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = rotation * lightDir;
+
+	// Calculate half-angle in tangent space
+	vec3 eyeDir = normalize(eyePosition - vertex.xyz);
+	vec3 halfAngle = normalize(eyeDir + lightDir);
+	oTSHalfAngle = rotation * halfAngle;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_BumpMappingVp.glsl	(revision 12083)
@@ -0,0 +1,47 @@
+#version 150
+
+/* Bump mapping vertex program
+   In this program, we want to calculate the tangent space light vector
+   on a per-vertex level which will get passed to the fragment program,
+   or to the fixed function dot3 operation, to produce the per-pixel
+   lighting effect. 
+*/
+// parameters
+uniform vec4 lightPosition; // object space
+uniform mat4 worldViewProj;
+
+in vec4 vertex;
+in vec3 normal;
+in vec3 tangent;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec3 oTSLightDir;
+
+void main()
+{
+	// Calculate output position
+	gl_Position = worldViewProj * vertex;
+
+	// Pass the main uvs straight through unchanged
+	oUv0 = uv0;
+
+	// Calculate tangent space light vector
+	// Get object space light direction
+	// Non-normalised since we'll do that in the fragment program anyway
+	vec3 lightDir = lightPosition.xyz - (vertex * lightPosition.w).xyz;
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+
+	// Fixed handedness
+	vec3 binormal = cross(normal, tangent);
+
+	// Form a rotation matrix out of the vectors, column major for glsl es 
+	mat3 rotation = mat3(vec3(tangent[0], binormal[0], normal[0]),
+						vec3(tangent[1], binormal[1], normal[1]),
+						vec3(tangent[2], binormal[2], normal[2]));
+	
+	// Transform the light vector according to this matrix
+	oTSLightDir = rotation * lightDir;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_CelShadingFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_CelShadingFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_CelShadingFp.glsl	(revision 12083)
@@ -0,0 +1,33 @@
+#version 150
+
+/* Cel shading fragment program for single-pass rendering */
+uniform vec4 diffuse;
+uniform vec4 specular;
+uniform sampler1D diffuseRamp;
+uniform sampler1D specularRamp;
+uniform sampler1D edgeRamp;
+
+in float diffuseIn;
+in float specularIn;
+in float edge;
+
+out vec4 fragColour;
+
+/*uniform lighting
+{
+	vec4 diffuse;
+	vec4 specular;
+} LightingParams;*/
+
+void main()
+{
+	// Step functions from textures
+	float diffuseStep = texture(diffuseRamp, diffuseIn).x;
+	float specularStep = texture(specularRamp, specularIn).x;
+	float edgeStep = texture(edgeRamp, edge).x;
+
+	fragColour = edgeStep * ((diffuse * diffuseStep) + 
+                            (specular * specularStep));
+//	fragColour = edgeStep * ((LightingParams.diffuse * diffuseStep) + 
+//                        (LightingParams.specular * specularStep));
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_CelShadingVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_CelShadingVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_CelShadingVp.glsl	(revision 12083)
@@ -0,0 +1,50 @@
+#version 150
+
+/* Cel shading vertex program for single-pass rendering
+   In this program, we want to calculate the diffuse and specular
+   ramp components, and the edge factor (for doing simple outlining)
+   For the outlining to look good, we need a pretty well curved model.
+*/
+// Parameters
+in vec4 vertex;
+in vec3 normal;
+
+uniform vec3 lightPosition; // object space
+uniform vec3 eyePosition;   // object space
+uniform vec4 shininess;
+uniform mat4 worldViewProj;
+
+//uniform transform
+//{
+//	vec4 shininess;
+//} MaterialShininess;
+
+out float diffuseIn;
+out float specularIn;
+out float edge;
+
+void main()
+{
+	// calculate output position
+	gl_Position = worldViewProj * vertex;
+
+	// calculate light vector
+	vec3 N = normalize(normal);
+	vec3 L = normalize(lightPosition - vertex.xyz);
+	
+	// Calculate diffuse component
+	diffuseIn = max(dot(N, L) , 0.0);
+
+	// Mask off specular if diffuse is 0
+	if (diffuseIn == 0.0)
+	    specularIn = 0.0;
+
+    // Calculate specular component
+    vec3 E = normalize(eyePosition - vertex.xyz);
+    vec3 H = normalize(L + E);
+    specularIn = pow(max(dot(N, H), 0.0), shininess.x);
+//    specularIn = pow(max(dot(N, H), 0.0), MaterialShininess.shininess.x);
+
+	// Edge detection, dot eye and normal vectors
+	edge = max(dot(N, E), 0.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_FresnelFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_FresnelFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_FresnelFp.glsl	(revision 12083)
@@ -0,0 +1,39 @@
+#version 150
+
+uniform vec4 tintColour;
+uniform float noiseScale;
+uniform float fresnelBias;
+uniform float fresnelScale;
+uniform float fresnelPower;
+uniform sampler2D noiseMap;
+uniform sampler2D reflectMap;
+uniform sampler2D refractMap;
+
+in vec3 noiseCoord;
+in vec4 projectionCoord;
+in vec3 eyeDir;
+in vec3 oNormal;
+
+out vec4 fragColour;
+
+// Fragment program for distorting a texture using a 3D noise texture
+void main()
+{
+	// Do the tex projection manually so we can distort _after_
+	vec2 final = projectionCoord.xy / projectionCoord.w;
+
+	// Noise
+	vec3 noiseNormal = (texture(noiseMap, (noiseCoord.xy / 5.0)).rgb - 0.5).rbg * noiseScale;
+	final += noiseNormal.xz;
+
+	// Fresnel
+	//normal = normalize(normal + noiseNormal.xz);
+	float fresnel = fresnelBias + fresnelScale * pow(1.0 + dot(eyeDir, oNormal), fresnelPower);
+
+	// Reflection / refraction
+	vec4 reflectionColour = texture(reflectMap, final);
+	vec4 refractionColour = texture(refractMap, final) + tintColour;
+
+	// Final colour
+	fragColour = mix(refractionColour, reflectionColour, fresnel);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_FresnelVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_FresnelVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_FresnelVp.glsl	(revision 12083)
@@ -0,0 +1,36 @@
+#version 150
+
+in vec4 uv0;
+in vec4 position;
+in vec3 normal;
+
+uniform mat4 worldViewProjMatrix;
+uniform vec3 eyePosition; // object space
+uniform float timeVal;
+uniform float scale;  // the amount to scale the noise texture by
+uniform float scroll; // the amount by which to scroll the noise
+uniform float noise;  // the noise perturb as a factor of the time
+
+out vec3 noiseCoord;
+out vec4 projectionCoord;
+out vec3 eyeDir;
+out vec3 oNormal;
+
+// Vertex program for fresnel reflections / refractions
+void main()
+{
+	gl_Position = worldViewProjMatrix * position;
+	// Projective texture coordinates, adjust for mapping
+	mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0, 
+                         0.0, -0.5, 0.0, 0.0,
+                         0.0, 0.0, 0.5, 0.0,
+                         0.5, 0.5, 0.5, 1.0);
+	projectionCoord = scalemat * gl_Position;
+
+	// Noise map coords
+	noiseCoord.xy = (uv0.xy + (timeVal * scroll)) * scale;
+	noiseCoord.z = noise * timeVal;
+
+	eyeDir = normalize(position.xyz - eyePosition); 
+	oNormal = normal.rgb;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_TextureArrayPS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_TextureArrayPS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_TextureArrayPS.glsl	(revision 12083)
@@ -0,0 +1,17 @@
+#version 150
+
+uniform sampler2DArray TextureArrayTex;
+in vec4 oUv;
+out vec4 fragColour;
+
+void main(void)
+{
+	vec4 texcoord;
+	texcoord = oUv;
+	texcoord.z = floor(texcoord.z);
+    vec4 c0 = texture(TextureArrayTex, texcoord.xyz);
+	texcoord.z += 1.0;
+    vec4 c1 = texture(TextureArrayTex, texcoord.xyz);
+
+	fragColour = mix(c0, c1, fract(oUv.z));
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Example_TextureArrayVS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Example_TextureArrayVS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Example_TextureArrayVS.glsl	(revision 12083)
@@ -0,0 +1,13 @@
+#version 150
+
+in vec4 uv0;
+in vec4 vertex;
+out vec4 oUv;
+
+uniform mat4 worldViewProj;
+
+void main(void)
+{
+	gl_Position = worldViewProj * vertex;
+	oUv = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GlassFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GlassFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GlassFP.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 150
+
+uniform sampler2D RT;
+uniform sampler2D NormalMap;
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+	vec4 normal = 2.0 * (texture(NormalMap, oUv0 * 2.5) - 0.5);
+
+	fragColour = texture(RT, oUv0 + normal.xy * 0.05);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassAmbientFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassAmbientFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassAmbientFp.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+#version 150
+
+uniform sampler2D diffuseMap;
+
+in vec4 oUv0;
+in vec4 oColour;
+
+out vec4 fragColour;
+
+/// grass_vp ambient
+void main()
+{	
+    vec4 texColor = texture(diffuseMap, oUv0.xy);
+    fragColour = vec4(oColour.rgb, texColor.a);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassAmbientVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassAmbientVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassAmbientVp.glsl	(revision 12083)
@@ -0,0 +1,39 @@
+#version 150
+
+
+uniform mat4 worldViewProj;
+uniform vec4 ambient;
+uniform vec4 offset;
+
+in vec4 position;
+in vec4 normal;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec4 oColour;
+
+/// grass_vp ambient
+void main()
+{	
+     // Position
+	vec4 mypos = position;
+	vec4 factor = vec4(1.0, 1.0, 1.0, 1.0) - uv0.yyyy;
+	mypos = mypos + offset * factor;
+  	gl_Position = worldViewProj * mypos;
+    // Texture Coord
+	oUv0.xy = uv0.xy;      
+    /*
+    // Normal
+    // Make vec from vertex to camera
+    vec4 EyeVec = camObjPos - mypos;
+    // Dot the v to eye and the normal to see if they point
+    //  in the same direction or opposite
+    float aligned = dot(normal, EyeVec); // -1..1
+    // If aligned is negative, we need to flip the normal
+    if (aligned < 0)  
+        normal = -normal;  
+    //oNormal = normal; 
+    */
+    // Color    
+	oColour = ambient; 
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassCasterFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassCasterFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassCasterFp.glsl	(revision 12083)
@@ -0,0 +1,25 @@
+#version 150
+
+uniform sampler2D diffuseMap;
+
+in vec4 oUv0;
+in vec2 oDepth;
+
+out vec4 fragColour;
+
+//////////////////////// GRASS SHADOW CASTER
+void main()
+{	
+	float alpha = texture(diffuseMap, oUv0.xy).a;
+	if (alpha > 0.001)
+    {
+       fragColour = vec4(1.0, 1.0, 1.0, 0.0);
+    }
+    else
+    {
+        float finalDepth = oDepth.x / oDepth.y;
+        // just smear across all components 
+        // therefore this one needs high individual channel precision
+        fragColour = vec4(vec3(finalDepth), 1.0);
+    }
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassCasterVp.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+#version 150
+
+uniform mat4 worldViewProj;
+uniform vec4 offset;
+uniform vec4 texelOffsets;
+
+in vec4 position;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec2 oDepth;
+
+//////////////////////// GRASS SHADOW CASTER
+// Shadow caster vertex program.
+void main()
+{
+	vec4 mypos = position;
+	vec4 factor = vec4(1.0, 1.0, 1.0, 1.0) - uv0.yyyy;
+	mypos = mypos + offset * factor;
+	gl_Position = worldViewProj * mypos;
+
+	// fix pixel / texel alignment
+	gl_Position.xy += texelOffsets.zw * gl_Position.w;
+    
+	oDepth.x = gl_Position.z;
+	oDepth.y = gl_Position.w;
+  
+  	oUv0 = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassFp.glsl	(revision 12083)
@@ -0,0 +1,23 @@
+#version 150
+
+////////////////////////////// MOVING GRASS
+// Vertex program to wave some grass about
+// Assumes UV texture coords of v==0 indicates the top of the grass
+uniform sampler2D diffuseMap;
+
+in vec4 oUv0;
+in vec4 oColour;
+
+out vec4 fragColour;
+
+void main()
+{	
+    vec4 texColor = texture(diffuseMap, oUv0.xy);
+    fragColour = vec4(texColor.rgb * oColour.rgb, texColor.a); 
+
+    // Do manual alpha rejection
+    if (texColor.a < 0.58)
+    {
+        discard;
+    }
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassReceiverFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassReceiverFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassReceiverFp.glsl	(revision 12083)
@@ -0,0 +1,41 @@
+#version 150
+
+uniform float fixedDepthBias;
+uniform float gradientClamp;
+uniform float gradientScaleBias;
+uniform sampler2D shadowMap;
+uniform sampler2D diffuseMap;
+uniform vec4 vertexLight;
+
+in vec4 oUv0;
+in vec4 oShadowUV;
+
+out vec4 fragColour;
+
+//////////////////////// GRASS SHADOW RECEIVER
+void main()
+{
+    if (oShadowUV.z > 0.0)
+    {
+       vec4 diffuse = texture(diffuseMap, oUv0.xy);
+       if (diffuse.a > 0.001)
+       {
+            fragColour = vec4(0.0);
+       }
+       else
+       {
+            vec4 normShadowUV = oShadowUV / oShadowUV.w;
+            vec4 shadowDepths = texture(shadowMap, normShadowUV.xy);
+
+            float gradientFactor = gradientClamp * gradientScaleBias;
+            float depthAdjust = gradientFactor + fixedDepthBias * shadowDepths.x;
+            float centerdepth = shadowDepths.x + depthAdjust;
+
+            fragColour = (centerdepth > normShadowUV.z) ? vec4(vertexLight.rgb, diffuse.a) : vec4(0.0, 0.0, 0.0, diffuse.a);
+       }
+    }
+    else
+    {
+        fragColour = vec4(0.0);
+    }
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassReceiverVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassReceiverVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassReceiverVp.glsl	(revision 12083)
@@ -0,0 +1,54 @@
+#version 150
+
+uniform mat4 world;
+uniform mat4 worldViewProj;
+uniform mat4 texViewProj;
+uniform vec4 camObjPos;
+uniform vec4 objSpaceLight;
+uniform vec4 lightColour;
+uniform vec4 offset;
+
+in vec4 position;
+in vec4 normal;
+in vec4 uv0;
+
+out vec4 oShadowUV;
+out vec3 oUv0;
+out vec4 oColour;
+
+//////////////////////// GRASS SHADOW RECEIVER
+void main()
+{	    
+	vec4 mypos = position;
+	vec4 factor = vec4(1.0, 1.0, 1.0, 1.0) - uv0.yyyy;
+	mypos = mypos + offset * factor;
+	gl_Position = worldViewProj * mypos;
+	oUv0.xy = uv0.xy;    
+    // Transform position to world space
+	vec4 worldPos = world * mypos;
+	// calculate shadow map coords
+	oShadowUV = texViewProj * worldPos;
+       
+    // Make vec from vertex to camera
+    vec4 EyeVec = camObjPos - mypos;
+    // Dot the v to eye and the normal to see if they point
+    // in the same direction or opposite
+    float alignedEye = dot(normal, EyeVec); // -1..1
+    // If aligned is negative, we need to flip the normal
+	vec4 myNormal = normal;
+    if (alignedEye < 0.0)
+        myNormal = -normal;
+    //oNormal = normal;
+    
+  	// get vertex light direction (support directional and point)
+	vec3 lightVec = normalize(objSpaceLight.xyz - (mypos.xyz * objSpaceLight.w).xyz);
+    // Dot the v to light and the normal to see if they point
+    // in the same direction or opposite
+    float alignedLight = dot(myNormal.xyz, lightVec); // -1..1
+    // If aligned is negative, shadowing/lighting is not possible.
+    oUv0.z = (alignedLight < 0.0) ? 0.0 : 1.0 ;
+         
+    float diffuseFactor = max(alignedLight, 0.0);
+	//oColour = diffuseFactor * lightColour;    
+	oColour = lightColour;    
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassTexVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassTexVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassTexVp.glsl	(revision 12083)
@@ -0,0 +1,23 @@
+#version 150
+
+out vec4 oUv0;
+
+in vec4 position;
+in vec4 uv0;
+
+uniform mat4 worldViewProj;
+uniform vec4 ambient;
+uniform vec4 objSpaceLight;
+uniform vec4 lightColour;
+uniform vec4 offset;
+
+void main()
+{	    
+     // Position
+	vec4 mypos = position;
+	vec4 factor = vec4(1.0, 1.0, 1.0, 1.0) - uv0.yyyy;
+	mypos = mypos + offset * factor;
+	gl_Position = worldViewProj * mypos;
+    // Texture Coord
+	oUv0.xy = uv0.xy;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrassVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrassVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrassVp.glsl	(revision 12083)
@@ -0,0 +1,35 @@
+#version 150
+
+////////////////////////////// MOVING GRASS
+// Vertex program to wave some grass about
+// Assumes UV texture coords of v==0 indicates the top of the grass
+uniform mat4 worldViewProj;
+uniform vec4 camObjPos;
+uniform vec4 ambient;
+uniform vec4 objSpaceLight;
+uniform vec4 lightColour;
+uniform vec4 offset;
+
+in vec4 position;
+in vec4 normal;
+in vec4 uv0;
+
+out vec4 oUv0;
+out vec4 oColour;
+
+void main()
+{
+	vec4 mypos = position;
+	vec4 factor = vec4(1.0, 1.0, 1.0, 1.0) - uv0.yyyy;
+	mypos = mypos + offset * factor;
+	gl_Position = worldViewProj * mypos;
+
+	oUv0 = uv0;
+    // Color
+	// get vertex light direction (support directional and point)
+	vec3 light = normalize(objSpaceLight.xyz - (mypos.xyz * objSpaceLight.w).xyz);
+	// grass is just 2D quads, so if light passes underneath we need to invert the normal
+	// abs() will have the same effect
+    float diffuseFactor = abs(dot(normal.xyz, light));
+	oColour = ambient + diffuseFactor * lightColour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/GrayScale.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/GrayScale.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/GrayScale.glsl	(revision 12083)
@@ -0,0 +1,11 @@
+#version 150
+
+uniform sampler2D RT;
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+    vec3 greyscale = vec3(dot(texture(RT, oUv0).rgb, vec3(0.3, 0.59, 0.11)));
+	fragColour = vec4(greyscale, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HWBasicInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HWBasicInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HWBasicInstancing.vert	(revision 12083)
@@ -0,0 +1,69 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 150
+
+//Vertex input
+in vec4 vertex;
+in vec3 normal;
+in vec4 uv0;
+in vec4 uv1;
+in vec4 uv2;
+in vec4 uv3;
+in vec3 tangent;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	out vec2 depth;
+#else
+	out vec2 _uv0;
+	out vec3 oNormal;
+	out vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		out vec4 oLightSpacePos;
+	#endif
+#endif
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	mat4 worldMatrix;
+	worldMatrix[0] = uv1;
+	worldMatrix[1] = uv2;
+	worldMatrix[2] = uv3;
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	vec4 worldPos		= vertex * worldMatrix;
+	vec3 worldNorm		= normal * mat3(worldMatrix);
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HW_VTFInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HW_VTFInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HW_VTFInstancing.vert	(revision 12083)
@@ -0,0 +1,131 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 150
+
+//Vertex input
+in vec4 vertex;
+in vec3 normal;
+
+#ifdef BONE_TWO_WEIGHTS
+	in vec4 blendWeights;
+#endif
+
+in vec4 uv0;
+in vec4 uv1;
+in vec4 uv2;
+	
+#if BONE_MATRIX_LUT
+	in vec4 uv3;
+	in vec4 uv4;
+	in vec4 uv5;
+#endif
+
+in vec3 tangent;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+uniform sampler2D matrixTexture;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	out vec2 depth;
+#else
+	out vec2 _uv0;
+	out vec3 oNormal;
+	out vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		out vec4 oLightSpacePos;
+	#endif
+#endif
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 worldPos;
+	vec3 worldNorm;
+
+#ifdef ST_DUAL_QUATERNION
+	mat2x4 blendDQ;	
+	blendDQ[0] = texture( matrixTexture, vec2(uv1.x, 0.0) + uv2.xy );
+	blendDQ[1] = texture( matrixTexture, vec2(uv1.y, 0.0) + uv2.xy );
+#ifdef BONE_TWO_WEIGHTS
+	mat2x4 blendDQ2;
+	blendDQ2[0] = texture( matrixTexture, vec2(uv1.z, 0.0) + uv2.xy );
+	blendDQ2[1] = texture( matrixTexture, vec2(uv1.w, 0.0) + uv2.xy );
+
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= blendWeights.x;
+	blendDQ += blendWeights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(normal, blendDQ);
+#else
+	mat4 worldMatrix;
+	worldMatrix[0] = texture( matrixTexture, uv1.xw + uv2.xy );
+	worldMatrix[1] = texture( matrixTexture, uv1.yw + uv2.xy );
+	worldMatrix[2] = texture( matrixTexture, uv1.zw + uv2.xy );
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	worldPos		= vertex * worldMatrix;
+	worldNorm		= normal * mat3(worldMatrix);
+#endif
+
+#if BONE_MATRIX_LUT
+	mat4 worldCompMatrix;
+	worldCompMatrix[0] = uv3;
+	worldCompMatrix[1] = uv4;
+	worldCompMatrix[2] = uv5;
+	worldCompMatrix[3] = vec4( 0, 0, 0, 1 );
+	
+	worldPos =  worldPos * worldCompMatrix;
+	worldNorm = worldNorm * mat3(worldCompMatrix);
+#endif
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HalftoneFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HalftoneFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HalftoneFP.glsl	(revision 12083)
@@ -0,0 +1,25 @@
+#version 150
+
+in vec4 pos;
+in vec2 oUv0;
+
+uniform vec2 numTiles;
+uniform vec2 iNumTiles;
+uniform vec2 iNumTiles2;
+uniform vec4 lum;
+uniform sampler2D RT;
+uniform sampler3D noise;
+
+out vec4 fragColour;
+
+void main()
+{
+	vec3 local;
+	local.xy = mod(oUv0, iNumTiles);
+	vec2 middle = oUv0 - local.xy;
+	local.xy = local.xy * numTiles;
+	middle +=  iNumTiles2;
+	local.z = dot(texture(RT, middle), lum);
+	vec4 c = vec4(texture(noise,local).r);
+	fragColour = c;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HardwareMorphAnimationVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HardwareMorphAnimationVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HardwareMorphAnimationVp.glsl	(revision 12083)
@@ -0,0 +1,23 @@
+#version 150
+
+in vec4 vertex;
+in vec4 normal;
+in vec4 uv0;
+in vec4 uv1; // pos2
+
+out vec2 oUv;
+out vec4 colour;
+
+uniform mat4 worldViewProj;
+uniform vec4 anim_t;
+
+// hardware morph animation (no normals)
+void main()
+{
+	// interpolate
+	vec4 interp = vec4(vertex.xyz + anim_t.x*(uv1.xyz - vertex.xyz), 1.0);
+	
+	gl_Position = worldViewProj * interp;
+	oUv = uv0.xy;
+	colour = vec4(1.0,0.0,0.0,1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HardwareMorphAnimationWithNormalsVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HardwareMorphAnimationWithNormalsVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HardwareMorphAnimationWithNormalsVp.glsl	(revision 12083)
@@ -0,0 +1,36 @@
+#version 150
+
+in vec4 vertex;
+in vec3 normal;
+in vec4 uv0;
+in vec4 uv1; // pos2
+in vec4 uv2; // normal2
+
+out vec2 oUv;
+out vec4 colour;
+
+uniform mat4 worldViewProj;
+uniform vec4 anim_t;
+uniform vec4 objSpaceLightPos;
+uniform vec4 ambient;
+
+// hardware morph animation (with normals)
+void main()
+{
+	// interpolate position
+	vec4 posinterp = vec4(vertex.xyz + anim_t.x*(uv1.xyz - vertex.xyz), 1.0);
+
+    // nlerp normal
+	vec3 ninterp = normal + anim_t.x*(uv2.xyz - normal);
+	ninterp = normalize(ninterp);
+
+	gl_Position = worldViewProj * posinterp;
+	oUv = uv0.xy;
+
+	vec3 lightDir = normalize(
+		objSpaceLightPos.xyz - (posinterp.xyz * objSpaceLightPos.w));
+
+	// Colour it red to make it easy to identify
+	float lit = clamp(dot(lightDir, ninterp), 0.0, 1.0);
+	colour = vec4((ambient.rgb + vec3(lit,lit,lit)) * vec3(1.0,0.0,0.0), 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HardwarePoseAnimationVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HardwarePoseAnimationVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HardwarePoseAnimationVp.glsl	(revision 12083)
@@ -0,0 +1,25 @@
+#version 150
+
+in vec4 vertex;
+in vec4 normal;
+in vec4 uv0;
+in vec4 uv1; // pose1
+in vec4 uv2; // pose2
+
+out vec2 oUv;
+out vec4 colour;
+
+uniform mat4 worldViewProj;
+uniform vec4 anim_t;
+
+// hardware pose animation (no normals)
+void main()
+{
+	// interpolate
+    vec4 interp = vec4(vertex + anim_t.x*uv1.xyz + anim_t.y*uv2.xyz, 1.0);
+
+	gl_Position = worldViewProj * interp;
+	oUv = uv0.xy;
+	colour = vec4(1.0,0.0,0.0,1.0);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HardwarePoseAnimationWithNormalsVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HardwarePoseAnimationWithNormalsVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HardwarePoseAnimationWithNormalsVp.glsl	(revision 12083)
@@ -0,0 +1,46 @@
+#version 150
+
+in vec4 vertex;
+in vec4 normal;
+in vec4 uv0;
+in vec4 uv1; // pose1pos
+in vec4 uv2; // pose1norm
+in vec4 uv3; // pose2pos
+in vec4 uv4; // pose2norm
+
+out vec2 oUv;
+out vec4 colour;
+
+uniform mat4 worldViewProj;
+uniform vec4 anim_t;
+uniform vec4 objSpaceLightPos;
+uniform vec4 ambient;
+
+// hardware pose animation (with normals)
+void main()
+{
+	// interpolate position
+	vec4 posinterp = vec4(pos + anim_t.x*uv1.xyz + anim_t.y*uv3.xyz, 1.0);
+
+    // nlerp normal
+	// nlerp normal
+	// First apply the pose normals (these are actual normals, not offsets)
+	vec3 ninterp = anim_t.x*uv2.xyz + anim_t.y*uv4.xyz;
+
+	// Now add back any influence of the original normal
+	// This depends on what the cumulative weighting left the normal at, if it's lacking or cancelled out
+	//float remainder = 1.0 - min(anim_t.x + anim_t.y, 1.0);
+	float remainder = 1.0 - min(length(ninterp), 1.0);
+	ninterp = ninterp + (normal * remainder);
+	ninterp = normalize(ninterp);
+
+	gl_Position = worldViewProj * posinterp;
+	oUv = uv0.xy;
+	
+	vec3 lightDir = normalize(
+		objSpaceLightPos.xyz - (posinterp.xyz * objSpaceLightPos.w));
+
+	// Colour it red to make it easy to identify
+	float lit = clamp(dot(lightDir, ninterp), 0.0, 1.0);
+	colour = vec4((ambient.rgb + vec3(lit,lit,lit)) * vec3(1.0,0.0,0.0), 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HeatBlurFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HeatBlurFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HeatBlurFp.glsl	(revision 12083)
@@ -0,0 +1,61 @@
+#version 150
+
+uniform sampler2D Input;
+uniform vec4 blurAmount;
+
+in vec2 uv;
+out vec4 fragColour;
+
+void main()
+{
+   int i;
+   vec4 tmpOutColor;
+   float  diffuseGlowFactor;
+   vec2 offsets[4];
+/*
+		// hazy blur
+		-1.8, -1.8,
+		-1.8, 1.8,
+		1.8, -1.8,
+		1.8, 1.8
+*/
+/*
+		// less-hazy blur
+	  -1.0,  2.0,
+	  -1.0, -1.0,
+	   1.0, -1.0,
+	   1.0,  1.0
+*/
+/*
+      -0.326212, -0.405805,
+      -0.840144, -0.073580,
+      -0.695914,  0.457137,
+      -0.203345,  0.620716
+*/
+
+   offsets[0] = vec2(-0.3,  0.4);
+   offsets[1] = vec2(-0.3,  -0.4);
+   offsets[2] = vec2(0.3,  -0.4);
+   offsets[3] = vec2(0.3,  0.4);
+
+   tmpOutColor = texture( Input, uv );	// UV coords are in image space
+
+   // calculate glow amount
+   diffuseGlowFactor = 0.0113 * (2.0 - max( tmpOutColor.r, tmpOutColor.g ));
+
+   // basic blur filter
+   for (i = 0; i < 4; i++) {
+      tmpOutColor += texture( Input, uv + blurAmount.x * diffuseGlowFactor * offsets[i] );
+   }
+
+   tmpOutColor *= 0.25;
+
+   // TIPS (old-skool strikes again!)
+   // Pay attention here! If you use the "out float4 outColor" directly
+   // in your steps while creating the output color (like you remove
+   // the "tmpOutColor" var and just use the "outColor" directly)
+   // your pixel-color output IS CHANGING EACH TIME YOU DO AN ASSIGNMENT TOO!
+   // A temporary variable, instead, acts like a per-pixel double buffer, and
+   // best of all, lead to better performance.
+   fragColour = tmpOutColor;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HeatBlurVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HeatBlurVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HeatBlurVp.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 150
+
+uniform vec4 position;
+out vec2 uv;
+
+uniform mat4 worldViewProj;
+in vec4 vertex;
+in vec2 uv0;
+
+void main()
+{
+    gl_Position = worldViewProj * vertex;
+    uv  = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HeatCasterFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HeatCasterFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HeatCasterFp.glsl	(revision 12083)
@@ -0,0 +1,9 @@
+#version 150
+
+in vec2 NDotV;
+out vec4 fragColour;
+
+void main()
+{
+   fragColour = vec4(NDotV.x);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/HeatCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/HeatCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/HeatCasterVp.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+#version 150
+
+uniform mat4 worldViewProj;
+uniform vec3 eyePosition;
+in vec4 position;
+in vec4 normal;
+out vec2 NDotV;
+
+void main()
+{
+   vec4 eyeDir = vec4(eyePosition - position.xyz, 0.0);
+   eyeDir = normalize(eyeDir);
+   gl_Position = worldViewProj * position;
+   NDotV = vec2(clamp( dot( normal, eyeDir ), 0.0, 1.0 ));
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Instancing.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Instancing.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Instancing.frag	(revision 12083)
@@ -0,0 +1,69 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+
+#version 150
+
+uniform sampler2D diffuseMap;
+
+uniform vec4	lightPosition;
+uniform vec3	cameraPosition;
+uniform vec3 	lightAmbient;
+uniform vec3	lightDiffuse;
+uniform vec3	lightSpecular;
+uniform vec4	lightAttenuation;
+uniform float	lightGloss;
+
+#if DEPTH_SHADOWRECEIVER
+uniform float invShadowMapSize;
+uniform sampler2DShadow shadowMap;
+
+//declare external function
+//vec4 calcDepthShadow(in vec4 inColour, in float lum);
+float calcDepthShadow(sampler2DShadow shadowMap, vec4 uv, float invShadowMapSize);
+#endif
+
+in vec2 _uv0;
+in vec3 oNormal;
+in vec3 oVPos;
+#if DEPTH_SHADOWRECEIVER
+	in vec4 oLightSpacePos;
+#endif
+out vec4 fragColour;
+
+//---------------------------------------------
+//Main Pixel Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 color = texture( diffuseMap, _uv0 );
+
+	float fShadow = 1.0;
+#if DEPTH_SHADOWRECEIVER
+	fShadow = calcDepthShadow( shadowMap, oLightSpacePos, invShadowMapSize );
+#endif
+
+	vec4 baseColour = texture( diffuseMap, _uv0 );
+
+	//Blinn-Phong lighting
+	vec3 normal	= normalize( oNormal );
+	vec3 lightDir		= lightPosition.xyz - oVPos * lightPosition.w;
+	vec3 eyeDir			= normalize( cameraPosition - oVPos );
+
+	float fLength	= length( lightDir );
+	lightDir			= normalize( lightDir );
+
+	float NdotL	= max( 0.0, dot( normal, lightDir ) );
+	vec3 halfVector		= normalize(lightDir + eyeDir);
+	float HdotN	= max( 0.0, dot( halfVector, normal ) );
+	
+	vec3 ambient  = lightAmbient * baseColour.xyz;
+	vec3 diffuse  = lightDiffuse * NdotL * baseColour.xyz;
+	vec3 specular = lightSpecular * pow( HdotN, lightGloss );
+	
+	vec3 directLighting = (diffuse + specular) * fShadow;
+	
+	fragColour = vec4( directLighting + ambient, baseColour.a );
+	//fragColour = baseColour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/InstancingMisc.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/InstancingMisc.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/InstancingMisc.vert	(revision 12083)
@@ -0,0 +1,62 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 150
+
+//Vertex input
+in vec4 vertex;
+in vec3 normal;
+in vec3 tangent;
+in vec4 uv0;
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+uniform mat4 worldMatrix;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	out vec2 depth;
+#else
+	out vec2 _uv0;
+	out vec3 oNormal;
+	out vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		out vec4 oLightSpacePos;
+	#endif
+#endif
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 worldPos		= vertex * worldMatrix;
+	vec3 worldNorm		= normal * mat3(worldMatrix);
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/InvertFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/InvertFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/InvertFP.glsl	(revision 12083)
@@ -0,0 +1,11 @@
+#version 150
+
+uniform sampler2D RT;
+in vec2 oUv0;
+in vec2 oUv1;
+out vec4 fragColour;
+
+void main()
+{
+	fragColour = 1.0 - texture(RT, oUv0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/LaplaceFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/LaplaceFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/LaplaceFP.glsl	(revision 12083)
@@ -0,0 +1,38 @@
+#version 150
+
+uniform sampler2D Image;
+uniform float scale;
+uniform float pixelSize;
+in vec2 oUv0;
+out vec4 fragColour;
+
+// The Laplace filter approximates the second order derivate,
+// that is, the rate of change of slope in the image. It can be
+// used for edge detection. The Laplace filter gives negative
+// response on the higher side of the edge and positive response
+// on the lower side.
+
+// This is the filter kernel:
+// 0  1  0
+// 1 -4  1
+// 0  1  0
+
+void main()
+{
+    vec2 samples[4];
+	samples[0] = vec2(0, -1);
+	samples[1] = vec2(-1, 0);
+	samples[2] = vec2(1, 0);
+	samples[3] = vec2(0, 1);
+
+    mediump vec4 tc = texture(Image, oUv0);
+    vec4 laplace = -4.0 * tc;
+
+    // Sample the neighbor pixels
+    for (int i = 0; i < 4; i++){
+       laplace += texture(Image, oUv0 + pixelSize * samples[i]);
+    }
+
+    fragColour = (0.5 + scale * laplace);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/LightToHeatFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/LightToHeatFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/LightToHeatFp.glsl	(revision 12083)
@@ -0,0 +1,36 @@
+#version 150
+
+uniform vec4 random_fractions;
+uniform vec4 heatBiasScale;
+uniform vec4 depth_modulator;
+
+uniform sampler2D Input;         // output of HeatVisionCaster_fp (NdotV)
+uniform sampler2D NoiseMap;
+uniform sampler2D HeatLookup;
+
+in vec4 diffuse;
+in vec2 uv;
+out vec4 fragColour;
+
+void main()
+{
+   float depth, heat, interference;
+
+   //  Output constant color:
+   depth = texture( Input, uv ).x;
+   depth *= (depth * depth_modulator).x;
+
+   heat = (depth * heatBiasScale.y);
+
+//   if (depth > 0)
+   {
+		interference = -0.5 + texture( NoiseMap, uv + vec2( random_fractions.x, random_fractions.y ) ).x;
+		interference *= interference;
+		interference *= 1.0 - heat;
+		heat += interference;//+ heatBiasScale.x;
+   }
+
+   // Clamp UVs
+   heat  = max( 0.005, min( 0.995, heat ) );
+   fragColour = texture( HeatLookup, vec2( heat, 0.0 ) );
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/LightToHeatVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/LightToHeatVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/LightToHeatVp.glsl	(revision 12083)
@@ -0,0 +1,13 @@
+#version 150
+
+in vec4 vertex;
+out vec2 uv;
+
+uniform mat4 worldViewProj;
+in vec2 uv0;
+
+void main()
+{
+    gl_Position = worldViewProj * vertex;
+    uv = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/MetaballFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/MetaballFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/MetaballFP.glsl	(revision 12083)
@@ -0,0 +1,28 @@
+#version 150
+
+// Ogre port of Nvidia's IsoSurf.cg file
+// Modified code follows. See http://developer.download.nvidia.com/SDK/10/opengl/samples.html for original
+//
+// Cg port of Yury Uralsky's metaball FX shader
+//
+// Authors: Simon Green and Yury Urlasky
+// Email: sdkfeedback@nvidia.com
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+out vec4 fragColour;
+in vec3 oNormal;
+
+// Pixel shader
+void main()
+{
+	// Sanitize input
+	vec3 N = normalize(oNormal);
+	vec3 L = vec3(0, 0, 1);
+    float nDotL = dot(N, L);
+
+    vec3 materials[2] = vec3[](vec3(1, 1, 1), vec3(0, 0, 0.5));
+
+	fragColour = vec4(abs(nDotL) * materials[int(nDotL < 0.0)], 0.1);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/NightVisionFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/NightVisionFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/NightVisionFP.glsl	(revision 12083)
@@ -0,0 +1,32 @@
+#version 150
+
+out vec4 fragColour;
+
+uniform sampler2D RT;
+uniform sampler3D noiseVol;
+
+in vec2 oUv0;
+uniform vec4 lum;
+uniform float time;
+
+void main()
+{
+	vec4 oC;
+	oC = texture(RT, oUv0);
+	
+	//obtain luminence value
+	oC = vec4(dot(oC,lum));
+	
+	//add some random noise
+	oC += 0.2 *(texture(noiseVol, vec3(oUv0*5,time)))- 0.05;
+	
+	//add lens circle effect
+	//(could be optimised by using texture)
+	float dist = distance(oUv0, vec2(0.5,0.5));
+	oC *= smoothstep(0.5,0.45,dist);
+	
+	//add rb to the brightest pixels
+	oC.rb = vec2(max(oC.r - 0.75, 0)*4);
+	
+	fragColour = oC;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Ocean2GLSL.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Ocean2GLSL.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Ocean2GLSL.frag	(revision 12083)
@@ -0,0 +1,73 @@
+/*********************************************************************NVMH3****
+Copyright NVIDIA Corporation 2003
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+	Simple ocean shader with animated bump map and geometric waves
+	Based partly on "Effective Water Simulation From Physical Models", GPU Gems
+
+11 Aug 05: converted from HLSL to GLSL by Jeff Doyle (nfz) to work in Ogre
+
+******************************************************************************/
+
+#version 150
+
+uniform sampler2D NormalMap;
+uniform samplerCube EnvironmentMap;
+uniform vec4 deepColor;
+uniform vec4 shallowColor;
+uniform vec4 reflectionColor;
+uniform float reflectionAmount;
+uniform float reflectionBlur;
+uniform float waterAmount;
+uniform float fresnelPower;
+uniform float fresnelBias;
+uniform float hdrMultiplier;
+
+in mat3 rotMatrix; // first row of the 3x3 transform from tangent to cube space
+in vec2 bumpCoord0;
+in vec2 bumpCoord1;
+in vec2 bumpCoord2;
+in vec3 eyeVector;
+
+out vec4 fragColour;
+
+void main(void)
+{
+	// sum normal maps
+	// sample from 3 different points so no texture repetition is noticeable
+    vec4 t0 = texture(NormalMap, bumpCoord0) * 2.0 - 1.0;
+    vec4 t1 = texture(NormalMap, bumpCoord1) * 2.0 - 1.0;
+    vec4 t2 = texture(NormalMap, bumpCoord2) * 2.0 - 1.0;
+    vec3 N = t0.xyz + t1.xyz + t2.xyz;
+
+    N = normalize(rotMatrix * N);
+
+	// reflection
+    vec3 E = normalize(eyeVector);
+    vec3 R = reflect(E, N);
+    // Ogre conversion for cube map lookup
+    R.z = -R.z;
+
+    vec4 reflection = texture(EnvironmentMap, R, reflectionBlur);
+    // cheap hdr effect
+    reflection.rgb *= (reflection.r + reflection.g + reflection.b) * hdrMultiplier;
+
+	// fresnel
+    float facing = 1.0 - dot(-E, N);
+    float fresnel = clamp(fresnelBias + pow(facing, fresnelPower), 0.0, 1.0);
+
+    vec4 waterColor = mix(shallowColor, deepColor, facing) * waterAmount;
+
+    reflection = mix(waterColor,  reflection * reflectionColor, fresnel) * reflectionAmount;
+    fragColour = waterColor + reflection;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Ocean2GLSL.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Ocean2GLSL.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Ocean2GLSL.vert	(revision 12083)
@@ -0,0 +1,94 @@
+/*********************************************************************NVMH3****
+Copyright NVIDIA Corporation 2003
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+	Simple ocean shader with animated bump map and geometric waves
+	Based partly on "Effective Water Simulation From Physical Models", GPU Gems
+
+11 Aug 05: converted from HLSL to GLSL by Jeff Doyle (nfz) to work in Ogre
+
+******************************************************************************/
+
+#version 150
+
+uniform vec3 eyePosition;
+uniform float BumpScale;
+uniform vec2 textureScale;
+uniform vec2 bumpSpeed;
+uniform float time;
+uniform float waveFreq;
+uniform float waveAmp;
+uniform mat4 worldViewProj;
+
+in vec4 vertex;
+in vec4 uv0;
+
+out mat3 rotMatrix; //  transform from tangent to obj space
+out vec2 bumpCoord0;
+out vec2 bumpCoord1;
+out vec2 bumpCoord2;
+out vec3 eyeVector;
+
+// wave functions
+struct Wave {
+  float freq;  // 2*PI / wavelength
+  float amp;   // amplitude
+  float phase; // speed * 2*PI / wavelength
+  vec2 dir;
+};
+
+
+void main(void)
+{
+	#define NWAVES 2
+
+	Wave wave[NWAVES];
+
+	wave[0] = Wave( waveFreq, waveAmp, 0.5, vec2(-1, 0) );
+	wave[1] = Wave( 3.0 * waveFreq, 0.33 * waveAmp, 1.7, vec2(-0.7, 0.7) );
+
+    vec4 P = vertex;
+
+	// sum waves
+	float ddx = 0.0, ddy = 0.0;
+	float deriv;
+	float angle;
+
+	// wave synthesis using two sine waves at different frequencies and phase shift
+	for(int i = 0; i<NWAVES; ++i)
+	{
+		angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
+		P.y += wave[i].amp * sin( angle );
+		// calculate derivate of wave function
+		deriv = wave[i].freq * wave[i].amp * cos(angle);
+		ddx -= deriv * wave[i].dir.x;
+		ddy -= deriv * wave[i].dir.y;
+	}
+
+	// compute the 3x3 transform from tangent space to object space
+	// compute tangent basis
+    vec3 T = normalize(vec3(1.0, ddy, 0.0)) * BumpScale;
+    vec3 B = normalize(vec3(0.0, ddx, 1.0)) * BumpScale;
+    vec3 N = normalize(vec3(ddx, 1.0, ddy));
+
+	rotMatrix = mat3(T, B, N);
+
+	gl_Position = worldViewProj * P;
+
+	// calculate texture coordinates for normal map lookup
+	bumpCoord0.xy = uv0.xy * textureScale + time * bumpSpeed;
+	bumpCoord1.xy = uv0.xy * textureScale * 2.0 + time * bumpSpeed * 4.0;
+	bumpCoord2.xy = uv0.xy * textureScale * 4.0 + time * bumpSpeed * 8.0;
+
+	eyeVector = P.xyz - eyePosition; // eye position in vertex space
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingFp.glsl	(revision 12083)
@@ -0,0 +1,43 @@
+#version 150
+
+uniform vec3 lightDiffuse;
+uniform vec3 lightSpecular;
+uniform vec4 scaleBias;
+
+uniform sampler2D normalHeightMap;
+uniform sampler2D diffuseMap;
+
+in vec3 oEyeDir;
+in vec3 oLightDir;
+in vec3 oHalfAngle;
+in vec4 oUv0;
+
+out vec4 fragColour;
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+void main()
+{
+    // Get the height using the tex coords
+    float height = texture(normalHeightMap, oUv0.xy).a;
+
+    // Calculate displacement
+    float displacement = (height * scaleBias.x) + scaleBias.y;
+	
+    vec3 uv2 = vec3(oUv0.xy, 1.0);
+	
+    // calculate the new tex coord to use for normal and diffuse
+    vec2 newTexCoord = ((oEyeDir * displacement) + uv2).xy;
+	
+    // get the new normal and diffuse values
+    vec3 normal = expand(texture(normalHeightMap, newTexCoord).xyz);
+    vec3 diffuse = texture(diffuseMap, newTexCoord).xyz;
+    vec3 specular = pow(clamp(dot(normal, oHalfAngle), 0.0, 1.0), 32.0) * lightSpecular;
+
+    vec3 col = diffuse * (clamp(dot(normal, oLightDir), 0.0, 1.0) * lightDiffuse) + specular;
+    fragColour = vec4(col, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingShadowsFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingShadowsFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingShadowsFp.glsl	(revision 12083)
@@ -0,0 +1,69 @@
+#version 150
+
+uniform vec4 lightDiffuse;
+uniform vec4 scaleBias;
+uniform vec4 spotParams;
+uniform vec4 lightDiffuse1;
+uniform vec4 spotParams1;
+
+uniform sampler2D normalHeightMap;
+uniform sampler2D diffuseMap;
+uniform sampler2D shadowMap1;
+uniform sampler2D shadowMap2;
+
+in vec3 tangentEyeDir;
+in vec3 tangentLightDir[2];
+in vec3 tangentSpotDir[2];
+in vec4 shadowUV[2];
+in vec4 oUv0;
+
+out vec4 fragColour;
+
+// Expand a range-compressed vector
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+void main()
+{
+	// get the height using the tex coords
+	float height = texture(normalHeightMap, oUv0.xy).a;
+	// scale and bias factors	
+	float scale = scaleBias.x;
+	float bias = scaleBias.y;
+
+	// calculate displacement	
+	float displacement = (height * scale) + bias;
+	//float displacement = (height * 0.04) - 0.02;
+	
+	vec3 scaledEyeDir = tangentEyeDir * displacement;
+	
+	// calculate the new tex coord to use for normal and diffuse
+	vec2 newTexCoord = (scaledEyeDir + oUv0.xyz).xy;
+	
+	// get the new normal and diffuse values
+	vec3 normal = expand(texture(normalHeightMap, newTexCoord).xyz);
+	vec4 diffuse = texture(diffuseMap, newTexCoord);
+	
+	vec4 col1 = diffuse * clamp(dot(normal, tangentLightDir[0]),0.0,1.0) * lightDiffuse;
+	// factor in spotlight angle
+	float rho = clamp(dot(tangentSpotDir[0], tangentLightDir[0]),0.0,1.0);
+	// factor = (rho - cos(outer/2) / cos(inner/2) - cos(outer/2)) ^ falloff
+	float spotFactor = pow(
+		clamp(rho - spotParams.y,0.0,1.0) / (spotParams.x - spotParams.y), spotParams.z);
+	col1 = col1 * spotFactor;
+	vec4 col2 = diffuse * clamp(dot(normal, tangentLightDir[1]),0.0,1.0) * lightDiffuse1;
+	// factor in spotlight angle
+	rho = clamp(dot(tangentSpotDir[1], tangentLightDir[1]),0.0,1.0);
+	// factor = (rho - cos(outer/2) / cos(inner/2) - cos(outer/2)) ^ falloff
+	spotFactor = pow(
+		clamp(rho - spotParams1.y,0.0,1.0) / (spotParams1.x - spotParams1.y), spotParams1.z);
+	col2 = col2 * spotFactor;
+
+	// shadow textures
+	col1 = col1 * textureProj(shadowMap1, shadowUV[0]);
+	col2 = col2 * textureProj(shadowMap2, shadowUV[1]);
+
+	fragColour = col1 + col2;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingShadowsVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingShadowsVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingShadowsVp.glsl	(revision 12083)
@@ -0,0 +1,58 @@
+#version 150
+
+uniform vec4 lightPosition; // object space 
+uniform vec4 lightPosition1; // object space 
+uniform vec4 eyePosition;   // object space 
+uniform vec4 spotDirection; // object space
+uniform vec4 spotDirection1; // object space
+uniform mat4 worldViewProj; // not actually used but here for compat with HLSL
+uniform mat4 worldMatrix;
+uniform mat4 texViewProj1;
+uniform mat4 texViewProj2;
+
+out vec3 tangentEyeDir;
+out vec3 tangentLightDir[2];
+out vec3 tangentSpotDir[2];
+out vec4 shadowUV[2];
+out vec4 oUv0;
+
+in vec3 tangent;
+in vec4 position;
+in vec3 normal;
+in vec4 uv0;
+
+void main()
+{
+	gl_Position = worldViewProj * position;
+
+	vec4 worldPos = worldMatrix * position;
+
+    oUv0 = uv0;
+
+	shadowUV[0] = texViewProj1 * worldPos;
+	shadowUV[1] = texViewProj2 * worldPos;
+
+	// calculate tangent space light vector 
+	// Get object space light direction 
+    vec3 lightDir = normalize(lightPosition.xyz -  (position.xyz * lightPosition.w));
+	vec3 lightDir1 = normalize(lightPosition1.xyz -  (position.xyz * lightPosition1.w));
+	
+	vec3 eyeDir = (eyePosition - position).xyz; 
+
+	// Calculate the binormal (NB we assume both normal and tangent are 
+	// already normalised) 
+	vec3 binormal = cross(normal, tangent); 
+
+	// Form a rotation matrix out of the vectors, column major for glsl es 
+	mat3 rotation = mat3(tangent, binormal, normal);
+    
+	// Transform the light vector according to this matrix 
+	tangentLightDir[0] = normalize(rotation * lightDir); 
+	tangentLightDir[1] = normalize(rotation * lightDir1); 
+	// Invert the Y on the eye dir since we'll be using this to alter UVs and
+	// GL has Y inverted
+	tangentEyeDir = normalize(rotation * eyeDir) * vec3(1.0, -1.0, 1.0); 
+
+	tangentSpotDir[0] = normalize(rotation * -spotDirection.xyz);
+	tangentSpotDir[1] = normalize(rotation * -spotDirection1.xyz);	
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMappingVp.glsl	(revision 12083)
@@ -0,0 +1,45 @@
+#version 150
+
+uniform vec4 lightPosition; // object space 
+uniform vec3 eyePosition;   // object space 
+uniform mat4 worldViewProj; // not actually used but here for compat with HLSL
+
+out vec3 oEyeDir;
+out vec3 oLightDir;
+out vec3 oHalfAngle;
+out vec4 oUv0;
+
+in vec3 normal;
+in vec3 tangent;
+in vec4 uv0;
+in vec4 position;
+
+/* Vertex program that moves light and eye vectors into texture tangent space at vertex */ 
+
+void main()
+{
+    // Calculate output position 
+	gl_Position = worldViewProj * position;
+
+    // Pass the main uvs straight through unchanged 
+    oUv0 = uv0;
+
+    vec3 lightDir = lightPosition.xyz - (position.xyz * lightPosition.w);
+
+	vec3 eyeDir = eyePosition - position.xyz; 
+    
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
+	// this equates to NxT, not TxN
+	vec3 localbinormal = cross(tangent, normal);
+
+	// Form a rotation matrix out of the vectors, column major for glsl es 
+	mat3 TBN = mat3(tangent, localbinormal, normal);
+    
+    // Transform the light vector according to this matrix 
+	oLightDir = normalize(TBN * lightDir); 
+	oEyeDir = normalize(TBN * eyeDir); 
+    oHalfAngle = normalize(oEyeDir + oLightDir);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMapping_specular.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMapping_specular.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OffsetMapping_specular.glsl	(revision 12083)
@@ -0,0 +1,48 @@
+#version 150
+
+uniform vec4 lightDiffuse;
+uniform vec4 lightSpecular;
+uniform vec4 scaleBias;
+uniform float exponent;
+uniform sampler2D normalHeightMap;
+
+in vec3 tangentEyeDir;
+in vec3 tangentLightDir[2];
+in vec4 shadowUV[2];
+in vec4 oUv0;
+
+out vec4 fragColour;
+
+vec4 lit(float NdotL, float NdotH, float m) {
+
+  float ambient = 1.0;
+  float diffuse = max(NdotL, 0.0);
+  float specular = step(0.0, NdotL) * max(NdotH * m, 0.0);
+
+  return vec4(ambient, diffuse, specular, 1.0);
+}
+
+vec3 expand(vec3 v)
+{
+	return (v - 0.5) * 2.0;
+}
+
+/*
+  Pixel Shader for doing bump mapping with parallax plus diffuse and specular lighting by masterfalcon
+*/
+void main()
+{
+	float height = texture(normalHeightMap, oUv0.xy).a;
+	float displacement = (height * scaleBias.x) + scaleBias.y;
+	vec2 newTexCoord = ((tangentEyeDir * displacement) + oUv0.xyz).xy;
+	vec3 bumpVec = expand(texture(normalHeightMap, newTexCoord).xyz);
+	vec3 N = normalize(bumpVec);
+
+	vec3 halfAngle = normalize(tangentEyeDir + tangentLightDir[0]); 
+	float NdotL = dot(normalize(tangentLightDir[0]), N);
+	float NdotH = dot(normalize(halfAngle), N); 
+
+	vec4 Lit = lit(NdotL, NdotH, exponent);
+	
+	fragColour = lightDiffuse * Lit.y + lightSpecular * Lit.z;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OldMovieFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OldMovieFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OldMovieFP.glsl	(revision 12083)
@@ -0,0 +1,56 @@
+#version 150
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+uniform sampler2D RT;
+uniform sampler2D SplotchesTx;
+uniform sampler1D Texture2;
+uniform sampler1D SepiaTx;
+uniform float time_cycle_period;
+uniform float flicker;
+uniform float DirtFrequency;
+uniform vec3 luminance;
+uniform float frameJitter;
+uniform float lumiShift;
+
+vec2 calcSpriteAddr(vec2 texCoord, float DirtFrequency1, float period)
+{
+   return texCoord + texture(Texture2, period * DirtFrequency1).xy;
+}
+
+vec4 getSplotches(vec2 spriteAddr)
+{
+   // get sprite address into paged texture coords space
+   spriteAddr = spriteAddr / 6.3;
+   spriteAddr = spriteAddr - (spriteAddr / 33.3);
+
+//   return texture(SplotchesTx, spriteAddr);
+   return vec4(1.0) * texture(SplotchesTx, spriteAddr).r;
+}
+
+void main()
+{
+   // get sprite address
+   vec2 spriteAddr = calcSpriteAddr(oUv0, DirtFrequency, time_cycle_period);
+
+   // add some dark and light splotches to the film
+   vec4 splotches = getSplotches(spriteAddr);
+   vec4 specs = 1.0 - getSplotches(spriteAddr / 3.0);
+
+   // convert color to base luminance
+   vec4 base = texture(RT, oUv0 + vec2(0.0, spriteAddr.y * frameJitter));
+   float lumi = dot(base.rgb, luminance);
+   // randomly shift luminance
+   lumi -= spriteAddr.x * lumiShift;
+   // tone map luminance
+   base.rgb = texture(SepiaTx, lumi).rgb;
+
+   // calc flicker speed
+   float darken = fract(flicker * time_cycle_period);
+
+   // we want darken to cycle between 0.6 and 1.0
+   darken = abs(darken - 0.5) * 0.4 + 0.6;
+   // composite dirt onto film
+   fragColour = base * splotches * darken + specs;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/OldTV.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/OldTV.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/OldTV.glsl	(revision 12083)
@@ -0,0 +1,46 @@
+#version 150
+
+in vec4 pos;
+in vec2 oUv0;
+out vec4 fragColour;
+
+uniform sampler2D Image;
+uniform sampler3D Rand;
+uniform sampler3D Noise;
+uniform float distortionFreq;
+uniform float distortionScale;
+uniform float distortionRoll;
+uniform float interference;
+uniform float frameLimit;
+uniform float frameShape;
+uniform float frameSharpness;
+uniform float time_0_X;
+uniform float sin_time_0_X;
+
+void main()
+{
+   // Define a frame shape
+   float f = (1 - pos.x * pos.x) * (1 - pos.y * pos.y);
+   float frame = clamp(frameSharpness * (pow(f, frameShape) - frameLimit), 0.0, 1.0);
+
+   // Interference ... just a texture filled with rand()
+   float rand = texture(Rand, vec3(1.5 * pos.x, 1.5 * pos.y, time_0_X)).x - 0.2;
+
+   // Some signed noise for the distortion effect
+   float noisy = texture(Noise, vec3(0, 0.5 * pos.y, 0.1 * time_0_X)).x - 0.5;
+
+   // Repeat a 1 - x^2 (0 < x < 1) curve and roll it with sinus.
+   float dst = fract(pos.y * distortionFreq + distortionRoll * sin_time_0_X);
+   dst *= (1 - dst);
+   // Make sure distortion is highest in the center of the image
+   dst /= 1 + distortionScale * abs(pos.y);
+
+   // ... and finally distort
+   vec2 inUv = oUv0;
+   inUv.x += distortionScale * noisy * dst;
+   vec4 image = texture(Image, inUv);
+
+   // Combine frame, distorted image and interference
+   fragColour = frame * (interference * rand + image);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayGS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayGS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayGS.glsl	(revision 12083)
@@ -0,0 +1,42 @@
+#version 150
+
+in block {
+	vec3 	pos;
+    vec4 	color;
+	float	radius;
+} ColoredFirework[];
+
+out block {
+	vec4 	pos;
+    vec4 	color;
+	vec2	texcoord;
+} Firework;
+
+uniform mat4 inverseView;
+uniform mat4 worldViewProj;
+
+layout(points) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+//The geometry shader that prepares the fireworks for display
+void main()
+{
+	vec3 g_positions[4] = vec3[4](vec3(-1, 1, 0), vec3(-1, -1, 0), vec3(1, 1, 0), vec3(1, -1, 0));
+    vec2 g_texcoords[4] = vec2[4](vec2(0, 1), vec2(1, 1), vec2(0, 0), vec2(1, 0));
+
+    //
+    // Emit two new triangles
+    //
+    for(int i=0; i<4; i++)
+    {
+		vec3 position = -g_positions[i] * ColoredFirework[0].radius;
+        position = mat3(inverseView) * position + ColoredFirework[0].pos;
+        gl_Position = worldViewProj * vec4(position, 1.0);
+
+        Firework.pos = gl_Position;
+        Firework.color = ColoredFirework[0].color;
+        Firework.texcoord = g_texcoords[i];
+        EmitVertex();
+    }
+    EndPrimitive();
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayPS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayPS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayPS.glsl	(revision 12083)
@@ -0,0 +1,17 @@
+#version 150
+
+in block {
+	vec4 	pos;
+    vec4 	color;
+	vec2	texcoord;
+} Firework;
+
+out vec4 fragColour;
+
+uniform sampler2D diffuseTex;
+
+//The pixels shaders that colors the fireworks
+void main()
+{
+	fragColour = texture(diffuseTex, Firework.texcoord) * Firework.color;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayVS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayVS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_DisplayVS.glsl	(revision 12083)
@@ -0,0 +1,65 @@
+#version 150
+
+//
+// Explanation of different particle types
+//
+#define PT_LAUNCHER 0 //Firework Launcher - launches a PT_SHELL every so many seconds
+#define PT_SHELL    1 //Unexploded shell - flies from the origin and explodes into many PT_EMBERXs
+#define PT_EMBER1   2 //basic particle - after it's emitted from the shell, it dies
+#define PT_EMBER2   3 //after it's emitted, it explodes again into many PT_EMBER1s
+#define PT_EMBER3   4 //just a differently colored ember1
+#define P_SHELLLIFE 3.0
+#define P_EMBER1LIFE 2.5
+#define P_EMBER2LIFE 1.5
+#define P_EMBER3LIFE 2.0
+
+in vec4 position;
+uniform float inTimer;
+uniform float inType;
+uniform vec3 inVelocity;
+
+out block {
+	vec3 	pos;
+    vec4 	color;
+	float	radius;
+} ColoredFirework;
+
+uniform mat4 worldViewProj;
+
+//The vertex shader that prepares the fireworks for display
+void main()
+{
+    //
+    // Pass the point through
+    //
+    ColoredFirework.pos = position.xyz; //Multiply by world matrix?
+    ColoredFirework.radius = 1.5;
+    
+    //  
+    // calculate the color
+    //
+    if( inType == PT_LAUNCHER )
+    {
+        ColoredFirework.color = vec4(1,0.1,0.1,1);
+        ColoredFirework.radius = 1.0;
+    }
+    else if( inType == PT_SHELL )
+    {
+        ColoredFirework.color = vec4(0.1,1,1,1);
+        ColoredFirework.radius = 1.0;
+    }
+    else if( inType == PT_EMBER1 )
+    {
+        ColoredFirework.color = vec4(1,1,0.1,1);
+        ColoredFirework.color *= (inTimer / P_EMBER1LIFE );
+    }
+    else if( inType == PT_EMBER2 )
+    {
+        ColoredFirework.color = vec4(1,0.1,1,1);
+    }
+    else if( inType == PT_EMBER3 )
+    {
+        ColoredFirework.color = vec4(1,0.1,0.1,1);
+        ColoredFirework.color *= (inTimer / P_EMBER3LIFE );
+    }
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_GenerateGS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_GenerateGS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_GenerateGS.glsl	(revision 12083)
@@ -0,0 +1,210 @@
+#version 150
+
+//
+// Explanation of different particle types
+//
+#define PT_LAUNCHER 0 //Firework Launcher - launches a PT_SHELL every so many seconds
+#define PT_SHELL    1 //Unexploded shell - flies from the origin and explodes into many PT_EMBERXs
+#define PT_EMBER1   2 //basic particle - after it's emitted from the shell, it dies
+#define PT_EMBER2   3 //after it's emitted, it explodes again into many PT_EMBER1s
+#define PT_EMBER3   4 //just a differently colored ember1
+#define P_SHELLLIFE 3.0
+#define P_EMBER1LIFE 2.5
+#define P_EMBER2LIFE 1.5
+#define P_EMBER3LIFE 2.0
+
+//These two were originally shader params, but they caused runtime errors
+#define NUM_EMBER_1S 30
+#define NUM_EMBER_2S 15
+#define NUM_EMBER_3S 10
+//This one was originally a variant, but this also causes runtime errors
+//#define MAX_EMBER_2S 15.0
+
+in block {
+	vec4 	Pos;
+	float 	Timer;
+    float 	Type;
+	vec3	Vel;
+} FireworkData[];
+
+layout(points) in;
+layout(points, max_vertices = 1) out;
+
+uniform sampler1D randomTex;
+uniform vec3 frameGravity;
+uniform float globalTime;
+uniform float elapsedTime;
+uniform float secondsPerFirework;
+out vec4 colour;
+//
+// Generic particle motion handler
+//
+
+void GSGenericHandler( vec3 Pos, vec3 Vel, float Timer, float Type,
+						float elapsedTime, 
+						vec3 frameGravity)
+{
+    gl_Position.xyz = Pos + (Vel * elapsedTime);
+    Vel += frameGravity;
+    Timer -= elapsedTime;
+	if (Pos.y > -100)
+	{
+		EmitVertex();//Pos : POSITION, Vel : TEXCOORD2, Timer : TEXCOORD0, Type : TEXCOORD1);
+	}
+}
+
+//
+// Sample a random direction from our random texture
+//
+vec3 RandomDir(float fOffset, float globalTime, sampler1D randomTex)
+{
+    float tCoord = (globalTime + fOffset) / 300.0;
+    return texture(randomTex, tCoord).rgb;
+}
+
+//
+// Launcher type particle handler
+//
+void GSLauncherHandler( vec3 Pos, vec3 Vel, float Timer, float Type, 
+						float elapsedTime, 
+						float globalTime, 
+						sampler1D randomTex,
+						float secondsPerFirework)
+{
+    if(Timer <= 0)
+    {
+        vec3 vRandom = normalize( RandomDir( Type, globalTime, randomTex) );
+		//Give it more of an up bias
+        vRandom = normalize(vRandom + vec3(0,2.5,0)); 
+		
+		//time to emit a new SHELL
+        gl_Position.xyz = Pos + Vel*elapsedTime;
+        vec3 outputVel = Vel + vRandom*35.0;
+        float  outputTimer = P_SHELLLIFE + vRandom.y*0.5;
+        float outputType = PT_SHELL;
+        EmitVertex();//(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
+        
+        //reset our timer
+        Timer = secondsPerFirework + vRandom.x*0.4;
+    }
+    else
+    {
+        Timer -= elapsedTime;
+    }
+    
+    //emit ourselves to keep us alive
+    EmitVertex();//( Pos : POSITION, Vel : TEXCOORD2, Timer : TEXCOORD0, Type : TEXCOORD1);
+}
+
+//
+// Shell type particle handler
+//	
+void GSShellHandler( vec3 Pos, vec3 Vel, float Timer, float Type,
+					float elapsedTime, 
+					float globalTime, 
+					sampler1D randomTex,
+					vec3 frameGravity)
+{
+    if(Timer <= 0)
+    {
+        vec3 outputPos;
+		vec3 outputVel;
+		float outputTimer;
+		float outputType;
+		
+        vec3 vRandom = vec3(0,0,0);
+        
+        //time to emit a series of new Ember1s  
+        for(int i=0; i<NUM_EMBER_1S; i++)
+        {
+            vRandom = normalize( RandomDir( Type+i, globalTime, randomTex ) );
+            gl_Position.xyz = Pos + Vel*elapsedTime;
+            outputVel = Vel + vRandom*15.0;
+            outputTimer = P_EMBER1LIFE;
+            outputType = PT_EMBER1;
+            EmitVertex();//(outputPos : POSITION, outputTimer : TEXCOORD0, outputType : TEXCOORD1, outputVel : TEXCOORD2);
+        }
+        
+        //find out how many Ember2s to emit
+		//Not doing this because it causes a runtime error
+		//int numEmber2s = abs(vRandom.x)*MAX_EMBER_2S;
+        for(int i=0; i<NUM_EMBER_2S; i++)
+        {
+            vRandom = normalize( RandomDir( Type, globalTime, randomTex) );
+            gl_Position.xyz = Pos + Vel*elapsedTime;
+            outputVel = Vel + vRandom*10.0;
+            outputTimer = P_EMBER2LIFE + 0.4*vRandom.x;
+            outputType = PT_EMBER2;
+            EmitVertex();//(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
+        }
+        
+    }
+    else
+    {
+        GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
+    }
+}
+
+//
+// Ember1 and Ember3 type particle handler
+//
+void GSEmber1Handler( vec3 Pos, vec3 Vel, float Timer, float Type,
+						float elapsedTime, 
+						vec3 frameGravity)
+{
+    if(Timer > 0)
+    {
+        GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
+    }
+}
+
+//
+// Ember2 type particle handler
+//
+void GSEmber2Handler( vec3 Pos, vec3 Vel, float Timer, float Type,
+						float elapsedTime, 
+						float globalTime, 
+						sampler1D randomTex,
+						vec3 frameGravity)
+{
+    if(Timer <= 0)
+    {
+		vec3 outputPos;
+		vec3 outputVel;
+		float outputTimer;
+		float outputType;
+    
+        //time to emit a series of new Ember3s  
+        for(int i=0; i<NUM_EMBER_3S; i++)
+        {
+            gl_Position.xyz = Pos + Vel*elapsedTime;
+            outputVel = Vel + normalize( RandomDir( Type + i, globalTime, randomTex ) )*10.0;
+            outputTimer = P_EMBER3LIFE;
+            outputType = PT_EMBER3;
+            EmitVertex();
+        }
+    }
+    else
+    {
+         GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
+    }
+}
+
+void main()
+{
+	if( FireworkData[0].Type == PT_LAUNCHER )
+        GSLauncherHandler( FireworkData[0].Pos.xyz, FireworkData[0].Vel, FireworkData[0].Timer, FireworkData[0].Type, 
+							elapsedTime, globalTime, randomTex, secondsPerFirework);
+	else if ( FireworkData[0].Type == PT_SHELL )
+        GSShellHandler( FireworkData[0].Pos.xyz, FireworkData[0].Vel, FireworkData[0].Timer, FireworkData[0].Type, 
+							elapsedTime, globalTime, randomTex, frameGravity);
+	else if ( FireworkData[0].Type == PT_EMBER1 ||
+              FireworkData[0].Type == PT_EMBER3 )
+        GSEmber1Handler( FireworkData[0].Pos.xyz, FireworkData[0].Vel, FireworkData[0].Timer, FireworkData[0].Type, 
+							elapsedTime, frameGravity);
+    else if( FireworkData[0].Type == PT_EMBER2 )
+        GSEmber2Handler( FireworkData[0].Pos.xyz, FireworkData[0].Vel, FireworkData[0].Timer, FireworkData[0].Type, 
+							elapsedTime, globalTime, randomTex, frameGravity);
+    colour = vec4(1.0,1.0,0.0,1.0);
+	EndPrimitive();
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_GenerateVS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_GenerateVS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ParticleGS_GenerateVS.glsl	(revision 12083)
@@ -0,0 +1,22 @@
+#version 150
+
+in vec4 vertex;
+uniform float inTimer;
+uniform float inType;
+uniform vec3 inVelocity;
+
+out block {
+	vec4 	Pos;
+	float 	Timer;
+    float 	Type;
+	vec3	Vel;
+} FireworkData;
+
+//The vertex shader that prepares the fireworks for display
+void main()
+{
+	FireworkData.Pos = vertex;
+	FireworkData.Timer = inTimer;
+	FireworkData.Type = inType;
+	FireworkData.Vel = inVelocity;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/PassthroughFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/PassthroughFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/PassthroughFP.glsl	(revision 12083)
@@ -0,0 +1,12 @@
+#version 150
+
+in vec4 colour;
+out vec4 fragColour;
+
+/*
+  Basic ambient lighting fragment program for GLSL ES
+*/
+void main()
+{
+	fragColour = colour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/PassthroughVP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/PassthroughVP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/PassthroughVP.glsl	(revision 12083)
@@ -0,0 +1,7 @@
+#version 150
+
+void main()																					
+{																							
+	//Transform the vertex (ModelViewProj matrix)											
+	gl_Position = ftransform();																
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/PosterizeFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/PosterizeFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/PosterizeFP.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+#version 150
+
+uniform sampler2D RT;
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+	float nColors = 8.0;
+	float gamma = 0.6;
+
+	vec4 texCol = vec4(texture(RT, oUv0));
+	vec3 tc = texCol.xyz;
+	tc = pow(tc, vec3(gamma));
+	tc = tc * nColors;
+	tc = floor(tc);
+	tc = tc / nColors;
+	tc = pow(tc, vec3(1.0/gamma));
+	fragColour = vec4(tc, texCol.w);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/Radial_Blur_FP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/Radial_Blur_FP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/Radial_Blur_FP.glsl	(revision 12083)
@@ -0,0 +1,60 @@
+#version 150
+
+//------------------------------------------------------
+//Radial_Blur_FP.glsl
+//  Implements radial blur to be used with the compositor
+//  It's very dependent on screen resolution
+//------------------------------------------------------
+
+uniform sampler2D tex;
+uniform float sampleDist;
+uniform float sampleStrength;
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+	float samples[10];
+	
+	samples[0] = -0.08;
+	samples[1] = -0.05;
+	samples[2] = -0.03;
+	samples[3] = -0.02;
+	samples[4] = -0.01;
+	samples[5] = 0.01;
+	samples[6] = 0.02;
+	samples[7] = 0.03;
+	samples[8] = 0.05;
+	samples[9] = 0.08;
+	
+   //Vector from pixel to the center of the screen
+   vec2 dir = 0.5 - oUv0;
+
+   //Distance from pixel to the center (distant pixels have stronger effect)
+   //float dist = distance( vec2( 0.5, 0.5 ), texCoord );
+   float dist = sqrt( dir.x*dir.x + dir.y*dir.y );
+
+
+   //Now that we have dist, we can normlize vector
+   dir = normalize( dir );
+
+   //Save the color to be used later
+   vec4 color = texture( tex, oUv0 );
+   //Average the pixels going along the vector
+   vec4 sum = color;
+   for (int i = 0; i < 10; i++)
+   {
+      vec4 res=texture( tex, oUv0 + dir * samples[i] * sampleDist );
+      sum += res;
+   }
+   sum /= 11.0;
+
+   //Calculate amount of blur based on
+   //distance and a strength parameter
+   float t = dist * sampleStrength;
+   t = clamp( t, 0.0, 1.0 );//We need 0 <= t <= 1
+
+   //Blend the original color with the averaged pixels
+   fragColour = mix( color, sum, t );
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/SampleFieldVS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/SampleFieldVS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/SampleFieldVS.glsl	(revision 12083)
@@ -0,0 +1,87 @@
+#version 150
+
+// Ogre port of Nvidia's IsoSurf.cg file
+// Modified code follows. See http://developer.download.nvidia.com/SDK/10/opengl/samples.html for original
+//
+// Cg port of Yury Uralsky's metaball FX shader
+//
+// Authors: Simon Green and Yury Urlasky
+// Email: sdkfeedback@nvidia.com
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+uniform float IsoValue = 1.0;
+uniform mat4 WorldViewProj;
+uniform mat4 origWorldViewIT;
+
+// Size of the sampling grid
+const ivec3 SizeMask = ivec3( 63, 63, 63 );
+const ivec3 SizeShift = ivec3( 0, 6, 12 );
+uniform vec4 Metaballs[2] = vec4[](vec4( -0.5, 0, 0, 0.2 ), vec4( 0.6, 0, 0, 0.1 ));
+
+in vec4 vertex;
+
+out VertexData {
+    vec3 N;
+    vec2 Field;
+} VertexOut;
+
+// Metaball function
+// Returns metaball function value in .w and its gradient in .xyz
+
+vec4 Metaball(vec3 Pos, vec3 Center, float RadiusSq)
+{
+	const float epsilon = 0.001;
+
+	vec3 Dist = Pos - Center;
+	float InvDistSq = 1 / (dot(Dist, Dist) + epsilon);
+
+	vec4 o;
+	o.xyz = -2 * RadiusSq * InvDistSq * InvDistSq * Dist;
+	o.w = RadiusSq * InvDistSq;
+	return o;
+}
+
+void main()
+{
+	// Sum up contributions from all metaballs
+/*	vec4 Field;
+	for (int i = 0; i<2; i++) 
+	{
+		Field += Metaball(vertex.xyz, Metaballs[i].xyz, Metaballs[i].w);
+	}
+	
+	mat3 WorldViewIT = mat3(origWorldViewIT[0].xyz, origWorldViewIT[1].xyz, origWorldViewIT[2].xyz);
+	
+	// Transform position and normals
+	gl_Position = WorldViewProj * vertex;
+	VertexOut.N = WorldViewIT * Field.xyz;	// we want normals in world space
+	VertexOut.Field.x = Field.w;
+	
+	// Generate in-out flags
+	VertexOut.Field.y = (Field.w < 1.0) ? 1 : 0;
+*/
+	vec3 Pos;
+
+	// Generate sampling point position based on its index
+	Pos.x = float((gl_VertexID >> SizeShift.x) & SizeMask.x) / (SizeMask.x + 1);
+	Pos.y = float((gl_VertexID >> SizeShift.y) & SizeMask.y) / (SizeMask.y + 1);
+	Pos.z = float((gl_VertexID >> SizeShift.z) & SizeMask.z) / (SizeMask.z + 1);
+	Pos = Pos*2 - 1;
+
+	// Sum up contributions from all metaballs
+	vec4 Field;
+	for (int i = 0; i<2; i++)
+		Field += Metaball(Pos, Metaballs[i].xyz, Metaballs[i].w);
+
+	// Transform position and normals
+	gl_Position = WorldViewProj * vec4(Pos, 1);
+	VertexOut.N = mat3(origWorldViewIT) * Field.xyz;	// we want normals in world space
+	VertexOut.Field.x = Field.w;
+
+	// Generate in-out flags
+	VertexOut.Field.y = (Field.w < IsoValue) ? 1 : 0;
+
+//	o.Color = (Field*0.5+0.5) * (Field.w / 10.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ShaderInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ShaderInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ShaderInstancing.vert	(revision 12083)
@@ -0,0 +1,117 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 150
+
+//Vertex input
+in vec4 vertex;
+in vec3 normal;
+in vec3 tangent;
+in vec4 uv0;
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+//uniform mat4x3 worldMatrix3x4Array[80];
+#ifdef ST_DUAL_QUATERNION
+uniform vec4 worldDualQuaternion2x4Array[240];
+#else
+uniform vec4 worldMatrix3x4Array[240]; //240 = 80*3
+#endif
+
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	out vec2 depth;
+#else
+	out vec2 _uv0;
+	out vec3 oNormal;
+	out vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		out vec4 oLightSpacePos;
+	#endif
+#endif
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+vec4 worldPos;
+vec3 worldNorm;
+
+#ifdef ST_DUAL_QUATERNION
+	int idx = int(blendIndices[0]) * 2;
+	mat2x4 blendDQ;
+	blendDQ[0] = worldDualQuaternion2x4Array[idx];
+	blendDQ[1] = worldDualQuaternion2x4Array[idx + 1];
+#ifdef BONE_TWO_WEIGHTS
+	int idx2 = int(blendIndices[1]) * 2;
+	mat2x4 blendDQ2;
+ 	blendDQ2[0] = worldDualQuaternion2x4Array[idx2];
+	blendDQ2[1] = worldDualQuaternion2x4Array[idx2 + 1];
+
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= blendWeights.x;
+	blendDQ += blendWeights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(normal, blendDQ);
+#else
+	mat4 worldMatrix;
+	int idx = int(blendIndices[0]) * 3;
+	worldMatrix[0] = worldMatrix3x4Array[idx];
+	worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+	worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	worldPos		= vertex * worldMatrix;
+	worldNorm		= normal * mat3(worldMatrix);
+#endif
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/SharpenEdgesFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/SharpenEdgesFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/SharpenEdgesFP.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+#version 150
+
+uniform sampler2D RT;
+uniform vec2 vTexelSize;
+
+in vec2 oUv0;
+in vec2 oUv1;
+out vec4 fragColour;
+
+void main()
+{
+	vec2 usedTexelED[8];
+	usedTexelED[0] = vec2(-1, -1);
+	usedTexelED[1] = vec2(0, -1);
+	usedTexelED[2] = vec2(1, -1);
+	usedTexelED[3] = vec2(-1, 0);
+	usedTexelED[4] = vec2(1, 0);
+	usedTexelED[5] = vec2(-1, 1);
+	usedTexelED[6] = vec2(0, 1);
+	usedTexelED[7] = vec2(1, 1);
+
+    vec4 tc = texture(RT, oUv0);
+	vec4 cAvgColor = vec4(9.0 * tc);
+
+	for(int t=0; t<8; t++)
+		cAvgColor -= texture(RT, oUv0 + vTexelSize * usedTexelED[t]);
+
+	fragColour = cAvgColor;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ShowNormals.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ShowNormals.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ShowNormals.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 150
+
+in vec4 position;
+in vec3 normal;
+
+out vec4 oUv0;
+
+uniform mat4 worldViewProj;
+
+void main()
+{
+	gl_Position = worldViewProj * position;
+	oUv0 = vec4(normal, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ShowTangents.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ShowTangents.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ShowTangents.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 150
+
+in vec4 position;
+in vec3 tangent;
+
+out vec4 oUv0;
+
+uniform mat4 worldViewProj;
+
+void main()
+{
+	gl_Position = worldViewProj * position;
+	oUv0 = vec4(tangent, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ShowUV.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ShowUV.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ShowUV.glsl	(revision 12083)
@@ -0,0 +1,13 @@
+#version 150
+
+in vec4 ambientUV;
+in vec4 ambColour;
+
+out vec4 fragColour;
+
+// Basic fragment program to display UV
+void main()
+{
+	// wrap values using fract
+	fragColour = vec4(fract(ambientUV.x), fract(ambientUV.y), 0.0, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/ShowUVdir3D.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/ShowUVdir3D.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/ShowUVdir3D.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+#version 150
+
+in vec4 oUv0;
+
+out vec4 fragColour;
+
+// Basic fragment program to display 3d uv
+void main()
+{
+	vec3 n = normalize(oUv0.xyz);
+	fragColour = vec4(n.x, n.y, n.z, 1.0);
+}
+
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex2_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex2_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex2_vp.glsl	(revision 12083)
@@ -0,0 +1,17 @@
+#version 150
+
+uniform mat4 worldViewProj;
+in vec4 vertex;
+in vec2 uv0;
+out vec2 oUv0;
+out vec2 oUv1;
+
+void main()
+{
+	// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    gl_Position = worldViewProj * vertex;
+
+    // Convert to image-space
+    oUv0 = uv0;
+    oUv1 = oUv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex2a_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex2a_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex2a_vp.glsl	(revision 12083)
@@ -0,0 +1,18 @@
+#version 150
+
+uniform mat4 worldViewProj;
+in vec4 vertex;
+in vec2 uv0;
+out vec2 oUv0;
+out vec2 oUv1;
+out vec4 pos;
+
+void main()
+{
+	// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    gl_Position = worldViewProj * vertex;
+
+    oUv0 = uv0;
+    oUv1 = -vertex.xy;
+    pos = gl_Position;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex3_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex3_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex3_vp.glsl	(revision 12083)
@@ -0,0 +1,22 @@
+#version 150
+
+uniform mat4 worldViewProj;
+in vec4 vertex;
+in vec2 uv0;
+out vec2 oUv0;
+out vec2 oUv1;
+out vec2 oUv2;
+out vec4 pos;
+
+void main()
+{
+	// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    gl_Position = worldViewProj * vertex;
+
+
+    // Convert to image-space
+    oUv0 = uv0;
+    oUv1 = oUv0;
+    oUv2 = oUv0;
+    pos = gl_Position;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex4_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex4_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_Tex4_vp.glsl	(revision 12083)
@@ -0,0 +1,22 @@
+#version 150
+
+uniform mat4 worldViewProj;
+in vec4 vertex;
+in vec2 uv0;
+out vec2 oUv0;
+out vec2 oUv1;
+out vec2 oUv2;
+out vec2 oUv3;
+out vec4 pos;
+
+void main()
+{
+	// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    gl_Position = worldViewProj * vertex;
+
+    oUv0 = uv0;
+    oUv1 = oUv0;
+    oUv2 = oUv0;
+    oUv3 = oUv0;
+    pos = gl_Position;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/StdQuad_vp.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+#version 150
+
+in vec4 vertex;
+in vec2 uv0;
+uniform mat4 worldViewProj;
+
+out vec2 oUv0;
+
+void main()                    
+{
+	gl_Position = worldViewProj * vertex;
+		
+	oUv0 = uv0;
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/SwizzleGP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/SwizzleGP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/SwizzleGP.glsl	(revision 12083)
@@ -0,0 +1,41 @@
+#version 150
+
+#extension GL_EXT_geometry_shader4 : enable													
+
+uniform vec4 origColor;																		
+uniform vec4 cloneColor;																	
+
+void main(void)																				
+{																							
+
+	//increment variable																	
+	int i;																					
+
+	/////////////////////////////////////////////////////////////							
+	//This example has two parts															
+	//	step a) draw the primitive pushed down the pipeline									
+	//		 there are gl_Vertices # of vertices											
+	//		 put the vertex value into gl_Position											
+	//		 use EmitVertex => 'create' a new vertex										
+	// 		use EndPrimitive to signal that you are done creating a primitive!				
+	//	step b) create a new piece of geometry (I.E. WHY WE ARE USING A GEOMETRY SHADER!)	
+	//		I just do the same loop, but swizzle the x and y values							
+	//	result => the line we want to draw, and the same line, but along the other axis		
+
+	//Pass-thru!																			
+	for(i=0; i< gl_VerticesIn; i++){														
+		gl_Position = gl_PositionIn[i];														
+		gl_FrontColor = origColor;															
+		EmitVertex();																		
+	}																						
+	EndPrimitive();																			
+	//New piece of geometry!  We just swizzle the x and y terms								
+	for(i=0; i< gl_VerticesIn; i++){														
+		gl_Position = gl_PositionIn[i];														
+		gl_Position.xy = gl_Position.yx;													
+		gl_FrontColor = cloneColor;															
+		EmitVertex();																		
+	}																						
+	EndPrimitive();																			
+
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/TessellateTetrahedraGS.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/TessellateTetrahedraGS.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/TessellateTetrahedraGS.glsl	(revision 12083)
@@ -0,0 +1,83 @@
+#version 150
+
+// Ogre port of Nvidia's IsoSurf.cg file
+// Modified code follows. See http://developer.download.nvidia.com/SDK/10/opengl/samples.html for original
+//
+// Cg port of Yury Uralsky's metaball FX shader
+//
+// Authors: Simon Green and Yury Urlasky
+// Email: sdkfeedback@nvidia.com
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Size of the sampling grid
+in VertexData {
+    vec3 N;
+    vec2 Field;
+} VertexIn[];
+
+out vec3 oNormal;
+
+uniform float IsoValue;
+
+layout(lines_adjacency) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+// TODO: Change this from outputting triangles to a triangle strip
+
+
+// Estimate where isosurface intersects grid edge with endpoints v0, v1
+void CalcIntersection(vec4 Pos0,
+					  vec3 N0,
+					  vec2 Field0,
+					  vec4 Pos1,
+					  vec3 N1,
+					  vec2 Field1)
+{
+	float t = (IsoValue - Field0.x) / (Field1.x - Field0.x);
+	gl_Position = mix(Pos0, Pos1, t);
+	oNormal = mix(N0, N1, t);
+    EmitVertex();
+}
+
+// Geometry shader
+// input: line with adjacency (tetrahedron)
+// outputs: zero, one or two triangles depending if isosurface intersects tetrahedron
+void main()
+{
+	// construct index for this tetrahedron
+	uint index = uint((int(VertexIn[0].Field.y) << 3) |
+                      (int(VertexIn[1].Field.y) << 2) |
+                      (int(VertexIn[2].Field.y) << 1) |
+                       int(VertexIn[3].Field.y));
+	
+	// don't bother if all vertices out or all vertices inside isosurface
+	if (index > uint(0) && index < uint(15))
+	{
+		// Uber-compressed version of the edge table.
+		uint edgeListHex[8] = 
+			uint[8](uint(0x0001cde0), uint(0x98b08c9d), uint(0x674046ce), uint(0x487bc480), 
+                    uint(0x21301d2e), uint(0x139bd910), uint(0x26376e20), uint(0x3b700000));
+
+		uint edgeValFull = edgeListHex[index/uint(2)];
+		uint three = uint(0x3);
+		uint edgeVal = (index % uint(2) == uint(1)) ? (edgeValFull & uint(0xFFFF)) : ((edgeValFull >> 16) & uint(0xFFFF));
+		ivec4 e0 = ivec4((edgeVal >> 14) & three, (edgeVal >> 12) & three, (edgeVal >> 10) & three, (edgeVal >> 8) & three);
+		ivec4 e1 = ivec4((edgeVal >> 6) & three, (edgeVal >> 4) & three, (edgeVal >> 2) & three, (edgeVal >> 0) & three);
+
+		CalcIntersection(gl_in[e0.x].gl_Position, VertexIn[e0.x].N, VertexIn[e0.x].Field,
+		                 gl_in[e0.y].gl_Position, VertexIn[e0.y].N, VertexIn[e0.y].Field);
+		CalcIntersection(gl_in[e0.z].gl_Position, VertexIn[e0.z].N, VertexIn[e0.z].Field,
+		                 gl_in[e0.w].gl_Position, VertexIn[e0.w].N, VertexIn[e0.w].Field);
+		CalcIntersection(gl_in[e1.x].gl_Position, VertexIn[e1.x].N, VertexIn[e1.x].Field,
+		                 gl_in[e1.y].gl_Position, VertexIn[e1.y].N, VertexIn[e1.y].Field);
+
+		// Emit additional triangle, if necessary
+		if (e1.z != -1) {
+			CalcIntersection(gl_in[e1.z].gl_Position, VertexIn[e1.z].N, VertexIn[e1.z].Field,
+			                 gl_in[e1.w].gl_Position, VertexIn[e1.w].N, VertexIn[e1.w].Field);
+		}
+        EndPrimitive();
+	}
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/TilingFP.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/TilingFP.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/TilingFP.glsl	(revision 12083)
@@ -0,0 +1,34 @@
+#version 150
+
+uniform sampler2D RT;
+uniform float NumTiles;
+uniform float Threshold;
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main()
+{
+	vec3 EdgeColor = vec3(0.7, 0.7, 0.7);
+
+    float size = 1.0/NumTiles;
+    vec2 Pbase = oUv0 - mod(oUv0, vec2(size));
+    vec2 PCenter = vec2(Pbase + (size/2.0));
+    vec2 st = (oUv0 - Pbase)/size;
+    vec4 c1 = vec4(0.0);
+    vec4 c2 = vec4(0.0);
+    vec4 invOff = vec4((1.0-EdgeColor),1.0);
+    if (st.x > st.y) { c1 = invOff; }
+    float threshholdB =  1.0 - Threshold;
+    if (st.x > threshholdB) { c2 = c1; }
+    if (st.y > threshholdB) { c2 = c1; }
+    vec4 cBottom = c2;
+    c1 = vec4(0.0);
+    c2 = vec4(0.0);
+    if (st.x > st.y) { c1 = invOff; }
+    if (st.x < Threshold) { c2 = c1; }
+    if (st.y < Threshold) { c2 = c1; }
+    vec4 cTop = c2;
+    vec4 tileColor = vec4(texture(RT, PCenter));
+    vec4 result = tileColor + cTop - cBottom;
+    fragColour = result;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/VTFInstancing.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/VTFInstancing.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/VTFInstancing.vert	(revision 12083)
@@ -0,0 +1,113 @@
+//---------------------------------------------------------------------------
+//These materials/shaders are part of the NEW InstanceManager implementation
+//Written by Matias N. Goldberg ("dark_sylinc")
+//---------------------------------------------------------------------------
+#version 150
+
+//Vertex input
+in vec4 vertex;
+in vec3 normal;
+
+#ifdef BONE_TWO_WEIGHTS
+	in vec4 blendWeights;
+#endif
+
+in vec4 uv0;
+in vec4 uv1;
+in vec4 uv2;
+in vec3 tangent;
+
+//Parameters
+uniform mat4 viewProjMatrix;
+uniform sampler2D matrixTexture;
+
+#if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER)
+uniform vec4 depthRange;
+#endif
+
+#if DEPTH_SHADOWRECEIVER
+uniform mat4 texViewProjMatrix;
+#endif
+
+//Output
+#if DEPTH_SHADOWCASTER
+	out vec2 depth;
+#else
+	out vec2 _uv0;
+	out vec3 oNormal;
+	out vec3 oVPos;
+	#if DEPTH_SHADOWRECEIVER
+		out vec4 oLightSpacePos;
+	#endif
+#endif
+
+vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ)
+{
+	vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position);
+	vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw));
+	blendPosition += trans;
+
+	return blendPosition;
+}
+
+vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ)
+{
+	return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal);
+}
+
+//---------------------------------------------
+//Main Vertex Shader
+//---------------------------------------------
+void main(void)
+{
+	vec4 worldPos;
+	vec3 worldNorm;
+
+#ifdef ST_DUAL_QUATERNION
+	mat2x4 blendDQ;	
+	blendDQ[0] = texture( matrixTexture, uv1.xy );
+	blendDQ[1] = texture( matrixTexture, uv1.zy );
+#ifdef BONE_TWO_WEIGHTS
+	mat2x4 blendDQ2;
+	blendDQ2[0] = texture( matrixTexture, uv2.xy );
+	blendDQ2[1] = texture( matrixTexture, uv2.zw );
+
+	//Accurate antipodality handling. For speed increase, remove the following line
+	if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0;
+	
+	//Blend the dual quaternions based on the weights
+	blendDQ *= blendWeights.x;
+	blendDQ += blendWeights.y*blendDQ2;
+	//Normalize the resultant dual quaternion
+	blendDQ /= length(blendDQ[0]);
+#endif
+	worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0);
+	worldNorm = calculateBlendNormal(normal, blendDQ);
+#else
+	mat4 worldMatrix;
+	worldMatrix[0] = texture( matrixTexture, uv1.xy );
+	worldMatrix[1] = texture( matrixTexture, uv1.zw );
+	worldMatrix[2] = texture( matrixTexture, uv2.xy );
+	worldMatrix[3] = vec4( 0, 0, 0, 1 );
+
+	worldPos		= vertex * worldMatrix;
+	worldNorm		= normal * mat3(worldMatrix);
+#endif
+
+	//Transform the position
+	gl_Position			= viewProjMatrix * worldPos;
+	
+#if DEPTH_SHADOWCASTER
+	depth.x				= (gl_Position.z - depthRange.x) * depthRange.w;
+	depth.y				= depthRange.w;
+#else
+	_uv0		= uv0.xy;
+	oNormal		= worldNorm;
+	oVPos		= worldPos.xyz;
+
+	#if DEPTH_SHADOWRECEIVER
+		oLightSpacePos		= texViewProjMatrix * worldPos;
+		oLightSpacePos.z	= (oLightSpacePos.z - depthRange.x) * depthRange.w;
+	#endif
+#endif
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/crowdVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/crowdVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/crowdVp.glsl	(revision 12083)
@@ -0,0 +1,64 @@
+#version 150
+
+uniform mat4 viewProjectionMatrix;
+uniform float numBones;
+uniform vec4 worldMatrix3x4Array[240];
+uniform vec4 lightDiffuseColour;
+uniform vec4 ambient;
+uniform vec4 lightPos;
+
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+in vec4 vertex;
+in vec3 normal;
+in vec4 uv0;
+in vec4 uv1;
+out vec4 colour;
+out vec4 oUv0;
+out vec4 oUv1;
+
+void main()
+{
+	vec3 blendPos = vec3(0);
+	vec3 blendNorm = vec3(0);
+	vec3 tmpPos = vec3(0);
+	vec3 tmpNorm = vec3(0);
+
+	int instanceOffset = int(uv1.x) * 3 * int(numBones);
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+		for (int row = 0; row < 3; ++row)
+		{
+		    int idx = instanceOffset + int(blendIndices[bone]) * 3 + row;
+			vec4 blendMatrixRow = worldMatrix3x4Array[idx];
+			tmpPos[row] = dot(blendMatrixRow, gl_Vertex);
+#if SHADOW_CASTER
+#else
+			tmpNorm[row] = dot(blendMatrixRow.xyz, gl_Normal);
+#endif	
+		}
+		// now weight this into final 
+		blendPos += tmpPos * blendWeights[bone];
+#if SHADOW_CASTER
+#else
+		blendNorm += tmpNorm * blendWeights[bone];
+#endif
+	}
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1);
+
+#if SHADOW_CASTER
+	colour = ambient;
+#else
+	// simple lighting model
+	vec3 lightDir = normalize(
+		lightPos.xyz - (blendPos.xyz * lightPos.w));
+	colour = ambient 
+		+ clamp(dot(lightDir, blendNorm), 0.0, 1.0) * lightDiffuseColour;
+#endif
+    colour = vec4(0);
+	oUv0 = uv0;	
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_bloom.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_bloom.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_bloom.glsl	(revision 12083)
@@ -0,0 +1,24 @@
+#version 150
+
+uniform sampler2D inRTT;
+
+uniform vec4 sampleOffsets[15];
+uniform vec4 sampleWeights[15];
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 1.0);
+	vec2 sampleUV;
+
+    for( int i = 0; i < 15; i++ )
+    {
+        // Sample from adjacent points, 7 each side and central
+        sampleUV = oUv0 + sampleOffsets[i].xy;
+        accum += sampleWeights[i] * texture(inRTT, sampleUV);
+    }
+
+    fragColour = accum;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale2x2luminence.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale2x2luminence.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale2x2luminence.glsl	(revision 12083)
@@ -0,0 +1,27 @@
+#version 150
+
+uniform sampler2D inRTT;
+uniform vec2 texelSize;
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main(void)
+{
+	
+    vec4 accum = vec4(0.0);
+	vec4 LUMINENCE_FACTOR = vec4(0.27, 0.67, 0.06, 0.0);
+
+    // Get colour from source
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-0.5, -0.5));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-0.5, 0.5));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(0.5, 0.5));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(0.5, -0.5));
+
+	// Adjust the accumulated amount by lum factor
+	float lum = dot(accum, LUMINENCE_FACTOR);
+
+	// Take average of 4 samples
+	lum *= 0.25;
+	fragColour = vec4(lum, lum, lum, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale3x3.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale3x3.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale3x3.glsl	(revision 12083)
@@ -0,0 +1,28 @@
+#version 150
+
+uniform sampler2D inRTT;
+uniform vec2 texelSize;
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+void main(void)
+{
+    vec4 accum = vec4(0.0);
+
+    // Get colour from source
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-1.0, -1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 0.0, -1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 1.0, -1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-1.0,  0.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 0.0,  0.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 1.0,  0.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-1.0,  1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 0.0,  1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 1.0,  1.0));
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+	fragColour = accum;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale3x3brightpass.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale3x3brightpass.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_downscale3x3brightpass.glsl	(revision 12083)
@@ -0,0 +1,39 @@
+#version 150
+
+uniform sampler2D inRTT;
+uniform sampler2D inLum;
+uniform vec2 texelSize;
+
+in vec2 oUv0;
+out vec4 fragColour;
+const vec4 BRIGHT_LIMITER = vec4(0.6, 0.6, 0.6, 0.0);
+
+// declare external function
+vec4 toneMap(in vec4 inColour, in float lum);
+
+void main(void)
+{
+    vec4 accum = vec4(0.0);
+
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-1.0, -1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 0.0, -1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 1.0, -1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-1.0,  0.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 0.0,  0.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 1.0,  0.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2(-1.0,  1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 0.0,  1.0));
+    accum += texture(inRTT, oUv0 + texelSize * vec2( 1.0,  1.0));
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+    // Reduce bright and clamp
+    accum = max(vec4(0.0, 0.0, 0.0, 1.0), accum - BRIGHT_LIMITER);
+
+	// Sample the luminence texture
+	vec4 lum = texture(inLum, vec2(0.5));
+	
+	// Tone map result
+	fragColour = toneMap(accum, lum.r);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_finalToneMapping.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_finalToneMapping.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_finalToneMapping.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+#version 150
+
+uniform sampler2D inRTT;
+uniform sampler2D inBloom;
+uniform sampler2D inLum;
+
+in vec2 oUv0;
+out vec4 fragColour;
+
+// declare external function
+vec4 toneMap(in vec4 inColour, in float lum);
+
+void main(void)
+{
+	// Get main scene colour
+    vec4 sceneCol = texture(inRTT, oUv0);
+
+	// Get luminence value
+	vec4 lum = texture(inLum, vec2(0.5));
+
+	// tone map this
+	vec4 toneMappedSceneCol = toneMap(sceneCol, lum.r);
+	
+	// Get bloom colour
+    vec4 bloom = texture(inBloom, oUv0);
+
+	// Add scene & bloom
+	fragColour = vec4(toneMappedSceneCol.rgb + bloom.rgb, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_tonemap_util.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_tonemap_util.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/hdr_tonemap_util.glsl	(revision 12083)
@@ -0,0 +1,28 @@
+#version 150
+
+const float MIDDLE_GREY = 0.72;
+const float FUDGE = 0.001;
+const float L_WHITE = 1.5;
+
+/** Tone mapping function 
+@note Only affects rgb, not a
+@param inColour The HDR colour
+@param lum The scene lumninence 
+@returns Tone mapped colour
+*/
+vec4 toneMap(in vec4 inColour, in float lum)
+{
+	// From Reinhard et al
+	// "Photographic Tone Reproduction for Digital Images"
+	
+	// Initial luminence scaling (equation 2)
+    inColour.rgb *= MIDDLE_GREY / (FUDGE + lum);
+
+	// Control white out (equation 4 nom)
+    inColour.rgb *= (1.0 + inColour.rgb / L_WHITE);
+
+	// Final mapping (equation 4 denom)
+	inColour.rgb /= (1.0 + inColour.rgb);
+	
+	return inColour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/instancingVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/instancingVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/instancingVp.glsl	(revision 12083)
@@ -0,0 +1,46 @@
+#version 150
+
+in vec4 position;
+in vec3 normal;
+in vec4 uv0;
+in float uv1;
+
+out vec4 oColor_0;
+#if SHADOW_CASTER
+#else
+out vec2 oTexcoord2_0;
+#endif
+
+uniform mat4x3 worldMatrix3x4Array[80];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 lightPos;
+uniform vec4 ambient;
+uniform vec4 lightDiffuseColour;
+
+void main()
+{
+#if SHADOW_CASTER
+	// transform by indexed matrix
+	vec4 transformedPos = vec4((worldMatrix3x4Array[int(uv1)] * position).xyz, 1.0);
+
+	// view / projection
+	gl_Position = viewProjectionMatrix * transformedPos;
+	
+	oColor_0 = ambient;
+#else
+	// transform by indexed matrix
+	vec4 transformedPos = vec4((worldMatrix3x4Array[int(uv1)] * position).xyz, 1.0);
+	
+	// view / projection
+	gl_Position = viewProjectionMatrix * transformedPos;
+	oTexcoord2_0 = uv0.xy;
+
+	vec3 norm = mat3(worldMatrix3x4Array[int(uv1)]) * normal;
+	
+	vec3 lightDir = 	normalize(
+		lightPos.xyz -  (transformedPos.xyz * lightPos.w));
+
+	oColor_0 = ambient + clamp(dot(lightDir, norm), 0.0, 1.0) * lightDiffuseColour;
+#endif
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/mrttestfp_quad.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/mrttestfp_quad.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/mrttestfp_quad.glsl	(revision 12083)
@@ -0,0 +1,20 @@
+#version 150
+
+uniform sampler2D rt0;
+uniform sampler2D rt1;
+uniform sampler2D rt2;
+uniform sampler2D rt3;
+
+in vec2 uv;
+out vec4 fragColour;
+
+void main(void)
+{
+    
+    //fragColour = texture(rt0, uv);
+    fragColour = texture(rt1, uv);
+    //fragColour = texture(rt2, uv);
+    //fragColour = texture(rt3, uv);
+	
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/mrttestfp_scene.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/mrttestfp_scene.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/mrttestfp_scene.glsl	(revision 12083)
@@ -0,0 +1,22 @@
+#version 150
+
+// Need to enable the draw buffers extension
+#extension GL_ARB_draw_buffers : enable
+
+uniform sampler2D tex0;
+
+void main()                    
+{
+	vec4 baseColour = texture(tex0, gl_TexCoord[0].xy);
+
+	gl_FragData[0] = baseColour;
+
+	gl_FragData[1] = baseColour * vec4(1, 0, 0, 1);
+
+	float abs = (baseColour.r + baseColour.g + baseColour.b) * 0.333;
+	gl_FragData[2] = vec4(abs, abs, abs, 1);
+	
+	float invabs = 1.0 - abs;
+	gl_FragData[3] = vec4(invabs, invabs, invabs, 1);
+}
+
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/oceanGLSL.frag
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/oceanGLSL.frag	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/oceanGLSL.frag	(revision 12083)
@@ -0,0 +1,48 @@
+// oceanGLSL.frag
+// fragment program for Ocean water simulation
+// 05 Aug 2005
+// adapted for Ogre by nfz
+// converted from HLSL to GLSL
+// original shader source from Render Monkey 1.6 Reflections Refractions.rfx
+
+// 06 Aug 2005: moved uvw calculation from fragment program into vertex program 
+
+#version 150
+
+uniform float fadeBias;
+uniform float fadeExp;
+uniform vec4 waterColor;
+uniform sampler3D Noise;
+uniform samplerCube skyBox;
+
+in vec3 uvw;
+in vec4 oNormal;
+in vec3 vVec;
+out vec4 fragColour;
+
+void main(void)
+{
+   vec3 noisy = texture(Noise, uvw).xyz;
+   
+   // convert to signed noise
+   vec3 bump = 2.0 * noisy - 1.0;
+   bump.xz *= 0.15;
+   // Make sure the normal always points upwards
+   // note that Ogres y axis is vertical (RM Z axis is vertical)
+   bump.y = 0.8 * abs(bump.y) + 0.2;
+   // Offset the surface normal with the bump
+   bump = normalize(oNormal.xyz + bump);
+
+   // Find the reflection vector
+   vec3 normView = normalize(vVec);
+   vec3 reflVec = reflect(normView, bump);
+   // Ogre has z flipped for cubemaps
+   reflVec.z = -reflVec.z;
+   vec4 refl = texture(skyBox, reflVec);
+
+   // set up for fresnel calc
+   float lrp = 1.0 - dot(-normView, bump);
+   
+   // Interpolate between the water color and reflection for fresnel effect
+   fragColour = mix(waterColor, refl, clamp(fadeBias + pow(lrp, fadeExp), 0.0, 1.0) );
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/oceanGLSL.vert
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/oceanGLSL.vert	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/oceanGLSL.vert	(revision 12083)
@@ -0,0 +1,37 @@
+// oceanGLSL.vert
+// vertex program for Ocean water simulation
+// 05 Aug 2005
+// adapted for Ogre by nfz
+// converted from HLSL to GLSL
+// original shader source from Render Monkey 1.6 Reflections Refractions.rfx
+
+// 06 Aug 2005: moved uvw calculation from fragment program into vertex program 
+
+#version 150
+
+uniform vec3 scale;
+uniform vec3 eyePosition;
+uniform vec2 waveSpeed;
+uniform float noiseSpeed;
+uniform float time_0_X;
+uniform mat4 worldViewProj;
+
+in vec4 vertex;
+in vec4 normal;
+
+out vec3 uvw;
+out vec4 oNormal;
+out vec3 vVec;
+
+void main(void)
+{
+   gl_Position = worldViewProj * vertex;
+   
+   //  the view vector needs to be in vertex space
+   vVec = vertex.xyz - eyePosition;
+   oNormal = normal;
+   // uvw is the calculated uvw coordinates based on vertex position
+   uvw = vertex.xyz * scale.xyz;
+   uvw.xz += waveSpeed * time_0_X;
+   uvw.y += uvw.z + noiseSpeed * time_0_X;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/pssmCasterFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/pssmCasterFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/pssmCasterFp.glsl	(revision 12083)
@@ -0,0 +1,11 @@
+#version 150
+
+in vec2 oDepth;
+out vec4 fragColour;
+uniform vec4 pssmSplitPoints;
+
+void main()
+{
+	float finalDepth = oDepth.x / oDepth.y;
+	fragColour = vec4(finalDepth, finalDepth, finalDepth, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/pssmCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/pssmCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/pssmCasterVp.glsl	(revision 12083)
@@ -0,0 +1,18 @@
+#version 150
+
+out vec2 oDepth;
+uniform mat4 worldViewProjMatrix;
+in vec4 vertex;
+
+void main()
+{
+	// This is the view space position
+	gl_Position = worldViewProjMatrix * vertex;
+
+	// Depth info for the fragment.
+	oDepth.x = gl_Position.z;
+	oDepth.y = gl_Position.w;
+
+	// Clamp z to zero. seem to do the trick. :-/
+	//oPosition.z = max(oPosition.z, 0);
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/pssmReceiverFp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/pssmReceiverFp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/pssmReceiverFp.glsl	(revision 12083)
@@ -0,0 +1,90 @@
+#version 150
+
+float shadowPCF(sampler2D shadowMap, vec4 shadowMapPos, vec2 offset)
+{
+	shadowMapPos = shadowMapPos / shadowMapPos.w;
+	vec2 uv = shadowMapPos.xy;
+	vec3 o = vec3(offset, -offset.x) * 0.3;
+
+	// Note: We using 2x2 PCF. Good enough and is a lot faster.
+	float c =	(shadowMapPos.z <= texture(shadowMap, uv.xy - o.xy).r) ? 1.0 : 0.0; // top left
+	c +=		(shadowMapPos.z <= texture(shadowMap, uv.xy + o.xy).r) ? 1.0 : 0.0; // bottom right
+	c +=		(shadowMapPos.z <= texture(shadowMap, uv.xy + o.zy).r) ? 1.0 : 0.0; // bottom left
+	c +=		(shadowMapPos.z <= texture(shadowMap, uv.xy - o.zy).r) ? 1.0 : 0.0; // top right
+
+	return c / 4.0;
+}
+
+uniform vec4 invShadowMapSize0;
+uniform vec4 invShadowMapSize1;
+uniform vec4 invShadowMapSize2;
+uniform vec4 pssmSplitPoints;
+uniform sampler2D diffuse;
+uniform sampler2D specular;
+uniform sampler2D normalMap;
+uniform sampler2D shadowMap0;
+uniform sampler2D shadowMap1;
+uniform sampler2D shadowMap2;
+uniform vec4 lightDiffuse;
+uniform vec4 lightSpecular;
+uniform vec4 ambient;
+
+in vec4 oUv0;
+in vec3 oLightDir;
+in vec3 oHalfAngle;
+in vec4 oLightPosition0;
+in vec4 oLightPosition1;
+in vec4 oLightPosition2;
+in vec3 oNormal;
+out vec4 fragColour;
+
+// to put it simply, this does 100% per pixel diffuse lighting
+void main()
+{
+	// calculate shadow
+	float shadowing = 1.0;
+	vec4 splitColour;
+	if (oUv0.z <= pssmSplitPoints.y)
+	{
+		splitColour = vec4(0.1, 0.0, 0.0, 1.0);
+		shadowing = shadowPCF(shadowMap0, oLightPosition0, invShadowMapSize0.xy);
+	}
+	else if (oUv0.z <= pssmSplitPoints.z)
+	{
+		splitColour = vec4(0.0, 0.1, 0.0, 1.0);
+		shadowing = shadowPCF(shadowMap1, oLightPosition1, invShadowMapSize1.xy);
+	}
+	else
+	{
+		splitColour = vec4(0.1, 0.1, 0.0, 1.0);
+		shadowing = shadowPCF(shadowMap2, oLightPosition2, invShadowMapSize2.xy);
+	}
+
+	// retrieve normalised light vector, expand from range-compressed
+	vec3 lightVec = normalize(oLightDir);
+
+	// retrieve half angle and normalise through cube map
+	vec3 halfAngle = normalize(oHalfAngle);
+
+	// get diffuse colour
+	vec4 diffuseColour = texture(diffuse, oUv0.xy);
+
+	// specular
+	vec4 specularColour = texture(specular, oUv0.xy);
+	float shininess = specularColour.w;
+	specularColour.w = 1.0;
+
+	// calculate lit value.
+	float diffuseCoeff = max(dot(oNormal, lightVec), 0.0);
+	float specularCoeff = step(0.0, dot(oNormal, lightVec)) * max(dot(oNormal, halfAngle) * (shininess * 128.0), 0.0);
+	vec4 lighting;
+	lighting.y = diffuseCoeff * shadowing;
+	lighting.z = specularCoeff * shadowing;
+//	vec4 lighting = lit(dot(oNormal, lightVec), dot(oNormal, halfAngle), shininess * 128.0) * shadowing;
+
+	// final lighting with diffuse and spec
+	fragColour = (diffuseColour * clamp(ambient + lightDiffuse * lighting.y, 0.0, 1.0)) + (lightSpecular * specularColour * lighting.z);
+	fragColour.w = diffuseColour.w;
+
+	//oColour += splitColour;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/pssmReceiverVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/pssmReceiverVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/pssmReceiverVp.glsl	(revision 12083)
@@ -0,0 +1,45 @@
+#version 150
+
+uniform vec4 lightPosition;				// object space
+uniform vec3 eyePosition;					// object space
+uniform mat4 worldViewProjMatrix;
+uniform mat4 texWorldViewProjMatrix0;
+uniform mat4 texWorldViewProjMatrix1;
+uniform mat4 texWorldViewProjMatrix2;
+
+out vec4 oUv0;
+out vec3 oLightDir;
+out vec3 oHalfAngle;
+out vec4 oLightPosition0;
+out vec4 oLightPosition1;
+out vec4 oLightPosition2;
+out vec3 oNormal;
+
+in vec4 position;
+in vec3 normal;
+in vec4 uv0;
+
+void main()
+{
+	// Calculate output position
+	gl_Position = worldViewProjMatrix * position;
+
+	// Pass the main uvs straight through unchanged
+	oUv0.xy = uv0.xy;
+	oUv0.z = gl_Position.z;
+
+	// Calculate tangent space light vector
+	// Get object space light direction
+	oLightDir = normalize(lightPosition.xyz - (position * lightPosition.w).xyz);
+
+	// Calculate half-angle in tangent space
+	vec3 eyeDir = normalize(eyePosition - position.xyz);
+	oHalfAngle = normalize(eyeDir + oLightDir);	
+
+	// Calculate the position of vertex in light space
+	oLightPosition0 = texWorldViewProjMatrix0 * position;
+	oLightPosition1 = texWorldViewProjMatrix1 * position;
+	oLightPosition2 = texWorldViewProjMatrix2 * position;
+
+	oNormal = normal;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/shadows.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/shadows.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/shadows.glsl	(revision 12083)
@@ -0,0 +1,148 @@
+/* Copyright Torus Knot Software Ltd 2012-2013
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Adapted by Matias N. Goldberg (Dark Sylinc) to GLSL based on the Cg file shadows.cg
+*/
+
+#version 150
+
+// Simple PCF 
+// Number of samples in one dimension (square for total samples)
+#define NUM_SHADOW_SAMPLES_1D 2.0
+#define SHADOW_FILTER_SCALE 1.0
+
+#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D
+
+vec4 offsetSample(vec4 uv, vec2 offset, float invMapSize)
+{
+	return vec4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w);
+}
+
+float calcDepthShadow(sampler2DShadow shadowMap, vec4 uv, float invShadowMapSize)
+{
+	// 4-sample PCF
+	
+	float shadow = 0.0;
+	float offset = (NUM_SHADOW_SAMPLES_1D/2.0 - 0.5) * SHADOW_FILTER_SCALE;
+	for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE)
+		for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE)
+		{
+			float depth = textureProj(shadowMap, offsetSample(uv, vec2(x, y), invShadowMapSize));
+			if (depth >= 1.0 || depth >= uv.z)
+				shadow += 1.0;
+		}
+
+	shadow /= SHADOW_SAMPLES;
+
+	return shadow;
+}
+
+
+float calcSimpleShadow(sampler2DShadow shadowMap, vec4 shadowMapPos)
+{
+	return textureProj(shadowMap, shadowMapPos);
+}
+
+float calcPSSMDepthShadow(sampler2DShadow shadowMap0, sampler2DShadow shadowMap1, sampler2DShadow shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = vec4(0.3, 0.0, 0, 0);
+		shadow = calcDepthShadow(shadowMap0, lsPos0, invShadowmapSize0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = vec4(0, 0.3, 0, 0);
+		shadow = calcDepthShadow(shadowMap1, lsPos1, invShadowmapSize1);
+	}
+	else
+	{
+		splitColour = vec4(0.0, 0.0, 0.3, 0);
+		shadow = calcDepthShadow(shadowMap2, lsPos2, invShadowmapSize2);
+	}
+
+	return shadow;
+}
+
+float calcPSSMSimpleShadow(sampler2DShadow shadowMap0, sampler2DShadow shadowMap1, sampler2DShadow shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	float shadow;
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		splitColour = vec4(0.3, 0.0, 0, 0);
+		shadow = calcSimpleShadow(shadowMap0, lsPos0);
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		splitColour = vec4(0, 0.3, 0, 0);
+		shadow = calcSimpleShadow(shadowMap1, lsPos1);
+	}
+	else
+	{
+		splitColour = vec4(0.0, 0.0, 0.3, 0);
+		shadow = calcSimpleShadow(shadowMap2, lsPos2);
+	}
+
+	return shadow;
+}
+
+
+
+vec3 calcPSSMDebugShadow(sampler2DShadow shadowMap0, sampler2DShadow shadowMap1, sampler2DShadow shadowMap2, 
+						   vec4 lsPos0, vec4 lsPos1, vec4 lsPos2,
+						   float invShadowmapSize0, float invShadowmapSize1, float invShadowmapSize2,
+						   vec4 pssmSplitPoints, float camDepth)
+{
+
+	vec4 splitColour;
+	// calculate shadow
+	if (camDepth <= pssmSplitPoints.y)
+	{
+		//splitColour = vec4(0.3, 0.0, 0, 0);
+		//splitColour = lsPos0 / lsPos0.w;
+		splitColour.rgb = vec3(textureProj(shadowMap0, lsPos0));
+	}
+	else if (camDepth <= pssmSplitPoints.z)
+	{
+		//splitColour = vec4(0, 0.3, 0, 0);
+		//splitColour = lsPos1 / lsPos1.w;
+		splitColour.rgb = vec3(textureProj(shadowMap1, lsPos1));
+	}
+	else
+	{
+		//splitColour = vec4(0.0, 0.0, 0.3, 0);
+		//splitColour = lsPos2 / lsPos2.w;
+		splitColour.rgb = vec3(textureProj(shadowMap2, lsPos2));
+	}
+
+	return splitColour.rgb;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/skinningTwoWeightsShadowCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/skinningTwoWeightsShadowCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/skinningTwoWeightsShadowCasterVp.glsl	(revision 12083)
@@ -0,0 +1,44 @@
+#version 150
+
+// Example GLSL program for skinning with two bone weights per vertex
+
+in vec4 vertex;
+in vec4 uv0;
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+// 3x4 matrix, passed as vec4's for compatibility with GL 2.0
+// GL 2.0 supports 3x4 matrices
+// Support 24 bones ie 24*3, but use 72 since our parser can pick that out for sizing
+uniform vec4 worldMatrix3x4Array[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 ambient;
+
+void main()
+{
+	vec3 blendPos = vec3(0,0,0);
+
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+        // ATI GLSL compiler can't handle indexing an array within an array so calculate the inner index first
+	    int idx = int(blendIndices[bone]) * 3;
+        // ATI GLSL compiler can't handle unrolling the loop so do it manually
+        // ATI GLSL has better performance when mat4 is used rather than using individual dot product
+        // There is a bug in ATI mat4 constructor (Cat 7.2) when indexed uniform array elements are used as vec4 parameter so manually assign
+		mat4 worldMatrix;
+		worldMatrix[0] = worldMatrix3x4Array[idx];
+		worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+		worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+		worldMatrix[3] = vec4(0);
+		// now weight this into final 
+		blendPos += (vertex * worldMatrix).xyz * blendWeights[bone];
+	}
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1);
+	
+	gl_FrontSecondaryColor = vec4(0,0,0,0);
+	gl_FrontColor = ambient;
+	gl_TexCoord[0] = uv0;
+}
Index: /data/branches/Shader_HS18/programs/Example/GLSL150/skinningTwoWeightsVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/Example/GLSL150/skinningTwoWeightsVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/Example/GLSL150/skinningTwoWeightsVp.glsl	(revision 12083)
@@ -0,0 +1,65 @@
+#version 150
+
+// Example GLSL program for skinning with two bone weights per vertex
+
+in vec4 vertex;
+in vec3 normal;
+in vec4 uv0;
+in vec4 blendIndices;
+in vec4 blendWeights;
+
+// 3x4 matrix, passed as vec4's for compatibility with GL 2.0
+// GL 2.0 supports 3x4 matrices
+// Support 24 bones ie 24*3, but use 72 since our parser can pick that out for sizing
+uniform vec4 worldMatrix3x4Array[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 lightPos[2];
+uniform vec4 lightDiffuseColour[2];
+uniform vec4 ambient;
+uniform vec4 diffuse;
+
+out vec4 colour;
+out vec4 uv;
+
+void main()
+{
+	vec3 blendPos = vec3(0.0, 0.0, 0.0);
+	vec3 blendNorm = vec3(0.0, 0.0, 0.0);
+	
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+        // ATI GLSL compiler can't handle indexing an array within an array so calculate the inner index first
+		int idx = int(blendIndices[bone]) * 3;
+        // ATI GLSL compiler can't handle unrolling the loop so do it manually
+        // ATI GLSL has better performance when mat4 is used rather than using individual dot product
+        // There is a bug in ATI mat4 constructor (Cat 7.2) when indexed uniform array elements are used as vec4 parameter so manually assign
+		mat4 worldMatrix;
+		worldMatrix[0] = worldMatrix3x4Array[idx];
+		worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+		worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+		worldMatrix[3] = vec4(0);
+		// now weight this into final 
+		float weight = blendWeights[bone];
+		blendPos += (vertex * worldMatrix).xyz * weight;
+		
+		mat3 worldRotMatrix = mat3(worldMatrix[0].xyz, worldMatrix[1].xyz, worldMatrix[2].xyz);
+		blendNorm += (normal * worldRotMatrix) * weight;
+	}
+
+	blendNorm = normalize(blendNorm);
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1.0);
+
+	// simple vertex lighting model
+	vec3 lightDir0 = normalize(
+		lightPos[0].xyz -  (blendPos * lightPos[0].w));
+	vec3 lightDir1 = normalize(
+		lightPos[1].xyz -  (blendPos * lightPos[1].w));
+		
+	colour = diffuse * (ambient + (clamp(dot(lightDir0, blendNorm), 0.0, 1.0) * lightDiffuseColour[0]) + 
+		(clamp(dot(lightDir1, blendNorm), 0.0, 1.0) * lightDiffuseColour[1]));	
+
+	uv = uv0;
+}
Index: /data/branches/Shader_HS18/programs/GLSL/ToonShader_ps.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/GLSL/ToonShader_ps.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/GLSL/ToonShader_ps.glsl	(revision 12083)
@@ -0,0 +1,4 @@
+void main()
+{
+	gl_FragColor = vec4(0.4, 0.4, 0.8, 1.0);
+}
Index: /data/branches/Shader_HS18/programs/GLSL/ToonShader_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/GLSL/ToonShader_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/GLSL/ToonShader_vs.glsl	(revision 12083)
@@ -0,0 +1,4 @@
+void main()
+{
+	gl_Position = ftransform();
+}
Index: /data/branches/Shader_HS18/programs/OLD/BloomFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/BloomFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/BloomFP.cg	(revision 12083)
@@ -0,0 +1,7 @@
+sampler RT1 : register(s0);
+sampler RT2 : register(s1);
+
+float4 Bloom_ps (float2 iTexCoord : TEXCOORD0) : COLOR
+{
+	return 0.5*tex2D(RT1, iTexCoord) + 0.5*tex2D(RT2, iTexCoord);
+}
Index: /data/branches/Shader_HS18/programs/OLD/Blur0_ps20.hlsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur0_ps20.hlsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur0_ps20.hlsl	(revision 12083)
@@ -0,0 +1,31 @@
+sampler RT: register(s0);
+// Simple blur filter
+
+float4 main(float2 texCoord: TEXCOORD0) : COLOR {
+
+	float2 samples[12] = {
+   	-0.326212, -0.405805,
+   	-0.840144, -0.073580,
+   	-0.695914,  0.457137,
+   	-0.203345,  0.620716,
+    	0.962340, -0.194983,
+    	0.473434, -0.480026,
+    	0.519456,  0.767022,
+    	0.185461, -0.893124,
+    	0.507431,  0.064425,
+    	0.896420,  0.412458,
+   	-0.321940, -0.932615,
+   	-0.791559, -0.597705,
+	};
+
+   float4 sum = tex2D(RT, texCoord);
+   for (int i = 0; i < 12; i++){
+      sum += tex2D(RT, texCoord + 0.025 * samples[i]);
+   }
+   return sum / 13;
+
+}
+
+
+
+
Index: /data/branches/Shader_HS18/programs/OLD/Blur0_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur0_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur0_vs.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+varying vec2 texCoord[5];
+
+void main()                    
+{
+	vec2 inPos = sign(gl_Vertex.xy);
+	gl_Position = vec4(inPos.xy, 0.0, 1.0);
+	
+	texCoord[0]  = (vec2(inPos.x, -inPos.y) + 1.0)/2.0;
+	
+	const float size = 0.01;
+	texCoord[1] = texCoord[0] + vec2(1.0, 0.0)*size;
+	texCoord[2] = texCoord[0] + vec2(2.0, 0.0)*size;
+	texCoord[3] = texCoord[0] + vec2(-1.0, 0.0)*size;
+	texCoord[4] = texCoord[0] + vec2(-2.0, 0.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/OLD/Blur0_vs11.hlsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur0_vs11.hlsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur0_vs11.hlsl	(revision 12083)
@@ -0,0 +1,22 @@
+struct VS_OUTPUT {
+   float4 Pos: POSITION;
+   float2 texCoord: TEXCOORD0;
+};
+
+VS_OUTPUT main(float4 Pos: POSITION){
+   VS_OUTPUT Out;
+
+   // Clean up inaccuracies
+   Pos.xy = sign(Pos.xy);
+
+   Out.Pos = float4(Pos.xy, 0, 1);
+   // Image-space
+   Out.texCoord.x = 0.5 * (1 + Pos.x);
+   Out.texCoord.y = 0.5 * (1 - Pos.y);
+
+   return Out;
+}
+
+
+
+
Index: /data/branches/Shader_HS18/programs/OLD/Blur1_ps20.hlsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur1_ps20.hlsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur1_ps20.hlsl	(revision 12083)
@@ -0,0 +1,28 @@
+sampler Blur0: register(s0);
+// Simple blur filter
+
+float4 main(float2 texCoord: TEXCOORD0) : COLOR {
+
+	float2 samples[12] = {
+   	-0.326212, -0.405805,
+   	-0.840144, -0.073580,
+   	-0.695914,  0.457137,
+   	-0.203345,  0.620716,
+    	0.962340, -0.194983,
+    	0.473434, -0.480026,
+    	0.519456,  0.767022,
+    	0.185461, -0.893124,
+    	0.507431,  0.064425,
+    	0.896420,  0.412458,
+   	-0.321940, -0.932615,
+   	-0.791559, -0.597705,
+	};
+
+   float4 sum = tex2D(Blur0, texCoord);
+   for (int i = 0; i < 12; i++){
+      sum += tex2D(Blur0, texCoord + 0.025 * samples[i]);
+   }
+   return sum / 13;
+
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/Blur1_vs.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur1_vs.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur1_vs.glsl	(revision 12083)
@@ -0,0 +1,15 @@
+varying vec2 texCoord[5];
+
+void main()                    
+{
+	vec2 inPos = sign(gl_Vertex.xy);
+	gl_Position = vec4(inPos.xy, 0.0, 1.0);
+	
+	texCoord[0]  = (vec2(inPos.x, -inPos.y) + 1.0)/2.0;
+	
+	const float size = 0.01;
+	texCoord[1] = texCoord[0] + vec2(0.0, 1.0)*size;
+	texCoord[2] = texCoord[0] + vec2(0.0, 2.0)*size;
+	texCoord[3] = texCoord[0] + vec2(0.0, -1.0)*size;
+	texCoord[4] = texCoord[0] + vec2(0.0, -2.0)*size;
+}
Index: /data/branches/Shader_HS18/programs/OLD/Blur1_vs11.hlsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur1_vs11.hlsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur1_vs11.hlsl	(revision 12083)
@@ -0,0 +1,19 @@
+struct VS_OUTPUT {
+   float4 Pos: POSITION;
+   float2 texCoord: TEXCOORD0;
+};
+
+VS_OUTPUT main(float4 Pos: POSITION){
+   VS_OUTPUT Out;
+
+   // Clean up inaccuracies
+   Pos.xy = sign(Pos.xy);
+
+   Out.Pos = float4(Pos.xy, 0, 1);
+   // Image-space
+   Out.texCoord.x = 0.5 * (1 + Pos.x);
+   Out.texCoord.y = 0.5 * (1 - Pos.y);
+
+   return Out;
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/Blur_ps.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Blur_ps.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Blur_ps.glsl	(revision 12083)
@@ -0,0 +1,14 @@
+uniform sampler2D tex0;
+
+varying vec2 texCoord[5];
+
+void main()
+{
+	vec4 sum = texture2D(tex0, texCoord[0]) + 
+			   texture2D(tex0, texCoord[1]) +
+			   texture2D(tex0, texCoord[2]) + 
+			   texture2D(tex0, texCoord[3]) +
+			   texture2D(tex0, texCoord[4]);
+	gl_FragColor = sum / 5.0;
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/BumpMapping.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/BumpMapping.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/BumpMapping.cg	(revision 12083)
@@ -0,0 +1,152 @@
+// General functions
+
+// Expand a range-compressed vector
+float3 expand(float3 v)
+{
+	return (v - 0.5) * 2;
+}
+
+
+/* Bump mapping vertex program
+   In this program, we want to calculate the tangent space light vector
+   on a per-vertex level which will get passed to the fragment program,
+   or to the fixed function dot3 operation, to produce the per-pixel
+   lighting effect.
+*/
+void main_vp(float4 position	: POSITION,
+			 float3 normal		: NORMAL,
+			 float2 uv			: TEXCOORD0,
+			 float3 tangent     : TANGENT0,
+			 // outputs
+			 out float4 oPosition    : POSITION,
+			 out float2 oUv			 : TEXCOORD0,
+			 out float3 oTSLightDir	 : TEXCOORD1,
+			 // parameters
+			 uniform float4 lightPosition, // object space
+			 uniform float4x4 worldViewProj)
+{
+	// calculate output position
+	oPosition = mul(worldViewProj, position);
+
+	// pass the main uvs straight through unchanged
+	oUv = uv;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	// Non-normalised since we'll do that in the fragment program anyway
+	float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
+	// this equates to NxT, not TxN
+	float3 binormal = cross(tangent, normal);
+
+	// Form a rotation matrix out of the vectors
+	float3x3 rotation = float3x3(tangent, binormal, normal);
+
+	// Transform the light vector according to this matrix
+	oTSLightDir = mul(rotation, lightDir);
+
+
+}
+
+void main_fp( float2 uv			: TEXCOORD0,
+			  float3 TSlightDir : TEXCOORD1,
+
+			  out float4 colour	: COLOR,
+
+			  uniform float4 lightDiffuse,
+			  uniform sampler2D   normalMap : register(s0),
+			  uniform samplerCUBE normalCubeMap : register(s1) )
+{
+	// retrieve normalised light vector, expand from range-compressed
+	float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
+
+	// get bump map vector, again expand from range-compressed
+	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
+
+	// Calculate dot product
+	colour = lightDiffuse * dot(bumpVec, lightVec);
+
+}
+
+/* Vertex program which includes specular component */
+void specular_vp(float4 position	: POSITION,
+			 	 float3 normal		: NORMAL,
+			 	 float2 uv			: TEXCOORD0,
+			 	 float3 tangent     : TANGENT0,
+			 	 // outputs
+			 	 out float4 oPosition    : POSITION,
+			 	 out float2 oUv			 : TEXCOORD0,
+			 	 out float3 oTSLightDir	 : TEXCOORD1,
+				 out float3 oTSHalfAngle : TEXCOORD2,
+			 	 // parameters
+				 uniform float4 lightPosition, // object space
+			 	 uniform float3 eyePosition,   // object space
+			 	 uniform float4x4 worldViewProj)
+{
+	// calculate output position
+	oPosition = mul(worldViewProj, position);
+
+	// pass the main uvs straight through unchanged
+	oUv = uv;
+
+	// calculate tangent space light vector
+	// Get object space light direction
+	float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
+
+	// Calculate the binormal (NB we assume both normal and tangent are
+	// already normalised)
+	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
+	// this equates to NxT, not TxN
+	float3 binormal = cross(tangent, normal);
+
+	// Form a rotation matrix out of the vectors
+	float3x3 rotation = float3x3(tangent, binormal, normal);
+
+	// Transform the light vector according to this matrix
+	oTSLightDir = mul(rotation, lightDir);
+
+	// Calculate half-angle in tangent space
+	float3 eyeDir = normalize(eyePosition - position.xyz);
+	float3 halfAngle = normalize(eyeDir + lightDir);
+	oTSHalfAngle = mul(rotation, halfAngle);
+
+
+}
+
+/* Fragment program which supports specular component */
+void specular_fp( float2 uv			: TEXCOORD0,
+			  float3 TSlightDir : TEXCOORD1,
+			  float3 TShalfAngle: TEXCOORD2,
+
+			  out float4 colour	: COLOR,
+
+			  uniform float4 lightDiffuse,
+			  uniform float4 lightSpecular,
+			  uniform float shine,
+			  uniform sampler2D   normalMap : register(s0),
+			  uniform samplerCUBE normalCubeMap : register(s1),
+			  uniform samplerCUBE normalCubeMap2 : register(s2)) // we need this second binding to be compatible with ps_1_1, ps_2_0 could reuse the other
+{
+	// retrieve normalised light vector, expand from range-compressed
+	float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
+
+	// retrieve half angle and normalise through cube map
+	float3 halfAngle = expand(texCUBE(normalCubeMap2, TShalfAngle).xyz);
+
+	// get bump map vector, again expand from range-compressed
+	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
+
+
+	float specFactor = pow(dot(bumpVec, halfAngle),shine);
+
+
+
+	// Calculate dot product for diffuse
+	colour = (lightDiffuse * saturate(dot(bumpVec, lightVec))) +
+			(lightSpecular * specFactor);
+
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/Combine_fp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Combine_fp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Combine_fp.cg	(revision 12083)
@@ -0,0 +1,15 @@
+float4 Combine_fp
+(
+    in float2 texCoord: TEXCOORD0,
+    
+    uniform sampler RT : register(s0),
+    uniform sampler Sum : register(s1),
+
+    uniform float blur
+) : COLOR
+{
+   float4 render = tex2D(RT, texCoord);
+   float4 sum = tex2D(Sum, texCoord);
+
+   return lerp(render, sum, blur);
+}
Index: /data/branches/Shader_HS18/programs/OLD/Example_Basic.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Example_Basic.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Example_Basic.cg	(revision 12083)
@@ -0,0 +1,272 @@
+/*
+  Basic ambient lighting vertex program
+*/
+void ambientOneTexture_vp(float4 position : POSITION,
+						  float2 uv		  : TEXCOORD0,
+						  
+						  out float4 oPosition : POSITION,
+						  out float2 oUv	   : TEXCOORD0,
+						  out float4 colour    : COLOR,
+
+						  uniform float4x4 worldViewProj,
+						  uniform float4 ambient)
+{
+	oPosition = mul(worldViewProj, position);
+	oUv = uv;
+	colour = ambient;
+}
+
+/*
+  Single-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningOneWeight_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = mul((float3x3)worldMatrix3x4Array[blendIdx], normal);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}	
+
+/*
+  Single-weight-per-vertex hardware skinning, shadow-caster pass
+*/
+void hardwareSkinningOneWeightCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+	colour = ambient;
+	
+}	
+
+/*
+  Two-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningTwoWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 2; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = float4(0.5, 0.5, 0.5, 1) + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}
+
+/*
+  Two-weight-per-vertex hardware skinning, shadow caster pass
+*/
+void hardwareSkinningTwoWeightsCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+
+	colour = ambient;
+		
+	
+}
+
+
+/*
+  Four-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningFourWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 4; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 4; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}
+
+void hardwareMorphAnimation(float3 pos1 : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pos2	  : TEXCOORD1,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
+void hardwarePoseAnimation(float3 pos : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pose1	  : TEXCOORD1,
+			  float3 pose2	  : TEXCOORD2,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos + anim_t.x*pose1 + anim_t.y*pose2, 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
Index: /data/branches/Shader_HS18/programs/OLD/Example_Basic.hlsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Example_Basic.hlsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Example_Basic.hlsl	(revision 12083)
@@ -0,0 +1,273 @@
+/*
+  Basic ambient lighting vertex program
+*/
+void ambientOneTexture_vp(float4 position : POSITION,
+						  float2 uv		  : TEXCOORD0,
+						  
+						  out float4 oPosition : POSITION,
+						  out float2 oUv	   : TEXCOORD0,
+						  out float4 colour    : COLOR,
+
+						  uniform float4x4 worldViewProj,
+						  uniform float4 ambient)
+{
+	oPosition = mul(worldViewProj, position);
+	oUv = uv;
+	colour = ambient;
+}
+
+/*
+  Single-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningOneWeight_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = mul((float3x3)worldMatrix3x4Array[blendIdx], normal);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}	
+
+/*
+  Single-weight-per-vertex hardware skinning, shadow-caster pass
+*/
+void hardwareSkinningOneWeightCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float  blendIdx : BLENDINDICES,
+	
+
+	out float4 oPosition : POSITION,
+	out float4 colour    : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(mul(worldMatrix3x4Array[blendIdx], position).xyz, 1.0);
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+	colour = ambient;
+	
+}	
+
+/*
+  Two-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningTwoWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 2; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}
+
+/*
+  Two-weight-per-vertex hardware skinning, shadow caster pass
+*/
+void hardwareSkinningTwoWeightsCaster_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 2; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	
+
+	colour = ambient;
+		
+	
+}
+
+
+/*
+  Four-weight-per-vertex hardware skinning, 2 lights
+  The trouble with vertex programs is they're not general purpose, but
+  fixed function hardware skinning is very poorly supported
+*/
+void hardwareSkinningFourWeights_vp(
+	float4 position : POSITION,
+	float3 normal   : NORMAL,
+	float2 uv       : TEXCOORD0,
+	float4 blendIdx : BLENDINDICES,
+	float4 blendWgt : BLENDWEIGHT,
+	
+
+	out float4 oPosition : POSITION,
+	out float2 oUv       : TEXCOORD0,
+	out float4 colour           : COLOR,
+	// Support up to 24 bones of float3x4
+	// vs_1_1 only supports 96 params so more than this is not feasible
+	uniform float3x4   worldMatrix3x4Array[24],
+	uniform float4x4 viewProjectionMatrix,
+	uniform float4   lightPos[2],
+	uniform float4   lightDiffuseColour[2],
+	uniform float4   ambient)
+{
+	// transform by indexed matrix
+	float4 blendPos = float4(0,0,0,0);
+	int i;
+	for (i = 0; i < 4; ++i)
+	{
+		blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
+	}
+	// view / projection
+	oPosition = mul(viewProjectionMatrix, blendPos);
+	// transform normal
+	float3 norm = float3(0,0,0);
+	for (i = 0; i < 4; ++i)
+	{
+		norm += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * 
+		blendWgt[i];
+	}
+	norm = normalize(norm);
+	// Lighting - support point and directional
+	float3 lightDir0 = 	normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	float3 lightDir1 = 	normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+
+	
+	oUv = uv;
+	colour = ambient + 
+		(saturate(dot(lightDir0, norm)) * lightDiffuseColour[0]) + 
+		(saturate(dot(lightDir1, norm)) * lightDiffuseColour[1]);
+	
+}
+
+void hardwareMorphAnimation(float3 pos1 : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pos2	  : TEXCOORD1,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos1 + anim_t.x*(pos2 - pos1), 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
+void hardwarePoseAnimation(float3 pos : POSITION,
+			  float4 normal		: NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  float3 pose1	  : TEXCOORD1,
+			  float3 pose2	  : TEXCOORD2,
+						  
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj, 
+			  uniform float4 anim_t)
+{
+	// interpolate
+	float4 interp = float4(pos + anim_t.x*pose1 + anim_t.y*pose2, 1.0f);
+	
+	oPosition = mul(worldViewProj, interp);
+	oUv = uv;
+	colour = float4(1,0,0,1);
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/GlassFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/GlassFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/GlassFP.cg	(revision 12083)
@@ -0,0 +1,9 @@
+sampler RT : register(s0);
+sampler NormalMap : register(s1);
+
+float4 main_ps(float2 iTexCoord : TEXCOORD0) : COLOR
+{
+	float4 normal = 2 * (tex2D(NormalMap, iTexCoord * 2.5) - 0.5);
+
+	return tex2D(RT, iTexCoord + normal.xy * 0.05);
+}
Index: /data/branches/Shader_HS18/programs/OLD/Grass.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Grass.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Grass.cg	(revision 12083)
@@ -0,0 +1,31 @@
+// Vertex program to wave some grass about
+// Simplistic, assumes base of the grass at 0
+void grass_vp(float4 position : POSITION,
+			  float3 normal   : NORMAL,
+			  float2 uv		  : TEXCOORD0,
+			  out float4 oPosition : POSITION,
+			  out float2 oUv	   : TEXCOORD0,
+			  out float4 colour    : COLOR,
+
+			  uniform float4x4 worldViewProj,
+			  uniform float4 ambient,
+			  uniform float4 objSpaceLight,
+			  uniform float4 lightColour,
+			  uniform float4 offset)
+{
+	float4 mypos = position;
+	//offset = float4(0.5, 0, 0, 0);
+	float4 factor = float4(1,1,1,1) - uv.yyyy;
+	mypos = mypos + offset * factor;
+	oPosition = mul(worldViewProj, mypos);
+
+	oUv = uv;
+	// get vertex light direction (support directional and point)
+	float3 light = normalize(
+		objSpaceLight.xyz -  (position.xyz * objSpaceLight.w));
+	float diffuseFactor = max(dot(normal, light), 0);
+	
+	
+	colour = ambient + diffuseFactor * lightColour;
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/GrayScale.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/GrayScale.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/GrayScale.cg	(revision 12083)
@@ -0,0 +1,18 @@
+sampler RT : register(s0);
+
+float4 GrayScale_ps(float2 iTexCoord : TEXCOORD0) : COLOR
+{
+    float3 greyscale = dot(tex2D(RT, iTexCoord).rgb, float3(0.3, 0.59, 0.11));
+	return float4(greyscale, 1.0);
+}
+
+float4 Embossed_ps(float2 iTexCoord : TEXCOORD0) : COLOR
+{
+    float4 Color;
+    Color.a = 1.0f;
+    Color.rgb = 0.5f;
+    Color -= tex2D( RT, iTexCoord - 0.001)*2.0f;
+    Color += tex2D( RT, iTexCoord + 0.001)*2.0f;
+    Color.rgb = (Color.r+Color.g+Color.b)/3.0f;
+    return Color;
+}
Index: /data/branches/Shader_HS18/programs/OLD/InvertFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/InvertFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/InvertFP.cg	(revision 12083)
@@ -0,0 +1,6 @@
+sampler RT : register(s0);
+
+float4 Invert_ps (float2 iTexCoord : TEXCOORD0) : COLOR
+{
+	return 1 - tex2D(RT, iTexCoord);
+}
Index: /data/branches/Shader_HS18/programs/OLD/LaplaceFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/LaplaceFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/LaplaceFP.cg	(revision 12083)
@@ -0,0 +1,36 @@
+sampler Image : register(s0);
+
+// The Laplace filter approximates the second order derivate,
+// that is, the rate of change of slope in the image. It can be
+// used for edge detection. The Laplace filter gives negative
+// response on the higher side of the edge and positive response
+// on the lower side.
+
+// This is the filter kernel:
+// 0  1  0
+// 1 -4  1
+// 0  1  0
+
+
+
+float4 Laplace_ps (float2 texCoord: TEXCOORD0,
+			uniform float scale,
+			uniform float pixelSize) : COLOR
+{
+
+    float2 samples[4] = {
+        0, -1,
+       -1,  0,
+        1,  0,
+        0,  1
+    };
+   float4 laplace = -4 * tex2D(Image, texCoord);
+
+   // Sample the neighbor pixels
+   for (int i = 0; i < 4; i++){
+      laplace += tex2D(Image, texCoord + pixelSize * samples[i]);
+   }
+
+   return (0.5 + scale * laplace);
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/OldMovieFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/OldMovieFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/OldMovieFP.cg	(revision 12083)
@@ -0,0 +1,54 @@
+sampler RT : register(s0);
+sampler SplotchesTx : register(s1);
+sampler Texture2 : register(s2);
+sampler SepiaTx : register(s3);
+
+float2 calcSpriteAddr(float2 texCoord, float DirtFrequency, float period)
+{
+   return texCoord + tex1D(Texture2, period  * DirtFrequency);
+}
+
+float4 getSplotches(float2 spriteAddr)
+{
+   // get sprite address into paged texture coords space
+   spriteAddr = spriteAddr / 6.3f;
+   //spriteAddr = spriteAddr - frac(spriteAddr);
+   spriteAddr = spriteAddr - (spriteAddr /33.3f);
+
+   return tex2D(SplotchesTx, spriteAddr);
+}
+
+float4 OldMovie_ps (float2 texCoord  : TEXCOORD0,
+				uniform float time_cycle_period,
+				uniform float flicker,
+				uniform float DirtFrequency,
+				uniform float3 luminance,
+				uniform float frameJitter,
+				uniform float lumiShift
+				) : COLOR
+{
+
+   // get sprite address
+   float2 spriteAddr = calcSpriteAddr(texCoord, DirtFrequency, time_cycle_period);
+
+    // add some dark and light splotches to the film
+   float4 splotches = getSplotches(spriteAddr);
+   float4 specs = 1.0f - getSplotches(spriteAddr / 3.0f);
+
+   // convert color to base luminance
+   float4 base = tex2D(RT, texCoord + float2(0, spriteAddr.y * frameJitter));
+   float lumi = dot(base.rgb, luminance);
+   // randomly shift luminance
+   lumi -= spriteAddr.x * lumiShift;
+   // tone map luminance
+   base.rgb = tex1D(SepiaTx, lumi );
+
+   // calc flicker speed
+   float darken = frac(flicker * time_cycle_period);
+
+   // we want darken to cycle between 0.6 and 1.0
+   darken = abs(darken - 0.5f) * 0.4f + 0.6f;
+   // composite dirt onto film
+   return base * splotches * darken + specs;
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/OldTV.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/OldTV.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/OldTV.cg	(revision 12083)
@@ -0,0 +1,42 @@
+
+
+sampler Image: register(s0);
+sampler Rand: register(s1);
+sampler Noise: register(s2);
+
+float4 OldTV_ps(float2 pos: TEXCOORD1, float2 img: TEXCOORD0,
+    uniform float distortionFreq: register(c3),
+    uniform float distortionScale: register(c4),
+    uniform float distortionRoll: register(c5),
+    uniform float interference: register(c7),
+    uniform float frameLimit: register(c8),
+    uniform float frameShape: register(c0),
+    uniform float frameSharpness: register(c1),
+    uniform float time_0_X: register(c2),
+    uniform float sin_time_0_X: register(c6)
+
+) : COLOR {
+   // Define a frame shape
+   float f = (1 - pos.x * pos.x) * (1 - pos.y * pos.y);
+   float frame = saturate(frameSharpness * (pow(f, frameShape) - frameLimit));
+
+   // Interference ... just a texture filled with rand()
+   float rand = tex3D(Rand, float3(1.5 * pos, time_0_X)) - 0.2;
+
+   // Some signed noise for the distortion effect
+   float noisy = tex3D(Noise, float3(0, 0.5 * pos.y, 0.1 * time_0_X)) - 0.5;
+
+   // Repeat a 1 - x^2 (0 < x < 1) curve and roll it with sinus.
+   float dst = frac(pos.y * distortionFreq + distortionRoll * sin_time_0_X);
+   dst *= (1 - dst);
+   // Make sure distortion is highest in the center of the image
+   dst /= 1 + distortionScale * abs(pos.y);
+
+   // ... and finally distort
+   img.x += distortionScale * noisy * dst;
+   float4 image = tex2D(Image, img);
+
+   // Combine frame, distorted image and interference
+   return frame * (interference * rand + image);
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/PosterizeFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/PosterizeFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/PosterizeFP.cg	(revision 12083)
@@ -0,0 +1,17 @@
+sampler RT : register(s0);
+
+float4 Posterize_ps (float2 iTexCoord : TEXCOORD0) : COLOR
+{
+
+	float nColors = 8;
+	float gamma = 0.6;
+
+	float4 texCol = tex2D(RT, iTexCoord);
+	float3 tc = texCol.xyz;
+	tc = pow(tc, gamma);
+	tc = tc * nColors;
+	tc = floor(tc);
+	tc = tc / nColors;
+	tc = pow(tc,1.0/gamma);
+	return float4(tc,texCol.w);
+}
Index: /data/branches/Shader_HS18/programs/OLD/Radial_Blur_FP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/Radial_Blur_FP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/Radial_Blur_FP.cg	(revision 12083)
@@ -0,0 +1,57 @@
+//------------------------------------------------------
+//Radial_Blur_FP.cg
+//  Implements radial blur to be used with the compositor
+//  It's very dependant on screen resolution
+//------------------------------------------------------
+
+uniform sampler tex: register(s0);
+
+static const float samples[10] =
+{
+-0.08,
+-0.05,
+-0.03,
+-0.02,
+-0.01,
+0.01,
+0.02,
+0.03,
+0.05,
+0.08
+};
+
+float4 main(float2 texCoord: TEXCOORD0,
+            uniform float sampleDist,
+            uniform float sampleStrength
+           ) : COLOR
+{
+   //Vector from pixel to the center of the screen
+   float2 dir = 0.5 - texCoord;
+
+   //Distance from pixel to the center (distant pixels have stronger effect)
+   //float dist = distance( float2( 0.5, 0.5 ), texCoord );
+   float dist = sqrt( dir.x*dir.x + dir.y*dir.y );
+
+
+   //Now that we have dist, we can normlize vector
+   dir = normalize( dir );
+
+   //Save the color to be used later
+   float4 color = tex2D( tex, texCoord );
+
+   //Average the pixels going along the vector
+   float4 sum = color;
+   for (int i = 0; i < 10; i++)
+   {
+      sum += tex2D( tex, texCoord + dir * samples[i] * sampleDist );
+   }
+   sum /= 11;
+
+   //Calculate amount of blur based on
+   //distance and a strength parameter
+   float t = dist * sampleStrength;
+   t = saturate( t );//We need 0 <= t <= 1
+
+   //Blend the original color with the averaged pixels
+   return lerp( color, sum, t );
+}
Index: /data/branches/Shader_HS18/programs/OLD/SharpenEdgesFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/SharpenEdgesFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/SharpenEdgesFP.cg	(revision 12083)
@@ -0,0 +1,23 @@
+sampler RT: register(s0);
+
+float4 sharpenEdges_fp(float2 iTexCoord: TEXCOORD0, uniform float2 vTexelSize) : COLOR
+{
+
+	float2 usedTexelED[8] = {
+		-1, -1,
+		 0, -1,
+		 1, -1,
+		-1,  0,
+		 1,  0,
+		-1,  1,
+		 0,  1,
+	     1,  1,
+	};
+
+	float4 cAvgColor= 9 * tex2D (RT, iTexCoord);
+
+	for(int t=0; t<8; t++)
+		cAvgColor -= tex2D(RT, iTexCoord + vTexelSize * usedTexelED[t]);
+
+	return cAvgColor;
+}
Index: /data/branches/Shader_HS18/programs/OLD/StdQuad_vp.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/StdQuad_vp.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/StdQuad_vp.cg	(revision 12083)
@@ -0,0 +1,113 @@
+void StdQuad_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+}
+
+void StdQuad_Tex2_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = uv0;
+}
+
+void StdQuad_Tex2a_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = inPos.xy;
+}
+
+void StdQuad_Tex3_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+    out float2 uv2 : TEXCOORD2,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = uv0;
+    uv2 = uv0;
+}
+
+void StdQuad_Tex4_vp
+(
+    in float4 inPos : POSITION,
+
+    out float4 pos : POSITION,
+    out float2 uv0 : TEXCOORD0,
+    out float2 uv1 : TEXCOORD1,
+    out float2 uv2 : TEXCOORD2,
+    out float2 uv3 : TEXCOORD3,
+
+    uniform float4x4 worldViewProj
+)
+{
+    // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
+    pos = mul(worldViewProj, inPos);
+
+    // The input positions adjusted by texel offsets, so clean up inaccuracies
+    inPos.xy = sign(inPos.xy);
+
+    // Convert to image-space
+    uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
+    uv1 = uv0;
+    uv2 = uv0;
+    uv3 = uv0;
+}
Index: /data/branches/Shader_HS18/programs/OLD/StdQuad_vp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/StdQuad_vp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/StdQuad_vp.glsl	(revision 12083)
@@ -0,0 +1,11 @@
+varying vec2 uv;
+
+void main()                    
+{
+	gl_Position = ftransform();
+	
+	vec2 inPos = sign(gl_Vertex.xy);
+	
+	uv = (vec2(inPos.x, -inPos.y) + 1.0)/2.0;
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/TilingFP.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/TilingFP.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/TilingFP.cg	(revision 12083)
@@ -0,0 +1,33 @@
+sampler RT : register(s0);
+
+float4 Tiling_ps(float4 inPos : POSITION,
+				float2 iTexCoord : TEXCOORD0,
+				uniform half NumTiles,
+				uniform half Threshhold) : COLOR
+{
+
+
+	half3 EdgeColor = {0.7, 0.7, 0.7};
+
+    half size = 1.0/NumTiles;
+    half2 Pbase = iTexCoord - fmod(iTexCoord, size.xx);
+    half2 PCenter = Pbase + (size/2.0).xx;
+    half2 st = (iTexCoord - Pbase)/size;
+    half4 c1 = (half4)0;
+    half4 c2 = (half4)0;
+    half4 invOff = half4((1-EdgeColor),1);
+    if (st.x > st.y) { c1 = invOff; }
+    half threshholdB =  1.0 - Threshhold;
+    if (st.x > threshholdB) { c2 = c1; }
+    if (st.y > threshholdB) { c2 = c1; }
+    half4 cBottom = c2;
+    c1 = (half4)0;
+    c2 = (half4)0;
+    if (st.x > st.y) { c1 = invOff; }
+    if (st.x < Threshhold) { c2 = c1; }
+    if (st.y < Threshhold) { c2 = c1; }
+    half4 cTop = c2;
+    half4 tileColor = tex2D(RT, PCenter);
+    half4 result = tileColor + cTop - cBottom;
+    return result;
+}
Index: /data/branches/Shader_HS18/programs/OLD/ToonShaderPS.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/ToonShaderPS.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/ToonShaderPS.cg	(revision 12083)
@@ -0,0 +1,11 @@
+float4 main(in float3 texCoord: TEXCOORD0) : COLOR
+{
+	float4 c;
+
+	c.r = 0.9;
+	c.g = 0.8;
+	c.b = 0.1;
+	c.a = 0.0;
+
+	return c;
+}
Index: /data/branches/Shader_HS18/programs/OLD/glow.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/glow.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/glow.cg	(revision 12083)
@@ -0,0 +1,72 @@
+//A.
+float4 GlowX_fp
+	(
+		float2 uv: TEXCOORD0,
+
+		uniform sampler2D scene: register(s0),
+		uniform float4 invTexSize
+	) : COLOR
+#define RENDER_SCENE 1
+#define BLUR_RADIUS 1
+{
+	float4 colour = float4(0);
+	float blurSize = BLUR_RADIUS * invTexSize.x;
+
+	//X-blur.
+	int x = uv.x/blurSize;
+	colour += tex2D(scene, float2((x - 4.0) * blurSize, uv.y)) * 1.0/25.0;
+	colour += tex2D(scene, float2((x - 3.0) * blurSize, uv.y)) * 2.0/25.0;
+	colour += tex2D(scene, float2((x - 2.0) * blurSize, uv.y)) * 3.0/25.0;
+	colour += tex2D(scene, float2((x - 1.0) * blurSize, uv.y)) * 4.0/25.0;
+	colour += tex2D(scene, float2((x + 0.0) * blurSize, uv.y)) * 5.0/25.0;
+	colour += tex2D(scene, float2((x + 1.0) * blurSize, uv.y)) * 4.0/25.0;
+	colour += tex2D(scene, float2((x + 2.0) * blurSize, uv.y)) * 3.0/25.0;
+	colour += tex2D(scene, float2((x + 3.0) * blurSize, uv.y)) * 2.0/25.0;
+	colour += tex2D(scene, float2((x + 4.0) * blurSize, uv.y)) * 1.0/25.0;
+
+	return colour;
+}
+
+//B.
+float4 GlowY_fp
+	(
+		float2 uv: TEXCOORD0,
+ 
+		uniform sampler2D blurX: register(s0),
+		uniform float4 invTexSize
+	) : COLOR
+{
+	float4 colour = float4(0);
+	float blurSize = BLUR_RADIUS * invTexSize.y;
+
+	//Y-blur.
+	int y = uv.y/blurSize;
+	colour += tex2D(blurX, float2(uv.x, (y - 4.0) * blurSize)) * 1.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y - 3.0) * blurSize)) * 2.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y - 2.0) * blurSize)) * 3.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y - 1.0) * blurSize)) * 4.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y + 0.0) * blurSize)) * 5.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y + 1.0) * blurSize)) * 4.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y + 2.0) * blurSize)) * 3.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y + 3.0) * blurSize)) * 2.0/25.0;
+	colour += tex2D(blurX, float2(uv.x, (y + 4.0) * blurSize)) * 1.0/25.0;
+
+	return colour;
+}
+
+//C.
+float4 GlowBlend_fp
+	(
+		float2 uv: TEXCOORD0,
+
+		uniform sampler2D scene: register(s0),
+		uniform sampler2D blurXY: register(s1)
+	) : COLOR
+{
+	//Add this to original, return.
+	return
+#if RENDER_SCENE
+		tex2D(scene, uv) +
+#endif
+		tex2D(blurXY, uv) * 1;
+}
Index: /data/branches/Shader_HS18/programs/OLD/hdr.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr.cg	(revision 12083)
@@ -0,0 +1,25 @@
+void morningskybox_fp (
+	float2 uv : TEXCOORD0,
+	out float4 colour : COLOR,
+
+	uniform sampler2D tex : register(s0) )
+{
+	colour = tex2D(tex, uv);
+
+	// blow out the light a bit
+	colour *= 1.7;
+}
+void morningcubemap_fp (
+	float3 uv : TEXCOORD0,
+	out float4 colour : COLOR,
+
+	uniform samplerCUBE tex : register(s0) )
+{
+	colour = texCUBE(tex, uv);
+
+	// blow out the light a bit
+	colour *= 1.7;
+}
+
+
+
Index: /data/branches/Shader_HS18/programs/OLD/hdr.hlsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr.hlsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr.hlsl	(revision 12083)
@@ -0,0 +1,228 @@
+// RGBE mode utilities
+// RGB each carry a mantissa, A carries a shared exponent
+// The exponent is calculated based on the largest colour channel
+
+
+float3 decodeRGBE8(in float4 rgbe)
+{
+    // get exponent (-128 since it can be +ve or -ve)
+	float exp = rgbe.a * 255 - 128;
+	
+	// expand out the rgb value
+	return rgbe.rgb * exp2(exp);
+}
+
+float4 encodeRGBE8(in float3 rgb)
+{
+	float4 ret;
+
+    // What is the largest colour channel?
+	float highVal = max(rgb.r, max(rgb.g, rgb.b));
+	
+	// Take the logarithm, clamp it to a whole value
+	float exp = ceil(log2(highVal));
+
+    // Divide the components by the shared exponent
+	ret.rgb = rgb / exp2(exp);
+	
+	// Store the shared exponent in the alpha channel
+	ret.a = (exp + 128) / 255;
+
+	return ret;
+}
+
+
+static const float4 LUMINENCE_FACTOR  = float4(0.27f, 0.67f, 0.06f, 0.0f);
+static const float MIDDLE_GREY = 0.72f;
+static const float FUDGE = 0.001f;
+static const float L_WHITE = 1.5f;
+static const float4 BRIGHT_LIMITER = float4(0.6f, 0.6f, 0.6f, 0.0f);
+
+
+/** Tone mapping function 
+@note Only affects rgb, not a
+@param inColour The HDR colour
+@param lum The scene lumninence 
+@returns Tone mapped colour
+*/
+float4 toneMap(float4 inColour, float lum)
+{
+	// From Reinhard et al
+	// "Photographic Tone Reproduction for Digital Images"
+	
+	// Initial luminence scaling (equation 2)
+    inColour.rgb *= MIDDLE_GREY / (FUDGE + lum);
+
+	// Control white out (equation 4 nom)
+    inColour.rgb *= (1.0f + inColour / L_WHITE);
+
+	// Final mapping (equation 4 denom)
+	inColour.rgb /= (1.0f + inColour);
+	
+	return inColour;
+
+}
+
+/* Downsample a 2x2 area and convert to greyscale
+*/
+float4 downscale2x2Luminence(
+	float2 uv : TEXCOORD0,
+	uniform float2 texelSize, // depends on size of source texture
+	uniform sampler2D inRTT : register(s0)
+    ) : COLOR
+{
+	
+    float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+	float2 texOffset[4] = {
+		-0.5, -0.5,
+		-0.5,  0.5, 
+		 0.5, -0.5,
+		 0.5, 0.5 };
+
+	for( int i = 0; i < 4; i++ )
+    {
+        // Get colour from source
+        accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
+    }
+    
+	// Adjust the accumulated amount by lum factor
+	// Cannot use float3's here because it generates dependent texture errors because of swizzle
+	float lum = dot(accum, LUMINENCE_FACTOR);
+	// take average of 4 samples
+	lum *= 0.25;
+	return lum;
+
+}
+
+/* Downsample a 3x3 area 
+ * This shader is used multiple times on different source sizes, so texel size has to be configurable
+*/
+float4 downscale3x3(
+	float2 uv : TEXCOORD0,
+	uniform float2 texelSize, // depends on size of source texture
+	uniform sampler2D inRTT : register(s0)
+    ) : COLOR
+{
+	
+    float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+	float2 texOffset[9] = {
+		-1.0, -1.0,
+		 0.0, -1.0,
+		 1.0, -1.0,
+		-1.0,  0.0,
+		 0.0,  0.0,
+		 1.0,  0.0,
+		-1.0,  1.0,
+		 0.0,  1.0,
+		 1.0,  1.0
+	};
+
+	for( int i = 0; i < 9; i++ )
+    {
+        // Get colour from source
+        accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
+    }
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+	return accum;
+
+}
+
+/* Downsample a 3x3 area from main RTT and perform a brightness pass
+*/
+float4 downscale3x3brightpass(
+	float2 uv : TEXCOORD0,
+	uniform float2 texelSize, // depends on size of source texture
+	uniform sampler2D inRTT : register(s0),
+	uniform sampler2D inLum : register(s1)
+    ) : COLOR
+{
+	
+    float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+	float2 texOffset[9] = {
+		-1.0, -1.0,
+		 0.0, -1.0,
+		 1.0, -1.0,
+		-1.0,  0.0,
+		 0.0,  0.0,
+		 1.0,  0.0,
+		-1.0,  1.0,
+		 0.0,  1.0,
+		 1.0,  1.0
+	};
+
+	for( int i = 0; i < 9; i++ )
+    {
+        // Get colour from source
+        accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
+    }
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+    // Reduce bright and clamp
+    accum = max(float4(0.0f, 0.0f, 0.0f, 1.0f), accum - BRIGHT_LIMITER);
+
+	// Sample the luminence texture
+	float4 lum = tex2D(inLum, float2(0.5f, 0.5f));
+	
+	// Tone map result
+	return toneMap(accum, lum.r);
+
+}
+
+/* Gaussian bloom, requires offsets and weights to be provided externally
+*/
+float4 bloom(
+		float2 uv : TEXCOORD0,
+		uniform float2 sampleOffsets[15],
+		uniform float4 sampleWeights[15],	
+		uniform sampler2D inRTT : register(s0)
+		) : COLOR
+{
+    float4 accum = float4(0.0f, 0.0f, 0.0f, 1.0f);
+	float2 sampleUV;
+    
+    for( int i = 0; i < 15; i++ )
+    {
+        // Sample from adjacent points, 7 each side and central
+        sampleUV = uv + sampleOffsets[i];
+        accum += sampleWeights[i] * tex2D(inRTT, sampleUV);
+    }
+    
+    return accum;
+	
+}
+		
+
+/* Final scene composition, with tone mapping
+*/
+float4 finalToneMapping(
+	float2 uv : TEXCOORD0,
+	uniform sampler2D inRTT : register(s0),
+	uniform sampler2D inBloom : register(s1),
+	uniform sampler2D inLum : register(s2)
+    ) : COLOR
+{
+	// Get main scene colour
+    float4 sceneCol = tex2D(inRTT, uv);
+
+	// Get luminence value
+	float4 lum = tex2D(inLum, float2(0.5f, 0.5f));
+
+	// tone map this
+	float4 toneMappedSceneCol = toneMap(sceneCol, lum.r);
+	
+	// Get bloom colour
+    float4 bloom = tex2D(inBloom, uv);
+
+	// Add scene & bloom
+	return float4(toneMappedSceneCol.rgb + bloom.rgb, 1.0f);
+     	
+}
+
+
Index: /data/branches/Shader_HS18/programs/OLD/hdr_bloom.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr_bloom.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr_bloom.glsl	(revision 12083)
@@ -0,0 +1,22 @@
+uniform sampler2D inRTT;
+
+uniform vec4 sampleOffsets[15];
+uniform vec4 sampleWeights[15];
+
+varying vec2 uv;
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 1.0);
+	vec2 sampleUV;
+    
+    for( int i = 0; i < 15; i++ )
+    {
+        // Sample from adjacent points, 7 each side and central
+        sampleUV = uv + sampleOffsets[i].xy;
+        accum += sampleWeights[i] * texture2D(inRTT, sampleUV);
+    }
+    
+    gl_FragColor = accum;
+	
+}
Index: /data/branches/Shader_HS18/programs/OLD/hdr_downscale2x2luminence.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr_downscale2x2luminence.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr_downscale2x2luminence.glsl	(revision 12083)
@@ -0,0 +1,24 @@
+uniform sampler2D inRTT;
+uniform vec2 texelSize;
+
+varying vec2 uv;
+
+void main(void)
+{
+	
+    vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+	vec4 LUMINENCE_FACTOR  = vec4(0.27, 0.67, 0.06, 0.0);
+
+    // Get colour from source
+    accum += texture2D(inRTT, uv + texelSize * vec2(-0.5, -0.5));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-0.5, 0.5));
+    accum += texture2D(inRTT, uv + texelSize * vec2(0.5, 0.5));
+    accum += texture2D(inRTT, uv + texelSize * vec2(0.5, -0.5));
+    
+	// Adjust the accumulated amount by lum factor
+	float lum = dot(accum, LUMINENCE_FACTOR);
+	// take average of 4 samples
+	lum *= 0.25;
+	gl_FragColor = vec4(lum, lum, lum, 1.0);
+
+}
Index: /data/branches/Shader_HS18/programs/OLD/hdr_downscale3x3.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr_downscale3x3.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr_downscale3x3.glsl	(revision 12083)
@@ -0,0 +1,26 @@
+uniform sampler2D inRTT;
+uniform vec2 texelSize;
+
+varying vec2 uv;
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+
+    // Get colour from source
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  1.0));
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+	gl_FragColor = accum;
+
+}
Index: /data/branches/Shader_HS18/programs/OLD/hdr_downscale3x3brightpass.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr_downscale3x3brightpass.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr_downscale3x3brightpass.glsl	(revision 12083)
@@ -0,0 +1,37 @@
+uniform sampler2D inRTT;
+uniform sampler2D inLum;
+uniform vec2 texelSize;
+
+varying vec2 uv;
+const vec4 BRIGHT_LIMITER = vec4(0.6, 0.6, 0.6, 0.0);
+
+// declare external function
+vec4 toneMap(in vec4 inColour, in float lum);
+
+void main(void)
+{
+    vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0, -1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  0.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2(-1.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 0.0,  1.0));
+    accum += texture2D(inRTT, uv + texelSize * vec2( 1.0,  1.0));
+    
+	// take average of 9 samples
+	accum *= 0.1111111111111111;
+
+    // Reduce bright and clamp
+    accum = max(vec4(0.0, 0.0, 0.0, 1.0), accum - BRIGHT_LIMITER);
+
+	// Sample the luminence texture
+	vec4 lum = texture2D(inLum, vec2(0.5, 0.5));
+	
+	// Tone map result
+	gl_FragColor = toneMap(accum, lum.r);
+
+}
Index: /data/branches/Shader_HS18/programs/OLD/hdr_finalToneMapping.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr_finalToneMapping.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr_finalToneMapping.glsl	(revision 12083)
@@ -0,0 +1,28 @@
+uniform sampler2D inRTT;
+uniform sampler2D inBloom;
+uniform sampler2D inLum;
+
+varying vec2 uv;
+
+// declare external function
+vec4 toneMap(in vec4 inColour, in float lum);
+
+void main(void)
+{
+	// Get main scene colour
+    vec4 sceneCol = texture2D(inRTT, uv);
+
+	// Get luminence value
+	vec4 lum = texture2D(inLum, vec2(0.5, 0.5));
+
+	// tone map this
+	vec4 toneMappedSceneCol = toneMap(sceneCol, lum.r);
+	
+	// Get bloom colour
+    vec4 bloom = texture2D(inBloom, uv);
+
+	// Add scene & bloom
+	gl_FragColor = vec4(toneMappedSceneCol.rgb + bloom.rgb, 1.0);
+    
+}
+
Index: /data/branches/Shader_HS18/programs/OLD/hdr_tonemap_util.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/hdr_tonemap_util.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/hdr_tonemap_util.glsl	(revision 12083)
@@ -0,0 +1,29 @@
+const float MIDDLE_GREY = 0.72;
+const float FUDGE = 0.001;
+const float L_WHITE = 1.5;
+
+/** Tone mapping function 
+@note Only affects rgb, not a
+@param inColour The HDR colour
+@param lum The scene lumninence 
+@returns Tone mapped colour
+*/
+vec4 toneMap(in vec4 inColour, in float lum)
+{
+	// From Reinhard et al
+	// "Photographic Tone Reproduction for Digital Images"
+	
+	// Initial luminence scaling (equation 2)
+    inColour.rgb *= MIDDLE_GREY / (FUDGE + lum);
+
+	// Control white out (equation 4 nom)
+    inColour.rgb *= (1.0 + inColour.rgb / L_WHITE);
+
+	// Final mapping (equation 4 denom)
+	inColour.rgb /= (1.0 + inColour.rgb);
+	
+	return inColour;
+
+}
+
+
Index: /data/branches/Shader_HS18/programs/OLD/ps_glow.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/ps_glow.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/ps_glow.cg	(revision 12083)
@@ -0,0 +1,26 @@
+struct vertexOut
+{
+    float4 position : POSITION;
+    float2 uv : TEXCOORD0;
+    float3 worldNormal : TEXCOORD1;
+    float3 worldView : TEXCOORD2;
+};
+
+float4 main(vertexOut input, uniform float alphaValue, uniform float cutoffAngle, uniform float exponent, uniform float time, uniform float4 color) : COLOR
+{
+    float3 Nn = normalize(input.worldNormal);
+    float3 Vn = normalize(input.worldView);
+    float alphaMod = dot(Nn, Vn);//this is a measure for how close we are to the edge of a model according to our view
+    float cutoff=cos(cutoffAngle * 3.14 / 180.0);//pi divided by 180
+    if(alphaMod<cutoff)//transform output range so it only affects angles close to 90 degrees
+    {
+        alphaMod/=cutoff;
+    }
+    else
+    {
+        alphaMod=1.0;
+    }
+    alphaMod = pow(alphaMod,exponent); //how fast should the intensity of the glow decrease
+    color.w = alphaMod * alphaValue * ((sin(time)/3.14 + 1.0) / 2.0 + 0.1);
+    return color;
+}
Index: /data/branches/Shader_HS18/programs/OLD/skinningTwoWeightsShadowCasterVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/skinningTwoWeightsShadowCasterVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/skinningTwoWeightsShadowCasterVp.glsl	(revision 12083)
@@ -0,0 +1,40 @@
+// Example GLSL program for skinning with two bone weights per vertex
+
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+// 3x4 matrix, passed as vec4's for compatibility with GL 2.0
+// GL 2.0 supports 3x4 matrices
+// Support 24 bones ie 24*3, but use 72 since our parser can pick that out for sizing
+uniform vec4 worldMatrix3x4Array[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 ambient;
+
+void main()
+{
+	vec3 blendPos = vec3(0,0,0);
+
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+        // ATI GLSL compiler can't handle indexing an array within an array so calculate the inner index first
+	    int idx = int(blendIndices[bone]) * 3;
+        // ATI GLSL compiler can't handle unrolling the loop so do it manually
+        // ATI GLSL has better performance when mat4 is used rather than using individual dot product
+        // There is a bug in ATI mat4 constructor (Cat 7.2) when indexed uniform array elements are used as vec4 parameter so manually assign
+		mat4 worldMatrix;
+		worldMatrix[0] = worldMatrix3x4Array[idx];
+		worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+		worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+		worldMatrix[3] = vec4(0);
+		// now weight this into final 
+		blendPos += (gl_Vertex * worldMatrix).xyz * blendWeights[bone];
+	}
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1);
+	
+	gl_FrontSecondaryColor = vec4(0,0,0,0);
+	gl_FrontColor = ambient;
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+}
Index: /data/branches/Shader_HS18/programs/OLD/skinningTwoWeightsVp.glsl
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/skinningTwoWeightsVp.glsl	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/skinningTwoWeightsVp.glsl	(revision 12083)
@@ -0,0 +1,57 @@
+// Example GLSL program for skinning with two bone weights per vertex
+
+attribute vec4 blendIndices;
+attribute vec4 blendWeights;
+
+// 3x4 matrix, passed as vec4's for compatibility with GL 2.0
+// GL 2.0 supports 3x4 matrices
+// Support 24 bones ie 24*3, but use 72 since our parser can pick that out for sizing
+uniform vec4 worldMatrix3x4Array[72];
+uniform mat4 viewProjectionMatrix;
+uniform vec4 lightPos[2];
+uniform vec4 lightDiffuseColour[2];
+
+void main()
+{
+	vec3 blendPos = vec3(0,0,0);
+	vec3 blendNorm = vec3(0,0,0);
+	
+	for (int bone = 0; bone < 2; ++bone)
+	{
+		// perform matrix multiplication manually since no 3x4 matrices
+        // ATI GLSL compiler can't handle indexing an array within an array so calculate the inner index first
+	    int idx = int(blendIndices[bone]) * 3;
+        // ATI GLSL compiler can't handle unrolling the loop so do it manually
+        // ATI GLSL has better performance when mat4 is used rather than using individual dot product
+        // There is a bug in ATI mat4 constructor (Cat 7.2) when indexed uniform array elements are used as vec4 parameter so manually assign
+		mat4 worldMatrix;
+		worldMatrix[0] = worldMatrix3x4Array[idx];
+		worldMatrix[1] = worldMatrix3x4Array[idx + 1];
+		worldMatrix[2] = worldMatrix3x4Array[idx + 2];
+		worldMatrix[3] = vec4(0);
+		// now weight this into final 
+	    float weight = blendWeights[bone];
+		blendPos += (gl_Vertex * worldMatrix).xyz * weight;
+		
+		mat3 worldRotMatrix = mat3(worldMatrix[0].xyz, worldMatrix[1].xyz, worldMatrix[2].xyz);
+		blendNorm += (gl_Normal * worldRotMatrix) * weight;
+
+	}
+
+	// apply view / projection to position
+	gl_Position = viewProjectionMatrix * vec4(blendPos, 1);
+
+	// simple vertex lighting model
+	vec3 lightDir0 = normalize(
+		lightPos[0].xyz -  (blendPos.xyz * lightPos[0].w));
+	vec3 lightDir1 = normalize(
+		lightPos[1].xyz -  (blendPos.xyz * lightPos[1].w));
+		
+	gl_FrontSecondaryColor = vec4(0);
+	gl_FrontColor = vec4(0.5, 0.5, 0.5, 1.0) 
+		+ clamp(dot(lightDir0, blendNorm), 0.0, 1.0) * lightDiffuseColour[0]
+		+ clamp(dot(lightDir1, blendNorm), 0.0, 1.0) * lightDiffuseColour[1];
+
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+	
+}
Index: /data/branches/Shader_HS18/programs/OLD/vs_glow.cg
===================================================================
--- /data/branches/Shader_HS18/programs/OLD/vs_glow.cg	(revision 12083)
+++ /data/branches/Shader_HS18/programs/OLD/vs_glow.cg	(revision 12083)
@@ -0,0 +1,28 @@
+struct vertexIn
+{
+    float4 position : POSITION;
+    float4 normal : NORMAL;
+    float2 uv : TEXCOORD0;
+};
+
+struct vertexOut
+{
+    float4 position : POSITION; //<! transformed position
+    float2 uv : TEXCOORD0; //<! passing on uv information
+    float3 worldNormal : TEXCOORD1; //<! surface normal transformed into world
+    float3 worldView : TEXCOORD2; //<! view direction transformed into world
+};
+
+vertexOut main(vertexIn input, uniform float4x4 iWorldTMatrix, uniform float4x4 iViewMatrix, uniform float4x4 worldMatrix, uniform float4x4 viewProjMatrix, uniform float inflate )
+{
+   vertexOut output;
+   float4 myPosition = input.position;
+   output.worldNormal=mul(iWorldTMatrix, input.normal).xyz; //transforming the normal
+   input.normal = normalize(float4(input.normal.xyz,0)); //normalizing the normal according to the three relevant parts
+   myPosition.xyz += inflate * input.normal; //inflating the model into a bigger shape
+   myPosition = mul(worldMatrix, myPosition); //transforming position into world
+   output.worldView = normalize(float3(iViewMatrix[0].w, iViewMatrix[1].w, iViewMatrix[2].w) - myPosition.xyz);//view direction according to world
+   output.position = mul(viewProjMatrix, myPosition); //finish transformation of the position into the projection space
+   output.uv = input.uv; //passing on uv information
+   return output;
+}
