2016-01-28 00:58:00 +01:00
|
|
|
#version 450
|
|
|
|
|
2016-01-03 19:41:00 +01:00
|
|
|
#ifdef GL_ES
|
|
|
|
precision mediump float;
|
|
|
|
#endif
|
|
|
|
|
2016-07-10 00:51:39 +02:00
|
|
|
#include "../compiled.glsl"
|
2016-10-17 17:39:40 +02:00
|
|
|
#include "../std/brdf.glsl"
|
2016-11-05 20:57:04 +01:00
|
|
|
#include "../std/math.glsl"
|
2017-02-22 15:50:19 +01:00
|
|
|
// #ifdef _VoxelGI
|
|
|
|
// #include "../std/conetrace.glsl"
|
|
|
|
// #endif
|
2017-03-12 17:29:22 +01:00
|
|
|
#ifdef _PolyLight
|
|
|
|
#include "../std/ltc.glsl"
|
|
|
|
#endif
|
2016-10-17 17:39:40 +02:00
|
|
|
#ifndef _NoShadows
|
|
|
|
#ifdef _PCSS
|
|
|
|
#include "../std/shadows_pcss.glsl"
|
|
|
|
#else
|
|
|
|
#include "../std/shadows.glsl"
|
|
|
|
#endif
|
|
|
|
#endif
|
2017-06-06 18:29:33 +02:00
|
|
|
#ifdef _DFRS
|
|
|
|
#include "../std/sdf.glsl"
|
|
|
|
#endif
|
2017-05-23 15:01:56 +02:00
|
|
|
#ifdef _SSS
|
|
|
|
#include "../std/sss.glsl"
|
|
|
|
#endif
|
2017-07-05 23:26:13 +02:00
|
|
|
#ifdef _SSRS
|
|
|
|
#include "../std/ssrs.glsl"
|
|
|
|
#endif
|
2016-10-17 17:39:40 +02:00
|
|
|
#include "../std/gbuffer.glsl"
|
2016-07-10 00:51:39 +02:00
|
|
|
|
2017-02-22 15:50:19 +01:00
|
|
|
// #ifdef _VoxelGI
|
|
|
|
//-!uniform sampler3D voxels;
|
|
|
|
// #endif
|
|
|
|
|
2016-05-13 00:08:11 +02:00
|
|
|
uniform sampler2D gbufferD;
|
2016-03-20 18:44:11 +01:00
|
|
|
uniform sampler2D gbuffer0;
|
2016-06-07 09:38:49 +02:00
|
|
|
uniform sampler2D gbuffer1;
|
2016-01-03 19:41:00 +01:00
|
|
|
|
2017-03-17 18:34:03 +01:00
|
|
|
// TODO: separate shaders
|
2016-07-17 20:29:53 +02:00
|
|
|
#ifndef _NoShadows
|
2016-10-17 17:39:40 +02:00
|
|
|
//!uniform sampler2D shadowMap;
|
2017-03-17 18:34:03 +01:00
|
|
|
//!uniform samplerCube shadowMapCube;
|
2016-09-08 14:08:31 +02:00
|
|
|
#ifdef _PCSS
|
2016-10-17 17:39:40 +02:00
|
|
|
//!uniform sampler2D snoise;
|
|
|
|
//!uniform float lampSizeUV;
|
2016-09-08 14:08:31 +02:00
|
|
|
#endif
|
2016-07-17 20:29:53 +02:00
|
|
|
#endif
|
2017-06-06 18:29:33 +02:00
|
|
|
#ifdef _DFRS
|
|
|
|
//!uniform sampler2D sdftex;
|
|
|
|
#endif
|
2016-06-07 09:38:49 +02:00
|
|
|
|
2016-08-09 23:51:40 +02:00
|
|
|
uniform mat4 invVP;
|
2016-08-25 00:26:01 +02:00
|
|
|
uniform mat4 LWVP;
|
2017-03-12 17:29:22 +01:00
|
|
|
uniform vec3 lightColor;
|
2016-06-26 12:11:51 +02:00
|
|
|
uniform vec3 lightDir;
|
2017-03-12 17:29:22 +01:00
|
|
|
uniform vec3 lightPos;
|
2017-03-18 18:44:21 +01:00
|
|
|
uniform vec2 lightPlane;
|
2016-06-26 12:11:51 +02:00
|
|
|
uniform int lightType;
|
2017-03-11 01:50:47 +01:00
|
|
|
uniform int lightShadow;
|
2016-08-12 13:48:04 +02:00
|
|
|
uniform float shadowsBias;
|
2017-03-11 01:50:47 +01:00
|
|
|
uniform vec2 spotlightData;
|
2016-11-08 15:14:56 +01:00
|
|
|
#ifdef _PolyLight
|
2017-03-11 01:50:47 +01:00
|
|
|
uniform vec3 lampArea0;
|
|
|
|
uniform vec3 lampArea1;
|
|
|
|
uniform vec3 lampArea2;
|
|
|
|
uniform vec3 lampArea3;
|
|
|
|
uniform sampler2D sltcMat;
|
|
|
|
uniform sampler2D sltcMag;
|
2016-11-08 15:14:56 +01:00
|
|
|
#endif
|
2016-03-20 18:44:11 +01:00
|
|
|
uniform vec3 eye;
|
2017-01-17 14:48:47 +01:00
|
|
|
#ifdef _SSRS
|
2017-07-05 23:26:13 +02:00
|
|
|
//!uniform mat4 VP;
|
2017-01-17 14:48:47 +01:00
|
|
|
#endif
|
2016-05-10 12:11:31 +02:00
|
|
|
|
2016-11-06 15:07:13 +01:00
|
|
|
#ifdef _LampColTex
|
2017-03-11 01:50:47 +01:00
|
|
|
uniform sampler2D texlampcolor;
|
2016-11-05 20:57:04 +01:00
|
|
|
#endif
|
|
|
|
|
2016-08-25 00:26:01 +02:00
|
|
|
in vec4 wvpposition;
|
2016-10-12 17:52:27 +02:00
|
|
|
out vec4 fragColor;
|
2016-06-26 12:11:51 +02:00
|
|
|
|
2016-07-17 20:29:53 +02:00
|
|
|
#ifndef _NoShadows
|
2017-03-02 10:15:22 +01:00
|
|
|
float shadowTest(const vec3 lPos) {
|
2016-11-07 16:11:35 +01:00
|
|
|
|
2016-11-07 22:10:11 +01:00
|
|
|
#ifdef _Clampstc
|
2016-11-07 16:11:35 +01:00
|
|
|
// Filtering out of bounds, remove
|
2016-11-07 17:01:21 +01:00
|
|
|
// const vec2 border = vec2(1.0 / shadowmapSize[0], 1.0 / shadowmapSize[1]) * 2.0;
|
|
|
|
// lPos.xy = clamp(lPos.xy, border[0], 1.0 - border[1]);
|
2016-11-07 16:11:35 +01:00
|
|
|
if (lPos.x < 0.0) return 1.0;
|
|
|
|
if (lPos.y < 0.0) return 1.0;
|
|
|
|
if (lPos.x > 1.0) return 1.0;
|
|
|
|
if (lPos.y > 1.0) return 1.0;
|
2016-11-07 22:10:11 +01:00
|
|
|
#endif
|
2016-11-07 16:11:35 +01:00
|
|
|
|
2016-09-08 14:08:31 +02:00
|
|
|
#ifdef _PCSS
|
2016-10-15 12:17:33 +02:00
|
|
|
return PCSS(lPos.xy, lPos.z - shadowsBias);
|
2016-09-08 14:08:31 +02:00
|
|
|
#else
|
2016-10-15 12:17:33 +02:00
|
|
|
return PCF(lPos.xy, lPos.z - shadowsBias);
|
2016-09-08 14:08:31 +02:00
|
|
|
#endif
|
2016-03-22 23:35:54 +01:00
|
|
|
}
|
2017-03-18 18:44:21 +01:00
|
|
|
float shadowTestCube(const vec3 lp, const vec3 l) {
|
|
|
|
return PCFCube(lp, -l, shadowsBias, lightPlane);
|
2017-03-17 18:34:03 +01:00
|
|
|
}
|
2016-07-17 20:29:53 +02:00
|
|
|
#endif
|
|
|
|
|
2016-01-24 22:32:51 +01:00
|
|
|
void main() {
|
2017-03-03 14:36:01 +01:00
|
|
|
vec2 texCoord = wvpposition.xy / wvpposition.w;
|
|
|
|
texCoord = texCoord * 0.5 + 0.5;
|
2017-06-23 15:47:51 +02:00
|
|
|
#ifdef _InvY
|
|
|
|
texCoord.y = 1.0 - texCoord.y;
|
|
|
|
#endif
|
2016-08-09 23:51:40 +02:00
|
|
|
|
2017-03-11 01:50:47 +01:00
|
|
|
vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, metallic/roughness, occlusion
|
|
|
|
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb,
|
2017-06-23 15:47:51 +02:00
|
|
|
// #ifdef _InvY // D3D
|
2017-03-28 14:30:51 +02:00
|
|
|
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0; // 0 - 1 => -1 - 1
|
2017-06-23 15:47:51 +02:00
|
|
|
// #else
|
2017-03-11 01:50:47 +01:00
|
|
|
// TODO: store_depth
|
2017-03-28 14:30:51 +02:00
|
|
|
float depth = (1.0 - g0.a) * 2.0 - 1.0;
|
2017-06-23 15:47:51 +02:00
|
|
|
// #endif
|
2016-03-20 18:44:11 +01:00
|
|
|
|
2016-06-30 13:22:05 +02:00
|
|
|
vec3 n;
|
2016-08-07 23:12:14 +02:00
|
|
|
n.z = 1.0 - abs(g0.x) - abs(g0.y);
|
|
|
|
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
2016-06-30 13:22:05 +02:00
|
|
|
n = normalize(n);
|
2016-04-16 13:19:03 +02:00
|
|
|
|
2016-10-17 17:39:40 +02:00
|
|
|
vec3 p = getPos2(invVP, depth, texCoord);
|
2016-08-29 09:56:34 +02:00
|
|
|
vec2 metrough = unpackFloat(g0.b);
|
2016-03-20 18:44:11 +01:00
|
|
|
|
2016-10-25 16:15:07 +02:00
|
|
|
vec3 v = normalize(eye - p);
|
2016-09-08 14:08:31 +02:00
|
|
|
float dotNV = dot(n, v);
|
2016-06-30 13:22:05 +02:00
|
|
|
|
2016-08-29 09:56:34 +02:00
|
|
|
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
|
|
|
|
vec3 f0 = surfaceF0(g1.rgb, metrough.x);
|
2016-06-30 13:22:05 +02:00
|
|
|
|
2017-03-18 18:44:21 +01:00
|
|
|
vec3 lp = lightPos - p;
|
|
|
|
vec3 l = normalize(lp);
|
2017-03-17 18:34:03 +01:00
|
|
|
|
2017-02-22 15:50:19 +01:00
|
|
|
float visibility = 1.0;
|
|
|
|
#ifndef _NoShadows
|
2017-03-17 18:34:03 +01:00
|
|
|
// TODO: merge..
|
2017-03-11 01:50:47 +01:00
|
|
|
if (lightShadow == 1) {
|
|
|
|
vec4 lampPos = LWVP * vec4(p, 1.0);
|
2017-03-17 18:34:03 +01:00
|
|
|
if (lampPos.w > 0.0) visibility = shadowTest(lampPos.xyz / lampPos.w);
|
|
|
|
}
|
|
|
|
else if (lightShadow == 2) { // Cube
|
2017-03-18 18:44:21 +01:00
|
|
|
visibility = shadowTestCube(lp, l);
|
2017-02-22 15:50:19 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-06-06 18:29:33 +02:00
|
|
|
#ifdef _DFRS
|
|
|
|
|
|
|
|
const float distmax = 40.0;
|
|
|
|
const float eps = 0.02;
|
|
|
|
const int maxSteps = 30;
|
|
|
|
float dist = 0.1;
|
|
|
|
|
|
|
|
// float test = mapsdf2(p);
|
|
|
|
// if (test < 0.1) {
|
|
|
|
// fragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
float lastd = distmax;
|
|
|
|
for (int i = 0; i < maxSteps; i++) {
|
|
|
|
vec3 rd = l * dist;
|
|
|
|
float d = sdBox(p + rd, vec3(1.0));
|
|
|
|
|
|
|
|
// Going out of volume box
|
|
|
|
// if (d > 0.0 && lastd < d) {
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// lastd = d;
|
|
|
|
|
|
|
|
if (d <= 0.0) { // In volume
|
|
|
|
d = mapsdf(p, rd);
|
|
|
|
|
|
|
|
if (d < eps) {
|
|
|
|
visibility = 0.0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { // To volume
|
|
|
|
// d += mapsdf(p, rd);
|
|
|
|
|
|
|
|
vec3 sampleBorder = clamp(p + rd, vec3(-1.0), vec3(1.0));
|
|
|
|
float phi = mapsdf2(sampleBorder, rd);
|
|
|
|
float dd = 0.1;
|
|
|
|
float grad_x = mapsdf2(sampleBorder + vec3(dd, 0, 0), rd) - phi;
|
|
|
|
float grad_y = mapsdf2(sampleBorder + vec3(0, dd, 0), rd) - phi;
|
|
|
|
vec3 grad = vec3(grad_x, grad_y, 1.0);
|
|
|
|
vec3 endpoint = sampleBorder - normalize(grad) * phi;
|
|
|
|
d = distance(endpoint, p + rd);
|
|
|
|
|
|
|
|
// float dd = 0.1;
|
|
|
|
// vec3 p0 = clamp(p, vec3(-1.0), vec3(1.0));
|
|
|
|
// vec3 p1 = clamp(p, vec3(-0.99), vec3(0.99));
|
|
|
|
// float r0 = mapsdf2(p0, rd);
|
|
|
|
// float r1 = mapsdf2(p1, rd);
|
|
|
|
// float h0 = 0.5 + (r0 * r0 - r1 * r1) / (2.0 * dd * dd);
|
|
|
|
// float ri = sqrt(abs(r0 * r0 - h0 * h0 * dd * dd));
|
|
|
|
// vec3 p2 = p0 + (p1 - p0) * h0;
|
|
|
|
// vec3 p3 = p2 + vec3(p1.z - p0.z, p1.y - p0.y, p1.x - p0.x) * ri;
|
|
|
|
// d = length((p + rd) - p3);
|
|
|
|
}
|
|
|
|
|
|
|
|
const float k = 2.0;
|
|
|
|
visibility = min(visibility, (k * d / dist));
|
|
|
|
dist += d;
|
|
|
|
|
|
|
|
if (dist > distmax) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-06-30 13:22:05 +02:00
|
|
|
// Per-light
|
2017-03-15 15:49:13 +01:00
|
|
|
#ifndef _NoLampFalloff
|
|
|
|
visibility *= attenuate(distance(p, lightPos));
|
|
|
|
#endif
|
|
|
|
if (lightType == 2) { // Spot
|
2017-03-11 01:50:47 +01:00
|
|
|
float spotEffect = dot(lightDir, l);
|
|
|
|
// x - cutoff, y - cutoff - exponent
|
|
|
|
if (spotEffect < spotlightData.x) {
|
|
|
|
visibility *= smoothstep(spotlightData.y, spotlightData.x, spotEffect);
|
|
|
|
}
|
|
|
|
}
|
2016-06-30 13:22:05 +02:00
|
|
|
|
|
|
|
vec3 h = normalize(v + l);
|
2016-09-08 14:08:31 +02:00
|
|
|
float dotNH = dot(n, h);
|
|
|
|
float dotVH = dot(v, h);
|
|
|
|
float dotNL = dot(n, l);
|
|
|
|
// float dotLV = dot(l, v);
|
|
|
|
// float dotLH = dot(l, h);
|
2016-06-30 13:22:05 +02:00
|
|
|
|
2016-11-08 15:14:56 +01:00
|
|
|
#ifdef _PolyLight
|
2016-11-06 15:07:13 +01:00
|
|
|
if (lightType == 3) { // Area
|
|
|
|
float theta = acos(dotNV);
|
|
|
|
vec2 tuv = vec2(metrough.y, theta / (0.5 * PI));
|
|
|
|
tuv = tuv * LUT_SCALE + LUT_BIAS;
|
2017-03-03 14:36:01 +01:00
|
|
|
vec4 t = texture(sltcMat, tuv);
|
2016-11-08 15:14:56 +01:00
|
|
|
mat3 invM = mat3(
|
2016-11-06 15:07:13 +01:00
|
|
|
vec3(1.0, 0.0, t.y),
|
|
|
|
vec3(0.0, t.z, 0.0),
|
|
|
|
vec3(t.w, 0.0, t.x));
|
|
|
|
|
2017-03-03 14:36:01 +01:00
|
|
|
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lampArea0, lampArea1, lampArea2, lampArea3);
|
2016-11-06 15:07:13 +01:00
|
|
|
ltcspec *= texture(sltcMag, tuv).a;
|
2017-03-03 14:36:01 +01:00
|
|
|
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lampArea0, lampArea1, lampArea2, lampArea3);
|
2017-06-25 23:16:49 +02:00
|
|
|
#ifdef _Cycles
|
|
|
|
float facdif = min((1.0 - metrough.x) * 3.0, 1.0);
|
|
|
|
float facspec = min(metrough.x * 3.0, 1.0);
|
|
|
|
fragColor.rgb = albedo * ltcdiff * facdif + ltcspec * facspec;
|
|
|
|
#else
|
|
|
|
fragColor.rgb = albedo * ltcdiff + ltcspec;
|
|
|
|
#endif
|
2016-11-06 15:07:13 +01:00
|
|
|
}
|
|
|
|
else {
|
2016-11-08 15:14:56 +01:00
|
|
|
#endif
|
2016-11-06 15:07:13 +01:00
|
|
|
|
2017-05-06 00:22:15 +02:00
|
|
|
#ifdef _Cycles
|
|
|
|
// Diff/glossy
|
|
|
|
float facdif = min((1.0 - metrough.x) * 3.0, 1.0);
|
|
|
|
float facspec = min(metrough.x * 3.0, 1.0);
|
|
|
|
float rough = pow(metrough.y, 0.5);
|
|
|
|
fragColor.rgb = orenNayarDiffuseBRDF(albedo, rough, dotNV, dotNL, dotVH) * max(1.0 - metrough.y, 0.88) * facdif + specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * 3.5 * facspec;
|
|
|
|
// Metallic
|
|
|
|
// fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
|
2016-09-08 14:08:31 +02:00
|
|
|
#else
|
2017-03-11 01:50:47 +01:00
|
|
|
fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
|
2016-09-08 14:08:31 +02:00
|
|
|
#endif
|
2016-08-29 09:56:34 +02:00
|
|
|
|
2016-11-08 15:14:56 +01:00
|
|
|
#ifdef _PolyLight
|
2016-06-30 13:22:05 +02:00
|
|
|
}
|
2016-11-08 15:14:56 +01:00
|
|
|
#endif
|
2016-06-30 13:22:05 +02:00
|
|
|
|
|
|
|
// Aniso spec
|
2016-10-17 17:39:40 +02:00
|
|
|
// #ifdef _Aniso
|
2016-08-29 09:56:34 +02:00
|
|
|
// float shinyParallel = metrough.y;
|
2016-06-30 13:22:05 +02:00
|
|
|
// float shinyPerpendicular = 0.08;
|
|
|
|
// vec3 fiberDirection = vec3(0.0, 1.0, 8.0);
|
2017-03-11 01:50:47 +01:00
|
|
|
// fragColor.rgb = diffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH, dotLV) + wardSpecular(n, h, dotNL, dotNV, dotNH, fiberDirection, shinyParallel, shinyPerpendicular);
|
2016-10-17 17:39:40 +02:00
|
|
|
// #endif
|
2016-11-05 20:57:04 +01:00
|
|
|
|
2017-03-11 01:50:47 +01:00
|
|
|
fragColor.rgb *= lightColor;
|
2016-11-06 15:07:13 +01:00
|
|
|
|
|
|
|
#ifdef _LampColTex
|
2017-03-11 01:50:47 +01:00
|
|
|
// fragColor.rgb *= texture(texlampcolor, envMapEquirect(l)).rgb;
|
|
|
|
fragColor.rgb *= pow(texture(texlampcolor, l.xy).rgb, vec3(2.2));
|
2016-11-05 20:57:04 +01:00
|
|
|
#endif
|
2016-06-30 13:22:05 +02:00
|
|
|
|
2016-06-26 12:11:51 +02:00
|
|
|
#ifdef _SSS
|
2017-05-23 15:01:56 +02:00
|
|
|
if (floor(g1.a) == 2) {
|
|
|
|
if (lightShadow == 1) fragColor.rgb += fragColor.rgb * SSSSTransmittance(1.0, 0.005, p, n, l, shadowMap, LWVP);
|
|
|
|
else fragColor.rgb += fragColor.rgb * SSSSTransmittanceCube(1.0, 0.005, p, n, l, shadowMapCube, LWVP);
|
2016-05-01 00:56:40 +02:00
|
|
|
}
|
2016-06-26 12:11:51 +02:00
|
|
|
#endif
|
2016-03-20 18:44:11 +01:00
|
|
|
|
2017-01-17 14:48:47 +01:00
|
|
|
#ifdef _SSRS
|
2017-07-05 23:26:13 +02:00
|
|
|
float tvis = traceShadow(-l, p, gbuffer0, invVP, eye);
|
2017-01-17 14:48:47 +01:00
|
|
|
// vec2 coords = getProjectedCoord(hitCoord);
|
|
|
|
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
|
|
|
|
// float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);
|
|
|
|
// tvis *= screenEdgeFactor;
|
|
|
|
visibility *= tvis;
|
|
|
|
#endif
|
|
|
|
|
2017-02-22 15:50:19 +01:00
|
|
|
// #ifdef _VoxelGI
|
|
|
|
// if (dotNL > 0.0) visibility *= traceShadowCone(p / voxelgiResolution.x, l, distance(p, lightPos) / voxelgiResolution.x, n);
|
|
|
|
// #endif
|
|
|
|
|
2017-03-11 01:50:47 +01:00
|
|
|
fragColor.rgb *= visibility;
|
2016-01-03 19:41:00 +01:00
|
|
|
}
|