Skip to content

Instantly share code, notes, and snippets.

@PopupAsylum
Last active January 6, 2017 13:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PopupAsylum/24b38c0714ac7e46387176c863db1900 to your computer and use it in GitHub Desktop.
Save PopupAsylum/24b38c0714ac7e46387176c863db1900 to your computer and use it in GitHub Desktop.
Box Projected Refraction
//get the worldspace ray from the camera to the pixel
float3 viewDir = normalize(i.vPositionWs.xyz - _WorldSpaceCameraPos);
//refract the ray on the worldspace normal with a uniform variable for refractive index
float3 refractedViewDir = refract(viewDir, vNormalWs.xyz, _PA_Index);
//get the worldspace position the refracted ray would emerge from the glass based on a uniform thickness
float3 refractedPosition = i.vPositionWs.xyz + refractedViewDir * _PA_Thickness;
//after emerging through the glass the ray would need to be re-refracted based on the exit normal,
//but we dont know the exit normal so just lerp towards the original direction based on a uniform value
refractedViewDir = lerp(viewDir, refractedViewDir, _PA_NormalInfluence);
//now werve got our refracted ray origin and direction, lookup the current reflection probe with a uniform value for frostiness
//PA_CubeRefraction is an adaptation of the UnityGI_IndirectSpecular function from UnityGlobalIllumination.cginc
fixed3 refraction = PA_CubeRefraction(refractedViewDir, refractedPosition, _PA_FrostedGlass);
//lerp from out original color to the refraction result based on another uniform
o.vColor.rgb = lerp(o.vColor.rgb, refraction, _PA_Transparency);
//PA_CubeRefraction is an adaptation of the UnityGI_IndirectSpecular function from UnityGlobalIllumination.cginc
float3 PA_CubeRefraction(float3 vViewDirectionWs, float3 vPositionWs, float frosted) {
float3 result = 0;
float3 vRefractionDirWs0 = vViewDirectionWs.xyz;
#if ( UNITY_SPECCUBE_BOX_PROJECTION )
{
vRefractionDirWs0.xyz = BoxProjectedCubemapDirection(vViewDirectionWs.xyz, vPositionWs.xyz, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
}
#endif
float3 vEnvMap0 = max(0.0, Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, vRefractionDirWs0, frosted));
#if ( UNITY_SPECCUBE_BLENDING )
{
const float flBlendFactor = 0.99999;
float flBlendLerp = saturate(unity_SpecCube0_BoxMin.w);
UNITY_BRANCH
if (flBlendLerp < flBlendFactor)
{
float3 vRefractionDirWs1 = vViewDirectionWs.xyz;
#if ( UNITY_SPECCUBE_BOX_PROJECTION )
{
vRefractionDirWs1.xyz = BoxProjectedCubemapDirection(vViewDirectionWs.xyz, vPositionWs.xyz, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
}
#endif
float3 vEnvMap1 = max(0.0, Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube1_HDR, vRefractionDirWs1, frosted));
result += lerp(vEnvMap1.rgb, vEnvMap0.rgb, flBlendLerp);
}
else
{
result += vEnvMap0.rgb;
}
}
#else
{
result += vEnvMap0.rgb;
}
#endif
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment