Project Description

The aim for this project was to create a collection of special effects commonly found in games. The special effects varied to model shaders, post processing effects and small systems, like a basic particle system and a lens flare system. It was mandatory that all the post processing effect could work separately and combined from each other.

The effects and their implementations were made in an already existing framework as an exercise to work within existing frameworks and build needed functionality into it without breaking the existing code base.

 

Code Snippits

struct input
{
  float4 position		: POSITION;
  float2 uv			: TEXCOORD0;

  float4 copyposition : TEXCOORD1;
  float3 normsunpos : TEXCOORD2;
  float4 sunpos : TEXCOORD3;
  float4 moonpos : TEXCOORD5;
  float4 projpos : TEXCOORD4;
};

struct output 
{
  float4 color : COLOR;
};

output pixelfunction( input IN	, uniform sampler2D gradient1: TEXUNIT0
                , uniform sampler2D gradient2: TEXUNIT1
                , uniform sampler2D suntexture: TEXUNIT2
                , uniform sampler2D sungradient: TEXUNIT3
                , uniform sampler2D moontexture: TEXUNIT4
                , uniform sampler2D moonmasktexture: TEXUNIT5
                , uniform sampler2D moonhalotexture: TEXUNIT6
                , uniform sampler2D starfieldtexture: TEXUNIT7
                , uniform sampler2D cloudfieldtexture: TEXUNIT8
                , uniform float moonsunangle
                , uniform float atmosthickness
                , uniform float skyscroll
                , uniform float lightstrength
                , uniform float clouds
                , uniform float stars
                 )
{
  output OUT;

  float aspect = 1080.0f/1920.0f;	
  float2 suninscreen = IN.sunpos.xy / IN.sunpos.w;
  float2 pixinscreen = IN.projpos.xy / IN.projpos.w;
  float2 sunuv = ((suninscreen - pixinscreen) * 4) + float2(0.5,0.45 / aspect);
  sunuv.y *= aspect;

  float2 pixelheight = float2(IN.copyposition.y,0);
  float gradientsclr = dot(IN.copyposition.xyz,IN.normsunpos.xyz);
  float3 suncolor = tex2D(suntexture,sunuv) * (tex2D(sungradient,pixelheight * atmosthickness) * gradientsclr);

  float2 mooninscreen = IN.moonpos.xy / IN.moonpos.w;
  float2 moonuv = ((mooninscreen - pixinscreen) * 4) + float2(0.5,0.5 / aspect);
  moonuv.y *= aspect;

  float3 moonmaskcolor = clamp(tex2D(moonmasktexture,moonuv) - moonsunangle,0,1);
  float3 moonhalocolor = tex2D(moonhalotexture,moonuv) * clamp(1-IN.normsunpos.y,0,1);
  float3 mooncolor = tex2D(moontexture,moonuv) * moonmaskcolor * tex2D(sungradient,pixelheight);

  float2 skyuv = float2(IN.copyposition.y * atmosthickness,0);
  float3 skycolor = clamp(lerp(tex2D( gradient2, skyuv ),tex2D( gradient1, skyuv ),abs(IN.normsunpos.y * atmosthickness)) * clamp(IN.normsunpos.y * atmosthickness,0.025,1),0,1);

 	float redcorrectscalar = clamp(1.0f-dot((IN.copyposition.xyz),IN.normsunpos.xyz),0,1);
 	float3 redcorrectcolor = ((float3( 1, 0.59, 0.16 ) * 0.90f  * redcorrectscalar)) * (1-clamp(IN.normsunpos.y * atmosthickness,0.0,1)) * clamp(IN.normsunpos.y * atmosthickness,0.0,1);

 	float3 starcolor = tex2D(starfieldtexture,IN.uv + float2(skyscroll * 0.1,0) ) * clamp(abs(IN.normsunpos.y),0,1) * redcorrectscalar;
  if(IN.normsunpos.y > 0)starcolor = float3(0,0,0);
  if(stars == 0)starcolor = float3(0,0,0);

  float4 cloudcolor = tex2D(cloudfieldtexture,IN.uv + float2(skyscroll * 0.2,-skyscroll * 0.1));
  cloudcolor.rgb +=  (tex2D(sungradient,pixelheight * atmosthickness))* (1-abs(IN.normsunpos.y));
  cloudcolor.rgb *= clamp(IN.normsunpos.y,0.025,1);
  cloudcolor.a *=  clouds;

  if(IN.sunpos.z < 0)	suncolor = float3(0,0,0);
  if(IN.moonpos.z < 0) mooncolor = float3(0,0,0);

  float3 correctedcolor = (skycolor - clamp(redcorrectcolor,0,1));
  correctedcolor = clamp(correctedcolor,0,1);
  OUT.color.rgb = lerp((correctedcolor) + suncolor + mooncolor + starcolor,cloudcolor.rgb,cloudcolor.a);
  OUT.color.rgb *= lightstrength;

  return OUT;
}

 

