summaryrefslogtreecommitdiffstats
path: root/res/effectlib/sampleArea.glsllib
diff options
context:
space:
mode:
Diffstat (limited to 'res/effectlib/sampleArea.glsllib')
-rw-r--r--res/effectlib/sampleArea.glsllib106
1 files changed, 106 insertions, 0 deletions
diff --git a/res/effectlib/sampleArea.glsllib b/res/effectlib/sampleArea.glsllib
new file mode 100644
index 0000000..ca04988
--- /dev/null
+++ b/res/effectlib/sampleArea.glsllib
@@ -0,0 +1,106 @@
+#ifndef SAMPLE_AREA_GLSLLIB
+#define SAMPLE_AREA_GLSLLIB 1
+
+#include "funcareaLightVars.glsllib"
+#include "funccalculateDiffuseAreaOld.glsllib"
+#include "funcsampleAreaGlossyDefault.glsllib"
+
+float rand1d(vec2 n)
+{
+ return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
+}
+
+vec3 quatRotate( vec4 q, vec3 v )
+{
+ return v + 2.0 * cross( cross( v, q.xyz ) + q.w * v, q.xyz );
+}
+
+vec3 lightUVToRay( in vec3 pos, in vec3 lightPos, in mat3 lightFrame, in float width, in float height, in vec2 uv )
+{
+ width *= dot(lightFrame[0], lightFrame[0]);
+ height *= dot(lightFrame[1], lightFrame[1]);
+
+ vec3 hitPos = lightPos + (uv.x - 0.5) * width * lightFrame[0] + (uv.y - 0.5) * height * lightFrame[1];
+ return normalize(hitPos - pos);
+}
+
+// This is usable only for planar rectangular lights. Will need to break this down into different paths for different shapes.
+float getUVHitBounds( in vec3 pos, in mat3 lightFrame, in vec3 lightPos, in float width, in float height, in vec3 V0, in vec3 V1, in vec3 V2, in vec3 V3, out vec2 UVmin, out vec2 UVmax )
+{
+ float d0 = dot( lightPos, lightFrame[2] );
+ float d1 = dot( pos, lightFrame[2] );
+
+ // If the point is behind the light, it can't be illuminated.
+ if (d0 < d1)
+ {
+ UVmin = vec2( -1.0, -1.0 );
+ UVmax = vec2( -1.0, -1.0 );
+ return 0.0;
+ }
+
+ // Compute where all the rays of the light beam hit the light plane
+ float t[4];
+ vec3 v[4];
+
+ v[0] = V0; v[1] = V1; v[2] = V2; v[3] = V3;
+ t[0] = (d0 - d1) / dot(V0, lightFrame[2]);
+ t[1] = (d0 - d1) / dot(V1, lightFrame[2]);
+ t[2] = (d0 - d1) / dot(V2, lightFrame[2]);
+ t[3] = (d0 - d1) / dot(V3, lightFrame[2]);
+
+ UVmin = vec2(1e6, 1e6);
+ UVmax = vec2(-1e6, -1e6);
+
+ // If any of them are "negative" relative to the ray direction
+ // We don't want to consider them.
+ bool weight[4];
+ float wtsum = 0.0;
+ weight[0] = (t[0] > 0.0);
+ weight[1] = (t[1] > 0.0);
+ weight[2] = (t[2] > 0.0);
+ weight[3] = (t[3] > 0.0);
+
+ width *= dot(lightFrame[0], lightFrame[0]);
+ height *= dot(lightFrame[1], lightFrame[1]);
+
+ for (int i = 0; i < 4; ++i)
+ {
+ vec3 curPos = pos + v[i] * t[i];
+ curPos -= lightPos;
+ vec2 curUV = vec2( dot(curPos, lightFrame[0]) / width, dot(curPos, lightFrame[1]) / height ) + vec2(0.5);
+
+ UVmin = min(UVmin, curUV); UVmax = max(UVmax, curUV);
+ wtsum += weight[i] ? 0.25 : 0.0;
+ }
+
+ return wtsum;
+}
+
+vec4 sampleAreaDiffuse( in mat3 tanFrame, in vec3 pos, in int lightIdx )
+{
+ float intensity = 0.0;
+ vec3 finalDir;
+ intensity = calculateDiffuseAreaOld( -arealights[lightIdx].direction.xyz, arealights[lightIdx].position.xyz,
+ arealights[lightIdx].up, arealights[lightIdx].right, pos, finalDir );
+ intensity *= clamp( dot(finalDir, tanFrame[2]), 0.0, 1.0 );
+ return vec4( intensity );
+}
+
+vec4 sampleAreaDiffuseTransmissive( in mat3 tanFrame, in vec3 pos, in int lightIdx, in vec4 transmissiveColor, in float translucentFalloff, float lightWrap )
+{
+ float intensity = 0.0;
+ vec3 finalDir;
+ intensity = calculateDiffuseAreaOld( -arealights[lightIdx].direction.xyz, arealights[lightIdx].position.xyz,
+ arealights[lightIdx].up, arealights[lightIdx].right, pos, finalDir );
+ intensity *= clamp( dot(finalDir, -tanFrame[2]), 0.0, 1.0 );
+
+ float l = 0.2126f * transmissiveColor.r + 0.7152f * transmissiveColor.g + 0.0722f * transmissiveColor.b;
+
+ float I = max( 0.0, ((dot(finalDir, -tanFrame[2]) + lightWrap)/ (1.0 + lightWrap)) );
+ float translucent_thickness = l * l;
+ float translucent_thickness_exp = exp( translucent_thickness * translucentFalloff) * I;
+
+ return vec4( translucent_thickness_exp * intensity );
+}
+
+#endif