summaryrefslogtreecommitdiffstats
path: root/Studio/Content/Effect Library/LightTable.effect
blob: 91f59131c5abafb4b4582125aa041490bf59ce01 (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<?xml version="1.0" encoding="UTF-8" ?>
<Effect>
	<MetaData>
	<Property name="SurfDist" formalName="Distance to Surface" description="Distance from camera to the paper surface" default="100"/>
        <Property name="BlurDist" formalName="Distance to Full Blur" description="Distance from the paper surface that\ncorresponds to fully blurred" default="100"/>
	<Property name="MaxBlur" formalName="Max Blur Radius" description="Blur radius defined as 'full blur'" min="1" max="100" default="50"/>
	<Property name="OverlayDif" formalName="Diffuse Texture" description="Texture overlay color for the paper surface" type="Texture" clamp="repeat" />
        <Property name="OverlayTrn" formalName="Translucent Texture" description="Texture overlay translucency for the\npaper surface" type="Texture" clamp="repeat" />
        <Property name="OverlayNrm" formalName="Normal Texture" description="Texture overlay normal for the paper\nsurface" type="Texture" clamp="repeat" />
	<Property name="OverlayScale" formalName="Texture Scale" description="Texture overlay scaling factor" type="Float2" default="1 1"/>
	<Property name="OverlayRot" formalName="Texture Rotation" description="Texture overlay rotation angle" default="0" min="0" max="360"/>
	<Property name="OverlayTrans" formalName="Translucency blocking" description="How much translucency through the overlay" default="2.0"/>
	<Property name="LightCol" formalName="Light Color" description="Color of the backlight" type="Color" default="1 1 1"/>
	<Property name="LightBrt" formalName="Light Brightness" description="Brightness of the backlight" default="1.0"/>
        <Property name="LightExp" formalName="Light Exposure" descriptoin="Pre-emptive exposure operation to prevent\nblowout" default="1.0"/>
	
        <Property name="DimplePos" formalName="Dimple Position" description="On-screen position of a depth\n'pressure dimple'" type="Float2" default="0 0"/>
	<Property name="DimpleDepth" formalName="Dimple Pressure" description="How deep the 'pressure dimple' goes" default="0"/>
        <Property name="DimpleSize" formalName="Dimple Size" description="How big the pressure dimple is in\nonscreen pixels" default="1" min="1" max="1000"/>
	
	<!-- Internal buffers plus a few extra options -->
	<Property name="DepthSampler" type="Texture" filter="nearest" clamp="clamp"/>
	<Property name="DistBuffer" type="Texture" filter="nearest" clamp="clamp"/>
	<Property name="BlurBuffer" type="Texture" filter="nearest" clamp="clamp"/>
	<Property name="SrcSampler" type="Texture" filter="linear" clamp="clamp"/>
	<Property name="HalfSampler" type="Texture" filter="linear" clamp="clamp"/>
	<Property name="BlurDebug" formalName="Debug Blur Amt" type="Boolean" default="False"/>
	<Property name="DepthDebug" formalName="Debug Depth Map" type="Boolean" default="False"/>
	</MetaData>
<Shaders>
	<Shared>
#include "depthpass.glsllib"

uniform vec2 CameraClipRange;
	</Shared>
	<Shader name="DOWNSAMPALPHA">
	<FragmentShader>
void frag()
{
	// Simple averaging blur, but makes sure to include the alpha channel from the blur weights
	// Only need to do this once to actually set the alphas in the blur buffers.
	vec4 smp0 = textureOffset(Texture0, TexCoord.xy, ivec2(-1,-1));
	vec4 smp1 = textureOffset(Texture0, TexCoord.xy, ivec2(0,-1));
	vec4 smp2 = textureOffset(Texture0, TexCoord.xy, ivec2(-1,0));
	vec4 smp3 = texture(Texture0, TexCoord.xy);
	
	smp0.w *= textureOffset(DistBuffer, TexCoord.xy, ivec2(-1,-1)).w;
	smp1.w *= textureOffset(DistBuffer, TexCoord.xy, ivec2(0,-1)).w;
	smp2.w *= textureOffset(DistBuffer, TexCoord.xy, ivec2(-1,0)).w;
	smp3.w *= texture(DistBuffer, TexCoord.xy).w;
	
	gl_FragColor = 0.25 * (smp0 + smp1 + smp2 + smp3);
}
	</FragmentShader>	
	</Shader>
	<Shader name="DOWNSAMPLE">
	<FragmentShader>
void frag() // Simple averaging blur.
{
	vec4 smp0 = textureOffset(Texture0, TexCoord.xy, ivec2(-1,-1));
	vec4 smp1 = textureOffset(Texture0, TexCoord.xy, ivec2(0,-1));
	vec4 smp2 = textureOffset(Texture0, TexCoord.xy, ivec2(-1,0));
	vec4 smp3 = texture(Texture0, TexCoord.xy);
	
	gl_FragColor = 0.25 * (smp0 + smp1 + smp2 + smp3);
}
	</FragmentShader>	
	</Shader>	
	<Shader name="FINDBLURAMT">
	<FragmentShader>
void frag()
{
	float planeDepth = SurfDist;
	
	vec2 dvec = gl_FragCoord.xy - vec2(DimplePos);	
	float dimple = dot(dvec, dvec) / (DimpleSize * DimpleSize);
	planeDepth += exp2(-dimple) * DimpleDepth;
	
	vec4 depthSample = texture(DepthSampler, TexCoord);
	float depthVal = getDepthValue( depthSample, CameraClipRange );
	float rawDepth = depthValueToLinearDistance( depthVal, CameraClipRange );
	
	if (DepthDebug)
	{
		gl_FragColor = vec4( (rawDepth - CameraClipRange.x) / (CameraClipRange.y - CameraClipRange.x) );
		return;
	}    
	
	float blurAmt = smoothstep(0.0, 1.0, (rawDepth - planeDepth) / BlurDist);
	gl_FragColor = vec4(blurAmt, blurAmt, blurAmt, 1.0 - blurAmt);
}
	</FragmentShader>
	</Shader>
	<Shader name="BLURX">
	<FragmentShader>
void frag()
{
	vec4 smp = texture(DistBuffer, TexCoord.xy);
	float sigma = clamp(smp.x * MaxBlur * 0.25, 1.0, 25.0);
	int smpCount = int(ceil( sigma ));
	vec4 value = texture(BlurBuffer, TexCoord.xy);
	float wtsum = 1.0;	
	for (int i = 1; i &lt;= smpCount; ++i)
	{
		// Base 2 Gaussian blur
		float wt = float(i) / (sigma * 0.5);
		wt = exp2( -wt*wt );
		value += wt * textureOffset(BlurBuffer, TexCoord.xy, ivec2(-i,0));
		value += wt * textureOffset(BlurBuffer, TexCoord.xy, ivec2(i,0));
		wtsum += wt * 2.0;
	}
	
	gl_FragColor = value / wtsum;
}
	</FragmentShader>
	</Shader>
	<Shader name="BLURY">
	<FragmentShader>
void frag()
{
	vec4 smp = texture(DistBuffer, TexCoord.xy);
	
	float sigma = clamp(smp.x * MaxBlur * 0.25, 1.0, 25.0);
	int smpCount = int(ceil( sigma ));
	vec4 value = texture(BlurBuffer, TexCoord.xy);
	value.w *= smp.w;
	float wtsum = 1.0;	
	for (int i = 1; i &lt;= smpCount; ++i)
	{
		// Base 2 Gaussian blur
		float wt = float(i) / (sigma * 0.5);
		wt = exp2( -wt*wt );
		value += wt * textureOffset(BlurBuffer, TexCoord.xy, ivec2(0,-i));
		value += wt * textureOffset(BlurBuffer, TexCoord.xy, ivec2(0,i));
		wtsum += wt * 2.0;
	}
	
	gl_FragColor = value / wtsum;
}	
	</FragmentShader>
	</Shader>
	<Shader name="COMBINE">
	<FragmentShader>
void frag()
{
	float blurFac = texture(DistBuffer, TexCoord.xy).x;
	float lod = log2(MaxBlur * blurFac);
	float fac0 = clamp(lod, 0.0, 1.0);
	float fac1 = clamp(lod-1.0, 0.0, 1.0);
	
	if (BlurDebug || DepthDebug)
	{
		gl_FragColor = vec4(blurFac);
		return;
	}
	
	vec4 result = texture(SrcSampler, TexCoord.xy);
	vec4 lvl1 = texture(HalfSampler, TexCoord.xy);
	vec4 fullBlr = texture(BlurBuffer, TexCoord.xy);

	// Basically this says that if the blur factor is really small (less than 2 pixels)
	// we favor the full resolution.  If it's between 2 and 4 pixels, we favor the half-res
	// version (which is like one mip level down)...  anything beyond that, we use the bottom
	// level which actually has the proper local blur.
	result = mix(mix(result, lvl1, fac0), fullBlr, fac1);
	
	// Transform the texture (assuming rotation about the center of the texture)
	float cosX = cos(OverlayRot * 0.01745329251);
	float sinX = sin(OverlayRot * 0.01745329251);
	mat3x3 texMat = mat3x3( 1.0, 0.0, -0.5, 0.0, 1.0, -0.5, 0.0, 0.0, 1.0 );
	texMat *= mat3x3( cosX, -sinX, 0.0, sinX, cosX, 0.0, 0.0, 0.0, 1.0);
	texMat *= mat3x3( 1.0, 0.0, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0 );
	texMat *= mat3x3( OverlayScale.x, 0.0, 0.0, 0.0, OverlayScale.y, 0.0, 0.0, 0.0, 1.0);
	vec3 texForm = texMat * vec3(TexCoord.xy, 1.0);
	vec4 overSmp = texture(OverlayDif, texForm.xy);
	float overTrn = 1.0 - texture(OverlayTrn, texForm.xy).x;
	float nDotL = (texture(OverlayNrm, texForm.xy).z - 0.5) * 2.0;
	
	// Want to see how much of a "difference" there is between the light
	// color and the object color.
	// We are basically acting as if the objects on the layer are occluders
	// so the alpha as a result of blurring is like a transparency.
	// The behavior is that the brighter the light is, the more of a "gap" there is
	vec3 backlight = LightCol.rgb * LightBrt;
	
	// Assume that the color map I'm using already tells us what N.dot.L is (for now)
	float translucency = exp2( -overTrn * OverlayTrans );
	
//	vec3 colorDelta = backlight - result.rgb;
//	float deltaC = dot(colorDelta, colorDelta) * (1.0 - result.w) * LightBrt / LightExp;
//	result.rgb -= result.rgb * smoothstep(deltaC, 1.0, result.w);

//	gl_FragColor = vec4( result.rgb, 1.0 );
//	return;
	
	backlight *= mix(vec3(1.0), result.rgb, result.w);
	backlight *= nDotL * translucency * overSmp.rgb;
	
	backlight = vec3(1.0) - exp2(-6.28*backlight/LightExp);
	
	gl_FragColor = vec4(backlight, 1.0);
}
	</FragmentShader>
	</Shader>
</Shaders>
<Passes>
	<Buffer name="halfBuffer" type="ubyte" format="rgba" filter="linear" wrap="clamp" size=".5" lifetime="frame"/>
	<Buffer name="qtrBuffer" type="ubyte" format="rgba" filter="linear" wrap="clamp" size=".25" lifetime="frame"/>
	<Buffer name="tempqtr" type="ubyte" format="rgba" filter="linear" wrap="clamp" size=".25" lifetime="frame"/>
	<Buffer name="blurweights" type="ubyte" format="rgba" filter="linear" wrap="clamp" size="1" lifetime="frame"/>
	<Pass shader="FINDBLURAMT" output="blurweights">
		<DepthInput param="DepthSampler"/>
	</Pass>
	<Pass shader="DOWNSAMPALPHA" input="[source]" output="halfBuffer">
		<BufferInput param="DistBuffer" value="blurweights" />
	</Pass>
	<Pass shader="DOWNSAMPLE" input="halfBuffer" output="qtrBuffer"/>
	<Pass shader="BLURX" output="tempqtr">
		<BufferInput param="BlurBuffer" value="qtrBuffer" />
		<BufferInput param="DistBuffer" value="blurweights" />
	</Pass>
	<Pass shader="BLURY" output="qtrBuffer">
		<BufferInput param="BlurBuffer" value="tempqtr" />
		<BufferInput param="DistBuffer" value="blurweights" />
	</Pass>
	<Pass shader="COMBINE">
		<BufferInput param="SrcSampler" value="[source]" />
		<BufferInput param="HalfSampler" value="halfBuffer" />
		<BufferInput param="BlurBuffer" value="qtrBuffer" />
		<BufferInput param="DistBuffer" value="blurweights" />
	</Pass>
</Passes>
</Effect>