struct input
{
  float4 position		: POSITION;		// (projected) position in screen space
  float4 pixelpos		: TEXCOORD5;		// (projected) position in screen space
  float4 posworld		: TEXCOORD6;
  float4 color		: COLOR;
  float4 pos			: TEXCOORD0;	// position in world space (not projected)
  float3 normal		: TEXCOORD1;
  float2 uv			: TEXCOORD2;
  float3 tangent		: TEXCOORD3;
  float3 binormal		: TEXCOORD4;
  float depth			: TEXCOORD7;
};

#define NEARPLANE 0.01
#define FARPLANE 1000.0

float ZfromDepth( float depth, float zNear, float zFar )
{
  // source: http://olivers.posterous.com/linear-depth-in-glsl-for-real
  // OpenGL only!
  return 2*zFar*zNear / (zFar + zNear - (zFar - zNear)*(2*depth -1));
}

struct output 
{
  float4 color : COLOR;
};
float3 expand(float3 v)
{
  return (v - 0.5) * 2;
}

float texwidth = 1.0f/512 * 10;
output pixelfunction( input IN, 
          uniform float4x4 worldCam, 
          uniform float4x4 ModelCamp, 
          uniform float4 lightPos,
          uniform float3 lightColor, 
          uniform float3 eyePosW, 
          uniform float uvoffset,
          uniform sampler2D normalmap: TEXUNIT0,
          uniform sampler2D reflectmap: TEXUNIT1,
          uniform sampler2D refractmap: TEXUNIT2,
          uniform sampler2D depthmap: TEXUNIT3
           )
{
  output OUT;

  float3 P = IN.pos.xyz;

    float3x3 tangentMatrix = float3x3( normalize( IN.tangent ), 
                                       normalize( IN.binormal ),
                                       normalize( IN.normal.xyz ) );

    float2 screenPosition = IN.pixelpos.xy / IN.pixelpos.w; 
    screenPosition = (screenPosition + 1.0)/2; 
    screenPosition.y = screenPosition.y; 

    float3 normalTex = expand(tex2D(normalmap, IN.uv).xyz);
    normalTex += expand(tex2D(normalmap, (IN.uv + float2(texwidth,0)) + uvoffset * 3.1f).xyz);
    normalTex += expand(tex2D(normalmap, (-IN.uv + float2(-texwidth,0)) + uvoffset * 5.2f).xyz);
    normalTex += expand(tex2D(normalmap, (IN.uv + float2(0,texwidth)) + uvoffset * 1.3f).xyz);
    normalTex += expand(tex2D(normalmap, (-IN.uv + float2(0,-texwidth)) + uvoffset * 4.8f).xyz);
    float3 N = normalize( (normalTex) );
    float3 refractTex = tex2D(refractmap, (screenPosition) - (N.xy * 0.0125f / IN.posworld.z)).xyz;
    float3 reflectTex = tex2D(reflectmap, (screenPosition) - (N.xy * 0.025f / IN.posworld.z)).xyz;

    float waterZdepth = IN.depth;
    float refractZdepth = ZfromDepth(tex2D(depthmap, (screenPosition)).xyz,NEARPLANE,FARPLANE);
    float distance = clamp(1/((refractZdepth - waterZdepth)),0,1);

    N = normalize(mul( N, tangentMatrix )); 	
    float3 L = normalize( lightPos - IN.pos.xyz );
    float3 V = normalize( eyePosW - IN.pos.xyz );
    float3 H = normalize ( L + V );

    float fresnel = dot(V,N);

    float specular = 0;
    float diffuse = saturate(dot(N, L));
    float remappedLambert = diffuse * 0.3 + 0.7;
    if ( diffuse > 0 )
    {
        specular = pow(saturate(dot(N, H)), 100);
    }     

    float4 diffuseColor = float4(0.4,1,1,1);
    float4 specularColor = float4(1,1,1,1) * specular;
    float3 deepColor = float3(0.2784,0.3961,1);

    float3 turqoise = float3(64.0f  / 255.0f, 224.0f  / 255.0f, 208.0f  / 255.0f);
    float3 reflectcolor = clamp(reflectTex * diffuseColor,0,1);
    float3 refractcolor = lerp(deepColor,refractTex * turqoise,distance);

  OUT.color.xyz = lerp(reflectcolor,refractcolor,clamp(fresnel,0,1)) + (specularColor * lightColor);
  return OUT;
}

 

