Skip to content

Instantly share code, notes, and snippets.

@andr3wmac
Created September 11, 2014 11:36
Show Gist options
  • Save andr3wmac/744527a4591cc92c2989 to your computer and use it in GitHub Desktop.
Save andr3wmac/744527a4591cc92c2989 to your computer and use it in GitHub Desktop.
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// 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 "../postFx.hlsl"
uniform sampler2D prepassTex : register(S0);
uniform sampler2D colorBufferTex : register(S1);
uniform float2 nearFar;
uniform float2 targetSize;
float4 main( PFXVertToPix IN ) : COLOR0
{
// We Need:
// ScreenPos
// ViewPos
// ViewNormal
// Calculate the camera stuff
float4 texCoord = float4( IN.uv0.xy, 0, 0 );
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0.xy );
float3 normal = prepassSample.rgb;
float depth = prepassSample.a;
// Calculate View Space Position
float3 viewPos = nearFar.y * depth * normalize(IN.wsEyeRay);
// Calculate View Space Reflection Vector!
float3 vspReflect = reflect(normalize(viewPos), normalize(normal));
// Normalize, in this way we only need to check the .z component
// to know how hard the reflection vector is facing the viewer
vspReflect = normalize(vspReflect);
// Transform the View Space Reflection to Screen Space
// This because we want to ray march in to the depth buffer in Screen Space
// Depth is linear in Screen Space per Screen Pixel
float3 vspPosReflect = viewPos + vspReflect;
float3 sspPosReflect = mul(float4(vspPosReflect, 1.0), g_mProj).xyz / vspPosReflect.z;
float3 sspReflect = sspPosReflect - IN.uv0.xy;
// Resize Screen Space Reflection to an appropriate length.
// We want to catch each pixel of the screen
float scalefactor = g_rlrOptions2.y / length(sspReflect.xy);
scalefactor *= 1 /* how many pixels at once (value = 1) */;
sspReflect *= scalefactor;
// Initial offsets
float3 vCurrOffset = IN.uv0.xy + sspReflect;
float3 vLastOffset = IN.uv0.xy;
// Number of samples
int nNumSamples = (int)(16); //(targetSize width of backbuffer (e.g. 1280) / 1);
int nCurrSample = 0;
// Calculate the number of samples to the edge! (min and maximum are 0 to 1)
float3 vFinalResult;
float vCurrSample;
float4 curPrepassSample;
float2 dx, dy;
dx = ddx( vCurrOffset.xy );
dy = ddy( vCurrOffset.xy );
while ( nCurrSample < nNumSamples )
{
// Sample from depth buffer
curPrepassSample = prepassUncondition( prePassBuffer, IN.uv0.xy );
vCurrSample = prepassSample.a;
if (vCurrSample < vCurrOffset.z)
{
// Calculate final offset
vLastOffset.xy = vLastOffset.xy + (vCurrSample - vLastOffset.z) * sspReflect.xy;
// Get Color
vFinalResult = tex2D( backBuffer, vLastOffset.xy ).xyz;
const float blendfact = 0.6;
float2 factors = float2(blendfact, blendfact);
// Blend
fvTotalDiffuse.xyz = lerp(vFinalResult, fvTotalDiffuse, max(max(factors.x /* linear curve */, factors.y * factors.y /* x^2 curve */), blendfact));
nCurrSample = nNumSamples + 1;
}
else
{
++nCurrSample;
vLastOffset = vCurrOffset;
vCurrOffset += sspReflect;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment