CG/HLSL Distort_Modified.cginc is a modified part of the open source Alloy shader for Unity game engine. I added the option to blur the refraction of light through a transparent surface. I added lines 83 through 122 from a simple blur algorithm and modified other parts of the code to integrate the effect into the shader.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/////////////////////////////////////////////////////////////////////////////////
/// @file Distort.cginc
/// @brief Forward distort pass vertex & fragment shaders.
/////////////////////////////////////////////////////////////////////////////////

#ifndef ALLOY_SHADERS_FORWARD_DISTORT_CGINC
#define ALLOY_SHADERS_FORWARD_DISTORT_CGINC

#define A_TEXEL_SIZE(a) a##_TexelSize

#ifndef A_DISTORT_TEXTURE
    #define A_DISTORT_TEXTURE _GrabTexture
#endif

#define A_DISTORT_TEXTURE_TEXEL_SIZE A_TEXEL_SIZE(A_DISTORT_TEXTURE)

#define A_BASE_PASS
#define A_TESSELLATION_PASS
#define A_INSTANCING_PASS
#define A_NORMAL_MAPPED_PASS
#define A_PARALLAX_MAPPED_PASS
#define A_VOLUMETRIC_PASS
#define A_CROSSFADE_PASS

#define A_FORWARD_TEXCOORD0 float3 normalProjection : TEXCOORD0;
#define A_FORWARD_TEXCOORD1 float4 grabUv : TEXCOORD1;

#include "Assets/Alloy/Shaders/Framework/Forward.cginc"

/// Grab texture containing copy of the back buffer.
sampler2D A_DISTORT_TEXTURE;

/// Grab texture dimension info.
/// (x: 1 / width, y: 1 / height, z: width, w: height).
float4 A_DISTORT_TEXTURE_TEXEL_SIZE;

/// Weight of the distortion effect.
/// Expects values in the range [0,1].
float _DistortWeight;

/// Strength of the distortion effect.
/// Expects values in the range [0,128].
float _DistortIntensity;

/// Mesh normals influence on distortion.
/// Expects values in the range [0,1].
float _DistortGeoWeight;

///
///Eric's variables
float _RefractionBlur;
float _RefractionBrightness;


void aMainVertexShader(
    AVertexInput v,
    out AFragmentInput o)
{
    aForwardVertexShader(v, o);
    o.normalProjection = mul((float3x3)UNITY_MATRIX_MVP, v.normal);
    o.grabUv = ComputeGrabScreenPos(o.pos);
    o.grabUv.z = UNITY_Z_0_FAR_FROM_CLIPSPACE(o.grabUv.z);
}

half4 aMainFragmentShader(
    AFragmentInput i
    A_FACING_SIGN_PARAM) : SV_Target
{
    // Transfer instancing and stereo IDs.
    ASurface s = aForwardSurface(i, A_FACING_SIGN);

    // Mesh normals distortion.
    // cf http://wiki.unity3d.com/index.php?title=Refraction
    float3 bump = s.normalTangent + i.normalProjection * abs(i.normalProjection);
    float2 offset = A_DISTORT_TEXTURE_TEXEL_SIZE.xy * lerp(s.normalTangent, bump, _DistortGeoWeight).xy;

    i.grabUv.xy += offset * (i.grabUv.z * _DistortWeight * _DistortIntensity);
   
    // Sample and combine textures.
    half3 refr = tex2Dproj(A_DISTORT_TEXTURE, UNITY_PROJ_COORD(i.grabUv)).rgb;
    //return aForwardColor(s, s.baseColor * refr);

    // ew added and modified code
    i.grabUv.y = i.grabUv.y * -1; // blur code below has the image upside down     

    float2 screenPos = i.grabUv.xy / (i.grabUv.w * .5); // original: float2 screenPos = i.screenPos.xy / i.screenPos.w;
    float depth = _RefractionBlur * 0.0005;

    screenPos.x = (screenPos.x) * 0.5; // original: screenPos.x = (screenPos.x + 1) * 0.5;

    screenPos.y = 1 - (screenPos.y + 2) * 0.5; // original: screenPos.y = 1 - (screenPos.y + 1) * 0.5;

    half3 sum = half3(0.0h, 0.0h, 0.0h); // original: half4 sum = half4(0.0h, 0.0h, 0.0h, 0.0h);
    sum += tex2D(_GrabTexture, float2(screenPos.x - 5.0 * depth, screenPos.y + 5.0 * depth)) * 0.025;
    sum += tex2D(_GrabTexture, float2(screenPos.x + 5.0 * depth, screenPos.y - 5.0 * depth)) * 0.025;

    sum += tex2D(_GrabTexture, float2(screenPos.x - 4.0 * depth, screenPos.y + 4.0 * depth)) * 0.05;
    sum += tex2D(_GrabTexture, float2(screenPos.x + 4.0 * depth, screenPos.y - 4.0 * depth)) * 0.05;

    sum += tex2D(_GrabTexture, float2(screenPos.x - 3.0 * depth, screenPos.y + 3.0 * depth)) * 0.09;
    sum += tex2D(_GrabTexture, float2(screenPos.x + 3.0 * depth, screenPos.y - 3.0 * depth)) * 0.09;

    sum += tex2D(_GrabTexture, float2(screenPos.x - 2.0 * depth, screenPos.y + 2.0 * depth)) * 0.12;
    sum += tex2D(_GrabTexture, float2(screenPos.x + 2.0 * depth, screenPos.y - 2.0 * depth)) * 0.12;

    sum += tex2D(_GrabTexture, float2(screenPos.x - 1.0 * depth, screenPos.y + 1.0 * depth)) *  0.15;
    sum += tex2D(_GrabTexture, float2(screenPos.x + 1.0 * depth, screenPos.y - 1.0 * depth)) *  0.15;

    sum += tex2D(_GrabTexture, screenPos - 5.0 * depth) * 0.025;
    sum += tex2D(_GrabTexture, screenPos - 4.0 * depth) * 0.05;
    sum += tex2D(_GrabTexture, screenPos - 3.0 * depth) * 0.09;
    sum += tex2D(_GrabTexture, screenPos - 2.0 * depth) * 0.12;
    sum += tex2D(_GrabTexture, screenPos - 1.0 * depth) * 0.15;
    sum += tex2D(_GrabTexture, screenPos) * 0.16;
    sum += tex2D(_GrabTexture, screenPos + 5.0 * depth) * 0.15;
    sum += tex2D(_GrabTexture, screenPos + 4.0 * depth) * 0.12;
    sum += tex2D(_GrabTexture, screenPos + 3.0 * depth) * 0.09;
    sum += tex2D(_GrabTexture, screenPos + 2.0 * depth) * 0.05;
    sum += tex2D(_GrabTexture, screenPos + 1.0 * depth) * 0.025;

    // return sum / 2;
    // ew added and modified code

    return aForwardColor(s, s.baseColor * (sum * _RefractionBrightness));
}

#endif // ALLOY_SHADERS_FORWARD_DISTORT_CGINC