struct input
{
  float4 position		: POSITION;
  float2 uv			: TEXCOORD0;
};

struct output 
{
  float4 color : COLOR;
};
#define NEARPLANE 0.01
#define FARPLANE 1000.0

#define NUM_DOF_SAMPLES 64

float ZfromDepth( float depth, float zNear, float zFar )
{
  // source: http://olivers.posterous.com/linear-depth-in-glsl-for-real
  // OpenGL only!
  return 2*zFar*zNear / (zFar + zNear - (zFar - zNear)*(2*depth -1));
}

float CalculateBlurriness(float curpixelz, float minrange, float maxrange)
{
  return (clamp( (curpixelz  - minrange) / (maxrange - minrange), 0, 1 ) * 2) - 1;
}

output pixelfunction( input IN, uniform sampler2D colortexture: TEXUNIT0, 
                uniform sampler2D depthtexture: TEXUNIT1,
                uniform float2 samples[NUM_DOF_SAMPLES],
                uniform float minrange,
                uniform float maxrange,
                uniform float blursize
                )
{
  output OUT;

  float curpixeldepth = tex2D(depthtexture, IN.uv);
  float curpixelz = abs(ZfromDepth(curpixeldepth,NEARPLANE, FARPLANE));

  float blurriness = CalculateBlurriness(curpixelz,minrange,maxrange);

  float totalweight = 1.0f;
  float3 finalColor = tex2D(colortexture, IN.uv).rgb; 

  int numsamples = NUM_DOF_SAMPLES;

  for(int i = 0; i < numsamples; i++)
  {
    float2 sampleuv = IN.uv + samples[i] * abs(blurriness) * blursize;

    float4 samplecolor = tex2D(colortexture, sampleuv);
    float sampledepth = tex2D(depthtexture, sampleuv);

    float samplez = abs(ZfromDepth(sampledepth, NEARPLANE,FARPLANE));
    float sampleblurriness = CalculateBlurriness(samplez,minrange,maxrange);

    float sampleweight;
    sampleweight = (sampledepth < curpixelz) ? abs(sampleblurriness) : 1.0;

    totalweight += sampleweight;	
    finalColor += samplecolor * sampleweight;
  }

  OUT.color.rgb = (finalColor.rgb / totalweight);	
  return OUT;
}