Shaders overhaul.
This commit is contained in:
parent
73e67e3c1e
commit
9edb0b0fa9
|
@ -13,7 +13,8 @@
|
|||
"texture_params": [],
|
||||
"vertex_shader": "blend_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "blend_pass.frag.glsl"
|
||||
"fragment_shader": "blend_pass.frag.glsl",
|
||||
"fragment_shader_path": "../include/pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -5,14 +5,13 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
//const float bloomTreshold = 3.0;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
//const float bloomTreshold = 3.0;
|
||||
|
||||
void main() {
|
||||
vec4 col = texture(tex, texCoord);
|
||||
float brightness = dot(col.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
@ -20,6 +19,5 @@ void main() {
|
|||
fragColor.rgb = vec3(col.rgb);
|
||||
return;
|
||||
}
|
||||
|
||||
fragColor.rgb = vec3(0.0);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// unpackFloat()
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0; // Roughness
|
||||
|
@ -16,10 +18,6 @@ uniform vec2 screenSize;
|
|||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 unpackFloat(float f) {
|
||||
return vec2(floor(f) / 1000.0, fract(f));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 tc = texCoord * ssrTextureScale;
|
||||
float roughness = unpackFloat(texture(gbuffer0, texCoord).b).y;
|
||||
|
|
|
@ -6,6 +6,8 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// getNor()
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbuffer0;
|
||||
|
@ -18,22 +20,9 @@ out vec4 fragColor;
|
|||
|
||||
const float blurWeights[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
const float discardThreshold = 0.95;
|
||||
// const float discardThreshold = 0.70;
|
||||
|
||||
vec3 result = vec3(0.0);
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
vec3 getNor(vec2 enc) {
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
float doBlur(float blurWeight, int pos, vec3 nor, vec2 texCoord) {
|
||||
vec2 texstep = dir / screenSize;
|
||||
|
||||
|
@ -54,20 +43,6 @@ float doBlur(float blurWeight, int pos, vec3 nor, vec2 texCoord) {
|
|||
|
||||
void main() {
|
||||
vec2 tc = texCoord * ssaoTextureScale;
|
||||
|
||||
// vec2 step = dir / screenSize;
|
||||
// vec3 result = texture(tex, tc + (step * 4.5)).rgb;
|
||||
// result += texture(tex, tc + (step * 3.5)).rgb;
|
||||
// result += texture(tex, tc + (step * 2.5)).rgb;
|
||||
// result += texture(tex, tc + step * 1.5).rgb;
|
||||
// result += texture(tex, tc).rgb;
|
||||
// result += texture(tex, tc - step * 1.5).rgb;
|
||||
// result += texture(tex, tc - (step * 2.5)).rgb;
|
||||
// result += texture(tex, tc - (step * 3.5)).rgb;
|
||||
// result += texture(tex, tc - (step * 4.5)).rgb;
|
||||
// result /= vec3(9.0);
|
||||
// fragColor.rgb = vec3(result);
|
||||
|
||||
vec3 nor = getNor(texture(gbuffer0, texCoord).rg);
|
||||
|
||||
// for (int i = 0; i < 9; i++) {
|
||||
|
@ -87,6 +62,5 @@ void main() {
|
|||
// }
|
||||
|
||||
result /= weight;
|
||||
// fragColor = vec4(result.rgb, 1.0);
|
||||
fragColor = vec4(result.rrr, 1.0); // SSAO only
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
//const float bloomStrength = 0.4;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 dir;
|
||||
|
@ -18,10 +19,8 @@ out vec4 fragColor;
|
|||
// const float weight[8] = float[] (0.197448, 0.174697, 0.120999, 0.065602, 0.02784, 0.009246, 0.002403, 0.000489);
|
||||
const float weight[10] = float[] (0.132572, 0.125472, 0.106373, 0.08078, 0.05495, 0.033482, 0.018275, 0.008934, 0.003912, 0.001535);
|
||||
|
||||
//const float bloomStrength = 0.4;
|
||||
|
||||
void main() {
|
||||
vec2 step = dir / screenSize;// * 3.0;
|
||||
vec2 step = dir / screenSize;
|
||||
|
||||
vec3 result = texture(tex, texCoord).rgb * weight[0];
|
||||
result += texture(tex, texCoord + step * 1.5).rgb * weight[1] * bloomStrength;
|
||||
|
|
|
@ -10,22 +10,8 @@ uniform sampler2D tex2;
|
|||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
const float exposure = 1.0;
|
||||
const float gamma = 2.2;
|
||||
|
||||
void main() {
|
||||
vec3 col = texture(tex, texCoord).rgb;
|
||||
vec3 col2 = texture(tex2, texCoord).rgb;
|
||||
|
||||
// Additive blending
|
||||
col += col2;
|
||||
|
||||
// Tone mapping
|
||||
// vec3 result = vec3(1.0) - exp(-col * exposure);
|
||||
|
||||
// Gamma correction
|
||||
// result = pow(result, vec3(1.0 / gamma));
|
||||
// fragColor.rgb = result;
|
||||
|
||||
fragColor.rgb = col;
|
||||
fragColor.rgb = col + col2;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/tonemap.glsl"
|
||||
// tonemapUncharted2()
|
||||
// tonemapFilmic()
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbufferD;
|
||||
|
@ -44,33 +47,21 @@ const float fstop = 20; // f-stop value
|
|||
|
||||
const float aspectRatio = 800.0 / 600.0;
|
||||
|
||||
#ifdef _CompoPos
|
||||
vec3 getPos(float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _CompoFog
|
||||
// const vec3 compoFogColor = vec3(0.5, 0.6, 0.7);
|
||||
// const float compoFogAmountA = 1.0; // b = 0.01
|
||||
// const float compoFogAmountB = 1.0; // c = 0.1
|
||||
// vec3 applyFog(vec3 rgb, // original color of the pixel
|
||||
// float distance, // camera to point distance
|
||||
// vec3 rayOri, // camera position
|
||||
// vec3 rayDir) { // camera to point vector
|
||||
// float fogAmount = compoFogAmountB * exp(-rayOri.y * compoFogAmountA) * (1.0 - exp(-distance * rayDir.y * compoFogAmountA)) / rayDir.y;
|
||||
// return mix(rgb, compoFogColor, fogAmount);
|
||||
// float distance, // camera to point distance
|
||||
// vec3 rayOri, // camera position
|
||||
// vec3 rayDir) { // camera to point vector
|
||||
// float fogAmount = compoFogAmountB * exp(-rayOri.y * compoFogAmountA) * (1.0 - exp(-distance * rayDir.y * compoFogAmountA)) / rayDir.y;
|
||||
// return mix(rgb, compoFogColor, fogAmount);
|
||||
// }
|
||||
vec3 applyFog(vec3 rgb, float distance) {
|
||||
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
|
||||
float fogAmount = 1.0 - exp(-distance * 0.0055);
|
||||
return mix(rgb, compoFogColor, fogAmount);
|
||||
// float fogAmount = 1.0 - exp(-distance * compoFogAmountA);
|
||||
float fogAmount = 1.0 - exp(-distance * 0.0055);
|
||||
return mix(rgb, compoFogColor, fogAmount);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -79,8 +70,8 @@ float vignette() {
|
|||
// dist = smoothstep(vignout + (fstop / vignfade), vignin + (fstop / vignfade), dist);
|
||||
// return clamp(dist, 0.0, 1.0);
|
||||
// vignetting from iq
|
||||
// return 0.4 + 0.6 * pow(16.0 * texCoord.x * texCoord.y * (1.0 - texCoord.x) * (1.0 - texCoord.y), 0.2);
|
||||
return 0.3 + 0.7 * pow(16.0 * texCoord.x * texCoord.y * (1.0 - texCoord.x) * (1.0 - texCoord.y), 0.2);
|
||||
// return 0.4 + 0.6 * pow(16.0 * texCoord.x * texCoord.y * (1.0 - texCoord.x) * (1.0 - texCoord.y), 0.2);
|
||||
return 0.3 + 0.7 * pow(16.0 * texCoord.x * texCoord.y * (1.0 - texCoord.x) * (1.0 - texCoord.y), 0.2);
|
||||
}
|
||||
|
||||
// #ifdef _CompoDOF
|
||||
|
@ -127,36 +118,11 @@ vec3 lensflare(vec2 uv, vec2 pos) {
|
|||
|
||||
vec3 c = vec3(0.0);
|
||||
c.r += f2 + f4 + f5 + f6;
|
||||
c.g += f22 + f42 + f52 + f62;
|
||||
c.b += f23 + f43 + f53 + f63;
|
||||
c.g += f22 + f42 + f52 + f62;
|
||||
c.b += f23 + f43 + f53 + f63;
|
||||
return c;
|
||||
}
|
||||
|
||||
//Based on Filmic Tonemapping Operators http://filmicgames.com/archives/75
|
||||
vec3 tonemapFilmic(vec3 color) {
|
||||
vec3 x = max(vec3(0.0), color - 0.004);
|
||||
return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
|
||||
}
|
||||
vec3 tonemapReinhard(vec3 color) {
|
||||
return color / (color + vec3(1.0));
|
||||
}
|
||||
vec3 uncharted2Tonemap(vec3 x) {
|
||||
const float A = 0.15;
|
||||
const float B = 0.50;
|
||||
const float C = 0.10;
|
||||
const float D = 0.20;
|
||||
const float E = 0.02;
|
||||
const float F = 0.30;
|
||||
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
|
||||
}
|
||||
vec3 tonemapUncharted2(vec3 color) {
|
||||
const float W = 11.2;
|
||||
const float exposureBias = 2.0;
|
||||
vec3 curr = uncharted2Tonemap(exposureBias * color);
|
||||
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||
return curr * whiteScale;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 texCo = texCoord;
|
||||
#ifdef _CompoFishEye
|
||||
|
@ -167,7 +133,7 @@ void main() {
|
|||
float power = (2.0 * PI / (2.0 * sqrt(dot(m, m)))) * fishEyeStrength;
|
||||
float bind;
|
||||
if (power > 0.0) { bind = sqrt(dot(m, m)); }
|
||||
else { bind = m.x; }
|
||||
else { bind = m.x; }
|
||||
if (power > 0.0) {
|
||||
texCo = m + normalize(d) * tan(r * power) * bind / tan(bind * power);
|
||||
}
|
||||
|
@ -178,9 +144,9 @@ void main() {
|
|||
|
||||
#ifdef _CompoFXAA
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
vec2 tcrgbNW = (texCo + vec2(-1.0, -1.0) * texStep);
|
||||
vec2 tcrgbNE = (texCo + vec2(1.0, -1.0) * texStep);
|
||||
vec2 tcrgbSW = (texCo + vec2(-1.0, 1.0) * texStep);
|
||||
|
@ -188,43 +154,43 @@ void main() {
|
|||
vec2 tcrgbM = vec2(texCo);
|
||||
|
||||
vec3 rgbNW = texture(tex, tcrgbNW).rgb;
|
||||
vec3 rgbNE = texture(tex, tcrgbNE).rgb;
|
||||
vec3 rgbSW = texture(tex, tcrgbSW).rgb;
|
||||
vec3 rgbSE = texture(tex, tcrgbSE).rgb;
|
||||
vec4 texColor = texture(tex, tcrgbM);
|
||||
vec3 rgbNE = texture(tex, tcrgbNE).rgb;
|
||||
vec3 rgbSW = texture(tex, tcrgbSW).rgb;
|
||||
vec3 rgbSE = texture(tex, tcrgbSE).rgb;
|
||||
vec4 texColor = texture(tex, tcrgbM);
|
||||
vec3 rgbM = texColor.rgb;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
|
||||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * texStep;
|
||||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * texStep;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
texture(tex, texCo + dir * (1.0 / 3.0 - 0.5)).rgb +
|
||||
texture(tex, texCo + dir * (2.0 / 3.0 - 0.5)).rgb);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture(tex, texCo + dir * -0.5).rgb +
|
||||
texture(tex, texCo + dir * 0.5).rgb);
|
||||
texture(tex, texCo + dir * (1.0 / 3.0 - 0.5)).rgb +
|
||||
texture(tex, texCo + dir * (2.0 / 3.0 - 0.5)).rgb);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture(tex, texCo + dir * -0.5).rgb +
|
||||
texture(tex, texCo + dir * 0.5).rgb);
|
||||
|
||||
vec4 col;
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax)) col = vec4(rgbA, texColor.a);
|
||||
else col = vec4(rgbB, texColor.a);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax)) col = vec4(rgbA, texColor.a);
|
||||
else col = vec4(rgbB, texColor.a);
|
||||
#else
|
||||
vec4 col = texture(tex, texCo);
|
||||
#endif
|
||||
|
@ -271,7 +237,7 @@ void main() {
|
|||
|
||||
#ifdef _CompoGrain
|
||||
// const float compoGrainStrength = 4.0;
|
||||
float x = (texCoord.x + 4.0) * (texCoord.y + 4.0) * (time * 10.0);
|
||||
float x = (texCoord.x + 4.0) * (texCoord.y + 4.0) * (time * 10.0);
|
||||
col.rgb += vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.005) * compoGrainStrength;
|
||||
#endif
|
||||
|
||||
|
@ -292,7 +258,7 @@ void main() {
|
|||
col.rgb = pow(col.rgb, vec3(1.0 / 2.2));
|
||||
|
||||
#ifdef _CompoBW
|
||||
// col.rgb = vec3(clamp(dot(col.rgb, col.rgb), 0.0, 1.0));
|
||||
// col.rgb = vec3(clamp(dot(col.rgb, col.rgb), 0.0, 1.0));
|
||||
col.rgb = vec3((col.r * 0.3 + col.g * 0.59 + col.b * 0.11) / 3.0) * 2.5;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,10 +16,9 @@ out vec2 texCoord;
|
|||
out vec3 viewRay;
|
||||
#endif
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = texture(tex, texCoord);
|
||||
}
|
|
@ -9,7 +9,8 @@
|
|||
"texture_params": [],
|
||||
"vertex_shader": "copy_pass.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "copy_pass.frag.glsl"
|
||||
"fragment_shader": "copy_pass.frag.glsl",
|
||||
"fragment_shader_path": "../include/pass.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -5,50 +5,16 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// getNor()
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec3 eye;
|
||||
uniform vec3 eyeLook;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
vec3 getPos(float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
// float linearDepth = projectionB / (depth - projectionA);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
|
||||
vec2 unpackFloat(float f) {
|
||||
float index = floor(f) / 1000.0;
|
||||
float alpha = fract(f);
|
||||
return vec2(index, alpha);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Normals
|
||||
vec4 col = texture(tex, texCoord);
|
||||
vec2 enc = col.rg;
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vec3 n = getNor(col.rg);
|
||||
fragColor = vec4(n * 0.5 + 0.5, 1.0);
|
||||
|
||||
// vec3 p = getPos(depth);
|
||||
// vec3 baseColor = g1.rgb;
|
||||
// vec2 metrough = unpackFloat(g1.a);
|
||||
// float metalness = metrough.x;
|
||||
// float roughness = metrough.y;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "debug_normals.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass_viewray.vert.glsl",
|
||||
"vertex_shader_path": "../include/pass.vert.glsl",
|
||||
"fragment_shader": "debug_normals.frag.glsl"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
|
@ -33,47 +36,35 @@ in vec4 matColor;
|
|||
out vec4[2] fragColor;
|
||||
|
||||
mat3 cotangentFrame(vec3 nor, vec3 pos, vec2 uv) {
|
||||
// Get edge vectors of the pixel triangle
|
||||
vec3 dp1 = dFdx(pos);
|
||||
vec3 dp2 = dFdy(pos);
|
||||
vec2 duv1 = dFdx(uv);
|
||||
vec2 duv2 = dFdy(uv);
|
||||
// Solve the linear system
|
||||
vec3 dp2perp = cross(dp2, nor);
|
||||
vec3 dp1perp = cross(nor, dp1);
|
||||
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
// Construct a scale-invariant frame
|
||||
float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
|
||||
return mat3(T * invmax, B * invmax, nor);
|
||||
// Get edge vectors of the pixel triangle
|
||||
vec3 dp1 = dFdx(pos);
|
||||
vec3 dp2 = dFdy(pos);
|
||||
vec2 duv1 = dFdx(uv);
|
||||
vec2 duv2 = dFdy(uv);
|
||||
// Solve the linear system
|
||||
vec3 dp2perp = cross(dp2, nor);
|
||||
vec3 dp1perp = cross(nor, dp1);
|
||||
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
// Construct a scale-invariant frame
|
||||
float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
|
||||
return mat3(T * invmax, B * invmax, nor);
|
||||
}
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
vec4 reconstructPos(float z, vec2 uv_f) {
|
||||
vec4 sPos = vec4(uv_f * 2.0 - 1.0, z, 1.0);
|
||||
sPos = invVP * sPos;
|
||||
return vec4((sPos.xyz / sPos.w), sPos.w);
|
||||
}
|
||||
|
||||
float packFloat(float f1, float f2) {
|
||||
int index = int(f1 * 1000);
|
||||
float alpha = f2 == 0.0 ? f2 : (f2 - 0.0001);
|
||||
float result = index + alpha;
|
||||
return result;
|
||||
vec4 reconstructPos(float depth, vec2 uv) {
|
||||
vec4 sPos = vec4(uv * 2.0 - 1.0, depth, 1.0);
|
||||
sPos = invVP * sPos;
|
||||
return vec4((sPos.xyz / sPos.w), 1.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 screenPosition = wvpposition.xy / wvpposition.w;
|
||||
vec2 depthUV = screenPosition * 0.5 + 0.5;
|
||||
// depthUV += vec2(0.5 / screenSize); // Half pixel offset
|
||||
float depth = texture(gbufferD, depthUV).r * 2.0 - 1.0;
|
||||
// depthUV += vec2(0.5 / screenSize); // Half pixel offset
|
||||
float depth = texture(gbufferD, depthUV).r * 2.0 - 1.0;
|
||||
|
||||
vec4 worldPos = reconstructPos(depth, depthUV);
|
||||
worldPos.w = 1.0;
|
||||
|
||||
|
||||
// Angle reject
|
||||
// Reconstruct normal
|
||||
// vec3 dnor = normalize(cross(dFdx(worldPos.xyz), dFdy(worldPos.xyz)));
|
||||
|
@ -100,7 +91,6 @@ void main() {
|
|||
// Use separate texture for base color in the future
|
||||
fragColor[1].rgb = baseColor.rgb;
|
||||
fragColor[1].a = baseColor.a;
|
||||
// fragColor[1].a = packFloat(roughness, metalness) * baseColor.a;
|
||||
|
||||
#ifdef _MetTex
|
||||
float metalness = texture(smetal, texCoord).r;
|
||||
|
@ -113,29 +103,28 @@ void main() {
|
|||
#ifdef _NorTex
|
||||
vec3 normal = texture(snormal, texCoord).rgb * 2.0 - 1.0;
|
||||
vec3 nn = normalize(normal);
|
||||
vec3 dp1 = dFdx(worldPos.xyz);
|
||||
vec3 dp2 = dFdy(worldPos.xyz);
|
||||
vec2 duv1 = dFdx(texCoord);
|
||||
vec2 duv2 = dFdy(texCoord);
|
||||
vec3 dp2perp = cross(dp2, nn);
|
||||
vec3 dp1perp = cross(nn, dp1);
|
||||
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
|
||||
mat3 TBN = mat3(T * invmax, B * invmax, nn);
|
||||
vec3 dp1 = dFdx(worldPos.xyz);
|
||||
vec3 dp2 = dFdy(worldPos.xyz);
|
||||
vec2 duv1 = dFdx(texCoord);
|
||||
vec2 duv2 = dFdy(texCoord);
|
||||
vec3 dp2perp = cross(dp2, nn);
|
||||
vec3 dp1perp = cross(nn, dp1);
|
||||
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
|
||||
mat3 TBN = mat3(T * invmax, B * invmax, nn);
|
||||
vec3 n = normalize(TBN * nn);
|
||||
|
||||
n /= (abs(n.x) + abs(n.y) + abs(n.z));
|
||||
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
|
||||
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
|
||||
|
||||
fragColor[0].rg = n.xy;
|
||||
#else
|
||||
fragColor[0].rg = vec2(1.0);
|
||||
#endif
|
||||
|
||||
// fragColor[0].b unused for now so we can rewrite it
|
||||
fragColor[0].b = 0.0;
|
||||
// use separete RG texture for normal storage in the future
|
||||
fragColor[0].b = 0.0; // Unused for now so we can rewrite it
|
||||
// Use separete RG texture for normal storage in the future
|
||||
// Color mask does not disable write for all buffers so mask is overwritten
|
||||
// Half of color alpha to soft normals blend
|
||||
fragColor[0].a = baseColor.a / 2.0;
|
||||
|
|
|
@ -8,24 +8,12 @@ precision highp float;
|
|||
#define _BaseTex
|
||||
#endif
|
||||
|
||||
#ifdef _RampID
|
||||
#include "../std/math.glsl"
|
||||
// hash()
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
// in vec3 nor;
|
||||
// #ifdef _BaseTex
|
||||
// in vec2 tex;
|
||||
// #endif
|
||||
// #ifdef _VCols
|
||||
// in vec3 col;
|
||||
// #endif
|
||||
// #ifdef _NorTex
|
||||
// in vec3 tan;
|
||||
// #endif
|
||||
// #ifdef _Skinning
|
||||
// in vec4 bone;
|
||||
// in vec4 weight;
|
||||
// #endif
|
||||
// #ifdef _Instancing
|
||||
// in vec3 off;
|
||||
// #endif
|
||||
|
||||
uniform mat4 VP;
|
||||
uniform mat4 W;
|
||||
|
@ -40,26 +28,9 @@ uniform int uid;
|
|||
out vec4 wvpposition;
|
||||
out vec4 matColor;
|
||||
// out vec3 orientation;
|
||||
// #ifdef _BaseTex
|
||||
// out vec2 texCoord;
|
||||
// #endif
|
||||
// out vec4 lampPos;
|
||||
// out vec4 matColor;
|
||||
// #ifdef _NorTex
|
||||
// out mat3 TBN;
|
||||
// #else
|
||||
// out vec3 normal;
|
||||
// #endif
|
||||
|
||||
#ifdef _RampID
|
||||
float hash(vec2 p) {
|
||||
float h = dot(p, vec2(127.1, 311.7));
|
||||
return fract(sin(h) * 43758.5453123);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 sPos = (vec4(pos, 1.0));
|
||||
vec4 sPos = vec4(pos, 1.0);
|
||||
wvpposition = VP * W * sPos;
|
||||
|
||||
// orientation = normalize(WV[1].xyz);
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
// packFloat()
|
||||
|
||||
uniform float mask;
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
|
@ -63,16 +67,6 @@ in vec4 matColor;
|
|||
out vec4[2] fragColor;
|
||||
#endif
|
||||
|
||||
float packFloat(float f1, float f2) {
|
||||
float index = floor(f1 * 1000.0); // Temporary
|
||||
float alpha = clamp(f2, 0.0, 1.0 - 0.001);
|
||||
return index + alpha;
|
||||
}
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
#ifdef _Probes
|
||||
float distanceBox(vec3 point, vec3 center, vec3 halfExtents) {
|
||||
vec3 d = abs(point - center) - halfExtents;
|
||||
|
|
|
@ -5,13 +5,10 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
|
||||
// #ifdef _HeightTex
|
||||
// #define _NorTex
|
||||
// #endif
|
||||
// #ifdef _NorTex
|
||||
// #define _Tex
|
||||
// #endif
|
||||
#ifdef _Skinning
|
||||
#include "../std/skinning.glsl"
|
||||
// getSkinningDualQuat()
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
|
@ -39,19 +36,11 @@ uniform vec4 baseCol;
|
|||
uniform mat4 WV;
|
||||
uniform mat4 P;
|
||||
#endif
|
||||
// #ifdef _HeightTex
|
||||
// uniform vec3 eye;
|
||||
// uniform vec3 light;
|
||||
// uniform mat4 W;
|
||||
// #endif
|
||||
#ifdef _Skinning
|
||||
// uniform float skinBones[skinMaxBones * 12]; // Defaults to 50
|
||||
uniform float skinBones[skinMaxBones * 8]; // Dual quat
|
||||
//!uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
#ifdef _Probes
|
||||
// #ifndef _HeightTex
|
||||
uniform mat4 W;
|
||||
// #endif
|
||||
#endif
|
||||
#ifdef _Veloc
|
||||
uniform mat4 prevWVP;
|
||||
|
@ -66,10 +55,6 @@ out vec4 matColor;
|
|||
#else
|
||||
out vec3 normal;
|
||||
#endif
|
||||
// #ifdef _HeightTex
|
||||
// out vec3 tanLightDir;
|
||||
// out vec3 tanEyeDir;
|
||||
// #endif
|
||||
#ifdef _Probes
|
||||
out vec4 wpos;
|
||||
#endif
|
||||
|
@ -78,95 +63,13 @@ out vec4 matColor;
|
|||
out vec4 prevwvppos;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
// Geometric Skinning with Approximate Dual Quaternion Blending, Kavan
|
||||
// Based on https://github.com/tcoppex/aer-engine/blob/master/demos/aura/data/shaders/Skinning.glsl
|
||||
void getSkinningDualQuat(vec4 weights, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[int(bone.x) * 8 + 0];
|
||||
matA[0][1] = skinBones[int(bone.x) * 8 + 1];
|
||||
matA[0][2] = skinBones[int(bone.x) * 8 + 2];
|
||||
matA[0][3] = skinBones[int(bone.x) * 8 + 3];
|
||||
matB[0][0] = skinBones[int(bone.x) * 8 + 4];
|
||||
matB[0][1] = skinBones[int(bone.x) * 8 + 5];
|
||||
matB[0][2] = skinBones[int(bone.x) * 8 + 6];
|
||||
matB[0][3] = skinBones[int(bone.x) * 8 + 7];
|
||||
matA[1][0] = skinBones[int(bone.y) * 8 + 0];
|
||||
matA[1][1] = skinBones[int(bone.y) * 8 + 1];
|
||||
matA[1][2] = skinBones[int(bone.y) * 8 + 2];
|
||||
matA[1][3] = skinBones[int(bone.y) * 8 + 3];
|
||||
matB[1][0] = skinBones[int(bone.y) * 8 + 4];
|
||||
matB[1][1] = skinBones[int(bone.y) * 8 + 5];
|
||||
matB[1][2] = skinBones[int(bone.y) * 8 + 6];
|
||||
matB[1][3] = skinBones[int(bone.y) * 8 + 7];
|
||||
matA[2][0] = skinBones[int(bone.z) * 8 + 0];
|
||||
matA[2][1] = skinBones[int(bone.z) * 8 + 1];
|
||||
matA[2][2] = skinBones[int(bone.z) * 8 + 2];
|
||||
matA[2][3] = skinBones[int(bone.z) * 8 + 3];
|
||||
matB[2][0] = skinBones[int(bone.z) * 8 + 4];
|
||||
matB[2][1] = skinBones[int(bone.z) * 8 + 5];
|
||||
matB[2][2] = skinBones[int(bone.z) * 8 + 6];
|
||||
matB[2][3] = skinBones[int(bone.z) * 8 + 7];
|
||||
matA[3][0] = skinBones[int(bone.w) * 8 + 0];
|
||||
matA[3][1] = skinBones[int(bone.w) * 8 + 1];
|
||||
matA[3][2] = skinBones[int(bone.w) * 8 + 2];
|
||||
matA[3][3] = skinBones[int(bone.w) * 8 + 3];
|
||||
matB[3][0] = skinBones[int(bone.w) * 8 + 4];
|
||||
matB[3][1] = skinBones[int(bone.w) * 8 + 5];
|
||||
matB[3][2] = skinBones[int(bone.w) * 8 + 6];
|
||||
matB[3][3] = skinBones[int(bone.w) * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weights.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weights.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weights; // Real part
|
||||
B = matB * weights; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
||||
// mat4 getBoneMat(const int boneIndex) {
|
||||
// vec4 v0 = vec4(skinBones[boneIndex * 12 + 0],
|
||||
// skinBones[boneIndex * 12 + 1],
|
||||
// skinBones[boneIndex * 12 + 2],
|
||||
// skinBones[boneIndex * 12 + 3]);
|
||||
// vec4 v1 = vec4(skinBones[boneIndex * 12 + 4],
|
||||
// skinBones[boneIndex * 12 + 5],
|
||||
// skinBones[boneIndex * 12 + 6],
|
||||
// skinBones[boneIndex * 12 + 7]);
|
||||
// vec4 v2 = vec4(skinBones[boneIndex * 12 + 8],
|
||||
// skinBones[boneIndex * 12 + 9],
|
||||
// skinBones[boneIndex * 12 + 10],
|
||||
// skinBones[boneIndex * 12 + 11]);
|
||||
// return mat4(v0.x, v0.y, v0.z, v0.w,
|
||||
// v1.x, v1.y, v1.z, v1.w,
|
||||
// v2.x, v2.y, v2.z, v2.w,
|
||||
// 0, 0, 0, 1);
|
||||
// }
|
||||
// mat4 getSkinningMat() {
|
||||
// return weight.x * getBoneMat(int(bone.x)) +
|
||||
// weight.y * getBoneMat(int(bone.y)) +
|
||||
// weight.z * getBoneMat(int(bone.z)) +
|
||||
// weight.w * getBoneMat(int(bone.w));
|
||||
// }
|
||||
// mat3 getSkinningMatVec(const mat4 skinningMat) {
|
||||
// return mat3(skinningMat[0].xyz, skinningMat[1].xyz, skinningMat[2].xyz);
|
||||
// }
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 sPos = vec4(pos, 1.0);
|
||||
|
||||
#ifdef _Skinning
|
||||
// mat4 skinningMat = getSkinningMat();
|
||||
// mat3 skinningMatVec = getSkinningMatVec(skinningMat);
|
||||
// sPos = sPos * skinningMat;
|
||||
// vec3 _normal = normalize(mat3(N) * (nor * skinningMatVec));
|
||||
vec4 skinA;
|
||||
vec4 skinB;
|
||||
getSkinningDualQuat(weight, skinA, skinB);
|
||||
getSkinningDualQuat(ivec4(bone), weight, skinA, skinB);
|
||||
sPos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, sPos.xyz) + skinA.w * sPos.xyz); // Rotate
|
||||
sPos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate
|
||||
vec3 _normal = normalize(mat3(N) * (nor + 2.0 * cross(skinA.xyz, cross(skinA.xyz, nor) + skinA.w * nor)));
|
||||
|
@ -219,15 +122,4 @@ void main() {
|
|||
#else
|
||||
normal = _normal;
|
||||
#endif
|
||||
|
||||
// #ifdef _HeightTex
|
||||
// #ifndef _Probes
|
||||
// vec4 wpos = W * sPos;
|
||||
// #endif
|
||||
// vec3 lightDir = light - wpos.xyz;
|
||||
// vec3 eyeDir = /*normalize*/eye - wpos.xyz;
|
||||
// // Wrong bitangent handedness?
|
||||
// tanLightDir = vec3(dot(lightDir, tangent), dot(lightDir, -bitangent), dot(lightDir, _normal));
|
||||
// tanEyeDir = vec3(dot(eyeDir, tangent), dot(eyeDir, -bitangent), dot(eyeDir, _normal));
|
||||
// #endif
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
// packFloat()
|
||||
|
||||
uniform float mask;
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
|
@ -45,16 +49,6 @@ in vec2 te_texCoord;
|
|||
|
||||
out vec4[2] fragColor;
|
||||
|
||||
float packFloat(float f1, float f2) {
|
||||
float index = floor(f1 * 1000.0); // Temporary
|
||||
float alpha = clamp(f2, 0.0, 1.0 - 0.001);
|
||||
return index + alpha;
|
||||
}
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 newCoord = te_texCoord;
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@ in vec3 v_position[];
|
|||
in vec2 v_texCoord[];
|
||||
in vec3 v_normal[];
|
||||
#ifdef _NorTex
|
||||
in vec3 v_tangent[];
|
||||
in vec3 v_tangent[];
|
||||
#endif
|
||||
|
||||
out vec3 tc_position[];
|
||||
out vec2 tc_texCoord[];
|
||||
out vec3 tc_normal[];
|
||||
#ifdef _NorTex
|
||||
out vec3 tc_tangent[];
|
||||
out vec3 tc_tangent[];
|
||||
#endif
|
||||
|
||||
uniform float innerLevel;
|
||||
|
@ -25,19 +25,19 @@ uniform float outerLevel;
|
|||
#define ID gl_InvocationID
|
||||
|
||||
void main() {
|
||||
tc_position[ID] = v_position[ID];
|
||||
tc_texCoord[ID] = v_texCoord[ID];
|
||||
tc_normal[ID] = v_normal[ID];
|
||||
tc_position[ID] = v_position[ID];
|
||||
tc_texCoord[ID] = v_texCoord[ID];
|
||||
tc_normal[ID] = v_normal[ID];
|
||||
#ifdef _NorTex
|
||||
tc_tangent[ID] = v_tangent[ID];
|
||||
tc_tangent[ID] = v_tangent[ID];
|
||||
#endif
|
||||
|
||||
if (ID == 0) {
|
||||
gl_TessLevelInner[0] = innerLevel;
|
||||
gl_TessLevelInner[1] = innerLevel;
|
||||
gl_TessLevelOuter[0] = outerLevel;
|
||||
gl_TessLevelOuter[1] = outerLevel;
|
||||
gl_TessLevelOuter[2] = outerLevel;
|
||||
gl_TessLevelOuter[3] = outerLevel;
|
||||
}
|
||||
if (ID == 0) {
|
||||
gl_TessLevelInner[0] = innerLevel;
|
||||
gl_TessLevelInner[1] = innerLevel;
|
||||
gl_TessLevelOuter[0] = outerLevel;
|
||||
gl_TessLevelOuter[1] = outerLevel;
|
||||
gl_TessLevelOuter[2] = outerLevel;
|
||||
gl_TessLevelOuter[3] = outerLevel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ in vec3 tc_position[];
|
|||
in vec2 tc_texCoord[];
|
||||
in vec3 tc_normal[];
|
||||
#ifdef _NorTex
|
||||
in vec3 tc_tangent[];
|
||||
in vec3 tc_tangent[];
|
||||
#endif
|
||||
|
||||
out vec2 te_texCoord;
|
||||
#ifdef _NorTex
|
||||
out mat3 TBN;
|
||||
out mat3 TBN;
|
||||
#else
|
||||
out vec3 te_normal;
|
||||
out vec3 te_normal;
|
||||
#endif
|
||||
|
||||
uniform mat4 WVP;
|
||||
|
@ -25,37 +25,37 @@ uniform sampler2D sheight;
|
|||
uniform float heightStrength;
|
||||
|
||||
void main() {
|
||||
vec3 p0 = gl_TessCoord.x * tc_position[0];
|
||||
vec3 p1 = gl_TessCoord.y * tc_position[1];
|
||||
vec3 p2 = gl_TessCoord.z * tc_position[2];
|
||||
vec3 te_position = p0 + p1 + p2;
|
||||
vec3 p0 = gl_TessCoord.x * tc_position[0];
|
||||
vec3 p1 = gl_TessCoord.y * tc_position[1];
|
||||
vec3 p2 = gl_TessCoord.z * tc_position[2];
|
||||
vec3 te_position = p0 + p1 + p2;
|
||||
|
||||
vec3 n0 = gl_TessCoord.x * tc_normal[0];
|
||||
vec3 n1 = gl_TessCoord.y * tc_normal[1];
|
||||
vec3 n2 = gl_TessCoord.z * tc_normal[2];
|
||||
vec3 _te_normal = normalize(n0 + n1 + n2);
|
||||
vec3 n0 = gl_TessCoord.x * tc_normal[0];
|
||||
vec3 n1 = gl_TessCoord.y * tc_normal[1];
|
||||
vec3 n2 = gl_TessCoord.z * tc_normal[2];
|
||||
vec3 _te_normal = normalize(n0 + n1 + n2);
|
||||
|
||||
vec2 tc0 = gl_TessCoord.x * tc_texCoord[0];
|
||||
vec2 tc1 = gl_TessCoord.y * tc_texCoord[1];
|
||||
vec2 tc2 = gl_TessCoord.z * tc_texCoord[2];
|
||||
te_texCoord = tc0 + tc1 + tc2;
|
||||
vec2 tc0 = gl_TessCoord.x * tc_texCoord[0];
|
||||
vec2 tc1 = gl_TessCoord.y * tc_texCoord[1];
|
||||
vec2 tc2 = gl_TessCoord.z * tc_texCoord[2];
|
||||
te_texCoord = tc0 + tc1 + tc2;
|
||||
|
||||
te_position += _te_normal * texture(sheight, te_texCoord).r * heightStrength;
|
||||
|
||||
_te_normal = normalize(mat3(N) * _te_normal);
|
||||
te_position += _te_normal * texture(sheight, te_texCoord).r * heightStrength;
|
||||
|
||||
_te_normal = normalize(mat3(N) * _te_normal);
|
||||
|
||||
#ifdef _NorTex
|
||||
vec3 t0 = gl_TessCoord.x * tc_tangent[0];
|
||||
vec3 t1 = gl_TessCoord.y * tc_tangent[1];
|
||||
vec3 t2 = gl_TessCoord.z * tc_tangent[2];
|
||||
vec3 te_tangent = normalize(t0 + t1 + t2);
|
||||
vec3 t0 = gl_TessCoord.x * tc_tangent[0];
|
||||
vec3 t1 = gl_TessCoord.y * tc_tangent[1];
|
||||
vec3 t2 = gl_TessCoord.z * tc_tangent[2];
|
||||
vec3 te_tangent = normalize(t0 + t1 + t2);
|
||||
|
||||
vec3 tangent = normalize(mat3(N) * (te_tangent));
|
||||
vec3 bitangent = normalize(cross(_te_normal, tangent));
|
||||
TBN = mat3(tangent, bitangent, _te_normal);
|
||||
vec3 tangent = normalize(mat3(N) * (te_tangent));
|
||||
vec3 bitangent = normalize(cross(_te_normal, tangent));
|
||||
TBN = mat3(tangent, bitangent, _te_normal);
|
||||
#else
|
||||
te_normal = _te_normal;
|
||||
te_normal = _te_normal;
|
||||
#endif
|
||||
|
||||
gl_Position = WVP * vec4(te_position, 1.0);
|
||||
gl_Position = WVP * vec4(te_position, 1.0);
|
||||
}
|
||||
|
|
|
@ -19,16 +19,16 @@ uniform float outerLevel;
|
|||
#define ID gl_InvocationID
|
||||
|
||||
void main() {
|
||||
tc_position[ID] = v_position[ID];
|
||||
tc_texCoord[ID] = v_texCoord[ID];
|
||||
tc_normal[ID] = v_normal[ID];
|
||||
tc_position[ID] = v_position[ID];
|
||||
tc_texCoord[ID] = v_texCoord[ID];
|
||||
tc_normal[ID] = v_normal[ID];
|
||||
|
||||
if (ID == 0) {
|
||||
gl_TessLevelInner[0] = innerLevel;
|
||||
gl_TessLevelInner[1] = innerLevel;
|
||||
gl_TessLevelOuter[0] = outerLevel;
|
||||
gl_TessLevelOuter[1] = outerLevel;
|
||||
gl_TessLevelOuter[2] = outerLevel;
|
||||
gl_TessLevelOuter[3] = outerLevel;
|
||||
}
|
||||
if (ID == 0) {
|
||||
gl_TessLevelInner[0] = innerLevel;
|
||||
gl_TessLevelInner[1] = innerLevel;
|
||||
gl_TessLevelOuter[0] = outerLevel;
|
||||
gl_TessLevelOuter[1] = outerLevel;
|
||||
gl_TessLevelOuter[2] = outerLevel;
|
||||
gl_TessLevelOuter[3] = outerLevel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,21 +14,21 @@ uniform sampler2D sheight;
|
|||
uniform float heightStrength;
|
||||
|
||||
void main() {
|
||||
vec3 p0 = gl_TessCoord.x * tc_position[0];
|
||||
vec3 p1 = gl_TessCoord.y * tc_position[1];
|
||||
vec3 p2 = gl_TessCoord.z * tc_position[2];
|
||||
vec3 te_position = p0 + p1 + p2;
|
||||
vec3 p0 = gl_TessCoord.x * tc_position[0];
|
||||
vec3 p1 = gl_TessCoord.y * tc_position[1];
|
||||
vec3 p2 = gl_TessCoord.z * tc_position[2];
|
||||
vec3 te_position = p0 + p1 + p2;
|
||||
|
||||
vec3 n0 = gl_TessCoord.x * tc_normal[0];
|
||||
vec3 n1 = gl_TessCoord.y * tc_normal[1];
|
||||
vec3 n2 = gl_TessCoord.z * tc_normal[2];
|
||||
vec3 _te_normal = normalize(n0 + n1 + n2);
|
||||
vec3 n0 = gl_TessCoord.x * tc_normal[0];
|
||||
vec3 n1 = gl_TessCoord.y * tc_normal[1];
|
||||
vec3 n2 = gl_TessCoord.z * tc_normal[2];
|
||||
vec3 _te_normal = normalize(n0 + n1 + n2);
|
||||
|
||||
vec2 tc0 = gl_TessCoord.x * tc_texCoord[0];
|
||||
vec2 tc1 = gl_TessCoord.y * tc_texCoord[1];
|
||||
vec2 tc2 = gl_TessCoord.z * tc_texCoord[2];
|
||||
vec2 te_texCoord = tc0 + tc1 + tc2;
|
||||
vec2 tc0 = gl_TessCoord.x * tc_texCoord[0];
|
||||
vec2 tc1 = gl_TessCoord.y * tc_texCoord[1];
|
||||
vec2 tc2 = gl_TessCoord.z * tc_texCoord[2];
|
||||
vec2 te_texCoord = tc0 + tc1 + tc2;
|
||||
|
||||
te_position += _te_normal * texture(sheight, te_texCoord).r * heightStrength;
|
||||
gl_Position = LWVP * vec4(te_position, 1.0);
|
||||
te_position += _te_normal * texture(sheight, te_texCoord).r * heightStrength;
|
||||
gl_Position = LWVP * vec4(te_position, 1.0);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,18 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
// ...
|
||||
#include "../std/math.glsl"
|
||||
// envMapEquirect()
|
||||
#include "../std/shirr.glsl"
|
||||
// shIrradiance()
|
||||
//!uniform float shirr[27];
|
||||
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
#endif
|
||||
|
||||
uniform float shirr[27];
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
|
@ -21,7 +27,7 @@ uniform float shirr[27];
|
|||
uniform sampler2D snormal;
|
||||
#endif
|
||||
#ifdef _NorStr
|
||||
uniform float normalStrength;
|
||||
uniform float normalStrength;
|
||||
#endif
|
||||
#ifdef _OccTex
|
||||
uniform sampler2D socclusion;
|
||||
|
@ -34,7 +40,7 @@ uniform float shirr[27];
|
|||
uniform float roughness;
|
||||
#endif
|
||||
#ifdef _RoughStr
|
||||
uniform float roughnessStrength;
|
||||
uniform float roughnessStrength;
|
||||
#endif
|
||||
#ifdef _MetTex
|
||||
uniform sampler2D smetal;
|
||||
|
@ -66,85 +72,6 @@ in vec3 eyeDir;
|
|||
#endif
|
||||
out vec4[2] fragColor;
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.y * nor.x +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
|
||||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * envmapNumMipmaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh, float lh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
vec3 lambert(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
|
||||
vec3 diffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh, float lv) {
|
||||
return lambert(albedo, nl);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _NorTex
|
||||
|
@ -154,18 +81,18 @@ void main() {
|
|||
vec3 n = normalize(normal);
|
||||
#endif
|
||||
#ifdef _NorStr
|
||||
n *= normalStrength;
|
||||
n *= normalStrength;
|
||||
#endif
|
||||
|
||||
// Move out
|
||||
vec3 l;
|
||||
if (lightType == 0) { // Sun
|
||||
l = lightDir;
|
||||
}
|
||||
else { // Point, spot
|
||||
l = normalize(lightPos - position.xyz);
|
||||
}
|
||||
float dotNL = max(dot(n, l), 0.0);
|
||||
vec3 l;
|
||||
if (lightType == 0) { // Sun
|
||||
l = lightDir;
|
||||
}
|
||||
else { // Point, spot
|
||||
l = normalize(lightPos - position.xyz);
|
||||
}
|
||||
float dotNL = max(dot(n, l), 0.0);
|
||||
|
||||
vec3 baseColor = matColor.rgb;
|
||||
#ifdef _BaseTex
|
||||
|
@ -197,7 +124,7 @@ void main() {
|
|||
float roughness = texture(srough, texCoord).r;
|
||||
#endif
|
||||
#ifdef _RoughStr
|
||||
roughness *= roughnessStrength;
|
||||
roughness *= roughnessStrength;
|
||||
#endif
|
||||
|
||||
#ifdef _OccTex
|
||||
|
@ -207,14 +134,14 @@ void main() {
|
|||
// Direct
|
||||
vec3 direct = diffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH, dotLV) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH, dotLH);
|
||||
|
||||
if (lightType == 2) { // Spot
|
||||
float spotEffect = dot(lightDir, l);
|
||||
if (spotEffect < spotlightCutoff) {
|
||||
spotEffect = smoothstep(spotlightCutoff - spotlightExponent, spotlightCutoff, spotEffect);
|
||||
direct *= spotEffect;
|
||||
}
|
||||
}
|
||||
|
||||
if (lightType == 2) { // Spot
|
||||
float spotEffect = dot(lightDir, l);
|
||||
if (spotEffect < spotlightCutoff) {
|
||||
spotEffect = smoothstep(spotlightCutoff - spotlightExponent, spotlightCutoff, spotEffect);
|
||||
direct *= spotEffect;
|
||||
}
|
||||
}
|
||||
|
||||
direct = direct * lightColor * lightStrength;
|
||||
|
||||
// Indirect
|
||||
|
@ -227,7 +154,7 @@ void main() {
|
|||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);// + 1.0;
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);// + 1.0;
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _EnvLDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
|
@ -239,17 +166,16 @@ void main() {
|
|||
indirect = indirect * envmapStrength;// * lightColor * lightStrength;
|
||||
|
||||
|
||||
|
||||
vec4 premultipliedReflect = vec4(vec3(direct + indirect * occlusion), matColor.a);
|
||||
// vec4 premultipliedReflect = vec4(1.0, 0.0, 0.0, 0.01);
|
||||
// vec4 premultipliedReflect = baseColor;
|
||||
|
||||
float fragZ = wvpposition.z / wvpposition.w;
|
||||
float a = min(1.0, premultipliedReflect.a) * 8.0 + 0.01;
|
||||
float b = -fragZ * 0.95 + 1.0;
|
||||
float b = -fragZ * 0.95 + 1.0;
|
||||
float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
|
||||
// accum = premultipliedReflect * w;
|
||||
// revealage = premultipliedReflect.a;
|
||||
// accum = premultipliedReflect * w;
|
||||
// revealage = premultipliedReflect.a;
|
||||
// RT0 = vec4(C * w, a)
|
||||
// RT1 = vec4(vec3(a * w), 1)
|
||||
fragColor[0] = vec4(premultipliedReflect.rgb * w, premultipliedReflect.a);
|
||||
|
|
|
@ -5,10 +5,14 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#ifdef _Skinning
|
||||
#include "../std/skinning.glsl"
|
||||
// getSkinningDualQuat()
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
#ifdef _BaseTex
|
||||
#ifdef _Tex
|
||||
in vec2 tex;
|
||||
#endif
|
||||
#ifdef _VCols
|
||||
|
@ -32,7 +36,7 @@ uniform mat4 P;
|
|||
uniform vec4 baseCol;
|
||||
uniform vec3 eye;
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[skinMaxBones * 8];
|
||||
//!uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
|
||||
out vec4 wvpposition;
|
||||
|
@ -40,7 +44,6 @@ out vec3 position;
|
|||
#ifdef _Tex
|
||||
out vec2 texCoord;
|
||||
#endif
|
||||
// out vec4 lampPos;
|
||||
out vec4 matColor;
|
||||
out vec3 eyeDir;
|
||||
#ifdef _NorTex
|
||||
|
@ -49,62 +52,13 @@ out vec3 eyeDir;
|
|||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
void getSkinningDualQuat(vec4 weights, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[int(bone.x) * 8 + 0];
|
||||
matA[0][1] = skinBones[int(bone.x) * 8 + 1];
|
||||
matA[0][2] = skinBones[int(bone.x) * 8 + 2];
|
||||
matA[0][3] = skinBones[int(bone.x) * 8 + 3];
|
||||
matB[0][0] = skinBones[int(bone.x) * 8 + 4];
|
||||
matB[0][1] = skinBones[int(bone.x) * 8 + 5];
|
||||
matB[0][2] = skinBones[int(bone.x) * 8 + 6];
|
||||
matB[0][3] = skinBones[int(bone.x) * 8 + 7];
|
||||
matA[1][0] = skinBones[int(bone.y) * 8 + 0];
|
||||
matA[1][1] = skinBones[int(bone.y) * 8 + 1];
|
||||
matA[1][2] = skinBones[int(bone.y) * 8 + 2];
|
||||
matA[1][3] = skinBones[int(bone.y) * 8 + 3];
|
||||
matB[1][0] = skinBones[int(bone.y) * 8 + 4];
|
||||
matB[1][1] = skinBones[int(bone.y) * 8 + 5];
|
||||
matB[1][2] = skinBones[int(bone.y) * 8 + 6];
|
||||
matB[1][3] = skinBones[int(bone.y) * 8 + 7];
|
||||
matA[2][0] = skinBones[int(bone.z) * 8 + 0];
|
||||
matA[2][1] = skinBones[int(bone.z) * 8 + 1];
|
||||
matA[2][2] = skinBones[int(bone.z) * 8 + 2];
|
||||
matA[2][3] = skinBones[int(bone.z) * 8 + 3];
|
||||
matB[2][0] = skinBones[int(bone.z) * 8 + 4];
|
||||
matB[2][1] = skinBones[int(bone.z) * 8 + 5];
|
||||
matB[2][2] = skinBones[int(bone.z) * 8 + 6];
|
||||
matB[2][3] = skinBones[int(bone.z) * 8 + 7];
|
||||
matA[3][0] = skinBones[int(bone.w) * 8 + 0];
|
||||
matA[3][1] = skinBones[int(bone.w) * 8 + 1];
|
||||
matA[3][2] = skinBones[int(bone.w) * 8 + 2];
|
||||
matA[3][3] = skinBones[int(bone.w) * 8 + 3];
|
||||
matB[3][0] = skinBones[int(bone.w) * 8 + 4];
|
||||
matB[3][1] = skinBones[int(bone.w) * 8 + 5];
|
||||
matB[3][2] = skinBones[int(bone.w) * 8 + 6];
|
||||
matB[3][3] = skinBones[int(bone.w) * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weights.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weights.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weights; // Real part
|
||||
B = matB * weights; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 sPos = vec4(pos, 1.0);
|
||||
|
||||
#ifdef _Skinning
|
||||
vec4 skinA;
|
||||
vec4 skinB;
|
||||
getSkinningDualQuat(weight, skinA, skinB);
|
||||
getSkinningDualQuat(ivec4(bone), weight, skinA, skinB);
|
||||
sPos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, sPos.xyz) + skinA.w * sPos.xyz); // Rotate
|
||||
sPos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate
|
||||
vec3 _normal = normalize(mat3(N) * (nor + 2.0 * cross(skinA.xyz, cross(skinA.xyz, nor) + skinA.w * nor)));
|
||||
|
|
|
@ -5,15 +5,27 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
// unpackFloat()
|
||||
#include "../std/math.glsl"
|
||||
// envMapEquirect()
|
||||
#include "../std/brdf.glsl"
|
||||
// ...
|
||||
#ifdef _Probes
|
||||
#include "../std/shirr_probe.glsl"
|
||||
#else
|
||||
#include "../std/shirr.glsl"
|
||||
#endif
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
#ifdef _Probes
|
||||
uniform float shirr[27 * 6]; // Maximum of 6 SH sets
|
||||
//!uniform float shirr[27 * 6]; // Maximum of 6 SH sets
|
||||
#else
|
||||
uniform float shirr[27];
|
||||
//!uniform float shirr[27];
|
||||
#endif
|
||||
uniform float envmapStrength;
|
||||
#ifdef _Rad
|
||||
|
@ -37,123 +49,6 @@ in vec2 texCoord;
|
|||
#endif
|
||||
out vec4 fragColor;
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
// baseColor texture already counted
|
||||
return roughness * envmapNumMipmaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
vec3 getPos(float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec2 unpackFloat(float f) {
|
||||
return vec2(floor(f) / 1000.0, fract(f));
|
||||
}
|
||||
|
||||
#ifdef _Probes
|
||||
vec3 shIrradiance(vec3 nor, float scale, int probe) {
|
||||
#else
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
#endif
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
#ifdef _Probes
|
||||
if (probe == 0) {
|
||||
#endif
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
#ifdef _Probes
|
||||
}
|
||||
else if (probe == 1) {
|
||||
cl00 = vec3(shirr[27 + 0], shirr[27 + 1], shirr[27 + 2]); cl1m1 = vec3(shirr[27 + 3], shirr[27 + 4], shirr[27 + 5]);
|
||||
cl10 = vec3(shirr[27 + 6], shirr[27 + 7], shirr[27 + 8]); cl11 = vec3(shirr[27 + 9], shirr[27 + 10], shirr[27 + 11]);
|
||||
cl2m2 = vec3(shirr[27 + 12], shirr[27 + 13], shirr[27 + 14]); cl2m1 = vec3(shirr[27 + 15], shirr[27 + 16], shirr[27 + 17]);
|
||||
cl20 = vec3(shirr[27 + 18], shirr[27 + 19], shirr[27 + 20]); cl21 = vec3(shirr[27 + 21], shirr[27 + 22], shirr[27 + 23]);
|
||||
cl22 = vec3(shirr[27 + 24], shirr[27 + 25], shirr[27 + 26]);
|
||||
}
|
||||
else if (probe == 2) {
|
||||
cl00 = vec3(shirr[27 * 2 + 0], shirr[27 * 2 + 1], shirr[27 * 2 + 2]); cl1m1 = vec3(shirr[27 * 2 + 3], shirr[27 * 2 + 4], shirr[27 * 2 + 5]);
|
||||
cl10 = vec3(shirr[27 * 2 + 6], shirr[27 * 2 + 7], shirr[27 * 2 + 8]); cl11 = vec3(shirr[27 * 2 + 9], shirr[27 * 2 + 10], shirr[27 * 2 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 2 + 12], shirr[27 * 2 + 13], shirr[27 * 2 + 14]); cl2m1 = vec3(shirr[27 * 2 + 15], shirr[27 * 2 + 16], shirr[27 * 2 + 17]);
|
||||
cl20 = vec3(shirr[27 * 2 + 18], shirr[27 * 2 + 19], shirr[27 * 2 + 20]); cl21 = vec3(shirr[27 * 2 + 21], shirr[27 * 2 + 22], shirr[27 * 2 + 23]);
|
||||
cl22 = vec3(shirr[27 * 2 + 24], shirr[27 * 2 + 25], shirr[27 * 2 + 26]);
|
||||
}
|
||||
else if (probe == 3) {
|
||||
cl00 = vec3(shirr[27 * 3 + 0], shirr[27 * 3 + 1], shirr[27 * 3 + 2]); cl1m1 = vec3(shirr[27 * 3 + 3], shirr[27 * 3 + 4], shirr[27 * 3 + 5]);
|
||||
cl10 = vec3(shirr[27 * 3 + 6], shirr[27 * 3 + 7], shirr[27 * 3 + 8]); cl11 = vec3(shirr[27 * 3 + 9], shirr[27 * 3 + 10], shirr[27 * 3 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 3 + 12], shirr[27 * 3 + 13], shirr[27 * 3 + 14]); cl2m1 = vec3(shirr[27 * 3 + 15], shirr[27 * 3 + 16], shirr[27 * 3 + 17]);
|
||||
cl20 = vec3(shirr[27 * 3 + 18], shirr[27 * 3 + 19], shirr[27 * 3 + 20]); cl21 = vec3(shirr[27 * 3 + 21], shirr[27 * 3 + 22], shirr[27 * 3 + 23]);
|
||||
cl22 = vec3(shirr[27 * 3 + 24], shirr[27 * 3 + 25], shirr[27 * 3 + 26]);
|
||||
}
|
||||
else if (probe == 4) {
|
||||
cl00 = vec3(shirr[27 * 4 + 0], shirr[27 * 4 + 1], shirr[27 * 4 + 2]); cl1m1 = vec3(shirr[27 * 4 + 3], shirr[27 * 4 + 4], shirr[27 * 4 + 5]);
|
||||
cl10 = vec3(shirr[27 * 4 + 6], shirr[27 * 4 + 7], shirr[27 * 4 + 8]); cl11 = vec3(shirr[27 * 4 + 9], shirr[27 * 4 + 10], shirr[27 * 4 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 4 + 12], shirr[27 * 4 + 13], shirr[27 * 4 + 14]); cl2m1 = vec3(shirr[27 * 4 + 15], shirr[27 * 4 + 16], shirr[27 * 4 + 17]);
|
||||
cl20 = vec3(shirr[27 * 4 + 18], shirr[27 * 4 + 19], shirr[27 * 4 + 20]); cl21 = vec3(shirr[27 * 4 + 21], shirr[27 * 4 + 22], shirr[27 * 4 + 23]);
|
||||
cl22 = vec3(shirr[27 * 4 + 24], shirr[27 * 4 + 25], shirr[27 * 4 + 26]);
|
||||
}
|
||||
else if (probe == 5) {
|
||||
cl00 = vec3(shirr[27 * 5 + 0], shirr[27 * 5 + 1], shirr[27 * 5 + 2]); cl1m1 = vec3(shirr[27 * 5 + 3], shirr[27 * 5 + 4], shirr[27 * 5 + 5]);
|
||||
cl10 = vec3(shirr[27 * 5 + 6], shirr[27 * 5 + 7], shirr[27 * 5 + 8]); cl11 = vec3(shirr[27 * 5 + 9], shirr[27 * 5 + 10], shirr[27 * 5 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 5 + 12], shirr[27 * 5 + 13], shirr[27 * 5 + 14]); cl2m1 = vec3(shirr[27 * 5 + 15], shirr[27 * 5 + 16], shirr[27 * 5 + 17]);
|
||||
cl20 = vec3(shirr[27 * 5 + 18], shirr[27 * 5 + 19], shirr[27 * 5 + 20]); cl21 = vec3(shirr[27 * 5 + 21], shirr[27 * 5 + 22], shirr[27 * 5 + 23]);
|
||||
cl22 = vec3(shirr[27 * 5 + 24], shirr[27 * 5 + 25], shirr[27 * 5 + 26]);
|
||||
}
|
||||
#endif
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.y * nor.x +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
|
||||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, metallic/roughness, mask
|
||||
|
||||
|
@ -166,7 +61,7 @@ void main() {
|
|||
|
||||
#ifdef _Rad
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
vec3 p = getPos(depth);
|
||||
vec3 p = getPos(eye, eyeLook, viewRay, depth);
|
||||
vec3 v = normalize(eye - p.xyz);
|
||||
#endif
|
||||
|
||||
|
@ -177,7 +72,7 @@ void main() {
|
|||
float probeFract = fract(probeFactor);
|
||||
vec3 indirect;
|
||||
#ifdef _Rad
|
||||
float lod = getMipLevelFromRoughness(metrough.y);
|
||||
float lod = getMipFromRoughness(metrough.y, envmapNumMipmaps);
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
vec2 envCoordRefl = envMapEquirect(reflectionWorld);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envCoordRefl, lod).rgb;
|
||||
|
@ -200,7 +95,7 @@ void main() {
|
|||
vec3 indirect = shIrradiance(n, 2.2) / PI;
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(metrough.y);
|
||||
float lod = getMipFromRoughness(metrough.y, envmapNumMipmaps);
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -5,62 +5,40 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
// ...
|
||||
#ifndef _NoShadows
|
||||
#ifdef _PCSS
|
||||
#include "../std/shadows_pcss.glsl"
|
||||
// PCSS()
|
||||
#else
|
||||
#include "../std/shadows.glsl"
|
||||
// PCF()
|
||||
#endif
|
||||
#endif
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
// unpackFloat()
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
||||
#ifndef _NoShadows
|
||||
uniform sampler2D shadowMap;
|
||||
//!uniform sampler2D shadowMap;
|
||||
#ifdef _PCSS
|
||||
uniform sampler2D snoise;
|
||||
uniform float lampSizeUV; // 0.55
|
||||
uniform float lampNear; // 0.5
|
||||
//!uniform sampler2D snoise;
|
||||
//!uniform float lampSizeUV;
|
||||
//!uniform float lampNear;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
uniform sampler2D ssaotex;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
uniform sampler3D voxels;
|
||||
const float voxelGridWorldSize = 150.0;
|
||||
const int voxelDimensions = 512;
|
||||
const float maxDist = 30.0;
|
||||
const float alphaTreshold = 0.95;
|
||||
const int numCones = 6;
|
||||
vec3 coneDirections[6] = vec3[](
|
||||
vec3(0, 1, 0),
|
||||
vec3(0, 0.5, 0.866025),
|
||||
vec3(0.823639, 0.5, 0.267617),
|
||||
vec3(0.509037, 0.5, -0.700629),
|
||||
vec3(-0.509037, 0.5, -0.700629),
|
||||
vec3(-0.823639, 0.5, 0.267617));
|
||||
float coneWeights[6] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
|
||||
// #ifdef _LTC
|
||||
// uniform sampler2D sltcMat;
|
||||
// uniform sampler2D sltcMag;
|
||||
// uniform float time;
|
||||
// const float roughness = 0.25;
|
||||
// const vec3 dcolor = vec3(1.0, 1.0, 1.0);
|
||||
// const vec3 scolor = vec3(1.0, 1.0, 1.0);
|
||||
// const float intensity = 4.0; // 0-10
|
||||
// const float width = 4.0;
|
||||
// const float height = 4.0;
|
||||
// const int sampleCount = 0;
|
||||
// const int NUM_SAMPLES = 8;
|
||||
// const float LUT_SIZE = 64.0;
|
||||
// const float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;
|
||||
// const float LUT_BIAS = 0.5/LUT_SIZE;
|
||||
// vec2 mys[NUM_SAMPLES];
|
||||
// vec3 L0 = vec3(0.0);
|
||||
// vec3 L1 = vec3(0.0);
|
||||
// vec3 L2 = vec3(0.0);
|
||||
// vec3 L3 = vec3(0.0);
|
||||
// vec3 L4 = vec3(0.0);
|
||||
// #endif
|
||||
|
||||
uniform mat4 invVP;
|
||||
uniform mat4 LWVP;
|
||||
uniform vec3 lightPos;
|
||||
|
@ -104,270 +82,7 @@ vec3 SSSSTransmittance(float translucency, float sssWidth, vec3 worldPosition, v
|
|||
}
|
||||
#endif
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0 - f0) * exp2((-5.55473 * vh - 6.98316) * vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ((nl * (1.0 - a) + a) * (nv * (1.0 - a) + a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a * a;
|
||||
float denom = pow(nh * nh * (a2 - 1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
}
|
||||
// Gotanda 2012, Beyond a Simple Physically Based Blinn-Phong Model in Real-Time
|
||||
// http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf
|
||||
vec3 orenNayarDiffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh) {
|
||||
float a = roughness * roughness;
|
||||
float s = a;
|
||||
float s2 = s * s;
|
||||
float vl = 2.0 * vh * vh - 1.0; // Double angle identity
|
||||
float Cosri = vl - nv * nl;
|
||||
float C1 = 1.0 - 0.5 * s2 / (s2 + 0.33);
|
||||
float test = 1.0;
|
||||
if (Cosri >= 0.0) test = (1.0 / (max(nl, nv)));
|
||||
float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * test;
|
||||
return albedo * max(0.0, nl) * (C1 + C2) * (1.0 + roughness * 0.5);
|
||||
}
|
||||
vec3 lambertDiffuseBRDF(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
|
||||
#ifndef _NoShadows
|
||||
#ifndef _PCSS
|
||||
float texture2DCompare(vec2 uv, float compare){
|
||||
float depth = texture(shadowMap, uv).r;// * 2.0 - 1.0; // - mult compare instead
|
||||
return step(compare, depth);
|
||||
}
|
||||
float texture2DShadowLerp(vec2 uv, float compare){
|
||||
const vec2 texelSize = vec2(1.0) / shadowmapSize;
|
||||
vec2 f = fract(uv * shadowmapSize + 0.5);
|
||||
vec2 centroidUV = floor(uv * shadowmapSize + 0.5) / shadowmapSize;
|
||||
float lb = texture2DCompare(centroidUV, compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize, compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
float PCF(vec2 uv, float compare) {
|
||||
// float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
compare = compare * 0.5 + 0.5;
|
||||
float result = texture2DShadowLerp(uv + (vec2(-1.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(-1.0, 0.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(-1.0, 1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(0.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv, compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(0.0, 1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, 0.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, 1.0) / shadowmapSize), compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
#else // _PCSS
|
||||
// Based on ThreeJS and nvidia pcss
|
||||
// const int pcssRings = 11;
|
||||
const int NUM_SAMPLES = 17;
|
||||
const float radiusStep = 1.0 / float(NUM_SAMPLES);
|
||||
const float angleStep = PI2 * float(pcssRings) / float(NUM_SAMPLES);
|
||||
vec2 poissonDisk0; vec2 poissonDisk1; vec2 poissonDisk2;
|
||||
vec2 poissonDisk3; vec2 poissonDisk4; vec2 poissonDisk5;
|
||||
vec2 poissonDisk6; vec2 poissonDisk7; vec2 poissonDisk8;
|
||||
vec2 poissonDisk9; vec2 poissonDisk10; vec2 poissonDisk11;
|
||||
vec2 poissonDisk12; vec2 poissonDisk13; vec2 poissonDisk14;
|
||||
vec2 poissonDisk15; vec2 poissonDisk16;
|
||||
void initPoissonSamples(const in vec2 randomSeed) {
|
||||
float angle = texture(snoise, randomSeed).r * PI2;
|
||||
float radius = radiusStep;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
poissonDisk0 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk1 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk2 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk3 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk4 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk5 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk6 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk7 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk8 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk9 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk10 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk11 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk12 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk13 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk14 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk15 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk16 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
// }
|
||||
}
|
||||
float findBlocker(const in vec2 uv, const in float zReceiver) {
|
||||
// This uses similar triangles to compute what area of the shadow map we should search
|
||||
float searchRadius = lampSizeUV * (zReceiver - lampNear) / zReceiver;
|
||||
float blockerDepthSum = 0.0;
|
||||
int numBlockers = 0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float shadowMapDepth = texture(shadowMap, uv + poissonDisk0 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk1 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk2 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk3 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk4 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk5 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk6 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk7 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk8 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk9 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk10 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk11 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk12 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk13 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk14 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk15 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk16 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
// }
|
||||
if (numBlockers == 0) return -1.0;
|
||||
return blockerDepthSum / float(numBlockers);
|
||||
}
|
||||
float filterPCF(vec2 uv, float zReceiver, float filterRadius) {
|
||||
float sum = 0.0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float depth = texture(shadowMap, uv + poissonDisk0 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk1 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk2 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk3 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk4 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk5 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk6 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk7 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk8 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk9 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk10 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk11 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk12 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk13 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk14 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk15 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk16 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
depth = texture(shadowMap, uv + -poissonDisk0.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk1.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk2.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk3.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk4.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk5.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk6.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk7.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk8.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk9.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk10.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk11.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk12.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk13.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk14.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk15.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk16.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
return sum / (2.0 * float(NUM_SAMPLES));
|
||||
}
|
||||
float PCSS(vec2 uv, float zReceiver) {
|
||||
initPoissonSamples(uv);
|
||||
float avgBlockerDepth = findBlocker(uv, zReceiver);
|
||||
if (avgBlockerDepth == -1.0) return 1.0;
|
||||
float penumbraRatio = (zReceiver - avgBlockerDepth) / avgBlockerDepth;
|
||||
float filterRadius = penumbraRatio * lampSizeUV * lampNear / zReceiver;
|
||||
return filterPCF(uv, zReceiver, filterRadius);
|
||||
}
|
||||
#endif
|
||||
float shadowTest(vec4 lPos) {
|
||||
lPos.xyz /= lPos.w;
|
||||
lPos.xy = lPos.xy * 0.5 + 0.5;
|
||||
|
@ -379,259 +94,6 @@ float shadowTest(vec4 lPos) {
|
|||
}
|
||||
#endif
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
// vec3 getPos(float depth) {
|
||||
// vec3 vray = normalize(viewRay);
|
||||
// const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
// const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
// float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
// float viewZDist = dot(eyeLook, vray);
|
||||
// vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
// return wposition;
|
||||
// }
|
||||
vec3 getPos(float depth, vec2 coord) {
|
||||
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
pos = invVP * pos;
|
||||
pos.xyz /= pos.w;
|
||||
return pos.xyz;// - eye;
|
||||
}
|
||||
|
||||
vec2 unpackFloat(float f) {
|
||||
return vec2(floor(f) / 1000.0, fract(f));
|
||||
}
|
||||
|
||||
// Linearly Transformed Cosines
|
||||
// https://eheitzresearch.wordpress.com/415-2/
|
||||
// vec3 mul(mat3 m, vec3 v) {
|
||||
// return m * v;
|
||||
// }
|
||||
// mat3 mul(mat3 m1, mat3 m2) {
|
||||
// return m1 * m2;
|
||||
// }
|
||||
// mat3 transpose2(mat3 v) {
|
||||
// mat3 tmp;
|
||||
// tmp[0] = vec3(v[0].x, v[1].x, v[2].x);
|
||||
// tmp[1] = vec3(v[0].y, v[1].y, v[2].y);
|
||||
// tmp[2] = vec3(v[0].z, v[1].z, v[2].z);
|
||||
|
||||
// return tmp;
|
||||
// }
|
||||
// float IntegrateEdge(vec3 v1, vec3 v2) {
|
||||
// float cosTheta = dot(v1, v2);
|
||||
// cosTheta = clamp(cosTheta, -0.9999, 0.9999);
|
||||
// float theta = acos(cosTheta);
|
||||
// float res = cross(v1, v2).z * theta / sin(theta);
|
||||
// return res;
|
||||
// }
|
||||
// int ClipQuadToHorizon(/*inout vec3 L[5], out int n*/) {
|
||||
// // detect clipping config
|
||||
// int config = 0;
|
||||
// if (L0.z > 0.0) config += 1;
|
||||
// if (L1.z > 0.0) config += 2;
|
||||
// if (L2.z > 0.0) config += 4;
|
||||
// if (L3.z > 0.0) config += 8;
|
||||
|
||||
// // clip
|
||||
// int n = 0;
|
||||
// if (config == 0) {
|
||||
// // clip all
|
||||
// }
|
||||
// else if (config == 1) { // V1 clip V2 V3 V4
|
||||
// n = 3;
|
||||
// L1 = -L1.z * L0 + L0.z * L1;
|
||||
// L2 = -L3.z * L0 + L0.z * L3;
|
||||
// }
|
||||
// else if (config == 2) { // V2 clip V1 V3 V4
|
||||
// n = 3;
|
||||
// L0 = -L0.z * L1 + L1.z * L0;
|
||||
// L2 = -L2.z * L1 + L1.z * L2;
|
||||
// }
|
||||
// else if (config == 3) { // V1 V2 clip V3 V4
|
||||
// n = 4;
|
||||
// L2 = -L2.z * L1 + L1.z * L2;
|
||||
// L3 = -L3.z * L0 + L0.z * L3;
|
||||
// }
|
||||
// else if (config == 4) { // V3 clip V1 V2 V4
|
||||
// n = 3;
|
||||
// L0 = -L3.z * L2 + L2.z * L3;
|
||||
// L1 = -L1.z * L2 + L2.z * L1;
|
||||
// }
|
||||
// else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
// n = 0;
|
||||
// }
|
||||
// else if (config == 6) { // V2 V3 clip V1 V4
|
||||
// n = 4;
|
||||
// L0 = -L0.z * L1 + L1.z * L0;
|
||||
// L3 = -L3.z * L2 + L2.z * L3;
|
||||
// }
|
||||
// else if (config == 7) { // V1 V2 V3 clip V4
|
||||
// n = 5;
|
||||
// L4 = -L3.z * L0 + L0.z * L3;
|
||||
// L3 = -L3.z * L2 + L2.z * L3;
|
||||
// }
|
||||
// else if (config == 8) { // V4 clip V1 V2 V3
|
||||
// n = 3;
|
||||
// L0 = -L0.z * L3 + L3.z * L0;
|
||||
// L1 = -L2.z * L3 + L3.z * L2;
|
||||
// L2 = L3;
|
||||
// }
|
||||
// else if (config == 9) { // V1 V4 clip V2 V3
|
||||
// n = 4;
|
||||
// L1 = -L1.z * L0 + L0.z * L1;
|
||||
// L2 = -L2.z * L3 + L3.z * L2;
|
||||
// }
|
||||
// else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
// n = 0;
|
||||
// }
|
||||
// else if (config == 11) { // V1 V2 V4 clip V3
|
||||
// n = 5;
|
||||
// L4 = L3;
|
||||
// L3 = -L2.z * L3 + L3.z * L2;
|
||||
// L2 = -L2.z * L1 + L1.z * L2;
|
||||
// }
|
||||
// else if (config == 12) { // V3 V4 clip V1 V2
|
||||
// n = 4;
|
||||
// L1 = -L1.z * L2 + L2.z * L1;
|
||||
// L0 = -L0.z * L3 + L3.z * L0;
|
||||
// }
|
||||
// else if (config == 13) { // V1 V3 V4 clip V2
|
||||
// n = 5;
|
||||
// L4 = L3;
|
||||
// L3 = L2;
|
||||
// L2 = -L1.z * L2 + L2.z * L1;
|
||||
// L1 = -L1.z * L0 + L0.z * L1;
|
||||
// }
|
||||
// else if (config == 14) { // V2 V3 V4 clip V1
|
||||
// n = 5;
|
||||
// L4 = -L0.z * L3 + L3.z * L0;
|
||||
// L0 = -L0.z * L1 + L1.z * L0;
|
||||
// }
|
||||
// else if (config == 15) { // V1 V2 V3 V4
|
||||
// n = 4;
|
||||
// }
|
||||
|
||||
// if (n == 3)
|
||||
// L3 = L0;
|
||||
// if (n == 4)
|
||||
// L4 = L0;
|
||||
// return n;
|
||||
// }
|
||||
// vec3 LTC_Evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3, bool twoSided) {
|
||||
// // construct orthonormal basis around N
|
||||
// vec3 T1, T2;
|
||||
// T1 = normalize(V - N*dot(V, N));
|
||||
// T2 = cross(N, T1);
|
||||
|
||||
// // rotate area light in (T1, T2, R) basis
|
||||
// Minv = mul(Minv, transpose2(mat3(T1, T2, N)));
|
||||
|
||||
// // polygon (allocate 5 vertices for clipping)
|
||||
// // vec3 L[5];
|
||||
// L0 = mul(Minv, points0 - P);
|
||||
// L1 = mul(Minv, points1 - P);
|
||||
// L2 = mul(Minv, points2 - P);
|
||||
// L3 = mul(Minv, points3 - P);
|
||||
|
||||
// int n = ClipQuadToHorizon(/*L, n*/);
|
||||
|
||||
// if (n == 0) {
|
||||
// return vec3(0, 0, 0);
|
||||
// }
|
||||
|
||||
// // project onto sphere
|
||||
// L0 = normalize(L0);
|
||||
// L1 = normalize(L1);
|
||||
// L2 = normalize(L2);
|
||||
// L3 = normalize(L3);
|
||||
// L4 = normalize(L4);
|
||||
|
||||
// // integrate
|
||||
// float sum = 0.0;
|
||||
|
||||
// sum += IntegrateEdge(L0, L1);
|
||||
// sum += IntegrateEdge(L1, L2);
|
||||
// sum += IntegrateEdge(L2, L3);
|
||||
|
||||
// if (n >= 4) {
|
||||
// sum += IntegrateEdge(L3, L4);
|
||||
// }
|
||||
// if (n == 5) {
|
||||
// sum += IntegrateEdge(L4, L0);
|
||||
// }
|
||||
|
||||
// sum = twoSided ? abs(sum) : max(0.0, -sum);
|
||||
|
||||
// vec3 Lo_i = vec3(sum, sum, sum);
|
||||
|
||||
// return Lo_i;
|
||||
// }
|
||||
|
||||
#ifdef _Aniso
|
||||
float wardSpecular(vec3 N, vec3 H, float dotNL, float dotNV, float dotNH, vec3 fiberDirection, float shinyParallel, float shinyPerpendicular) {
|
||||
if(dotNL < 0.0 || dotNV < 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
// fiberDirection - parse from rotation
|
||||
// shinyParallel - roughness
|
||||
// shinyPerpendicular - anisotropy
|
||||
|
||||
vec3 fiberParallel = normalize(fiberDirection);
|
||||
vec3 fiberPerpendicular = normalize(cross(N, fiberDirection));
|
||||
float dotXH = dot(fiberParallel, H);
|
||||
float dotYH = dot(fiberPerpendicular, H);
|
||||
float coeff = sqrt(dotNL/dotNV) / (4.0 * PI * shinyParallel * shinyPerpendicular);
|
||||
float theta = (pow(dotXH/shinyParallel, 2.0) + pow(dotYH/shinyPerpendicular, 2.0)) / (1.0 + dotNH);
|
||||
return clamp(coeff * exp(-2.0 * theta), 0.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
vec4 sampleVoxels(vec3 worldPosition, float lod) {
|
||||
vec3 offset = vec3(1.0 / voxelDimensions, 1.0 / voxelDimensions, 0);
|
||||
vec3 texco = worldPosition / (voxelGridWorldSize * 0.5);
|
||||
texco = texco * 0.5 + 0.5 + offset;
|
||||
return textureLod(voxels, texco, lod);
|
||||
}
|
||||
vec4 coneTrace(vec3 posWorld, vec3 direction, vec3 norWorld, float tanHalfAngle, out float occlusion) {
|
||||
const float voxelWorldSize = voxelGridWorldSize / voxelDimensions;
|
||||
float dist = voxelWorldSize; // Start one voxel away to avoid self occlusion
|
||||
vec3 startPos = posWorld + norWorld * voxelWorldSize;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
float alpha = 0.0;
|
||||
occlusion = 0.0;
|
||||
while (dist < maxDist && alpha < alphaTreshold) {
|
||||
// Smallest sample diameter possible is the voxel size
|
||||
float diameter = max(voxelWorldSize, 2.0 * tanHalfAngle * dist);
|
||||
float lodLevel = log2(diameter / voxelWorldSize);
|
||||
vec4 voxelColor = sampleVoxels(startPos + dist * direction, lodLevel);
|
||||
// Front-to-back compositing
|
||||
float a = (1.0 - alpha);
|
||||
color += a * voxelColor.rgb;
|
||||
alpha += a * voxelColor.a;
|
||||
occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter);
|
||||
dist += diameter * 0.5; // * 2.0
|
||||
}
|
||||
return vec4(color, alpha);
|
||||
}
|
||||
vec4 indirectLight(vec3 posWorld, mat3 tanToWorld, vec3 norWorld, out float occlusion) {
|
||||
vec4 color = vec4(0);
|
||||
occlusion = 0.0;
|
||||
|
||||
for (int i = 0; i < numCones; i++) {
|
||||
float coneOcclusion;
|
||||
const float tanangle = tan(30):
|
||||
color += coneWeights[i] * coneTrace(posWorld, tanToWorld * coneDirections[i], norWorld, tanangle, coneOcclusion);
|
||||
occlusion += coneWeights[i] * coneOcclusion;
|
||||
}
|
||||
occlusion = 1.0 - occlusion;
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec2 screenPosition = wvpposition.xy / wvpposition.w;
|
||||
vec2 texCoord = screenPosition * 0.5 + 0.5;
|
||||
|
@ -647,8 +109,7 @@ void main() {
|
|||
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vec3 p = getPos(depth, texCoord);
|
||||
// vec3 p = getPos(depth);
|
||||
vec3 p = getPos2(invVP, depth, texCoord);
|
||||
vec2 metrough = unpackFloat(g0.b);
|
||||
|
||||
vec3 v = normalize(eye - p.xyz);
|
||||
|
@ -697,10 +158,12 @@ void main() {
|
|||
}
|
||||
|
||||
// Aniso spec
|
||||
// #ifdef _Aniso
|
||||
// float shinyParallel = metrough.y;
|
||||
// float shinyPerpendicular = 0.08;
|
||||
// vec3 fiberDirection = vec3(0.0, 1.0, 8.0);
|
||||
// vec3 direct = diffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH, dotLV) + wardSpecular(n, h, dotNL, dotNV, dotNH, fiberDirection, shinyParallel, shinyPerpendicular);
|
||||
// #endif
|
||||
direct = direct * lightColor * lightStrength;
|
||||
|
||||
|
||||
|
@ -727,13 +190,13 @@ void main() {
|
|||
mat3 tanToWorld = inverse(transpose(mat3(tangent, bitangent, n)));
|
||||
|
||||
float diffOcclusion = 0.0;
|
||||
vec3 indirectDiffusea = indirectLight(p, tanToWorld, n, diffOcclusion).rgb * 4.0;
|
||||
vec3 indirectDiffusea = coneTraceIndirect(p, tanToWorld, n, diffOcclusion).rgb * 4.0;
|
||||
indirectDiffusea *= albedoa;
|
||||
diffOcclusion = min(1.0, 1.5 * diffOcclusion);
|
||||
|
||||
vec3 reflectWorld = reflect(-v, n);
|
||||
float specularOcclusion;
|
||||
float lodOffset = 0.0;//getMipLevelFromRoughness(roughness);
|
||||
float lodOffset = 0.0;//getMipFromRoughness(roughness, numMips);
|
||||
vec3 indirectSpecular = coneTrace(p, reflectWorld, n, 0.07 + lodOffset, specularOcclusion).rgb;
|
||||
|
||||
if (metrough.y > 0.0) { // Temp..
|
||||
|
|
|
@ -5,26 +5,45 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
// surfaceAlbedo()
|
||||
// surfaceF0()
|
||||
// orenNayarDiffuseBRDF()
|
||||
// lambertDiffuseBRDF()
|
||||
// specularBRDF()
|
||||
#ifdef _Rad
|
||||
#include "../std/math.glsl"
|
||||
// envMapEquirect()
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
#ifdef _PCSS
|
||||
#include "../std/shadows_pcss.glsl"
|
||||
// PCSS()
|
||||
#else
|
||||
#include "../std/shadows.glsl"
|
||||
// PCF()
|
||||
#endif
|
||||
#endif
|
||||
#include "../std/shirr.glsl"
|
||||
// shIrradiance()
|
||||
//!uniform float shirr[27];
|
||||
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
uniform sampler2D shadowMap;
|
||||
//!uniform sampler2D shadowMap;
|
||||
#ifdef _PCSS
|
||||
uniform sampler2D snoise;
|
||||
uniform float lampSizeUV;
|
||||
uniform float lampNear;
|
||||
//!uniform sampler2D snoise;
|
||||
//!uniform float lampSizeUV;
|
||||
//!uniform float lampNear;
|
||||
#endif
|
||||
#endif
|
||||
uniform float shirr[27];
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
uniform int envmapNumMipmaps;
|
||||
#endif
|
||||
// uniform sampler2D sltcMat;
|
||||
// uniform sampler2D sltcMag;
|
||||
#ifdef _NorTex
|
||||
uniform sampler2D snormal;
|
||||
#endif
|
||||
|
@ -49,10 +68,6 @@ uniform sampler2D srough;
|
|||
#else
|
||||
uniform float metalness;
|
||||
#endif
|
||||
// #ifdef _HeightTex
|
||||
// uniform sampler2D sheight;
|
||||
// uniform float heightStrength;
|
||||
// #endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
uniform bool receiveShadow;
|
||||
|
@ -67,43 +82,11 @@ uniform float shadowsBias;
|
|||
uniform vec3 eye;
|
||||
|
||||
#ifdef _VoxelGI
|
||||
uniform sampler3D voxels;
|
||||
const float voxelGridWorldSize = 150.0;
|
||||
const int voxelDimensions = 512;
|
||||
const float maxDist = 30.0;
|
||||
const float alphaTreshold = 0.95;
|
||||
const int numCones = 6;
|
||||
vec3 coneDirections[6] = vec3[](
|
||||
vec3(0, 1, 0),
|
||||
vec3(0, 0.5, 0.866025),
|
||||
vec3(0.823639, 0.5, 0.267617),
|
||||
vec3(0.509037, 0.5, -0.700629),
|
||||
vec3(-0.509037, 0.5, -0.700629),
|
||||
vec3(-0.823639, 0.5, 0.267617));
|
||||
float coneWeights[6] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
|
||||
uniform sampler2D ssaotex;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
//!uniform sampler3D voxels;
|
||||
#endif
|
||||
|
||||
// LTC
|
||||
// uniform vec3 light;
|
||||
// //// const float roughness = 0.25;
|
||||
// const vec3 dcolor = vec3(1.0, 1.0, 1.0);
|
||||
// const vec3 scolor = vec3(1.0, 1.0, 1.0);
|
||||
// const float intensity = 4.0; // 0-10
|
||||
// const float width = 4.0;
|
||||
// const float height = 4.0;
|
||||
// const vec2 resolution = vec2(800.0, 600.0);
|
||||
// const int sampleCount = 0;
|
||||
// const int NUM_SAMPLES = 8;
|
||||
// const float LUT_SIZE = 64.0;
|
||||
// const float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;
|
||||
// const float LUT_BIAS = 0.5/LUT_SIZE;
|
||||
// //// vec2 mys[NUM_SAMPLES];
|
||||
// vec3 L0 = vec3(0.0);
|
||||
// vec3 L1 = vec3(0.0);
|
||||
// vec3 L2 = vec3(0.0);
|
||||
// vec3 L3 = vec3(0.0);
|
||||
// vec3 L4 = vec3(0.0);
|
||||
|
||||
in vec3 position;
|
||||
#ifdef _Tex
|
||||
in vec2 texCoord;
|
||||
|
@ -119,244 +102,6 @@ in vec3 eyeDir;
|
|||
out vec4 fragColor;
|
||||
|
||||
#ifndef _NoShadows
|
||||
#ifndef _PCSS
|
||||
// float linstep(float low, float high, float v) {
|
||||
// return clamp((v - low) / (high - low), 0.0, 1.0);
|
||||
// }
|
||||
// float VSM(vec2 uv, float compare) {
|
||||
// vec2 moments = texture(shadowMap, uv).xy;
|
||||
// float p = smoothstep(compare - 0.02, compare, moments.x);
|
||||
// float variance = max(moments.y - moments.x * moments.x, -0.001);
|
||||
// float d = compare - moments.x;
|
||||
// float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
|
||||
// return clamp(max(p, p_max), 0.0, 1.0);
|
||||
// }
|
||||
float texture2DCompare(vec2 uv, float compare){
|
||||
float depth = texture(shadowMap, uv).r * 2.0 - 1.0;
|
||||
return step(compare, depth);
|
||||
}
|
||||
float texture2DShadowLerp(vec2 size, vec2 uv, float compare){
|
||||
vec2 texelSize = vec2(1.0) / size;
|
||||
vec2 f = fract(uv * size + 0.5);
|
||||
vec2 centroidUV = floor(uv * size + 0.5) / size;
|
||||
|
||||
float lb = texture2DCompare(centroidUV + texelSize * vec2(0.0, 0.0), compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize * vec2(1.0, 1.0), compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
float PCF(vec2 uv, float compare) {
|
||||
float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
|
||||
vec2 off = vec2(-1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
#else // _PCSS
|
||||
const int NUM_SAMPLES = 17;
|
||||
const float radiusStep = 1.0 / float(NUM_SAMPLES);
|
||||
const float angleStep = PI2 * float(pcssRings) / float(NUM_SAMPLES);
|
||||
vec2 poissonDisk0; vec2 poissonDisk1; vec2 poissonDisk2;
|
||||
vec2 poissonDisk3; vec2 poissonDisk4; vec2 poissonDisk5;
|
||||
vec2 poissonDisk6; vec2 poissonDisk7; vec2 poissonDisk8;
|
||||
vec2 poissonDisk9; vec2 poissonDisk10; vec2 poissonDisk11;
|
||||
vec2 poissonDisk12; vec2 poissonDisk13; vec2 poissonDisk14;
|
||||
vec2 poissonDisk15; vec2 poissonDisk16;
|
||||
void initPoissonSamples(const in vec2 randomSeed) {
|
||||
float angle = texture(snoise, randomSeed).r * PI2;
|
||||
float radius = radiusStep;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
poissonDisk0 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk1 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk2 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk3 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk4 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk5 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk6 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk7 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk8 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk9 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk10 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk11 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk12 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk13 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk14 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk15 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk16 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
// }
|
||||
}
|
||||
float findBlocker(const in vec2 uv, const in float zReceiver) {
|
||||
// This uses similar triangles to compute what area of the shadow map we should search
|
||||
float searchRadius = lampSizeUV * (zReceiver - lampNear) / zReceiver;
|
||||
float blockerDepthSum = 0.0;
|
||||
int numBlockers = 0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float shadowMapDepth = texture(shadowMap, uv + poissonDisk0 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk1 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk2 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk3 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk4 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk5 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk6 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk7 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk8 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk9 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk10 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk11 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk12 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk13 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk14 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk15 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk16 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
// }
|
||||
if (numBlockers == 0) return -1.0;
|
||||
return blockerDepthSum / float(numBlockers);
|
||||
}
|
||||
float filterPCF(vec2 uv, float zReceiver, float filterRadius) {
|
||||
float sum = 0.0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float depth = texture(shadowMap, uv + poissonDisk0 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk1 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk2 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk3 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk4 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk5 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk6 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk7 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk8 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk9 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk10 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk11 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk12 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk13 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk14 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk15 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk16 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
depth = texture(shadowMap, uv + -poissonDisk0.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk1.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk2.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk3.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk4.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk5.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk6.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk7.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk8.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk9.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk10.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk11.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk12.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk13.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk14.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk15.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk16.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
return sum / (2.0 * float(NUM_SAMPLES));
|
||||
}
|
||||
float PCSS(vec2 uv, float zReceiver) {
|
||||
initPoissonSamples(uv);
|
||||
float avgBlockerDepth = findBlocker(uv, zReceiver);
|
||||
if (avgBlockerDepth == -1.0) return 1.0;
|
||||
float penumbraRatio = (zReceiver - avgBlockerDepth) / avgBlockerDepth;
|
||||
float filterRadius = penumbraRatio * lampSizeUV * lampNear / zReceiver;
|
||||
return filterPCF(uv, zReceiver, filterRadius);
|
||||
}
|
||||
#endif
|
||||
float shadowTest(vec4 lPos) {
|
||||
lPos.xyz /= lPos.w;
|
||||
lPos.xy = lPos.xy * 0.5 + 0.5;
|
||||
|
@ -371,361 +116,12 @@ float shadowTest(vec4 lPos) {
|
|||
}
|
||||
#endif
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.y * nor.x +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
|
||||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
|
||||
vec2 LightingFuncGGX_FV(float dotLH, float roughness) {
|
||||
float alpha = roughness*roughness;
|
||||
|
||||
// F
|
||||
float F_a, F_b;
|
||||
float dotLH5 = pow(1.0 - dotLH, 5.0);
|
||||
F_a = 1.0;
|
||||
F_b = dotLH5;
|
||||
|
||||
// V
|
||||
float vis;
|
||||
float k = alpha / 2.0;
|
||||
float k2 = k * k;
|
||||
float invK2 = 1.0 - k2;
|
||||
//vis = rcp(dotLH * dotLH * invK2 + k2);
|
||||
vis = inversesqrt(dotLH * dotLH * invK2 + k2);
|
||||
|
||||
return vec2(F_a * vis, F_b * vis);
|
||||
}
|
||||
|
||||
float LightingFuncGGX_D(float dotNH, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSqr = alpha * alpha;
|
||||
float pi = 3.14159;
|
||||
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
float D = alphaSqr / (pi * denom * denom);
|
||||
return D;
|
||||
}
|
||||
|
||||
// John Hable - Optimizing GGX Shaders
|
||||
// http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
|
||||
float LightingFuncGGX_OPT3(float dotNL, float dotLH, float dotNH, float roughness, float F0) {
|
||||
// vec3 H = normalize(V + L);
|
||||
// float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
// float dotLH = clamp(dot(L, H), 0.0, 1.0);
|
||||
// float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
float D = LightingFuncGGX_D(dotNH, roughness);
|
||||
vec2 FV_helper = LightingFuncGGX_FV(dotLH, roughness);
|
||||
float FV = F0 * FV_helper.x + (1.0 - F0) * FV_helper.y;
|
||||
float specular = dotNL * D * FV;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
#ifdef _OrenNayar
|
||||
vec3 orenNayarDiffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh) {
|
||||
float a = roughness * roughness;
|
||||
float s = a;
|
||||
float s2 = s * s;
|
||||
float vl = 2.0 * vh * vh - 1.0; // Double angle identity
|
||||
float Cosri = vl - nv * nl;
|
||||
float C1 = 1.0 - 0.5 * s2 / (s2 + 0.33);
|
||||
float test = 1.0;
|
||||
if (Cosri >= 0.0) test = (1.0 / (max(nl, nv)));
|
||||
float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * test;
|
||||
return albedo * max(0.0, nl) * (C1 + C2) * (1.0 + roughness * 0.5);
|
||||
}
|
||||
#else
|
||||
vec3 lambertDiffuseBRDF(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * envmapNumMipmaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Linearly Transformed Cosines
|
||||
/*
|
||||
vec3 mul(mat3 m, vec3 v) {
|
||||
return m * v;
|
||||
}
|
||||
mat3 mul(mat3 m1, mat3 m2) {
|
||||
return m1 * m2;
|
||||
}
|
||||
mat3 transpose2(mat3 v) {
|
||||
mat3 tmp;
|
||||
tmp[0] = vec3(v[0].x, v[1].x, v[2].x);
|
||||
tmp[1] = vec3(v[0].y, v[1].y, v[2].y);
|
||||
tmp[2] = vec3(v[0].z, v[1].z, v[2].z);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
float IntegrateEdge(vec3 v1, vec3 v2) {
|
||||
float cosTheta = dot(v1, v2);
|
||||
cosTheta = clamp(cosTheta, -0.9999, 0.9999);
|
||||
float theta = acos(cosTheta);
|
||||
float res = cross(v1, v2).z * theta / sin(theta);
|
||||
return res;
|
||||
}
|
||||
int ClipQuadToHorizon() { //inout vec3 L[5], out int n) {
|
||||
// detect clipping config
|
||||
int config = 0;
|
||||
if (L0.z > 0.0) config += 1;
|
||||
if (L1.z > 0.0) config += 2;
|
||||
if (L2.z > 0.0) config += 4;
|
||||
if (L3.z > 0.0) config += 8;
|
||||
|
||||
// clip
|
||||
int n = 0;
|
||||
if (config == 0) {
|
||||
// clip all
|
||||
}
|
||||
else if (config == 1) { // V1 clip V2 V3 V4
|
||||
n = 3;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 2) { // V2 clip V1 V3 V4
|
||||
n = 3;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 3) { // V1 V2 clip V3 V4
|
||||
n = 4;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
L3 = -L3.z * L0 + L0.z * L3;
|
||||
}
|
||||
else if (config == 4) { // V3 clip V1 V2 V4
|
||||
n = 3;
|
||||
L0 = -L3.z * L2 + L2.z * L3;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
}
|
||||
else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 6) { // V2 V3 clip V1 V4
|
||||
n = 4;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 7) { // V1 V2 V3 clip V4
|
||||
n = 5;
|
||||
L4 = -L3.z * L0 + L0.z * L3;
|
||||
L3 = -L3.z * L2 + L2.z * L3;
|
||||
}
|
||||
else if (config == 8) { // V4 clip V1 V2 V3
|
||||
n = 3;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
L1 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = L3;
|
||||
}
|
||||
else if (config == 9) { // V1 V4 clip V2 V3
|
||||
n = 4;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
L2 = -L2.z * L3 + L3.z * L2;
|
||||
}
|
||||
else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
n = 0;
|
||||
}
|
||||
else if (config == 11) { // V1 V2 V4 clip V3
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = -L2.z * L3 + L3.z * L2;
|
||||
L2 = -L2.z * L1 + L1.z * L2;
|
||||
}
|
||||
else if (config == 12) { // V3 V4 clip V1 V2
|
||||
n = 4;
|
||||
L1 = -L1.z * L2 + L2.z * L1;
|
||||
L0 = -L0.z * L3 + L3.z * L0;
|
||||
}
|
||||
else if (config == 13) { // V1 V3 V4 clip V2
|
||||
n = 5;
|
||||
L4 = L3;
|
||||
L3 = L2;
|
||||
L2 = -L1.z * L2 + L2.z * L1;
|
||||
L1 = -L1.z * L0 + L0.z * L1;
|
||||
}
|
||||
else if (config == 14) { // V2 V3 V4 clip V1
|
||||
n = 5;
|
||||
L4 = -L0.z * L3 + L3.z * L0;
|
||||
L0 = -L0.z * L1 + L1.z * L0;
|
||||
}
|
||||
else if (config == 15) { // V1 V2 V3 V4
|
||||
n = 4;
|
||||
}
|
||||
|
||||
if (n == 3)
|
||||
L3 = L0;
|
||||
if (n == 4)
|
||||
L4 = L0;
|
||||
return n;
|
||||
}
|
||||
vec3 LTC_Evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3, bool twoSided) {
|
||||
// construct orthonormal basis around N
|
||||
vec3 T1, T2;
|
||||
T1 = normalize(V - N*dot(V, N));
|
||||
T2 = cross(N, T1);
|
||||
|
||||
// rotate area light in (T1, T2, R) basis
|
||||
Minv = mul(Minv, transpose2(mat3(T1, T2, N)));
|
||||
|
||||
// polygon (allocate 5 vertices for clipping)
|
||||
// vec3 L[5];
|
||||
L0 = mul(Minv, points0 - P);
|
||||
L1 = mul(Minv, points1 - P);
|
||||
L2 = mul(Minv, points2 - P);
|
||||
L3 = mul(Minv, points3 - P);
|
||||
|
||||
int n = ClipQuadToHorizon(); //L, n);
|
||||
|
||||
if (n == 0) {
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
// project onto sphere
|
||||
L0 = normalize(L0);
|
||||
L1 = normalize(L1);
|
||||
L2 = normalize(L2);
|
||||
L3 = normalize(L3);
|
||||
L4 = normalize(L4);
|
||||
|
||||
// integrate
|
||||
float sum = 0.0;
|
||||
|
||||
sum += IntegrateEdge(L0, L1);
|
||||
sum += IntegrateEdge(L1, L2);
|
||||
sum += IntegrateEdge(L2, L3);
|
||||
|
||||
if (n >= 4) {
|
||||
sum += IntegrateEdge(L3, L4);
|
||||
}
|
||||
if (n == 5) {
|
||||
sum += IntegrateEdge(L4, L0);
|
||||
}
|
||||
|
||||
sum = twoSided ? abs(sum) : max(0.0, -sum);
|
||||
|
||||
vec3 Lo_i = vec3(sum, sum, sum);
|
||||
|
||||
return Lo_i;
|
||||
}*/
|
||||
|
||||
#ifdef _Toon
|
||||
float stepmix(float edge0, float edge1, float E, float x) {
|
||||
float T = clamp(0.5 * (x - edge0 + E) / E, 0.0, 1.0);
|
||||
return mix(edge0, edge1, T);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _VoxelGI
|
||||
vec4 sampleVoxels(vec3 worldPosition, float lod) {
|
||||
vec3 offset = vec3(1.0 / voxelDimensions, 1.0 / voxelDimensions, 0);
|
||||
vec3 texco = worldPosition / (voxelGridWorldSize * 0.5);
|
||||
texco = texco * 0.5 + 0.5 + offset;
|
||||
return textureLod(voxels, texco, lod);
|
||||
}
|
||||
// See https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
vec4 coneTrace(vec3 posWorld, vec3 direction, vec3 norWorld, float tanHalfAngle, out float occlusion) {
|
||||
const float voxelWorldSize = voxelGridWorldSize / voxelDimensions;
|
||||
float dist = voxelWorldSize; // Start one voxel away to avoid self occlusion
|
||||
vec3 startPos = posWorld + norWorld * voxelWorldSize;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
float alpha = 0.0;
|
||||
occlusion = 0.0;
|
||||
while (dist < maxDist && alpha < alphaTreshold) {
|
||||
// Smallest sample diameter possible is the voxel size
|
||||
float diameter = max(voxelWorldSize, 2.0 * tanHalfAngle * dist);
|
||||
float lodLevel = log2(diameter / voxelWorldSize);
|
||||
vec4 voxelColor = sampleVoxels(startPos + dist * direction, lodLevel);
|
||||
// Front-to-back compositing
|
||||
float a = (1.0 - alpha);
|
||||
color += a * voxelColor.rgb;
|
||||
alpha += a * voxelColor.a;
|
||||
occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter);
|
||||
dist += diameter * 0.5; // * 2.0
|
||||
}
|
||||
return vec4(color, alpha);
|
||||
}
|
||||
vec4 indirectLight(vec3 posWorld, mat3 tanToWorld, vec3 norWorld, out float occlusion) {
|
||||
vec4 color = vec4(0);
|
||||
occlusion = 0.0;
|
||||
|
||||
for (int i = 0; i < numCones; i++) {
|
||||
float coneOcclusion;
|
||||
const float tanangle = tan(30):
|
||||
color += coneWeights[i] * coneTrace(posWorld, tanToWorld * coneDirections[i], norWorld, tanangle, coneOcclusion);
|
||||
occlusion += coneWeights[i] * coneOcclusion;
|
||||
}
|
||||
occlusion = 1.0 - occlusion;
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
// #ifdef _Toon
|
||||
// float stepmix(float edge0, float edge1, float E, float x) {
|
||||
// float T = clamp(0.5 * (x - edge0 + E) / E, 0.0, 1.0);
|
||||
// return mix(edge0, edge1, T);
|
||||
// }
|
||||
// #endif
|
||||
|
||||
void main() {
|
||||
|
||||
|
@ -805,7 +201,6 @@ void main() {
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
// #ifdef _Toon
|
||||
// vec3 v = normalize(eyeDir);
|
||||
// vec3 h = normalize(v + l);
|
||||
|
@ -908,7 +303,6 @@ void main() {
|
|||
// vec3 ltccol = ltcspec + ltcdiff * albedo;
|
||||
// ltccol /= 2.0*PI;
|
||||
|
||||
|
||||
// Direct
|
||||
#ifdef _OrenNayar
|
||||
vec3 direct = orenNayarDiffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
|
||||
|
@ -944,7 +338,7 @@ void main() {
|
|||
|
||||
vec3 reflectWorld = reflect(-v, n);
|
||||
float specularOcclusion;
|
||||
float lodOffset = 0.0;//getMipLevelFromRoughness(roughness);
|
||||
float lodOffset = 0.0;//getMipFromRoughness(roughness, numMips);
|
||||
vec3 indirectSpecular = coneTrace(reflectWorld, n, 0.07 + lodOffset, specularOcclusion).rgb;
|
||||
if (roughness > 0.0) { // Temp..
|
||||
vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;
|
||||
|
@ -965,7 +359,7 @@ void main() {
|
|||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);// + 1.0;
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);// + 1.0;
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _EnvLDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
|
@ -980,7 +374,6 @@ void main() {
|
|||
|
||||
fragColor = vec4(vec3(direct * visibility + indirect), 1.0);
|
||||
|
||||
|
||||
#ifdef _OccTex
|
||||
vec3 occ = texture(socclusion, texCoord).rgb;
|
||||
fragColor.rgb *= occ;
|
||||
|
@ -988,16 +381,10 @@ void main() {
|
|||
fragColor.rgb *= occlusion;
|
||||
#endif
|
||||
|
||||
|
||||
// LTC
|
||||
// fragColor.rgb = ltccol * 10.0 * visibility + indirect / 14.0;
|
||||
|
||||
|
||||
#ifdef _LDR
|
||||
// gl_FragColor = vec4(pow(fragColor.rgb, vec3(1.0 / 2.2)), fragColor.a);
|
||||
fragColor = vec4(pow(fragColor.rgb, vec3(1.0 / 2.2)), fragColor.a);
|
||||
// #else
|
||||
// gl_FragColor = vec4(fragColor.rgb, fragColor.a);
|
||||
//fragColor = vec4(fragColor.rgb, fragColor.a);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -5,6 +5,14 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#ifdef _Skinning
|
||||
#include "../std/skinning.glsl"
|
||||
// getSkinningDualQuat()
|
||||
#endif
|
||||
#ifdef _VR
|
||||
#include "../std/vr.glsl"
|
||||
// undistort()
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
|
@ -37,11 +45,11 @@ uniform mat4 LWVP;
|
|||
uniform vec4 baseCol;
|
||||
uniform vec3 eye;
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[skinMaxBones * 8];
|
||||
//!uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
#ifdef _VR
|
||||
uniform mat4 U; // Undistortion
|
||||
uniform float maxRadSq;
|
||||
// !uniform mat4 U;
|
||||
// !uniform float maxRadSq;
|
||||
#endif
|
||||
|
||||
out vec3 position;
|
||||
|
@ -57,88 +65,13 @@ out vec3 eyeDir;
|
|||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
void getSkinningDualQuat(vec4 weights, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[int(bone.x) * 8 + 0];
|
||||
matA[0][1] = skinBones[int(bone.x) * 8 + 1];
|
||||
matA[0][2] = skinBones[int(bone.x) * 8 + 2];
|
||||
matA[0][3] = skinBones[int(bone.x) * 8 + 3];
|
||||
matB[0][0] = skinBones[int(bone.x) * 8 + 4];
|
||||
matB[0][1] = skinBones[int(bone.x) * 8 + 5];
|
||||
matB[0][2] = skinBones[int(bone.x) * 8 + 6];
|
||||
matB[0][3] = skinBones[int(bone.x) * 8 + 7];
|
||||
matA[1][0] = skinBones[int(bone.y) * 8 + 0];
|
||||
matA[1][1] = skinBones[int(bone.y) * 8 + 1];
|
||||
matA[1][2] = skinBones[int(bone.y) * 8 + 2];
|
||||
matA[1][3] = skinBones[int(bone.y) * 8 + 3];
|
||||
matB[1][0] = skinBones[int(bone.y) * 8 + 4];
|
||||
matB[1][1] = skinBones[int(bone.y) * 8 + 5];
|
||||
matB[1][2] = skinBones[int(bone.y) * 8 + 6];
|
||||
matB[1][3] = skinBones[int(bone.y) * 8 + 7];
|
||||
matA[2][0] = skinBones[int(bone.z) * 8 + 0];
|
||||
matA[2][1] = skinBones[int(bone.z) * 8 + 1];
|
||||
matA[2][2] = skinBones[int(bone.z) * 8 + 2];
|
||||
matA[2][3] = skinBones[int(bone.z) * 8 + 3];
|
||||
matB[2][0] = skinBones[int(bone.z) * 8 + 4];
|
||||
matB[2][1] = skinBones[int(bone.z) * 8 + 5];
|
||||
matB[2][2] = skinBones[int(bone.z) * 8 + 6];
|
||||
matB[2][3] = skinBones[int(bone.z) * 8 + 7];
|
||||
matA[3][0] = skinBones[int(bone.w) * 8 + 0];
|
||||
matA[3][1] = skinBones[int(bone.w) * 8 + 1];
|
||||
matA[3][2] = skinBones[int(bone.w) * 8 + 2];
|
||||
matA[3][3] = skinBones[int(bone.w) * 8 + 3];
|
||||
matB[3][0] = skinBones[int(bone.w) * 8 + 4];
|
||||
matB[3][1] = skinBones[int(bone.w) * 8 + 5];
|
||||
matB[3][2] = skinBones[int(bone.w) * 8 + 6];
|
||||
matB[3][3] = skinBones[int(bone.w) * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weights.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weights.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weights; // Real part
|
||||
B = matB * weights; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _VR
|
||||
// GoogleVR Distortion using Vertex Displacement
|
||||
float distortionFactor(float rSquared) {
|
||||
float ret = 0.0;
|
||||
ret = rSquared * (ret + U[1][1]);
|
||||
ret = rSquared * (ret + U[0][1]);
|
||||
ret = rSquared * (ret + U[3][0]);
|
||||
ret = rSquared * (ret + U[2][0]);
|
||||
ret = rSquared * (ret + U[1][0]);
|
||||
ret = rSquared * (ret + U[0][0]);
|
||||
return ret + 1.0;
|
||||
}
|
||||
// Convert point from world space to undistorted camera space
|
||||
vec4 undistort(mat4 WV, vec4 pos) {
|
||||
// Go to camera space
|
||||
pos = WV * pos;
|
||||
const float nearClip = 0.1;
|
||||
if (pos.z <= -nearClip) { // Reminder: Forward is -Z
|
||||
// Undistort the point's coordinates in XY
|
||||
float r2 = clamp(dot(pos.xy, pos.xy) / (pos.z * pos.z), 0.0, maxRadSq);
|
||||
pos.xy *= distortionFactor(r2);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 sPos = vec4(pos, 1.0);
|
||||
|
||||
#ifdef _Skinning
|
||||
vec4 skinA;
|
||||
vec4 skinB;
|
||||
getSkinningDualQuat(weight, skinA, skinB);
|
||||
getSkinningDualQuat(ivec4(bone), weight, skinA, skinB);
|
||||
sPos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, sPos.xyz) + skinA.w * sPos.xyz); // Rotate
|
||||
sPos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate
|
||||
vec3 _normal = normalize(mat3(N) * (nor + 2.0 * cross(skinA.xyz, cross(skinA.xyz, nor) + skinA.w * nor)));
|
||||
|
|
|
@ -5,57 +5,57 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 texStep; // screenSizeInv
|
||||
uniform vec2 screenSizeInv;
|
||||
|
||||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
vec2 tcrgbNW = (texCoord + vec2(-1.0, -1.0) * texStep);
|
||||
vec2 tcrgbNE = (texCoord + vec2(1.0, -1.0) * texStep);
|
||||
vec2 tcrgbSW = (texCoord + vec2(-1.0, 1.0) * texStep);
|
||||
vec2 tcrgbSE = (texCoord + vec2(1.0, 1.0) * texStep);
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
vec2 tcrgbNW = (texCoord + vec2(-1.0, -1.0) * screenSizeInv);
|
||||
vec2 tcrgbNE = (texCoord + vec2(1.0, -1.0) * screenSizeInv);
|
||||
vec2 tcrgbSW = (texCoord + vec2(-1.0, 1.0) * screenSizeInv);
|
||||
vec2 tcrgbSE = (texCoord + vec2(1.0, 1.0) * screenSizeInv);
|
||||
vec2 tcrgbM = vec2(texCoord);
|
||||
|
||||
vec3 rgbNW = texture(tex, tcrgbNW).rgb;
|
||||
vec3 rgbNE = texture(tex, tcrgbNE).rgb;
|
||||
vec3 rgbSW = texture(tex, tcrgbSW).rgb;
|
||||
vec3 rgbSE = texture(tex, tcrgbSE).rgb;
|
||||
vec4 texColor = texture(tex, tcrgbM);
|
||||
vec3 rgbNE = texture(tex, tcrgbNE).rgb;
|
||||
vec3 rgbSW = texture(tex, tcrgbSW).rgb;
|
||||
vec3 rgbSE = texture(tex, tcrgbSE).rgb;
|
||||
vec4 texColor = texture(tex, tcrgbM);
|
||||
vec3 rgbM = texColor.rgb;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
|
||||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * texStep;
|
||||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * screenSizeInv;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
texture(tex, texCoord + dir * (1.0 / 3.0 - 0.5)).rgb +
|
||||
texture(tex, texCoord + dir * (2.0 / 3.0 - 0.5)).rgb);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture(tex, texCoord + dir * -0.5).rgb +
|
||||
texture(tex, texCoord + dir * 0.5).rgb);
|
||||
texture(tex, texCoord + dir * (1.0 / 3.0 - 0.5)).rgb +
|
||||
texture(tex, texCoord + dir * (2.0 / 3.0 - 0.5)).rgb);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture(tex, texCoord + dir * -0.5).rgb +
|
||||
texture(tex, texCoord + dir * 0.5).rgb);
|
||||
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax)) fragColor = vec4(rgbA, texColor.a);
|
||||
else fragColor = vec4(rgbB, texColor.a);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax)) fragColor = vec4(rgbA, texColor.a);
|
||||
else fragColor = vec4(rgbB, texColor.a);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"cull_mode": "none",
|
||||
"links": [
|
||||
{
|
||||
"name": "texStep",
|
||||
"name": "screenSizeInv",
|
||||
"link": "_screenSizeInv"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -9,5 +9,5 @@ in vec4 color;
|
|||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = color;
|
||||
fragColor = color;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
],
|
||||
"texture_params": [],
|
||||
"vertex_shader": "grease_pencil_shadows.vert.glsl",
|
||||
"fragment_shader": "grease_pencil_shadows.frag.glsl"
|
||||
"fragment_shader": "grease_pencil_shadows.frag.glsl",
|
||||
"fragment_shader_path": "../include/shadowmap.frag.glsl"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
|
@ -7,19 +7,41 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
// ...
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
// packFloat()
|
||||
#include "../std/tonemap.glsl"
|
||||
// tonemapUncharted2()
|
||||
#ifdef _Rad
|
||||
#include "../std/math.glsl"
|
||||
// envMapEquirect()
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
#ifdef _PCSS
|
||||
#include "../std/shadows_pcss.glsl"
|
||||
// PCSS()
|
||||
#else
|
||||
#include "../std/shadows.glsl"
|
||||
// PCF()
|
||||
#endif
|
||||
#endif
|
||||
#include "../std/shirr.glsl"
|
||||
// shIrradiance()
|
||||
//!uniform float shirr[27];
|
||||
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
uniform sampler2D shadowMap;
|
||||
#ifdef _PCSS
|
||||
uniform sampler2D snoise;
|
||||
uniform float lampSizeUV;
|
||||
uniform float lampNear;
|
||||
//!uniform sampler2D shadowMap;
|
||||
#ifdef _PCSS
|
||||
//!uniform sampler2D snoise;
|
||||
//!uniform float lampSizeUV;
|
||||
//!uniform float lampNear;
|
||||
#endif
|
||||
#endif
|
||||
uniform float shirr[27];
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
|
@ -29,7 +51,7 @@ uniform float shirr[27];
|
|||
uniform sampler2D snormal;
|
||||
#endif
|
||||
#ifdef _NorStr
|
||||
uniform float normalStrength;
|
||||
uniform float normalStrength;
|
||||
#endif
|
||||
#ifdef _OccTex
|
||||
uniform sampler2D socclusion;
|
||||
|
@ -42,17 +64,13 @@ uniform sampler2D srough;
|
|||
uniform float roughness;
|
||||
#endif
|
||||
#ifdef _RoughStr
|
||||
uniform float roughnessStrength;
|
||||
uniform float roughnessStrength;
|
||||
#endif
|
||||
#ifdef _MetTex
|
||||
uniform sampler2D smetal;
|
||||
#else
|
||||
uniform float metalness;
|
||||
#endif
|
||||
// #ifdef _HeightTex
|
||||
// uniform sampler2D sheight;
|
||||
// uniform float heightStrength;
|
||||
// #endif
|
||||
|
||||
uniform float envmapStrength;
|
||||
uniform bool receiveShadow;
|
||||
|
@ -81,236 +99,10 @@ in vec3 eyeDir;
|
|||
out vec4[2] fragColor;
|
||||
|
||||
#ifndef _NoShadows
|
||||
#ifndef _PCSS
|
||||
float texture2DCompare(vec2 uv, float compare) {
|
||||
float depth = texture(shadowMap, uv).r * 2.0 - 1.0;
|
||||
return step(compare, depth);
|
||||
}
|
||||
float texture2DShadowLerp(vec2 size, vec2 uv, float compare) {
|
||||
vec2 texelSize = vec2(1.0) / size;
|
||||
vec2 f = fract(uv * size + 0.5);
|
||||
vec2 centroidUV = floor(uv * size + 0.5) / size;
|
||||
|
||||
float lb = texture2DCompare(centroidUV + texelSize * vec2(0.0, 0.0), compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize * vec2(1.0, 1.0), compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
float PCF(vec2 uv, float compare) {
|
||||
float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
vec2 off = vec2(-1.0, -1.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1.0, 0.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1.0, 1.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0.0, -1.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0.0, 0.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0.0, 1.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1.0, -1.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1.0, 0.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1.0, 1.0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
#else // _PCSS
|
||||
const int NUM_SAMPLES = 17;
|
||||
const float radiusStep = 1.0 / float(NUM_SAMPLES);
|
||||
const float angleStep = PI2 * float(pcssRings) / float(NUM_SAMPLES);
|
||||
vec2 poissonDisk0; vec2 poissonDisk1; vec2 poissonDisk2;
|
||||
vec2 poissonDisk3; vec2 poissonDisk4; vec2 poissonDisk5;
|
||||
vec2 poissonDisk6; vec2 poissonDisk7; vec2 poissonDisk8;
|
||||
vec2 poissonDisk9; vec2 poissonDisk10; vec2 poissonDisk11;
|
||||
vec2 poissonDisk12; vec2 poissonDisk13; vec2 poissonDisk14;
|
||||
vec2 poissonDisk15; vec2 poissonDisk16;
|
||||
void initPoissonSamples(const in vec2 randomSeed) {
|
||||
float angle = texture(snoise, randomSeed).r * PI2;
|
||||
float radius = radiusStep;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
poissonDisk0 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk1 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk2 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk3 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk4 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk5 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk6 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk7 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk8 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk9 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk10 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk11 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk12 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk13 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk14 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk15 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk16 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
// }
|
||||
}
|
||||
float findBlocker(const in vec2 uv, const in float zReceiver) {
|
||||
// This uses similar triangles to compute what area of the shadow map we should search
|
||||
float searchRadius = lampSizeUV * (zReceiver - lampNear) / zReceiver;
|
||||
float blockerDepthSum = 0.0;
|
||||
int numBlockers = 0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float shadowMapDepth = texture(shadowMap, uv + poissonDisk0 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk1 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk2 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk3 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk4 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk5 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk6 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk7 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk8 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk9 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk10 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk11 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk12 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk13 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk14 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk15 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk16 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
// }
|
||||
if (numBlockers == 0) return -1.0;
|
||||
return blockerDepthSum / float(numBlockers);
|
||||
}
|
||||
float filterPCF(vec2 uv, float zReceiver, float filterRadius) {
|
||||
float sum = 0.0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float depth = texture(shadowMap, uv + poissonDisk0 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk1 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk2 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk3 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk4 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk5 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk6 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk7 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk8 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk9 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk10 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk11 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk12 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk13 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk14 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk15 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk16 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
depth = texture(shadowMap, uv + -poissonDisk0.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk1.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk2.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk3.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk4.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk5.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk6.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk7.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk8.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk9.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk10.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk11.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk12.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk13.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk14.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk15.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk16.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
return sum / (2.0 * float(NUM_SAMPLES));
|
||||
}
|
||||
float PCSS(vec2 uv, float zReceiver) {
|
||||
initPoissonSamples(uv);
|
||||
float avgBlockerDepth = findBlocker(uv, zReceiver);
|
||||
if (avgBlockerDepth == -1.0) return 1.0;
|
||||
float penumbraRatio = (zReceiver - avgBlockerDepth) / avgBlockerDepth;
|
||||
float filterRadius = penumbraRatio * lampSizeUV * lampNear / zReceiver;
|
||||
return filterPCF(uv, zReceiver, filterRadius);
|
||||
}
|
||||
#endif
|
||||
float shadowTest(vec4 lPos) {
|
||||
lPos.xyz = lPos.xyz / lPos.w;
|
||||
lPos.xy = lPos.xy * 0.5 + 0.5;
|
||||
#ifdef _PCSS
|
||||
#ifdef _PCSS
|
||||
return PCSS(lPos.xy, lPos.z - shadowsBias);
|
||||
#else
|
||||
return PCF(lPos.xy, lPos.z - shadowsBias);
|
||||
|
@ -318,170 +110,6 @@ float shadowTest(vec4 lPos) {
|
|||
}
|
||||
#endif
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.y * nor.x +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
|
||||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
vec2 LightingFuncGGX_FV(float dotLH, float roughness) {
|
||||
float alpha = roughness*roughness;
|
||||
|
||||
// F
|
||||
float F_a, F_b;
|
||||
float dotLH5 = pow(1.0 - dotLH, 5.0);
|
||||
F_a = 1.0;
|
||||
F_b = dotLH5;
|
||||
|
||||
// V
|
||||
float vis;
|
||||
float k = alpha / 2.0;
|
||||
float k2 = k * k;
|
||||
float invK2 = 1.0 - k2;
|
||||
//vis = rcp(dotLH * dotLH * invK2 + k2);
|
||||
vis = inversesqrt(dotLH * dotLH * invK2 + k2);
|
||||
|
||||
return vec2(F_a * vis, F_b * vis);
|
||||
}
|
||||
|
||||
float LightingFuncGGX_D(float dotNH, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSqr = alpha * alpha;
|
||||
float pi = 3.14159;
|
||||
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
float D = alphaSqr / (pi * denom * denom);
|
||||
return D;
|
||||
}
|
||||
|
||||
// John Hable - Optimizing GGX Shaders
|
||||
// http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
|
||||
float LightingFuncGGX_OPT3(float dotNL, float dotLH, float dotNH, float roughness, float F0) {
|
||||
// vec3 H = normalize(V + L);
|
||||
// float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
// float dotLH = clamp(dot(L, H), 0.0, 1.0);
|
||||
// float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
float D = LightingFuncGGX_D(dotNH, roughness);
|
||||
vec2 FV_helper = LightingFuncGGX_FV(dotLH, roughness);
|
||||
float FV = F0 * FV_helper.x + (1.0 - F0) * FV_helper.y;
|
||||
float specular = dotNL * D * FV;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
#ifdef _OrenNayar
|
||||
vec3 orenNayarDiffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh) {
|
||||
float a = roughness * roughness;
|
||||
float s = a;
|
||||
float s2 = s * s;
|
||||
float vl = 2.0 * vh * vh - 1.0; // Double angle identity
|
||||
float Cosri = vl - nv * nl;
|
||||
float C1 = 1.0 - 0.5 * s2 / (s2 + 0.33);
|
||||
float test = 1.0;
|
||||
if (Cosri >= 0.0) test = (1.0 / (max(nl, nv)));
|
||||
float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * test;
|
||||
return albedo * max(0.0, nl) * (C1 + C2) * (1.0 + roughness * 0.5);
|
||||
}
|
||||
#else
|
||||
vec3 lambertDiffuseBRDF(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * envmapNumMipmaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
float packFloat(float f1, float f2) {
|
||||
int index = int(f1 * 1000);
|
||||
float alpha = f2 == 0.0 ? f2 : (f2 - 0.0001);
|
||||
float result = index + alpha;
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 uncharted2Tonemap(vec3 x) {
|
||||
const float A = 0.15;
|
||||
const float B = 0.50;
|
||||
const float C = 0.10;
|
||||
const float D = 0.20;
|
||||
const float E = 0.02;
|
||||
const float F = 0.30;
|
||||
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
|
||||
}
|
||||
vec3 tonemapUncharted2(vec3 color) {
|
||||
const float W = 11.2;
|
||||
const float exposureBias = 2.0;
|
||||
vec3 curr = uncharted2Tonemap(exposureBias * color);
|
||||
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||
return curr * whiteScale;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef _NorTex
|
||||
|
@ -491,7 +119,7 @@ void main() {
|
|||
vec3 n = normalize(normal);
|
||||
#endif
|
||||
#ifdef _NorStr
|
||||
n *= normalStrength;
|
||||
n *= normalStrength;
|
||||
#endif
|
||||
|
||||
// Move out
|
||||
|
@ -545,14 +173,14 @@ void main() {
|
|||
float roughness = texture(srough, texCoord).r;
|
||||
#endif
|
||||
#ifdef _RoughStr
|
||||
roughness *= roughnessStrength;
|
||||
roughness *= roughnessStrength;
|
||||
#endif
|
||||
|
||||
// Direct
|
||||
#ifdef _OrenNayar
|
||||
vec3 direct = orenNayarDiffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
|
||||
vec3 direct = orenNayarDiffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
|
||||
#else
|
||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
|
||||
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
|
||||
#endif
|
||||
|
||||
if (lightType == 2) { // Spot
|
||||
|
@ -575,7 +203,7 @@ void main() {
|
|||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);// + 1.0;
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);// + 1.0;
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _EnvLDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
|
@ -596,12 +224,12 @@ void main() {
|
|||
|
||||
#ifdef _LDR
|
||||
outputColor.rgb = tonemapUncharted2(outputColor.rgb);
|
||||
fragColor[0] = vec4(pow(outputColor.rgb, vec3(1.0 / 2.2)), visibility);
|
||||
fragColor[0] = vec4(pow(outputColor.rgb, vec3(1.0 / 2.2)), visibility);
|
||||
#else
|
||||
fragColor[0] = vec4(outputColor.rgb, visibility);
|
||||
fragColor[0] = vec4(outputColor.rgb, visibility);
|
||||
#endif
|
||||
|
||||
n /= (abs(n.x) + abs(n.y) + abs(n.z));
|
||||
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
|
||||
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
|
||||
fragColor[1] = vec4(n.xy, packFloat(metalness, roughness), 0.0);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#ifdef _Skinning
|
||||
#include "../std/skinning.glsl"
|
||||
// getSkinningDualQuat()
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
|
@ -36,7 +40,7 @@ uniform mat4 LWVP;
|
|||
uniform vec4 baseCol;
|
||||
uniform vec3 eye;
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[skinMaxBones * 8];
|
||||
//!uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
|
||||
out vec3 position;
|
||||
|
@ -52,62 +56,13 @@ out vec3 eyeDir;
|
|||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
void getSkinningDualQuat(vec4 weights, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[int(bone.x) * 8 + 0];
|
||||
matA[0][1] = skinBones[int(bone.x) * 8 + 1];
|
||||
matA[0][2] = skinBones[int(bone.x) * 8 + 2];
|
||||
matA[0][3] = skinBones[int(bone.x) * 8 + 3];
|
||||
matB[0][0] = skinBones[int(bone.x) * 8 + 4];
|
||||
matB[0][1] = skinBones[int(bone.x) * 8 + 5];
|
||||
matB[0][2] = skinBones[int(bone.x) * 8 + 6];
|
||||
matB[0][3] = skinBones[int(bone.x) * 8 + 7];
|
||||
matA[1][0] = skinBones[int(bone.y) * 8 + 0];
|
||||
matA[1][1] = skinBones[int(bone.y) * 8 + 1];
|
||||
matA[1][2] = skinBones[int(bone.y) * 8 + 2];
|
||||
matA[1][3] = skinBones[int(bone.y) * 8 + 3];
|
||||
matB[1][0] = skinBones[int(bone.y) * 8 + 4];
|
||||
matB[1][1] = skinBones[int(bone.y) * 8 + 5];
|
||||
matB[1][2] = skinBones[int(bone.y) * 8 + 6];
|
||||
matB[1][3] = skinBones[int(bone.y) * 8 + 7];
|
||||
matA[2][0] = skinBones[int(bone.z) * 8 + 0];
|
||||
matA[2][1] = skinBones[int(bone.z) * 8 + 1];
|
||||
matA[2][2] = skinBones[int(bone.z) * 8 + 2];
|
||||
matA[2][3] = skinBones[int(bone.z) * 8 + 3];
|
||||
matB[2][0] = skinBones[int(bone.z) * 8 + 4];
|
||||
matB[2][1] = skinBones[int(bone.z) * 8 + 5];
|
||||
matB[2][2] = skinBones[int(bone.z) * 8 + 6];
|
||||
matB[2][3] = skinBones[int(bone.z) * 8 + 7];
|
||||
matA[3][0] = skinBones[int(bone.w) * 8 + 0];
|
||||
matA[3][1] = skinBones[int(bone.w) * 8 + 1];
|
||||
matA[3][2] = skinBones[int(bone.w) * 8 + 2];
|
||||
matA[3][3] = skinBones[int(bone.w) * 8 + 3];
|
||||
matB[3][0] = skinBones[int(bone.w) * 8 + 4];
|
||||
matB[3][1] = skinBones[int(bone.w) * 8 + 5];
|
||||
matB[3][2] = skinBones[int(bone.w) * 8 + 6];
|
||||
matB[3][3] = skinBones[int(bone.w) * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weights.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weights.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weights; // Real part
|
||||
B = matB * weights; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 sPos = vec4(pos, 1.0);
|
||||
|
||||
#ifdef _Skinning
|
||||
vec4 skinA;
|
||||
vec4 skinB;
|
||||
getSkinningDualQuat(weight, skinA, skinB);
|
||||
getSkinningDualQuat(ivec4(bone), weight, skinA, skinB);
|
||||
sPos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, sPos.xyz) + skinA.w * sPos.xyz); // Rotate
|
||||
sPos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate
|
||||
vec3 _normal = normalize(mat3(N) * (nor + 2.0 * cross(skinA.xyz, cross(skinA.xyz, nor) + skinA.w * nor)));
|
||||
|
|
|
@ -8,14 +8,36 @@ precision mediump float;
|
|||
#define _LDR
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/brdf.glsl"
|
||||
// ...
|
||||
#ifdef _Rad
|
||||
#include "../std/math.glsl"
|
||||
// envMapEquirect()
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
#ifdef _PCSS
|
||||
#include "../std/shadows_pcss.glsl"
|
||||
// PCSS()
|
||||
#else
|
||||
#include "../std/shadows.glsl"
|
||||
// PCF()
|
||||
#endif
|
||||
#endif
|
||||
#include "../std/shirr.glsl"
|
||||
// shIrradiance()
|
||||
//!uniform float shirr[27];
|
||||
|
||||
#ifdef _BaseTex
|
||||
uniform sampler2D sbase;
|
||||
#endif
|
||||
#ifndef _NoShadows
|
||||
uniform sampler2D shadowMap;
|
||||
//!uniform sampler2D shadowMap;
|
||||
#ifdef _PCSS
|
||||
//!uniform sampler2D snoise;
|
||||
//!uniform float lampSizeUV;
|
||||
//!uniform float lampNear;
|
||||
#endif
|
||||
#endif
|
||||
uniform float shirr[27];
|
||||
#ifdef _Rad
|
||||
uniform sampler2D senvmapRadiance;
|
||||
uniform sampler2D senvmapBrdf;
|
||||
|
@ -61,182 +83,14 @@ in vec3 eyeDir;
|
|||
out vec4 fragColor;
|
||||
|
||||
#ifndef _NoShadows
|
||||
float texture2DCompare(vec2 uv, float compare) {
|
||||
float depth = texture(shadowMap, uv).r * 2.0 - 1.0;
|
||||
return step(compare, depth);
|
||||
}
|
||||
float texture2DShadowLerp(vec2 size, vec2 uv, float compare) {
|
||||
vec2 texelSize = vec2(1.0) / size;
|
||||
vec2 f = fract(uv * size + 0.5);
|
||||
vec2 centroidUV = floor(uv * size + 0.5) / size;
|
||||
|
||||
float lb = texture2DCompare(centroidUV + texelSize * vec2(0.0, 0.0), compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize * vec2(1.0, 1.0), compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
float PCF(vec2 uv, float compare) {
|
||||
float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
|
||||
vec2 off = vec2(-1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(-1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(0, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, -1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 0) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
off = vec2(1, 1) / shadowmapSize;
|
||||
result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
||||
float shadowTest(vec4 lPos) {
|
||||
lPos.xyz = lPos.xyz / lPos.w;
|
||||
lPos.xyz /= lPos.w;
|
||||
lPos.xy = lPos.xy * 0.5 + 0.5;
|
||||
#ifdef _PCSS
|
||||
return PCSS(lPos.xy, lPos.z - shadowsBias);
|
||||
#else
|
||||
return PCF(lPos.xy, lPos.z - shadowsBias);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.y * nor.x +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
|
||||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
vec2 LightingFuncGGX_FV(float dotLH, float roughness) {
|
||||
float alpha = roughness*roughness;
|
||||
|
||||
// F
|
||||
float F_a, F_b;
|
||||
float dotLH5 = pow(1.0 - dotLH, 5.0);
|
||||
F_a = 1.0;
|
||||
F_b = dotLH5;
|
||||
|
||||
// V
|
||||
float vis;
|
||||
float k = alpha / 2.0;
|
||||
float k2 = k * k;
|
||||
float invK2 = 1.0 - k2;
|
||||
//vis = rcp(dotLH * dotLH * invK2 + k2);
|
||||
vis = inversesqrt(dotLH * dotLH * invK2 + k2);
|
||||
|
||||
return vec2(F_a * vis, F_b * vis);
|
||||
}
|
||||
|
||||
float LightingFuncGGX_D(float dotNH, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSqr = alpha * alpha;
|
||||
float pi = 3.14159;
|
||||
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
float D = alphaSqr / (pi * denom * denom);
|
||||
return D;
|
||||
}
|
||||
|
||||
// John Hable - Optimizing GGX Shaders
|
||||
// http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
|
||||
float LightingFuncGGX_OPT3(float dotNL, float dotLH, float dotNH, float roughness, float F0) {
|
||||
// vec3 H = normalize(V + L);
|
||||
// float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
// float dotLH = clamp(dot(L, H), 0.0, 1.0);
|
||||
// float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
float D = LightingFuncGGX_D(dotNH, roughness);
|
||||
vec2 FV_helper = LightingFuncGGX_FV(dotLH, roughness);
|
||||
float FV = F0 * FV_helper.x + (1.0 - F0) * FV_helper.y;
|
||||
float specular = dotNL * D * FV;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 f_schlick(vec3 f0, float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(float nl, float nv, float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(float nh, float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(vec3 f0, float roughness, float nl, float nh, float nv, float vh, float lh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
vec3 lambert(vec3 albedo, float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
|
||||
vec3 diffuseBRDF(vec3 albedo, float roughness, float nv, float nl, float vh, float lv) {
|
||||
return lambert(albedo, nl);
|
||||
}
|
||||
|
||||
vec3 surfaceAlbedo(vec3 baseColor, float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(vec3 baseColor, float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
#ifdef _Rad
|
||||
float getMipLevelFromRoughness(float roughness) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * envmapNumMipmaps;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -305,7 +159,7 @@ void main() {
|
|||
|
||||
#ifdef _Rad
|
||||
vec3 reflectionWorld = reflect(-v, n);
|
||||
float lod = getMipLevelFromRoughness(roughness);// + 1.0;
|
||||
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);// + 1.0;
|
||||
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
|
||||
#ifdef _EnvLDR
|
||||
prefilteredColor = pow(prefilteredColor, vec3(2.2));
|
||||
|
|
|
@ -5,6 +5,10 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#ifdef _Skinning
|
||||
#include "../std/skinning.glsl"
|
||||
// getSkinningDualQuat()
|
||||
#endif
|
||||
|
||||
#ifdef _NorTex
|
||||
#define _Tex
|
||||
|
@ -37,7 +41,7 @@ uniform mat4 LWVP;
|
|||
uniform vec4 baseCol;
|
||||
uniform vec3 eye;
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[skinMaxBones * 8];
|
||||
//!uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
|
||||
out vec3 position;
|
||||
|
@ -53,62 +57,13 @@ out vec3 eyeDir;
|
|||
out vec3 normal;
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
void getSkinningDualQuat(vec4 weights, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[int(bone.x) * 8 + 0];
|
||||
matA[0][1] = skinBones[int(bone.x) * 8 + 1];
|
||||
matA[0][2] = skinBones[int(bone.x) * 8 + 2];
|
||||
matA[0][3] = skinBones[int(bone.x) * 8 + 3];
|
||||
matB[0][0] = skinBones[int(bone.x) * 8 + 4];
|
||||
matB[0][1] = skinBones[int(bone.x) * 8 + 5];
|
||||
matB[0][2] = skinBones[int(bone.x) * 8 + 6];
|
||||
matB[0][3] = skinBones[int(bone.x) * 8 + 7];
|
||||
matA[1][0] = skinBones[int(bone.y) * 8 + 0];
|
||||
matA[1][1] = skinBones[int(bone.y) * 8 + 1];
|
||||
matA[1][2] = skinBones[int(bone.y) * 8 + 2];
|
||||
matA[1][3] = skinBones[int(bone.y) * 8 + 3];
|
||||
matB[1][0] = skinBones[int(bone.y) * 8 + 4];
|
||||
matB[1][1] = skinBones[int(bone.y) * 8 + 5];
|
||||
matB[1][2] = skinBones[int(bone.y) * 8 + 6];
|
||||
matB[1][3] = skinBones[int(bone.y) * 8 + 7];
|
||||
matA[2][0] = skinBones[int(bone.z) * 8 + 0];
|
||||
matA[2][1] = skinBones[int(bone.z) * 8 + 1];
|
||||
matA[2][2] = skinBones[int(bone.z) * 8 + 2];
|
||||
matA[2][3] = skinBones[int(bone.z) * 8 + 3];
|
||||
matB[2][0] = skinBones[int(bone.z) * 8 + 4];
|
||||
matB[2][1] = skinBones[int(bone.z) * 8 + 5];
|
||||
matB[2][2] = skinBones[int(bone.z) * 8 + 6];
|
||||
matB[2][3] = skinBones[int(bone.z) * 8 + 7];
|
||||
matA[3][0] = skinBones[int(bone.w) * 8 + 0];
|
||||
matA[3][1] = skinBones[int(bone.w) * 8 + 1];
|
||||
matA[3][2] = skinBones[int(bone.w) * 8 + 2];
|
||||
matA[3][3] = skinBones[int(bone.w) * 8 + 3];
|
||||
matB[3][0] = skinBones[int(bone.w) * 8 + 4];
|
||||
matB[3][1] = skinBones[int(bone.w) * 8 + 5];
|
||||
matB[3][2] = skinBones[int(bone.w) * 8 + 6];
|
||||
matB[3][3] = skinBones[int(bone.w) * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weights.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weights.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weights; // Real part
|
||||
B = matB * weights; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec4 sPos = vec4(pos, 1.0);
|
||||
|
||||
#ifdef _Skinning
|
||||
vec4 skinA;
|
||||
vec4 skinB;
|
||||
getSkinningDualQuat(weight, skinA, skinB);
|
||||
getSkinningDualQuat(ivec4(bone), weight, skinA, skinB);
|
||||
sPos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, sPos.xyz) + skinA.w * sPos.xyz); // Rotate
|
||||
sPos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate
|
||||
vec3 _normal = normalize(mat3(N) * (nor + 2.0 * cross(skinA.xyz, cross(skinA.xyz, nor) + skinA.w * nor)));
|
||||
|
|
|
@ -5,6 +5,10 @@ precision highp float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#ifdef _Skinning
|
||||
#include "../std/skinning.glsl"
|
||||
// getSkinningDualQuat()
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 nor;
|
||||
|
@ -31,56 +35,7 @@ uniform mat4 WV;
|
|||
uniform mat4 P;
|
||||
#endif
|
||||
#ifdef _Skinning
|
||||
uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
|
||||
#ifdef _Skinning
|
||||
void getSkinningDualQuat(vec4 weights, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[int(bone.x) * 8 + 0];
|
||||
matA[0][1] = skinBones[int(bone.x) * 8 + 1];
|
||||
matA[0][2] = skinBones[int(bone.x) * 8 + 2];
|
||||
matA[0][3] = skinBones[int(bone.x) * 8 + 3];
|
||||
matB[0][0] = skinBones[int(bone.x) * 8 + 4];
|
||||
matB[0][1] = skinBones[int(bone.x) * 8 + 5];
|
||||
matB[0][2] = skinBones[int(bone.x) * 8 + 6];
|
||||
matB[0][3] = skinBones[int(bone.x) * 8 + 7];
|
||||
matA[1][0] = skinBones[int(bone.y) * 8 + 0];
|
||||
matA[1][1] = skinBones[int(bone.y) * 8 + 1];
|
||||
matA[1][2] = skinBones[int(bone.y) * 8 + 2];
|
||||
matA[1][3] = skinBones[int(bone.y) * 8 + 3];
|
||||
matB[1][0] = skinBones[int(bone.y) * 8 + 4];
|
||||
matB[1][1] = skinBones[int(bone.y) * 8 + 5];
|
||||
matB[1][2] = skinBones[int(bone.y) * 8 + 6];
|
||||
matB[1][3] = skinBones[int(bone.y) * 8 + 7];
|
||||
matA[2][0] = skinBones[int(bone.z) * 8 + 0];
|
||||
matA[2][1] = skinBones[int(bone.z) * 8 + 1];
|
||||
matA[2][2] = skinBones[int(bone.z) * 8 + 2];
|
||||
matA[2][3] = skinBones[int(bone.z) * 8 + 3];
|
||||
matB[2][0] = skinBones[int(bone.z) * 8 + 4];
|
||||
matB[2][1] = skinBones[int(bone.z) * 8 + 5];
|
||||
matB[2][2] = skinBones[int(bone.z) * 8 + 6];
|
||||
matB[2][3] = skinBones[int(bone.z) * 8 + 7];
|
||||
matA[3][0] = skinBones[int(bone.w) * 8 + 0];
|
||||
matA[3][1] = skinBones[int(bone.w) * 8 + 1];
|
||||
matA[3][2] = skinBones[int(bone.w) * 8 + 2];
|
||||
matA[3][3] = skinBones[int(bone.w) * 8 + 3];
|
||||
matB[3][0] = skinBones[int(bone.w) * 8 + 4];
|
||||
matB[3][1] = skinBones[int(bone.w) * 8 + 5];
|
||||
matB[3][2] = skinBones[int(bone.w) * 8 + 6];
|
||||
matB[3][3] = skinBones[int(bone.w) * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weights.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weights.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weights; // Real part
|
||||
B = matB * weights; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
||||
//!uniform float skinBones[skinMaxBones * 8];
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
@ -89,7 +44,7 @@ void main() {
|
|||
#ifdef _Skinning
|
||||
vec4 skinA;
|
||||
vec4 skinB;
|
||||
getSkinningDualQuat(weight, skinA, skinB);
|
||||
getSkinningDualQuat(ivec4(bone), weight, skinA, skinB);
|
||||
sPos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, sPos.xyz) + skinA.w * sPos.xyz); // Rotate
|
||||
sPos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate
|
||||
#endif
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
in fragData {
|
||||
#ifdef _Tex
|
||||
vec2 texuv;
|
||||
vec2 texuv;
|
||||
#endif
|
||||
flat int axis;
|
||||
vec4 lampPos;
|
||||
flat int axis;
|
||||
vec4 lampPos;
|
||||
} frag;
|
||||
|
||||
uniform layout(RGBA8) image3D voxels;
|
||||
|
@ -24,33 +24,33 @@ const int voxelDimensions = 512;
|
|||
|
||||
void main() {
|
||||
#ifdef _BaseTex
|
||||
vec4 matCol = texture(sbase, frag.texuv);
|
||||
vec4 matCol = texture(sbase, frag.texuv);
|
||||
#else
|
||||
vec4 matCol = baseCol;
|
||||
#endif
|
||||
|
||||
// vec3 lampPos = frag.lampPos.xyz / frag.lampPos.w;
|
||||
// lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
// float distanceFromLight = texture(shadowMap, lampPos.xy).r * 2.0 - 1.0;
|
||||
// const float shadowsBias = 0.0001;
|
||||
// vec3 lampPos = frag.lampPos.xyz / frag.lampPos.w;
|
||||
// lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
// float distanceFromLight = texture(shadowMap, lampPos.xy).r * 2.0 - 1.0;
|
||||
// const float shadowsBias = 0.0001;
|
||||
// float visibility = float(distanceFromLight > lampPos.z - shadowsBias);
|
||||
float visibility = 1.0;
|
||||
|
||||
ivec3 camPos = ivec3(gl_FragCoord.x, gl_FragCoord.y, voxelDimensions * gl_FragCoord.z);
|
||||
ivec3 texPos;
|
||||
if (frag.axis == 1) {
|
||||
texPos.x = voxelDimensions - camPos.z;
|
||||
texPos.x = voxelDimensions - camPos.z;
|
||||
texPos.z = camPos.x;
|
||||
texPos.y = camPos.y;
|
||||
}
|
||||
else if (frag.axis == 2) {
|
||||
texPos.z = camPos.y;
|
||||
texPos.z = camPos.y;
|
||||
texPos.y = voxelDimensions - camPos.z;
|
||||
texPos.x = camPos.x;
|
||||
}
|
||||
else {
|
||||
texPos = camPos;
|
||||
texPos = camPos;
|
||||
}
|
||||
texPos.z = voxelDimensions - texPos.z - 1;
|
||||
imageStore(voxels, texPos, vec4(matCol.rgb * visibility, 1.0));
|
||||
}
|
||||
imageStore(voxels, texPos, vec4(matCol.rgb * visibility, 1.0));
|
||||
}
|
||||
|
|
|
@ -5,17 +5,17 @@ layout(triangle_strip, max_vertices = 3) out;
|
|||
|
||||
in vertData {
|
||||
#ifdef _Tex
|
||||
vec2 texuv;
|
||||
vec2 texuv;
|
||||
#endif
|
||||
vec4 lampPos;
|
||||
vec4 lampPos;
|
||||
} vertices[];
|
||||
|
||||
out fragData {
|
||||
#ifdef _Tex
|
||||
vec2 texuv;
|
||||
vec2 texuv;
|
||||
#endif
|
||||
flat int axis;
|
||||
vec4 lampPos;
|
||||
flat int axis;
|
||||
vec4 lampPos;
|
||||
} frag;
|
||||
|
||||
uniform mat4 PX;
|
||||
|
@ -23,34 +23,34 @@ uniform mat4 PY;
|
|||
uniform mat4 PZ;
|
||||
|
||||
void main() {
|
||||
vec3 p1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;
|
||||
vec3 p2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;
|
||||
vec3 absnor = abs(normalize(cross(p1, p2)));
|
||||
vec3 p1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;
|
||||
vec3 p2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;
|
||||
vec3 absnor = abs(normalize(cross(p1, p2)));
|
||||
|
||||
mat4 P;
|
||||
// Dominant axis
|
||||
if (absnor.x >= absnor.y && absnor.x >= absnor.z) {
|
||||
frag.axis = 1;
|
||||
P = PX;
|
||||
}
|
||||
else if (absnor.y >= absnor.x && absnor.y >= absnor.z) {
|
||||
frag.axis = 2;
|
||||
P = PY;
|
||||
}
|
||||
else {
|
||||
frag.axis = 3;
|
||||
P = PZ;
|
||||
}
|
||||
|
||||
for (int i = 0; i < gl_in.length(); i++) {
|
||||
vec3 middlePos = gl_in[0].gl_Position.xyz / 3.0 + gl_in[1].gl_Position.xyz / 3.0 + gl_in[2].gl_Position.xyz / 3.0;
|
||||
mat4 P;
|
||||
// Dominant axis
|
||||
if (absnor.x >= absnor.y && absnor.x >= absnor.z) {
|
||||
frag.axis = 1;
|
||||
P = PX;
|
||||
}
|
||||
else if (absnor.y >= absnor.x && absnor.y >= absnor.z) {
|
||||
frag.axis = 2;
|
||||
P = PY;
|
||||
}
|
||||
else {
|
||||
frag.axis = 3;
|
||||
P = PZ;
|
||||
}
|
||||
|
||||
for (int i = 0; i < gl_in.length(); i++) {
|
||||
vec3 middlePos = gl_in[0].gl_Position.xyz / 3.0 + gl_in[1].gl_Position.xyz / 3.0 + gl_in[2].gl_Position.xyz / 3.0;
|
||||
#ifdef _Tex
|
||||
frag.texuv = vertices[i].texuv;
|
||||
frag.texuv = vertices[i].texuv;
|
||||
#endif
|
||||
frag.lampPos = vertices[i].lampPos;
|
||||
gl_Position = P * gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
frag.lampPos = vertices[i].lampPos;
|
||||
gl_Position = P * gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
|
|
@ -24,15 +24,15 @@ uniform mat4 W;
|
|||
|
||||
out vertData {
|
||||
#ifdef _BaseTex
|
||||
vec2 texuv;
|
||||
vec2 texuv;
|
||||
#endif
|
||||
vec4 lampPos;
|
||||
vec4 lampPos;
|
||||
} vert;
|
||||
|
||||
void main() {
|
||||
#ifdef _Tex
|
||||
vert.texuv = tex;
|
||||
vert.texuv = tex;
|
||||
#endif
|
||||
vert.lampPos = LWVP * vec4(pos, 1.0);
|
||||
gl_Position = W * vec4(pos, 1.0);
|
||||
vert.lampPos = LWVP * vec4(pos, 1.0);
|
||||
gl_Position = W * vec4(pos, 1.0);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
|
@ -23,19 +24,9 @@ out vec4 fragColor;
|
|||
// const float motionBlurIntensity = 1.0;
|
||||
// const int samples = 8;
|
||||
|
||||
vec3 getPos(float depth, vec2 coord) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
|
||||
vec2 getVelocity(vec2 coord, float depth) {
|
||||
vec4 currentPos = vec4(coord.xy * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 worldPos = vec4(getPos(depth, coord), 1.0);
|
||||
vec4 worldPos = vec4(getPos(eye, eyelook, viewRay, depth), 1.0);
|
||||
vec4 previousPos = prevVP * worldPos;
|
||||
previousPos /= previousPos.w;
|
||||
vec2 velocity = (currentPos - previousPos).xy / 40.0;
|
||||
|
@ -66,49 +57,49 @@ void main() {
|
|||
// for(int i = 1; i < samples; ++i) {
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
|
||||
offset += velocity;
|
||||
if (texture(gbuffer0, offset).a != 1.0) {
|
||||
color += texture(tex, offset);
|
||||
color += texture(tex, offset);
|
||||
processed++;
|
||||
}
|
||||
// }
|
||||
|
|
|
@ -11,7 +11,6 @@ precision mediump float;
|
|||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D sveloc;
|
||||
uniform sampler2D tex;
|
||||
|
||||
// uniform vec2 texStep;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
@ -33,7 +32,6 @@ void main() {
|
|||
// const int MAX_SAMPLES = 8;
|
||||
// int samples = clamp(int(speed), 1, MAX_SAMPLES);
|
||||
const int samples = 8;
|
||||
|
||||
// for (int i = 1; i < samples; ++i) {
|
||||
vec2 offset = velocity * (float(0) / float(samples - 1) - 0.5);
|
||||
col += texture(tex, texCoord + offset);
|
||||
|
|
|
@ -14,11 +14,10 @@ uniform vec3 ray11;
|
|||
out vec3 initialRay;
|
||||
out vec2 texCoord;
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
texCoord = pos.xy * madd + madd;
|
||||
initialRay = mix(mix(ray00, ray01, texCoord.y), mix(ray10, ray11, texCoord.y), texCoord.x);
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
initialRay = mix(mix(ray00, ray01, texCoord.y), mix(ray10, ray11, texCoord.y), texCoord.x);
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,31 +11,30 @@ uniform vec2 screenSizeInv;
|
|||
|
||||
out vec2 texCoord;
|
||||
out vec2 pixcoord;
|
||||
// out vec4 offset[3];
|
||||
out vec4 offset0;
|
||||
out vec4 offset1;
|
||||
out vec4 offset2;
|
||||
|
||||
const int SMAA_MAX_SEARCH_STEPS = 16;
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
texCoord = pos.xy * madd + madd;
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
// Blend Weight Calculation Vertex Shader
|
||||
// void SMAABlendingWeightCalculationVS(vec2 texcoord, out vec2 pixcoord, out vec4 offset[3]) {
|
||||
pixcoord = texCoord * screenSize;
|
||||
|
||||
// Blend Weight Calculation Vertex Shader
|
||||
// void SMAABlendingWeightCalculationVS(vec2 texcoord, out vec2 pixcoord, out vec4 offset[3]) {
|
||||
pixcoord = texCoord * screenSize;
|
||||
// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
|
||||
offset0 = screenSizeInv.xyxy * vec4(-0.25, -0.125, 1.25, -0.125) + texCoord.xyxy;
|
||||
offset1 = screenSizeInv.xyxy * vec4(-0.125, -0.25, -0.125, 1.25) + texCoord.xyxy;
|
||||
|
||||
// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
|
||||
offset0 = screenSizeInv.xyxy * vec4(-0.25, -0.125, 1.25, -0.125) + texCoord.xyxy;
|
||||
offset1 = screenSizeInv.xyxy * vec4(-0.125, -0.25, -0.125, 1.25) + texCoord.xyxy;
|
||||
// And these for the searches, they indicate the ends of the loops:
|
||||
offset2 = screenSizeInv.xxyy *
|
||||
(vec4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS)) +
|
||||
vec4(offset0.xz, offset1.yw);
|
||||
// }
|
||||
|
||||
// And these for the searches, they indicate the ends of the loops:
|
||||
offset2 = screenSizeInv.xxyy *
|
||||
(vec4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS)) +
|
||||
vec4(offset0.xz, offset1.yw);
|
||||
// }
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ precision mediump float;
|
|||
uniform sampler2D colorTex;
|
||||
|
||||
in vec2 texCoord;
|
||||
// in vec4 offset[3];
|
||||
in vec4 offset0;
|
||||
in vec4 offset1;
|
||||
in vec4 offset2;
|
||||
|
@ -61,10 +60,10 @@ out vec4 fragColor;
|
|||
// Misc functions
|
||||
// Gathers current pixel, and the top-left neighbors.
|
||||
// vec3 SMAAGatherNeighbours(vec2 texcoord/*, vec4 offset[3], sampler2D tex*/) {
|
||||
// float P = texture(tex, texcoord).r;
|
||||
// float Pleft = texture(tex, offset0.xy).r;
|
||||
// float Ptop = texture(tex, offset0.zw).r;
|
||||
// return vec3(P, Pleft, Ptop);
|
||||
// float P = texture(tex, texcoord).r;
|
||||
// float Pleft = texture(tex, offset0.xy).r;
|
||||
// float Ptop = texture(tex, offset0.zw).r;
|
||||
// return vec3(P, Pleft, Ptop);
|
||||
// }
|
||||
|
||||
// Edge Detection Pixel Shaders (First Pass)
|
||||
|
@ -80,134 +79,134 @@ out vec4 fragColor;
|
|||
// IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and
|
||||
// thus 'colorTex' should be a non-sRGB texture.
|
||||
vec2 SMAALumaEdgeDetectionPS(vec2 texcoord/*, vec4 offset[3], sampler2D colorTex*/
|
||||
//#if SMAA_PREDICATION
|
||||
//, sampler2D predicationTex
|
||||
//#endif
|
||||
) {
|
||||
// Calculate the threshold:
|
||||
//#if SMAA_PREDICATION
|
||||
//vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex));
|
||||
//#else
|
||||
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
||||
//#endif
|
||||
//#if SMAA_PREDICATION
|
||||
//, sampler2D predicationTex
|
||||
//#endif
|
||||
) {
|
||||
// Calculate the threshold:
|
||||
//#if SMAA_PREDICATION
|
||||
//vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex));
|
||||
//#else
|
||||
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
||||
//#endif
|
||||
|
||||
// Calculate lumas:
|
||||
vec3 weights = vec3(0.2126, 0.7152, 0.0722);
|
||||
float L = dot(texture(colorTex, texcoord).rgb, weights);
|
||||
// Calculate lumas:
|
||||
vec3 weights = vec3(0.2126, 0.7152, 0.0722);
|
||||
float L = dot(texture(colorTex, texcoord).rgb, weights);
|
||||
|
||||
float Lleft = dot(texture(colorTex, offset0.xy).rgb, weights);
|
||||
float Ltop = dot(texture(colorTex, offset0.zw).rgb, weights);
|
||||
float Lleft = dot(texture(colorTex, offset0.xy).rgb, weights);
|
||||
float Ltop = dot(texture(colorTex, offset0.zw).rgb, weights);
|
||||
|
||||
// We do the usual threshold:
|
||||
vec4 delta;
|
||||
delta.xy = abs(L - vec2(Lleft, Ltop));
|
||||
vec2 edges = step(threshold, delta.xy);
|
||||
// We do the usual threshold:
|
||||
vec4 delta;
|
||||
delta.xy = abs(L - vec2(Lleft, Ltop));
|
||||
vec2 edges = step(threshold, delta.xy);
|
||||
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
discard;
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
discard;
|
||||
|
||||
// Calculate right and bottom deltas:
|
||||
float Lright = dot(texture(colorTex, offset1.xy).rgb, weights);
|
||||
float Lbottom = dot(texture(colorTex, offset1.zw).rgb, weights);
|
||||
delta.zw = abs(L - vec2(Lright, Lbottom));
|
||||
// Calculate right and bottom deltas:
|
||||
float Lright = dot(texture(colorTex, offset1.xy).rgb, weights);
|
||||
float Lbottom = dot(texture(colorTex, offset1.zw).rgb, weights);
|
||||
delta.zw = abs(L - vec2(Lright, Lbottom));
|
||||
|
||||
// Calculate the maximum delta in the direct neighborhood:
|
||||
vec2 maxDelta = max(delta.xy, delta.zw);
|
||||
// Calculate the maximum delta in the direct neighborhood:
|
||||
vec2 maxDelta = max(delta.xy, delta.zw);
|
||||
|
||||
// Calculate left-left and top-top deltas:
|
||||
float Lleftleft = dot(texture(colorTex, offset2.xy).rgb, weights);
|
||||
float Ltoptop = dot(texture(colorTex, offset2.zw).rgb, weights);
|
||||
delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop));
|
||||
// Calculate left-left and top-top deltas:
|
||||
float Lleftleft = dot(texture(colorTex, offset2.xy).rgb, weights);
|
||||
float Ltoptop = dot(texture(colorTex, offset2.zw).rgb, weights);
|
||||
delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop));
|
||||
|
||||
// Calculate the final maximum delta:
|
||||
maxDelta = max(maxDelta.xy, delta.zw);
|
||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
// Calculate the final maximum delta:
|
||||
maxDelta = max(maxDelta.xy, delta.zw);
|
||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
|
||||
// Local contrast adaptation:
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
// Local contrast adaptation:
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
|
||||
return edges;
|
||||
return edges;
|
||||
}
|
||||
|
||||
// Color Edge Detection
|
||||
// IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and
|
||||
// thus 'colorTex' should be a non-sRGB texture.
|
||||
vec2 SMAAColorEdgeDetectionPS(vec2 texcoord/*, vec4 offset[3], sampler2D colorTex*/
|
||||
//#if SMAA_PREDICATION
|
||||
//, sampler2D predicationTex
|
||||
//#endif
|
||||
) {
|
||||
// Calculate the threshold:
|
||||
//#if SMAA_PREDICATION
|
||||
//vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex);
|
||||
//#else
|
||||
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
||||
//#endif
|
||||
//#if SMAA_PREDICATION
|
||||
//, sampler2D predicationTex
|
||||
//#endif
|
||||
) {
|
||||
// Calculate the threshold:
|
||||
//#if SMAA_PREDICATION
|
||||
//vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex);
|
||||
//#else
|
||||
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
||||
//#endif
|
||||
|
||||
// Calculate color deltas:
|
||||
vec4 delta;
|
||||
vec3 C = texture(colorTex, texcoord).rgb;
|
||||
// Calculate color deltas:
|
||||
vec4 delta;
|
||||
vec3 C = texture(colorTex, texcoord).rgb;
|
||||
|
||||
vec3 Cleft = texture(colorTex, offset0.xy).rgb;
|
||||
vec3 t = abs(C - Cleft);
|
||||
delta.x = max(max(t.r, t.g), t.b);
|
||||
vec3 Cleft = texture(colorTex, offset0.xy).rgb;
|
||||
vec3 t = abs(C - Cleft);
|
||||
delta.x = max(max(t.r, t.g), t.b);
|
||||
|
||||
vec3 Ctop = texture(colorTex, offset0.zw).rgb;
|
||||
t = abs(C - Ctop);
|
||||
delta.y = max(max(t.r, t.g), t.b);
|
||||
vec3 Ctop = texture(colorTex, offset0.zw).rgb;
|
||||
t = abs(C - Ctop);
|
||||
delta.y = max(max(t.r, t.g), t.b);
|
||||
|
||||
// We do the usual threshold:
|
||||
vec2 edges = step(threshold, delta.xy);
|
||||
// We do the usual threshold:
|
||||
vec2 edges = step(threshold, delta.xy);
|
||||
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
discard;
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
discard;
|
||||
|
||||
// Calculate right and bottom deltas:
|
||||
vec3 Cright = texture(colorTex, offset1.xy).rgb;
|
||||
t = abs(C - Cright);
|
||||
delta.z = max(max(t.r, t.g), t.b);
|
||||
// Calculate right and bottom deltas:
|
||||
vec3 Cright = texture(colorTex, offset1.xy).rgb;
|
||||
t = abs(C - Cright);
|
||||
delta.z = max(max(t.r, t.g), t.b);
|
||||
|
||||
vec3 Cbottom = texture(colorTex, offset1.zw).rgb;
|
||||
t = abs(C - Cbottom);
|
||||
delta.w = max(max(t.r, t.g), t.b);
|
||||
vec3 Cbottom = texture(colorTex, offset1.zw).rgb;
|
||||
t = abs(C - Cbottom);
|
||||
delta.w = max(max(t.r, t.g), t.b);
|
||||
|
||||
// Calculate the maximum delta in the direct neighborhood:
|
||||
vec2 maxDelta = max(delta.xy, delta.zw);
|
||||
// Calculate the maximum delta in the direct neighborhood:
|
||||
vec2 maxDelta = max(delta.xy, delta.zw);
|
||||
|
||||
// Calculate left-left and top-top deltas:
|
||||
vec3 Cleftleft = texture(colorTex, offset2.xy).rgb;
|
||||
t = abs(C - Cleftleft);
|
||||
delta.z = max(max(t.r, t.g), t.b);
|
||||
// Calculate left-left and top-top deltas:
|
||||
vec3 Cleftleft = texture(colorTex, offset2.xy).rgb;
|
||||
t = abs(C - Cleftleft);
|
||||
delta.z = max(max(t.r, t.g), t.b);
|
||||
|
||||
vec3 Ctoptop = texture(colorTex, offset2.zw).rgb;
|
||||
t = abs(C - Ctoptop);
|
||||
delta.w = max(max(t.r, t.g), t.b);
|
||||
vec3 Ctoptop = texture(colorTex, offset2.zw).rgb;
|
||||
t = abs(C - Ctoptop);
|
||||
delta.w = max(max(t.r, t.g), t.b);
|
||||
|
||||
// Calculate the final maximum delta:
|
||||
maxDelta = max(maxDelta.xy, delta.zw);
|
||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
// Calculate the final maximum delta:
|
||||
maxDelta = max(maxDelta.xy, delta.zw);
|
||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
|
||||
// Local contrast adaptation:
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
// Local contrast adaptation:
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
|
||||
return edges;
|
||||
return edges;
|
||||
}
|
||||
|
||||
// Depth Edge Detection
|
||||
// vec2 SMAADepthEdgeDetectionPS(vec2 texcoord, /*vec4 offset[3],*/ sampler2D depthTex) {
|
||||
// vec3 neighbours = SMAAGatherNeighbours(texcoord, /*offset,*/ depthTex);
|
||||
// vec2 delta = abs(neighbours.xx - vec2(neighbours.y, neighbours.z));
|
||||
// vec2 edges = step(SMAA_DEPTH_THRESHOLD, delta);
|
||||
// vec3 neighbours = SMAAGatherNeighbours(texcoord, /*offset,*/ depthTex);
|
||||
// vec2 delta = abs(neighbours.xx - vec2(neighbours.y, neighbours.z));
|
||||
// vec2 edges = step(SMAA_DEPTH_THRESHOLD, delta);
|
||||
|
||||
// if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
// discard;
|
||||
// if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
||||
// discard;
|
||||
|
||||
// return edges;
|
||||
// return edges;
|
||||
// }
|
||||
|
||||
void main() {
|
||||
// fragColor.rg = SMAALumaEdgeDetectionPS(texCoord/*, offset, colorTex*/);
|
||||
fragColor.rg = SMAAColorEdgeDetectionPS(texCoord/*, offset, colorTex*/);
|
||||
// fragColor.rg = SMAALumaEdgeDetectionPS(texCoord/*, offset, colorTex*/);
|
||||
fragColor.rg = SMAAColorEdgeDetectionPS(texCoord/*, offset, colorTex*/);
|
||||
}
|
||||
|
|
|
@ -9,15 +9,13 @@ in vec2 pos;
|
|||
uniform vec2 screenSizeInv;
|
||||
|
||||
out vec2 texCoord;
|
||||
// out vec4 offset[3];
|
||||
out vec4 offset0;
|
||||
out vec4 offset1;
|
||||
out vec4 offset2;
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
// Edge Detection Vertex Shader
|
||||
|
|
|
@ -30,72 +30,72 @@ out vec4 fragColor;
|
|||
//}
|
||||
|
||||
vec4 SMAANeighborhoodBlendingPS(vec2 texcoord, vec4 offset/*, sampler2D colorTex, sampler2D blendTex*/
|
||||
//#if SMAA_REPROJECTION
|
||||
//, sampler2D velocityTex
|
||||
//#endif
|
||||
) {
|
||||
// Fetch the blending weights for current pixel:
|
||||
vec4 a;
|
||||
a.x = texture(blendTex, offset.xy).a; // Right
|
||||
a.y = texture(blendTex, offset.zw).g; // Top
|
||||
a.wz = texture(blendTex, texcoord).xz; // Bottom / Left
|
||||
//#if SMAA_REPROJECTION
|
||||
//, sampler2D velocityTex
|
||||
//#endif
|
||||
) {
|
||||
// Fetch the blending weights for current pixel:
|
||||
vec4 a;
|
||||
a.x = texture(blendTex, offset.xy).a; // Right
|
||||
a.y = texture(blendTex, offset.zw).g; // Top
|
||||
a.wz = texture(blendTex, texcoord).xz; // Bottom / Left
|
||||
|
||||
// Is there any blending weight with a value greater than 0.0?
|
||||
//SMAA_BRANCH
|
||||
if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5) {
|
||||
vec4 color = textureLod(colorTex, texcoord, 0.0);
|
||||
// Is there any blending weight with a value greater than 0.0?
|
||||
//SMAA_BRANCH
|
||||
if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5) {
|
||||
vec4 color = textureLod(colorTex, texcoord, 0.0);
|
||||
|
||||
//#if SMAA_REPROJECTION
|
||||
#ifdef _Veloc
|
||||
vec2 velocity = textureLod(sveloc, texCoord, 0.0).rg;
|
||||
// Pack velocity into the alpha channel:
|
||||
color.a = sqrt(5.0 * length(velocity));
|
||||
vec2 velocity = textureLod(sveloc, texCoord, 0.0).rg;
|
||||
// Pack velocity into the alpha channel:
|
||||
color.a = sqrt(5.0 * length(velocity));
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
else {
|
||||
bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical)
|
||||
return color;
|
||||
}
|
||||
else {
|
||||
bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical)
|
||||
|
||||
// Calculate the blending offsets:
|
||||
vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w);
|
||||
vec2 blendingWeight = a.yw;
|
||||
|
||||
//SMAAMovc(bvec4(h, h, h, h), blendingOffset, vec4(a.x, 0.0, a.z, 0.0));
|
||||
if (h) blendingOffset.x = a.x;
|
||||
if (h) blendingOffset.y = 0.0;
|
||||
if (h) blendingOffset.z = a.z;
|
||||
if (h) blendingOffset.w = 0.0;
|
||||
|
||||
// SMAAMovc(bvec2(h, h), blendingWeight, a.xz);
|
||||
if (h) blendingWeight.x = a.x;
|
||||
if (h) blendingWeight.y = a.z;
|
||||
|
||||
blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0));
|
||||
// Calculate the blending offsets:
|
||||
vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w);
|
||||
vec2 blendingWeight = a.yw;
|
||||
|
||||
//SMAAMovc(bvec4(h, h, h, h), blendingOffset, vec4(a.x, 0.0, a.z, 0.0));
|
||||
if (h) blendingOffset.x = a.x;
|
||||
if (h) blendingOffset.y = 0.0;
|
||||
if (h) blendingOffset.z = a.z;
|
||||
if (h) blendingOffset.w = 0.0;
|
||||
|
||||
// SMAAMovc(bvec2(h, h), blendingWeight, a.xz);
|
||||
if (h) blendingWeight.x = a.x;
|
||||
if (h) blendingWeight.y = a.z;
|
||||
|
||||
blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0));
|
||||
|
||||
// Calculate the texture coordinates:
|
||||
vec4 blendingCoord = blendingOffset * vec4(screenSizeInv.xy, -screenSizeInv.xy) + texcoord.xyxy;
|
||||
// Calculate the texture coordinates:
|
||||
vec4 blendingCoord = blendingOffset * vec4(screenSizeInv.xy, -screenSizeInv.xy) + texcoord.xyxy;
|
||||
|
||||
// We exploit bilinear filtering to mix current pixel with the chosen
|
||||
// neighbor:
|
||||
vec4 color = blendingWeight.x * textureLod(colorTex, blendingCoord.xy, 0.0);
|
||||
color += blendingWeight.y * textureLod(colorTex, blendingCoord.zw, 0.0);
|
||||
// We exploit bilinear filtering to mix current pixel with the chosen
|
||||
// neighbor:
|
||||
vec4 color = blendingWeight.x * textureLod(colorTex, blendingCoord.xy, 0.0);
|
||||
color += blendingWeight.y * textureLod(colorTex, blendingCoord.zw, 0.0);
|
||||
|
||||
//#if SMAA_REPROJECTION
|
||||
#ifdef _Veloc
|
||||
// Antialias velocity for proper reprojection in a later stage:
|
||||
vec2 velocity = blendingWeight.x * textureLod(sveloc, blendingCoord.xy, 0.0).rg;
|
||||
velocity += blendingWeight.y * textureLod(sveloc, blendingCoord.zw, 0.0).rg;
|
||||
// Antialias velocity for proper reprojection in a later stage:
|
||||
vec2 velocity = blendingWeight.x * textureLod(sveloc, blendingCoord.xy, 0.0).rg;
|
||||
velocity += blendingWeight.y * textureLod(sveloc, blendingCoord.zw, 0.0).rg;
|
||||
|
||||
// Pack velocity into the alpha channel:
|
||||
color.a = sqrt(5.0 * length(velocity));
|
||||
// Pack velocity into the alpha channel:
|
||||
color.a = sqrt(5.0 * length(velocity));
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
return vec4(0.0);
|
||||
return color;
|
||||
}
|
||||
return vec4(0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
fragColor = SMAANeighborhoodBlendingPS(texCoord, offset/*, colorTex, blendTex*/);
|
||||
fragColor = SMAANeighborhoodBlendingPS(texCoord, offset/*, colorTex, blendTex*/);
|
||||
}
|
||||
|
|
|
@ -11,10 +11,9 @@ uniform vec2 screenSizeInv;
|
|||
out vec2 texCoord;
|
||||
out vec4 offset;
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
// Neighborhood Blending Vertex Shader
|
||||
|
|
|
@ -18,6 +18,8 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
|
@ -29,45 +31,17 @@ uniform vec3 eye;
|
|||
uniform vec2 screenSize;
|
||||
uniform vec2 aspectRatio;
|
||||
|
||||
#ifndef _SSAO // SSAO disabled, remove it from render path nodes to completely prevent generation
|
||||
const float ssaoSize = 0.03;
|
||||
const float ssaoStrength = 0.20;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
// in vec3 viewRay;
|
||||
out vec4 fragColor;
|
||||
|
||||
// float rand(vec2 co) { // Unreliable
|
||||
// return fract(sin(dot(co.xy ,vec2(12.9898, 78.233))) * 43758.5453);
|
||||
// }
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
vec3 getPos(float depth, vec2 coord) {
|
||||
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
pos = invVP * pos;
|
||||
pos.xyz /= pos.w;
|
||||
return pos.xyz - eye;
|
||||
}
|
||||
// vec3 getPos(float depth) {
|
||||
// vec3 vray = normalize(viewRay);
|
||||
// const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
// const float projectionB = -(cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
// float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
// float viewZDist = dot(eyeLook, vray);
|
||||
// // vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
// vec3 wposition = vray * (linearDepth / viewZDist);
|
||||
// return wposition;
|
||||
// }
|
||||
|
||||
float doAO(vec2 kernelVec, vec2 randomVec, mat2 rotMat, vec3 currentPos, vec3 currentNormal, float currentDistance) {
|
||||
kernelVec.xy *= aspectRatio;
|
||||
float radius = ssaoSize * randomVec.y;
|
||||
kernelVec.xy = ((rotMat * kernelVec.xy) / currentDistance) * radius;
|
||||
vec2 coord = texCoord + kernelVec.xy;
|
||||
float depth = texture(gbufferD, coord).r * 2.0 - 1.0;
|
||||
vec3 pos = getPos(depth, coord) - currentPos;
|
||||
vec3 pos = getPos2NoEye(eye, invVP, depth, coord) - currentPos;
|
||||
|
||||
float angle = dot(pos, currentNormal);
|
||||
// angle *= step(0.3, angle / length(pos)); // Fix intersect
|
||||
|
@ -121,12 +95,12 @@ void main() {
|
|||
// const vec2 kernel19 = vec2(0.9510565,-0.3090169);
|
||||
|
||||
vec2 enc = texture(gbuffer0, texCoord).rg;
|
||||
vec3 currentNormal;
|
||||
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
vec3 currentNormal;
|
||||
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
currentNormal = normalize(currentNormal);
|
||||
|
||||
vec3 currentPos = getPos(depth, texCoord);
|
||||
vec3 currentPos = getPos2NoEye(eye, invVP, depth, texCoord);
|
||||
float currentDistance = length(currentPos);
|
||||
|
||||
vec2 randomVec = texture(snoise, (texCoord * screenSize) / 8.0).xy;
|
||||
|
@ -160,5 +134,5 @@ void main() {
|
|||
amount *= ssaoStrength / kernelSize;
|
||||
amount = 1.0 - amount;
|
||||
amount = max(0.0, amount);
|
||||
fragColor = vec4(amount, 0.0, 0.0, 1.0);
|
||||
fragColor = vec4(amount, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,3 @@
|
|||
// Alchemy AO
|
||||
// Compute kernel
|
||||
// var kernel:Array<Float> = [];
|
||||
// var kernelSize = 8;
|
||||
// for (i in 0...kernelSize) {
|
||||
// var angle = i / kernelSize;
|
||||
// angle *= 3.1415926535 * 2.0;
|
||||
// var x1 = Math.cos(angle);
|
||||
// var y1 = Math.sin(angle);
|
||||
// x1 = Std.int(x1 * 10000000) / 10000000;
|
||||
// y1 = Std.int(y1 * 10000000) / 10000000;
|
||||
// trace(x1, y1);
|
||||
// }
|
||||
#version 450
|
||||
|
||||
#ifdef GL_ES
|
||||
|
@ -18,6 +5,8 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
|
@ -31,45 +20,17 @@ uniform vec3 eyeLook;
|
|||
uniform vec2 screenSize;
|
||||
uniform vec2 aspectRatio;
|
||||
|
||||
#ifndef _SSAO // SSAO disabled, remove it from render path nodes to completely prevent generation
|
||||
const float ssaoSize = 0.03;
|
||||
const float ssaoStrength = 0.20;
|
||||
#endif
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec3 viewRay;
|
||||
out vec4 fragColor;
|
||||
|
||||
// float rand(vec2 co) { // Unreliable
|
||||
// return fract(sin(dot(co.xy ,vec2(12.9898, 78.233))) * 43758.5453);
|
||||
// }
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
// vec3 getPos(float depth, vec2 coord) {
|
||||
// vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
// pos = invVP * pos;
|
||||
// pos.xyz /= pos.w;
|
||||
// return pos.xyz - eye;
|
||||
// }
|
||||
vec3 getPos(float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = -(cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
// vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
vec3 wposition = vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
|
||||
float doAO(vec2 kernelVec, vec2 randomVec, mat2 rotMat, vec3 currentPos, vec3 currentNormal, float currentDistance) {
|
||||
kernelVec.xy *= aspectRatio;
|
||||
float radius = ssaoSize * randomVec.y;
|
||||
kernelVec.xy = ((rotMat * kernelVec.xy) / currentDistance) * radius;
|
||||
vec2 coord = texCoord + kernelVec.xy;
|
||||
float depth = texture(gbufferD, coord).r * 2.0 - 1.0;
|
||||
vec3 pos = getPos(depth) - currentPos;
|
||||
vec3 pos = getPosNoEye(eyeLook, viewRay, depth) - currentPos;
|
||||
|
||||
float angle = dot(pos, currentNormal);
|
||||
// angle *= step(0.3, angle / length(pos)); // Fix intersect
|
||||
|
@ -123,12 +84,12 @@ void main() {
|
|||
// const vec2 kernel19 = vec2(0.9510565,-0.3090169);
|
||||
|
||||
vec2 enc = texture(gbuffer0, texCoord).rg;
|
||||
vec3 currentNormal;
|
||||
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
vec3 currentNormal;
|
||||
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
currentNormal = normalize(currentNormal);
|
||||
|
||||
vec3 currentPos = getPos(depth);
|
||||
vec3 currentPos = getPosNoEye(eyeLook, viewRay, depth);
|
||||
float currentDistance = length(currentPos);
|
||||
|
||||
vec2 randomVec = texture(snoise, (texCoord * screenSize) / 8.0).xy;
|
||||
|
@ -165,7 +126,7 @@ void main() {
|
|||
// fragColor = vec4(amount, 0.0, 0.0, 1.0);
|
||||
|
||||
// Velocity is assumed to be calculated for motion blur, so we need to inverse it for reprojection
|
||||
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
|
||||
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
|
||||
float last = texture(slast, texCoord + velocity).r;
|
||||
fragColor = vec4((amount + last) * 0.5, 0.0, 0.0, 1.0);
|
||||
fragColor = vec4((amount + last) * 0.5, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// DSSDO
|
||||
// http://kayru.org/articles/dssdo/
|
||||
#version 450
|
||||
|
||||
|
@ -6,6 +5,10 @@
|
|||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap
|
||||
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0;
|
||||
uniform sampler2D gbuffer1;
|
||||
|
@ -13,7 +16,6 @@ uniform sampler2D snoise;
|
|||
uniform mat4 invVP;
|
||||
uniform vec3 eye;
|
||||
|
||||
const float PI = 3.1415926535;
|
||||
const vec2 screenSize = vec2(800.0, 600.0);
|
||||
const vec2 aspectRatio = vec2(min(1.0, screenSize.y / screenSize.x), min(1.0, screenSize.x / screenSize.y));
|
||||
|
||||
|
@ -29,24 +31,13 @@ const vec4 sh2_weight = vec4(sh2_weight_l1, sh2_weight_l0) / num_samples;
|
|||
in vec2 texCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
vec3 getPos(float depth, vec2 coord) {
|
||||
// vec4 pos = vec4(coord * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
pos = invVP * pos;
|
||||
pos.xyz /= pos.w;
|
||||
return pos.xyz - eye;
|
||||
}
|
||||
|
||||
vec4 doDO(vec3 point, vec3 noise, float radius, vec3 center_pos, float max_distance_inv, vec3 center_normal) {
|
||||
vec2 textureOffset = reflect( point.xy, noise.xy ).xy * radius;
|
||||
vec2 sample_tex = texCoord + textureOffset;
|
||||
|
||||
// float depth = 1.0 - texture(gbuffer0, sample_tex).a;
|
||||
float depth = texture(gbufferD, sample_tex).r * 2.0 - 1.0;
|
||||
vec3 sample_pos = getPos(depth, sample_tex);
|
||||
vec3 sample_pos = getPos2(invVP, depth, sample_tex);
|
||||
|
||||
vec3 center_to_sample = sample_pos - center_pos;
|
||||
float dist = length(center_to_sample);
|
||||
|
@ -61,16 +52,14 @@ vec4 doDO(vec3 point, vec3 noise, float radius, vec3 center_pos, float max_dista
|
|||
}
|
||||
|
||||
void main() {
|
||||
// float depth = 1.0 - texture(gbuffer0, texCoord).a;
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
// if (depth == 0.0) {
|
||||
if (depth == 1.0) {
|
||||
fragColor = vec4(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 points[num_samples];
|
||||
points[0] = vec3(-0.134, 0.044, -0.825);
|
||||
points[0] = vec3(-0.134, 0.044, -0.825);
|
||||
points[1] = vec3(0.045, -0.431, -0.529);
|
||||
points[2] = vec3(-0.537, 0.195, -0.371);
|
||||
points[3] = vec3(0.525, -0.397, 0.713);
|
||||
|
@ -104,14 +93,13 @@ void main() {
|
|||
points[31] = vec3(0.534, 0.157, -0.250);
|
||||
|
||||
vec2 enc = texture(gbuffer0, texCoord).rg;
|
||||
vec3 currentNormal;
|
||||
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
vec3 currentNormal;
|
||||
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
currentNormal = normalize(currentNormal);
|
||||
|
||||
vec3 currentPos = getPos(depth, texCoord);
|
||||
// float currentDistance = length(currentPos);
|
||||
|
||||
vec3 currentPos = getPos2(invVP, depth, texCoord);
|
||||
// float currentDistance = length(currentPos);
|
||||
|
||||
vec2 noise_texture_size = vec2(8.0,8.0);
|
||||
vec3 center_pos = currentPos;
|
||||
|
@ -161,5 +149,5 @@ void main() {
|
|||
occlusion_sh2 += doDO(points[31], noise, radius, center_pos, max_distance_inv, center_normal);
|
||||
// }
|
||||
|
||||
fragColor = vec4(vec3(1.0 - occlusion_sh2.rgb), 1.0);
|
||||
fragColor = vec4(vec3(1.0 - occlusion_sh2.rgb), 1.0);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/math.glsl"
|
||||
// rand()
|
||||
#include "../std/gbuffer.glsl"
|
||||
// octahedronWrap()
|
||||
// unpackFloat()
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbufferD;
|
||||
|
@ -27,10 +32,6 @@ out vec4 fragColor;
|
|||
vec3 hitCoord;
|
||||
float depth;
|
||||
|
||||
float rand(vec2 co) { // Unreliable
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
vec4 getProjectedCoord(vec3 hitCoord) {
|
||||
vec4 projectedCoord = P * vec4(hitCoord, 1.0);
|
||||
projectedCoord.xy /= projectedCoord.w;
|
||||
|
@ -38,158 +39,141 @@ vec4 getProjectedCoord(vec3 hitCoord) {
|
|||
return projectedCoord;
|
||||
}
|
||||
|
||||
vec3 getPos(float depth) {
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (projectionA - depth);
|
||||
return viewRay * linearDepth;
|
||||
}
|
||||
|
||||
float getDeltaDepth(vec3 hitCoord) {
|
||||
// depth = 1.0 - texture(gbuffer0, getProjectedCoord(hitCoord).xy).a;
|
||||
depth = texture(gbufferD, getProjectedCoord(hitCoord).xy).r * 2.0 - 1.0;
|
||||
vec3 viewPos = getPos(depth);
|
||||
vec3 viewPos = getPosView(viewRay, depth);
|
||||
return viewPos.z - hitCoord.z;
|
||||
}
|
||||
|
||||
vec4 binarySearch(vec3 dir) {
|
||||
// for (int i = 0; i < numBinarySearchSteps; i++) {
|
||||
// for (int i = 0; i < numBinarySearchSteps; i++) {
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
dir *= 0.5;
|
||||
hitCoord -= dir;
|
||||
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
////
|
||||
// dir *= 0.5;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// dir *= 0.5;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// dir *= 0.5;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// dir *= 0.5;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// dir *= 0.5;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// dir *= 0.5;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
// hitCoord -= dir;
|
||||
// if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
|
||||
|
||||
// Ugly discard of hits too far away
|
||||
if (abs(getDeltaDepth(hitCoord)) > 0.01) {
|
||||
return vec4(0.0);
|
||||
}
|
||||
// }
|
||||
return vec4(getProjectedCoord(hitCoord).xy, 0.0, 1.0);
|
||||
// }
|
||||
return vec4(getProjectedCoord(hitCoord).xy, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec4 rayCast(vec3 dir) {
|
||||
dir *= ssrRayStep;
|
||||
|
||||
// for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// for (int i = 0; i < maxSteps; i++) {
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
hitCoord += dir;
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
////
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// hitCoord += dir;
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// }
|
||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
vec2 octahedronWrap(vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
vec2 unpackFloat(float f) {
|
||||
float index = floor(f) / 1000.0;
|
||||
float alpha = fract(f);
|
||||
return vec2(index, alpha);
|
||||
// if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
|
||||
// }
|
||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 g0 = texture(gbuffer0, texCoord);
|
||||
float roughness = unpackFloat(g0.b).y;
|
||||
float roughness = unpackFloat(g0.b).y;
|
||||
|
||||
if (roughness == 1.0) {
|
||||
if (roughness == 1.0) {
|
||||
fragColor = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
@ -202,10 +186,10 @@ void main() {
|
|||
}
|
||||
|
||||
vec2 enc = g0.rg;
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
|
||||
vec4 viewNormal = vec4(n, 1.0);
|
||||
|
||||
|
@ -215,7 +199,7 @@ void main() {
|
|||
}
|
||||
|
||||
viewNormal = tiV * normalize(viewNormal);
|
||||
vec3 viewPos = getPos(d);
|
||||
vec3 viewPos = getPosView(viewRay, d);
|
||||
|
||||
vec3 reflected = normalize(reflect((viewPos.xyz), normalize(viewNormal.xyz)));
|
||||
hitCoord = viewPos.xyz;
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
* Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Adapted to CGE by Lubos Lenco
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
|
@ -71,13 +69,13 @@ vec4 SSSSBlur(float sssWidth) {
|
|||
kernel[9] = vec4(0.0192831, 0.00282018, 0.00084214, 1.28);
|
||||
kernel[10] = vec4(0.00471691, 0.000184771, 5.07565e-005, 2);
|
||||
|
||||
vec4 colorM = texture(tex, texCoord);
|
||||
vec4 colorM = texture(tex, texCoord);
|
||||
|
||||
// Initialize the stencil buffer in case it was not already available:
|
||||
// if (initStencil) // (Checked in compile time, it's optimized away)
|
||||
// if (SSSS_STREGTH_SOURCE == 0.0) discard;
|
||||
// Initialize the stencil buffer in case it was not already available:
|
||||
// if (initStencil) // (Checked in compile time, it's optimized away)
|
||||
// if (SSSS_STREGTH_SOURCE == 0.0) discard;
|
||||
|
||||
// Fetch linear depth of current pixel
|
||||
// Fetch linear depth of current pixel
|
||||
// vec4 g0 = texture(gbuffer0, texCoord);
|
||||
// float depth = 1.0 - g0.a;
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
|
@ -85,73 +83,73 @@ vec4 SSSSBlur(float sssWidth) {
|
|||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float depthM = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
|
||||
// Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window)
|
||||
float distanceToProjectionWindow = 1.0 / tan(0.5 * radians(SSSS_FOVY));
|
||||
float scale = distanceToProjectionWindow / depthM;
|
||||
// Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window)
|
||||
float distanceToProjectionWindow = 1.0 / tan(0.5 * radians(SSSS_FOVY));
|
||||
float scale = distanceToProjectionWindow / depthM;
|
||||
|
||||
// Calculate the final step to fetch the surrounding pixels
|
||||
vec2 finalStep = sssWidth * scale * dir;
|
||||
finalStep *= 1.0;//SSSS_STREGTH_SOURCE; // Modulate it using the alpha channel.
|
||||
finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
|
||||
// Calculate the final step to fetch the surrounding pixels
|
||||
vec2 finalStep = sssWidth * scale * dir;
|
||||
finalStep *= 1.0;//SSSS_STREGTH_SOURCE; // Modulate it using the alpha channel.
|
||||
finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
|
||||
|
||||
// Accumulate the center sample:
|
||||
vec4 colorBlurred = colorM;
|
||||
colorBlurred.rgb *= kernel[0].rgb;
|
||||
// Accumulate the center sample:
|
||||
vec4 colorBlurred = colorM;
|
||||
colorBlurred.rgb *= kernel[0].rgb;
|
||||
|
||||
// Accumulate the other samples
|
||||
// for (int i = 1; i < SSSS_N_SAMPLES; i++) {
|
||||
// Fetch color and depth for current sample
|
||||
vec2 offset = texCoord + kernel[1].a * finalStep;
|
||||
vec4 color = texture(tex, offset);
|
||||
// #if SSSS_FOLLOW_SURFACE == 1
|
||||
// If the difference in depth is huge, we lerp color back to "colorM":
|
||||
// float depth = texture(depthTex, offset).r;
|
||||
// float s = SSSSSaturate(300.0f * distanceToProjectionWindow *
|
||||
// sssWidth * abs(depthM - depth));
|
||||
// color.rgb = SSSSLerp(color.rgb, colorM.rgb, s);
|
||||
// #endif
|
||||
// Accumulate
|
||||
colorBlurred.rgb += kernel[1].rgb * color.rgb;
|
||||
// Accumulate the other samples
|
||||
// for (int i = 1; i < SSSS_N_SAMPLES; i++) {
|
||||
// Fetch color and depth for current sample
|
||||
vec2 offset = texCoord + kernel[1].a * finalStep;
|
||||
vec4 color = texture(tex, offset);
|
||||
// #if SSSS_FOLLOW_SURFACE == 1
|
||||
// If the difference in depth is huge, we lerp color back to "colorM":
|
||||
// float depth = texture(depthTex, offset).r;
|
||||
// float s = SSSSSaturate(300.0f * distanceToProjectionWindow *
|
||||
// sssWidth * abs(depthM - depth));
|
||||
// color.rgb = SSSSLerp(color.rgb, colorM.rgb, s);
|
||||
// #endif
|
||||
// Accumulate
|
||||
colorBlurred.rgb += kernel[1].rgb * color.rgb;
|
||||
|
||||
|
||||
offset = texCoord + kernel[2].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[2].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[2].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[3].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[3].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[3].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[4].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[4].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[4].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[5].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[5].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[5].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[6].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[6].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[6].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[7].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[7].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[7].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[8].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[8].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[8].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[9].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[9].rgb * color.rgb;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[9].rgb * color.rgb;
|
||||
|
||||
offset = texCoord + kernel[10].a * finalStep;
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[10].rgb * color.rgb;
|
||||
// }
|
||||
color = texture(tex, offset);
|
||||
colorBlurred.rgb += kernel[10].rgb * color.rgb;
|
||||
// }
|
||||
|
||||
return colorBlurred;
|
||||
return colorBlurred;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
|
114
Shaders/std/brdf.glsl
Executable file
114
Shaders/std/brdf.glsl
Executable file
|
@ -0,0 +1,114 @@
|
|||
|
||||
vec2 LightingFuncGGX_FV(const float dotLH, const float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
|
||||
// F
|
||||
float F_a, F_b;
|
||||
float dotLH5 = pow(1.0 - dotLH, 5.0);
|
||||
F_a = 1.0;
|
||||
F_b = dotLH5;
|
||||
|
||||
// V
|
||||
float vis;
|
||||
float k = alpha / 2.0;
|
||||
float k2 = k * k;
|
||||
float invK2 = 1.0 - k2;
|
||||
//vis = rcp(dotLH * dotLH * invK2 + k2);
|
||||
vis = inversesqrt(dotLH * dotLH * invK2 + k2);
|
||||
|
||||
return vec2(F_a * vis, F_b * vis);
|
||||
}
|
||||
|
||||
float LightingFuncGGX_D(const float dotNH, const float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alphaSqr = alpha * alpha;
|
||||
float pi = 3.14159;
|
||||
float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
float D = alphaSqr / (pi * denom * denom);
|
||||
return D;
|
||||
}
|
||||
|
||||
// John Hable - Optimizing GGX Shaders
|
||||
// http://www.filmicworlds.com/2014/04/21/optimizing-ggx-shaders-with-dotlh/
|
||||
float LightingFuncGGX_OPT3(const float dotNL, const float dotLH, const float dotNH, const float roughness, const float F0) {
|
||||
// vec3 H = normalize(V + L);
|
||||
// float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
// float dotLH = clamp(dot(L, H), 0.0, 1.0);
|
||||
// float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
float D = LightingFuncGGX_D(dotNH, roughness);
|
||||
vec2 FV_helper = LightingFuncGGX_FV(dotLH, roughness);
|
||||
float FV = F0 * FV_helper.x + (1.0 - F0) * FV_helper.y;
|
||||
float specular = dotNL * D * FV;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 f_schlick(const vec3 f0, const float vh) {
|
||||
return f0 + (1.0-f0)*exp2((-5.55473 * vh - 6.98316)*vh);
|
||||
}
|
||||
|
||||
float v_smithschlick(const float nl, const float nv, const float a) {
|
||||
return 1.0 / ( (nl*(1.0-a)+a) * (nv*(1.0-a)+a) );
|
||||
}
|
||||
|
||||
float d_ggx(const float nh, const float a) {
|
||||
float a2 = a*a;
|
||||
float denom = pow(nh*nh * (a2-1.0) + 1.0, 2.0);
|
||||
return a2 * (1.0 / 3.1415926535) / denom;
|
||||
}
|
||||
|
||||
vec3 specularBRDF(const vec3 f0, const float roughness, const float nl, const float nh, const float nv, const float vh) {
|
||||
float a = roughness * roughness;
|
||||
return d_ggx(nh, a) * clamp(v_smithschlick(nl, nv, a), 0.0, 1.0) * f_schlick(f0, vh) / 4.0;
|
||||
//return vec3(LightingFuncGGX_OPT3(nl, lh, nh, roughness, f0[0]));
|
||||
}
|
||||
|
||||
vec3 orenNayarDiffuseBRDF(const vec3 albedo, const float roughness, const float nv, const float nl, const float vh) {
|
||||
float a = roughness * roughness;
|
||||
float s = a;
|
||||
float s2 = s * s;
|
||||
float vl = 2.0 * vh * vh - 1.0; // Double angle identity
|
||||
float Cosri = vl - nv * nl;
|
||||
float C1 = 1.0 - 0.5 * s2 / (s2 + 0.33);
|
||||
float test = 1.0;
|
||||
if (Cosri >= 0.0) test = (1.0 / (max(nl, nv)));
|
||||
float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * test;
|
||||
return albedo * max(0.0, nl) * (C1 + C2) * (1.0 + roughness * 0.5);
|
||||
}
|
||||
|
||||
vec3 lambertDiffuseBRDF(const vec3 albedo, const float nl) {
|
||||
return albedo * max(0.0, nl);
|
||||
}
|
||||
|
||||
vec3 surfaceAlbedo(const vec3 baseColor, const float metalness) {
|
||||
return mix(baseColor, vec3(0.0), metalness);
|
||||
}
|
||||
|
||||
vec3 surfaceF0(const vec3 baseColor, const float metalness) {
|
||||
return mix(vec3(0.04), baseColor, metalness);
|
||||
}
|
||||
|
||||
float getMipFromRoughness(const float roughness, const float numMipmaps) {
|
||||
// First mipmap level = roughness 0, last = roughness = 1
|
||||
return roughness * numMipmaps;
|
||||
}
|
||||
|
||||
float wardSpecular(vec3 N, vec3 H, float dotNL, float dotNV, float dotNH, vec3 fiberDirection, float shinyParallel, float shinyPerpendicular) {
|
||||
if(dotNL < 0.0 || dotNV < 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
// fiberDirection - parse from rotation
|
||||
// shinyParallel - roughness
|
||||
// shinyPerpendicular - anisotropy
|
||||
|
||||
vec3 fiberParallel = normalize(fiberDirection);
|
||||
vec3 fiberPerpendicular = normalize(cross(N, fiberDirection));
|
||||
float dotXH = dot(fiberParallel, H);
|
||||
float dotYH = dot(fiberPerpendicular, H);
|
||||
const float PI = 3.1415926535;
|
||||
float coeff = sqrt(dotNL/dotNV) / (4.0 * PI * shinyParallel * shinyPerpendicular);
|
||||
float theta = (pow(dotXH/shinyParallel, 2.0) + pow(dotYH/shinyPerpendicular, 2.0)) / (1.0 + dotNH);
|
||||
return clamp(coeff * exp(-2.0 * theta), 0.0, 1.0);
|
||||
}
|
59
Shaders/std/conetrace.glsl
Executable file
59
Shaders/std/conetrace.glsl
Executable file
|
@ -0,0 +1,59 @@
|
|||
uniform sampler3D voxels;
|
||||
const float voxelGridWorldSize = 150.0;
|
||||
const int voxelDimensions = 512;
|
||||
const float maxDist = 30.0;
|
||||
const float alphaTreshold = 0.95;
|
||||
const int numCones = 6;
|
||||
vec3 coneDirections[6] = vec3[](
|
||||
vec3(0, 1, 0),
|
||||
vec3(0, 0.5, 0.866025),
|
||||
vec3(0.823639, 0.5, 0.267617),
|
||||
vec3(0.509037, 0.5, -0.700629),
|
||||
vec3(-0.509037, 0.5, -0.700629),
|
||||
vec3(-0.823639, 0.5, 0.267617));
|
||||
float coneWeights[6] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
|
||||
|
||||
vec4 sampleVoxels(vec3 worldPosition, float lod) {
|
||||
vec3 offset = vec3(1.0 / voxelDimensions, 1.0 / voxelDimensions, 0);
|
||||
vec3 texco = worldPosition / (voxelGridWorldSize * 0.5);
|
||||
texco = texco * 0.5 + 0.5 + offset;
|
||||
return textureLod(voxels, texco, lod);
|
||||
}
|
||||
|
||||
// See https://github.com/Cigg/Voxel-Cone-Tracing
|
||||
vec4 coneTrace(vec3 posWorld, vec3 direction, vec3 norWorld, float tanHalfAngle, out float occlusion) {
|
||||
const float voxelWorldSize = voxelGridWorldSize / voxelDimensions;
|
||||
float dist = voxelWorldSize; // Start one voxel away to avoid self occlusion
|
||||
vec3 startPos = posWorld + norWorld * voxelWorldSize;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
float alpha = 0.0;
|
||||
occlusion = 0.0;
|
||||
while (dist < maxDist && alpha < alphaTreshold) {
|
||||
// Smallest sample diameter possible is the voxel size
|
||||
float diameter = max(voxelWorldSize, 2.0 * tanHalfAngle * dist);
|
||||
float lodLevel = log2(diameter / voxelWorldSize);
|
||||
vec4 voxelColor = sampleVoxels(startPos + dist * direction, lodLevel);
|
||||
// Front-to-back compositing
|
||||
float a = (1.0 - alpha);
|
||||
color += a * voxelColor.rgb;
|
||||
alpha += a * voxelColor.a;
|
||||
occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter);
|
||||
dist += diameter * 0.5; // * 2.0
|
||||
}
|
||||
return vec4(color, alpha);
|
||||
}
|
||||
|
||||
vec4 coneTraceIndirect(vec3 posWorld, mat3 tanToWorld, vec3 norWorld, out float occlusion) {
|
||||
vec4 color = vec4(0);
|
||||
occlusion = 0.0;
|
||||
|
||||
for (int i = 0; i < numCones; i++) {
|
||||
float coneOcclusion;
|
||||
const float tanangle = tan(30):
|
||||
color += coneWeights[i] * coneTrace(posWorld, tanToWorld * coneDirections[i], norWorld, tanangle, coneOcclusion);
|
||||
occlusion += coneWeights[i] * coneOcclusion;
|
||||
}
|
||||
occlusion = 1.0 - occlusion;
|
||||
return color;
|
||||
}
|
65
Shaders/std/gbuffer.glsl
Executable file
65
Shaders/std/gbuffer.glsl
Executable file
|
@ -0,0 +1,65 @@
|
|||
#include "../compiled.glsl"
|
||||
|
||||
vec2 octahedronWrap(const vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
|
||||
vec3 getNor(const vec2 enc) {
|
||||
vec3 n;
|
||||
n.z = 1.0 - abs(enc.x) - abs(enc.y);
|
||||
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
|
||||
n = normalize(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 getPosView(const vec3 viewRay, const float depth) {
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (projectionA - depth);
|
||||
return viewRay * linearDepth;
|
||||
}
|
||||
|
||||
vec3 getPos(const vec3 eye, const vec3 eyeLook, const vec3 viewRay, const float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
|
||||
vec3 getPosNoEye(const vec3 eyeLook, const vec3 viewRay, const float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = -(cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
|
||||
vec3 getPos2(const mat4 invVP, const float depth, const vec2 coord) {
|
||||
// vec4 pos = vec4(coord * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
pos = invVP * pos;
|
||||
pos.xyz /= pos.w;
|
||||
return pos.xyz;
|
||||
}
|
||||
|
||||
vec3 getPos2NoEye(const vec3 eye, const mat4 invVP, const float depth, const vec2 coord) {
|
||||
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
pos = invVP * pos;
|
||||
pos.xyz /= pos.w;
|
||||
return pos.xyz - eye;
|
||||
}
|
||||
|
||||
float packFloat(const float f1, const float f2) {
|
||||
float index = floor(f1 * 1000.0); // Temporary
|
||||
float alpha = clamp(f2, 0.0, 1.0 - 0.001);
|
||||
return index + alpha;
|
||||
}
|
||||
|
||||
vec2 unpackFloat(float f) {
|
||||
return vec2(floor(f) / 1000.0, fract(f));
|
||||
}
|
188
Shaders/std/ltc.glsl
Executable file
188
Shaders/std/ltc.glsl
Executable file
|
@ -0,0 +1,188 @@
|
|||
// #ifdef _LTC
|
||||
// uniform sampler2D sltcMat;
|
||||
// uniform sampler2D sltcMag;
|
||||
// uniform float time;
|
||||
// const float roughness = 0.25;
|
||||
// const vec3 dcolor = vec3(1.0, 1.0, 1.0);
|
||||
// const vec3 scolor = vec3(1.0, 1.0, 1.0);
|
||||
// const float intensity = 4.0; // 0-10
|
||||
// const float width = 4.0;
|
||||
// const float height = 4.0;
|
||||
// const int sampleCount = 0;
|
||||
// const int NUM_SAMPLES = 8;
|
||||
// const float LUT_SIZE = 64.0;
|
||||
// const float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;
|
||||
// const float LUT_BIAS = 0.5/LUT_SIZE;
|
||||
// vec2 mys[NUM_SAMPLES];
|
||||
// vec3 L0 = vec3(0.0);
|
||||
// vec3 L1 = vec3(0.0);
|
||||
// vec3 L2 = vec3(0.0);
|
||||
// vec3 L3 = vec3(0.0);
|
||||
// vec3 L4 = vec3(0.0);
|
||||
// #endif
|
||||
|
||||
// Linearly Transformed Cosines
|
||||
// https://eheitzresearch.wordpress.com/415-2/
|
||||
// vec3 mul(mat3 m, vec3 v) {
|
||||
// return m * v;
|
||||
// }
|
||||
// mat3 mul(mat3 m1, mat3 m2) {
|
||||
// return m1 * m2;
|
||||
// }
|
||||
// mat3 transpose2(mat3 v) {
|
||||
// mat3 tmp;
|
||||
// tmp[0] = vec3(v[0].x, v[1].x, v[2].x);
|
||||
// tmp[1] = vec3(v[0].y, v[1].y, v[2].y);
|
||||
// tmp[2] = vec3(v[0].z, v[1].z, v[2].z);
|
||||
|
||||
// return tmp;
|
||||
// }
|
||||
// float IntegrateEdge(vec3 v1, vec3 v2) {
|
||||
// float cosTheta = dot(v1, v2);
|
||||
// cosTheta = clamp(cosTheta, -0.9999, 0.9999);
|
||||
// float theta = acos(cosTheta);
|
||||
// float res = cross(v1, v2).z * theta / sin(theta);
|
||||
// return res;
|
||||
// }
|
||||
// int ClipQuadToHorizon(/*inout vec3 L[5], out int n*/) {
|
||||
// // detect clipping config
|
||||
// int config = 0;
|
||||
// if (L0.z > 0.0) config += 1;
|
||||
// if (L1.z > 0.0) config += 2;
|
||||
// if (L2.z > 0.0) config += 4;
|
||||
// if (L3.z > 0.0) config += 8;
|
||||
|
||||
// // clip
|
||||
// int n = 0;
|
||||
// if (config == 0) {
|
||||
// // clip all
|
||||
// }
|
||||
// else if (config == 1) { // V1 clip V2 V3 V4
|
||||
// n = 3;
|
||||
// L1 = -L1.z * L0 + L0.z * L1;
|
||||
// L2 = -L3.z * L0 + L0.z * L3;
|
||||
// }
|
||||
// else if (config == 2) { // V2 clip V1 V3 V4
|
||||
// n = 3;
|
||||
// L0 = -L0.z * L1 + L1.z * L0;
|
||||
// L2 = -L2.z * L1 + L1.z * L2;
|
||||
// }
|
||||
// else if (config == 3) { // V1 V2 clip V3 V4
|
||||
// n = 4;
|
||||
// L2 = -L2.z * L1 + L1.z * L2;
|
||||
// L3 = -L3.z * L0 + L0.z * L3;
|
||||
// }
|
||||
// else if (config == 4) { // V3 clip V1 V2 V4
|
||||
// n = 3;
|
||||
// L0 = -L3.z * L2 + L2.z * L3;
|
||||
// L1 = -L1.z * L2 + L2.z * L1;
|
||||
// }
|
||||
// else if (config == 5) { // V1 V3 clip V2 V4) impossible
|
||||
// n = 0;
|
||||
// }
|
||||
// else if (config == 6) { // V2 V3 clip V1 V4
|
||||
// n = 4;
|
||||
// L0 = -L0.z * L1 + L1.z * L0;
|
||||
// L3 = -L3.z * L2 + L2.z * L3;
|
||||
// }
|
||||
// else if (config == 7) { // V1 V2 V3 clip V4
|
||||
// n = 5;
|
||||
// L4 = -L3.z * L0 + L0.z * L3;
|
||||
// L3 = -L3.z * L2 + L2.z * L3;
|
||||
// }
|
||||
// else if (config == 8) { // V4 clip V1 V2 V3
|
||||
// n = 3;
|
||||
// L0 = -L0.z * L3 + L3.z * L0;
|
||||
// L1 = -L2.z * L3 + L3.z * L2;
|
||||
// L2 = L3;
|
||||
// }
|
||||
// else if (config == 9) { // V1 V4 clip V2 V3
|
||||
// n = 4;
|
||||
// L1 = -L1.z * L0 + L0.z * L1;
|
||||
// L2 = -L2.z * L3 + L3.z * L2;
|
||||
// }
|
||||
// else if (config == 10) { // V2 V4 clip V1 V3) impossible
|
||||
// n = 0;
|
||||
// }
|
||||
// else if (config == 11) { // V1 V2 V4 clip V3
|
||||
// n = 5;
|
||||
// L4 = L3;
|
||||
// L3 = -L2.z * L3 + L3.z * L2;
|
||||
// L2 = -L2.z * L1 + L1.z * L2;
|
||||
// }
|
||||
// else if (config == 12) { // V3 V4 clip V1 V2
|
||||
// n = 4;
|
||||
// L1 = -L1.z * L2 + L2.z * L1;
|
||||
// L0 = -L0.z * L3 + L3.z * L0;
|
||||
// }
|
||||
// else if (config == 13) { // V1 V3 V4 clip V2
|
||||
// n = 5;
|
||||
// L4 = L3;
|
||||
// L3 = L2;
|
||||
// L2 = -L1.z * L2 + L2.z * L1;
|
||||
// L1 = -L1.z * L0 + L0.z * L1;
|
||||
// }
|
||||
// else if (config == 14) { // V2 V3 V4 clip V1
|
||||
// n = 5;
|
||||
// L4 = -L0.z * L3 + L3.z * L0;
|
||||
// L0 = -L0.z * L1 + L1.z * L0;
|
||||
// }
|
||||
// else if (config == 15) { // V1 V2 V3 V4
|
||||
// n = 4;
|
||||
// }
|
||||
|
||||
// if (n == 3)
|
||||
// L3 = L0;
|
||||
// if (n == 4)
|
||||
// L4 = L0;
|
||||
// return n;
|
||||
// }
|
||||
// vec3 LTC_Evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3, bool twoSided) {
|
||||
// // construct orthonormal basis around N
|
||||
// vec3 T1, T2;
|
||||
// T1 = normalize(V - N*dot(V, N));
|
||||
// T2 = cross(N, T1);
|
||||
|
||||
// // rotate area light in (T1, T2, R) basis
|
||||
// Minv = mul(Minv, transpose2(mat3(T1, T2, N)));
|
||||
|
||||
// // polygon (allocate 5 vertices for clipping)
|
||||
// // vec3 L[5];
|
||||
// L0 = mul(Minv, points0 - P);
|
||||
// L1 = mul(Minv, points1 - P);
|
||||
// L2 = mul(Minv, points2 - P);
|
||||
// L3 = mul(Minv, points3 - P);
|
||||
|
||||
// int n = ClipQuadToHorizon(/*L, n*/);
|
||||
|
||||
// if (n == 0) {
|
||||
// return vec3(0, 0, 0);
|
||||
// }
|
||||
|
||||
// // project onto sphere
|
||||
// L0 = normalize(L0);
|
||||
// L1 = normalize(L1);
|
||||
// L2 = normalize(L2);
|
||||
// L3 = normalize(L3);
|
||||
// L4 = normalize(L4);
|
||||
|
||||
// // integrate
|
||||
// float sum = 0.0;
|
||||
|
||||
// sum += IntegrateEdge(L0, L1);
|
||||
// sum += IntegrateEdge(L1, L2);
|
||||
// sum += IntegrateEdge(L2, L3);
|
||||
|
||||
// if (n >= 4) {
|
||||
// sum += IntegrateEdge(L3, L4);
|
||||
// }
|
||||
// if (n == 5) {
|
||||
// sum += IntegrateEdge(L4, L0);
|
||||
// }
|
||||
|
||||
// sum = twoSided ? abs(sum) : max(0.0, -sum);
|
||||
|
||||
// vec3 Lo_i = vec3(sum, sum, sum);
|
||||
|
||||
// return Lo_i;
|
||||
// }
|
17
Shaders/std/math.glsl
Executable file
17
Shaders/std/math.glsl
Executable file
|
@ -0,0 +1,17 @@
|
|||
|
||||
float hash(const vec2 p) {
|
||||
float h = dot(p, vec2(127.1, 311.7));
|
||||
return fract(sin(h) * 43758.5453123);
|
||||
}
|
||||
|
||||
vec2 envMapEquirect(const vec3 normal) {
|
||||
const float PI = 3.1415926535;
|
||||
const float PI2 = PI * 2.0;
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
float rand(vec2 co) { // Unreliable
|
||||
return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
43
Shaders/std/shadows.glsl
Executable file
43
Shaders/std/shadows.glsl
Executable file
|
@ -0,0 +1,43 @@
|
|||
#include "../compiled.glsl"
|
||||
|
||||
uniform sampler2D shadowMap;
|
||||
|
||||
float texture2DCompare(const vec2 uv, const float compare){
|
||||
float depth = texture(shadowMap, uv).r; // * 2.0 - 1.0; // - mult compare instead
|
||||
return step(compare, depth);
|
||||
}
|
||||
|
||||
float texture2DShadowLerp(const vec2 uv, const float compare){
|
||||
const vec2 texelSize = vec2(1.0) / shadowmapSize;
|
||||
vec2 f = fract(uv * shadowmapSize + 0.5);
|
||||
vec2 centroidUV = floor(uv * shadowmapSize + 0.5) / shadowmapSize;
|
||||
float lb = texture2DCompare(centroidUV, compare);
|
||||
float lt = texture2DCompare(centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = texture2DCompare(centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = texture2DCompare(centroidUV + texelSize, compare);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
return c;
|
||||
}
|
||||
|
||||
float PCF(const vec2 uv, float compare) {
|
||||
// float result = 0.0;
|
||||
// for (int x = -1; x <= 1; x++){
|
||||
// for(int y = -1; y <= 1; y++){
|
||||
// vec2 off = vec2(x, y) / shadowmapSize;
|
||||
// result += texture2DShadowLerp(shadowmapSize, uv + off, compare);
|
||||
compare = compare * 0.5 + 0.5;
|
||||
float result = texture2DShadowLerp(uv + (vec2(-1.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(-1.0, 0.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(-1.0, 1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(0.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv, compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(0.0, 1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, -1.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, 0.0) / shadowmapSize), compare);
|
||||
result += texture2DShadowLerp(uv + (vec2(1.0, 1.0) / shadowmapSize), compare);
|
||||
// }
|
||||
// }
|
||||
return result / 9.0;
|
||||
}
|
191
Shaders/std/shadows_pcss.glsl
Executable file
191
Shaders/std/shadows_pcss.glsl
Executable file
|
@ -0,0 +1,191 @@
|
|||
// Based on ThreeJS and nvidia pcss
|
||||
|
||||
#include "../compiled.glsl"
|
||||
|
||||
uniform sampler2D shadowMap;
|
||||
uniform sampler2D snoise;
|
||||
uniform float lampSizeUV;
|
||||
uniform float lampNear;
|
||||
|
||||
const int NUM_SAMPLES = 17;
|
||||
const float radiusStep = 1.0 / float(NUM_SAMPLES);
|
||||
const float angleStep = PI2 * float(pcssRings) / float(NUM_SAMPLES);
|
||||
|
||||
vec2 poissonDisk0; vec2 poissonDisk1; vec2 poissonDisk2;
|
||||
vec2 poissonDisk3; vec2 poissonDisk4; vec2 poissonDisk5;
|
||||
vec2 poissonDisk6; vec2 poissonDisk7; vec2 poissonDisk8;
|
||||
vec2 poissonDisk9; vec2 poissonDisk10; vec2 poissonDisk11;
|
||||
vec2 poissonDisk12; vec2 poissonDisk13; vec2 poissonDisk14;
|
||||
vec2 poissonDisk15; vec2 poissonDisk16;
|
||||
|
||||
void initPoissonSamples(const vec2 randomSeed) {
|
||||
float angle = texture(snoise, randomSeed).r * PI2;
|
||||
float radius = radiusStep;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
poissonDisk0 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk1 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk2 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk3 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk4 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk5 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk6 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk7 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk8 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk9 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk10 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk11 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk12 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk13 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk14 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk15 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
poissonDisk16 = vec2(cos(angle), sin(angle)) * pow(radius, 0.75);
|
||||
radius += radiusStep; angle += angleStep;
|
||||
// }
|
||||
}
|
||||
|
||||
float findBlocker(const vec2 uv, const float zReceiver) {
|
||||
// This uses similar triangles to compute what area of the shadow map we should search
|
||||
float searchRadius = lampSizeUV * (zReceiver - lampNear) / zReceiver;
|
||||
float blockerDepthSum = 0.0;
|
||||
int numBlockers = 0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float shadowMapDepth = texture(shadowMap, uv + poissonDisk0 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk1 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk2 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk3 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk4 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk5 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk6 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk7 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk8 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk9 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk10 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk11 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk12 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk13 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk14 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk15 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
shadowMapDepth = texture(shadowMap, uv + poissonDisk16 * searchRadius).r * 2.0 - 1.0;
|
||||
if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers++; }
|
||||
// }
|
||||
if (numBlockers == 0) return -1.0;
|
||||
return blockerDepthSum / float(numBlockers);
|
||||
}
|
||||
|
||||
float filterPCF(const vec2 uv, const float zReceiver, const float filterRadius) {
|
||||
float sum = 0.0;
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float depth = texture(shadowMap, uv + poissonDisk0 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk1 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk2 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk3 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk4 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk5 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk6 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk7 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk8 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk9 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk10 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk11 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk12 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk13 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk14 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk15 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + poissonDisk16 * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
// for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
depth = texture(shadowMap, uv + -poissonDisk0.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk1.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk2.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk3.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk4.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk5.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk6.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk7.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk8.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk9.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk10.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk11.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk12.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk13.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk14.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk15.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
depth = texture(shadowMap, uv + -poissonDisk16.yx * filterRadius).r * 2.0 - 1.0;
|
||||
if (zReceiver <= depth) sum += 1.0;
|
||||
// }
|
||||
return sum / (2.0 * float(NUM_SAMPLES));
|
||||
}
|
||||
|
||||
float PCSS(const vec2 uv, const float zReceiver) {
|
||||
initPoissonSamples(uv);
|
||||
float avgBlockerDepth = findBlocker(uv, zReceiver);
|
||||
if (avgBlockerDepth == -1.0) return 1.0;
|
||||
float penumbraRatio = (zReceiver - avgBlockerDepth) / avgBlockerDepth;
|
||||
float filterRadius = penumbraRatio * lampSizeUV * lampNear / zReceiver;
|
||||
return filterPCF(uv, zReceiver, filterRadius);
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
uniform float shirr[27];
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
vec3 shIrradiance(const vec3 nor, const float scale) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
|
@ -16,8 +16,8 @@ vec3 shIrradiance(vec3 nor, float scale) {
|
|||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
|
@ -27,5 +27,5 @@ vec3 shIrradiance(vec3 nor, float scale) {
|
|||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
) * scale;
|
||||
}
|
||||
|
|
68
Shaders/std/shirr_probe.glsl
Executable file
68
Shaders/std/shirr_probe.glsl
Executable file
|
@ -0,0 +1,68 @@
|
|||
uniform float shirr[27 * 6]; // Maximum of 6 SH sets
|
||||
|
||||
vec3 shIrradiance(vec3 nor, float scale, int probe) {
|
||||
const float c1 = 0.429043;
|
||||
const float c2 = 0.511664;
|
||||
const float c3 = 0.743125;
|
||||
const float c4 = 0.886227;
|
||||
const float c5 = 0.247708;
|
||||
vec3 cl00, cl1m1, cl10, cl11, cl2m2, cl2m1, cl20, cl21, cl22;
|
||||
if (probe == 0) {
|
||||
cl00 = vec3(shirr[0], shirr[1], shirr[2]);
|
||||
cl1m1 = vec3(shirr[3], shirr[4], shirr[5]);
|
||||
cl10 = vec3(shirr[6], shirr[7], shirr[8]);
|
||||
cl11 = vec3(shirr[9], shirr[10], shirr[11]);
|
||||
cl2m2 = vec3(shirr[12], shirr[13], shirr[14]);
|
||||
cl2m1 = vec3(shirr[15], shirr[16], shirr[17]);
|
||||
cl20 = vec3(shirr[18], shirr[19], shirr[20]);
|
||||
cl21 = vec3(shirr[21], shirr[22], shirr[23]);
|
||||
cl22 = vec3(shirr[24], shirr[25], shirr[26]);
|
||||
}
|
||||
else if (probe == 1) {
|
||||
cl00 = vec3(shirr[27 + 0], shirr[27 + 1], shirr[27 + 2]); cl1m1 = vec3(shirr[27 + 3], shirr[27 + 4], shirr[27 + 5]);
|
||||
cl10 = vec3(shirr[27 + 6], shirr[27 + 7], shirr[27 + 8]); cl11 = vec3(shirr[27 + 9], shirr[27 + 10], shirr[27 + 11]);
|
||||
cl2m2 = vec3(shirr[27 + 12], shirr[27 + 13], shirr[27 + 14]); cl2m1 = vec3(shirr[27 + 15], shirr[27 + 16], shirr[27 + 17]);
|
||||
cl20 = vec3(shirr[27 + 18], shirr[27 + 19], shirr[27 + 20]); cl21 = vec3(shirr[27 + 21], shirr[27 + 22], shirr[27 + 23]);
|
||||
cl22 = vec3(shirr[27 + 24], shirr[27 + 25], shirr[27 + 26]);
|
||||
}
|
||||
else if (probe == 2) {
|
||||
cl00 = vec3(shirr[27 * 2 + 0], shirr[27 * 2 + 1], shirr[27 * 2 + 2]); cl1m1 = vec3(shirr[27 * 2 + 3], shirr[27 * 2 + 4], shirr[27 * 2 + 5]);
|
||||
cl10 = vec3(shirr[27 * 2 + 6], shirr[27 * 2 + 7], shirr[27 * 2 + 8]); cl11 = vec3(shirr[27 * 2 + 9], shirr[27 * 2 + 10], shirr[27 * 2 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 2 + 12], shirr[27 * 2 + 13], shirr[27 * 2 + 14]); cl2m1 = vec3(shirr[27 * 2 + 15], shirr[27 * 2 + 16], shirr[27 * 2 + 17]);
|
||||
cl20 = vec3(shirr[27 * 2 + 18], shirr[27 * 2 + 19], shirr[27 * 2 + 20]); cl21 = vec3(shirr[27 * 2 + 21], shirr[27 * 2 + 22], shirr[27 * 2 + 23]);
|
||||
cl22 = vec3(shirr[27 * 2 + 24], shirr[27 * 2 + 25], shirr[27 * 2 + 26]);
|
||||
}
|
||||
else if (probe == 3) {
|
||||
cl00 = vec3(shirr[27 * 3 + 0], shirr[27 * 3 + 1], shirr[27 * 3 + 2]); cl1m1 = vec3(shirr[27 * 3 + 3], shirr[27 * 3 + 4], shirr[27 * 3 + 5]);
|
||||
cl10 = vec3(shirr[27 * 3 + 6], shirr[27 * 3 + 7], shirr[27 * 3 + 8]); cl11 = vec3(shirr[27 * 3 + 9], shirr[27 * 3 + 10], shirr[27 * 3 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 3 + 12], shirr[27 * 3 + 13], shirr[27 * 3 + 14]); cl2m1 = vec3(shirr[27 * 3 + 15], shirr[27 * 3 + 16], shirr[27 * 3 + 17]);
|
||||
cl20 = vec3(shirr[27 * 3 + 18], shirr[27 * 3 + 19], shirr[27 * 3 + 20]); cl21 = vec3(shirr[27 * 3 + 21], shirr[27 * 3 + 22], shirr[27 * 3 + 23]);
|
||||
cl22 = vec3(shirr[27 * 3 + 24], shirr[27 * 3 + 25], shirr[27 * 3 + 26]);
|
||||
}
|
||||
else if (probe == 4) {
|
||||
cl00 = vec3(shirr[27 * 4 + 0], shirr[27 * 4 + 1], shirr[27 * 4 + 2]); cl1m1 = vec3(shirr[27 * 4 + 3], shirr[27 * 4 + 4], shirr[27 * 4 + 5]);
|
||||
cl10 = vec3(shirr[27 * 4 + 6], shirr[27 * 4 + 7], shirr[27 * 4 + 8]); cl11 = vec3(shirr[27 * 4 + 9], shirr[27 * 4 + 10], shirr[27 * 4 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 4 + 12], shirr[27 * 4 + 13], shirr[27 * 4 + 14]); cl2m1 = vec3(shirr[27 * 4 + 15], shirr[27 * 4 + 16], shirr[27 * 4 + 17]);
|
||||
cl20 = vec3(shirr[27 * 4 + 18], shirr[27 * 4 + 19], shirr[27 * 4 + 20]); cl21 = vec3(shirr[27 * 4 + 21], shirr[27 * 4 + 22], shirr[27 * 4 + 23]);
|
||||
cl22 = vec3(shirr[27 * 4 + 24], shirr[27 * 4 + 25], shirr[27 * 4 + 26]);
|
||||
}
|
||||
else if (probe == 5) {
|
||||
cl00 = vec3(shirr[27 * 5 + 0], shirr[27 * 5 + 1], shirr[27 * 5 + 2]); cl1m1 = vec3(shirr[27 * 5 + 3], shirr[27 * 5 + 4], shirr[27 * 5 + 5]);
|
||||
cl10 = vec3(shirr[27 * 5 + 6], shirr[27 * 5 + 7], shirr[27 * 5 + 8]); cl11 = vec3(shirr[27 * 5 + 9], shirr[27 * 5 + 10], shirr[27 * 5 + 11]);
|
||||
cl2m2 = vec3(shirr[27 * 5 + 12], shirr[27 * 5 + 13], shirr[27 * 5 + 14]); cl2m1 = vec3(shirr[27 * 5 + 15], shirr[27 * 5 + 16], shirr[27 * 5 + 17]);
|
||||
cl20 = vec3(shirr[27 * 5 + 18], shirr[27 * 5 + 19], shirr[27 * 5 + 20]); cl21 = vec3(shirr[27 * 5 + 21], shirr[27 * 5 + 22], shirr[27 * 5 + 23]);
|
||||
cl22 = vec3(shirr[27 * 5 + 24], shirr[27 * 5 + 25], shirr[27 * 5 + 26]);
|
||||
}
|
||||
return (
|
||||
c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
|
||||
c3 * cl20 * nor.x * nor.x +
|
||||
c4 * cl00 -
|
||||
c5 * cl20 +
|
||||
2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
|
||||
2.0 * c1 * cl21 * nor.y * nor.x +
|
||||
2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
|
||||
2.0 * c2 * cl11 * nor.y +
|
||||
2.0 * c2 * cl1m1 * (-nor.z) +
|
||||
2.0 * c2 * cl10 * nor.x
|
||||
) * scale;
|
||||
}
|
50
Shaders/std/skinning.glsl
Executable file
50
Shaders/std/skinning.glsl
Executable file
|
@ -0,0 +1,50 @@
|
|||
// Geometric Skinning with Approximate Dual Quaternion Blending, Kavan
|
||||
// Based on https://github.com/tcoppex/aer-engine/blob/master/demos/aura/data/shaders/Skinning.glsl
|
||||
uniform float skinBones[skinMaxBones * 8];
|
||||
|
||||
void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B) {
|
||||
// Retrieve the real and dual part of the dual-quaternions
|
||||
mat4 matA, matB;
|
||||
matA[0][0] = skinBones[bone.x * 8 + 0];
|
||||
matA[0][1] = skinBones[bone.x * 8 + 1];
|
||||
matA[0][2] = skinBones[bone.x * 8 + 2];
|
||||
matA[0][3] = skinBones[bone.x * 8 + 3];
|
||||
matB[0][0] = skinBones[bone.x * 8 + 4];
|
||||
matB[0][1] = skinBones[bone.x * 8 + 5];
|
||||
matB[0][2] = skinBones[bone.x * 8 + 6];
|
||||
matB[0][3] = skinBones[bone.x * 8 + 7];
|
||||
matA[1][0] = skinBones[bone.y * 8 + 0];
|
||||
matA[1][1] = skinBones[bone.y * 8 + 1];
|
||||
matA[1][2] = skinBones[bone.y * 8 + 2];
|
||||
matA[1][3] = skinBones[bone.y * 8 + 3];
|
||||
matB[1][0] = skinBones[bone.y * 8 + 4];
|
||||
matB[1][1] = skinBones[bone.y * 8 + 5];
|
||||
matB[1][2] = skinBones[bone.y * 8 + 6];
|
||||
matB[1][3] = skinBones[bone.y * 8 + 7];
|
||||
matA[2][0] = skinBones[bone.z * 8 + 0];
|
||||
matA[2][1] = skinBones[bone.z * 8 + 1];
|
||||
matA[2][2] = skinBones[bone.z * 8 + 2];
|
||||
matA[2][3] = skinBones[bone.z * 8 + 3];
|
||||
matB[2][0] = skinBones[bone.z * 8 + 4];
|
||||
matB[2][1] = skinBones[bone.z * 8 + 5];
|
||||
matB[2][2] = skinBones[bone.z * 8 + 6];
|
||||
matB[2][3] = skinBones[bone.z * 8 + 7];
|
||||
matA[3][0] = skinBones[bone.w * 8 + 0];
|
||||
matA[3][1] = skinBones[bone.w * 8 + 1];
|
||||
matA[3][2] = skinBones[bone.w * 8 + 2];
|
||||
matA[3][3] = skinBones[bone.w * 8 + 3];
|
||||
matB[3][0] = skinBones[bone.w * 8 + 4];
|
||||
matB[3][1] = skinBones[bone.w * 8 + 5];
|
||||
matB[3][2] = skinBones[bone.w * 8 + 6];
|
||||
matB[3][3] = skinBones[bone.w * 8 + 7];
|
||||
// Handles antipodality by sticking joints in the same neighbourhood
|
||||
// weight.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||||
weight.xyz *= sign(matA[3] * matA).xyz;
|
||||
// Apply weights
|
||||
A = matA * weight; // Real part
|
||||
B = matB * weight; // Dual part
|
||||
// Normalize
|
||||
float invNormA = 1.0 / length(A);
|
||||
A *= invNormA;
|
||||
B *= invNormA;
|
||||
}
|
36
Shaders/std/skinning_mat.glsl
Executable file
36
Shaders/std/skinning_mat.glsl
Executable file
|
@ -0,0 +1,36 @@
|
|||
uniform float skinBones[skinMaxBones * 12];
|
||||
|
||||
mat4 getBoneMat(const int boneIndex) {
|
||||
vec4 v0 = vec4(skinBones[boneIndex * 12 + 0],
|
||||
skinBones[boneIndex * 12 + 1],
|
||||
skinBones[boneIndex * 12 + 2],
|
||||
skinBones[boneIndex * 12 + 3]);
|
||||
vec4 v1 = vec4(skinBones[boneIndex * 12 + 4],
|
||||
skinBones[boneIndex * 12 + 5],
|
||||
skinBones[boneIndex * 12 + 6],
|
||||
skinBones[boneIndex * 12 + 7]);
|
||||
vec4 v2 = vec4(skinBones[boneIndex * 12 + 8],
|
||||
skinBones[boneIndex * 12 + 9],
|
||||
skinBones[boneIndex * 12 + 10],
|
||||
skinBones[boneIndex * 12 + 11]);
|
||||
return mat4(v0.x, v0.y, v0.z, v0.w,
|
||||
v1.x, v1.y, v1.z, v1.w,
|
||||
v2.x, v2.y, v2.z, v2.w,
|
||||
0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
mat4 getSkinningMat(ivec4 bone, vec4 weight) {
|
||||
return weight.x * getBoneMat(bone.x) +
|
||||
weight.y * getBoneMat(bone.y) +
|
||||
weight.z * getBoneMat(bone.z) +
|
||||
weight.w * getBoneMat(bone.w);
|
||||
}
|
||||
|
||||
mat3 getSkinningMatVec(const mat4 skinningMat) {
|
||||
return mat3(skinningMat[0].xyz, skinningMat[1].xyz, skinningMat[2].xyz);
|
||||
}
|
||||
|
||||
// mat4 skinningMat = getSkinningMat();
|
||||
// mat3 skinningMatVec = getSkinningMatVec(skinningMat);
|
||||
// sPos = sPos * skinningMat;
|
||||
// vec3 _normal = normalize(mat3(N) * (nor * skinningMatVec));
|
28
Shaders/std/tonemap.glsl
Executable file
28
Shaders/std/tonemap.glsl
Executable file
|
@ -0,0 +1,28 @@
|
|||
|
||||
vec3 uncharted2Tonemap(const vec3 x) {
|
||||
const float A = 0.15;
|
||||
const float B = 0.50;
|
||||
const float C = 0.10;
|
||||
const float D = 0.20;
|
||||
const float E = 0.02;
|
||||
const float F = 0.30;
|
||||
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
|
||||
}
|
||||
|
||||
vec3 tonemapUncharted2(const vec3 color) {
|
||||
const float W = 11.2;
|
||||
const float exposureBias = 2.0;
|
||||
vec3 curr = uncharted2Tonemap(exposureBias * color);
|
||||
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||
return curr * whiteScale;
|
||||
}
|
||||
|
||||
// Based on Filmic Tonemapping Operators http://filmicgames.com/archives/75
|
||||
vec3 tonemapFilmic(const vec3 color) {
|
||||
vec3 x = max(vec3(0.0), color - 0.004);
|
||||
return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
|
||||
}
|
||||
|
||||
vec3 tonemapReinhard(const vec3 color) {
|
||||
return color / (color + vec3(1.0));
|
||||
}
|
26
Shaders/std/vr.glsl
Executable file
26
Shaders/std/vr.glsl
Executable file
|
@ -0,0 +1,26 @@
|
|||
uniform mat4 U; // Undistortion
|
||||
uniform float maxRadSq;
|
||||
|
||||
// GoogleVR Distortion using Vertex Displacement
|
||||
float distortionFactor(float rSquared) {
|
||||
float ret = 0.0;
|
||||
ret = rSquared * (ret + U[1][1]);
|
||||
ret = rSquared * (ret + U[0][1]);
|
||||
ret = rSquared * (ret + U[3][0]);
|
||||
ret = rSquared * (ret + U[2][0]);
|
||||
ret = rSquared * (ret + U[1][0]);
|
||||
ret = rSquared * (ret + U[0][0]);
|
||||
return ret + 1.0;
|
||||
}
|
||||
// Convert point from world space to undistorted camera space
|
||||
vec4 undistort(const mat4 WV, vec4 pos) {
|
||||
// Go to camera space
|
||||
pos = WV * pos;
|
||||
const float nearClip = 0.1;
|
||||
if (pos.z <= -nearClip) { // Reminder: Forward is -Z
|
||||
// Undistort the point's coordinates in XY
|
||||
float r2 = clamp(dot(pos.xy, pos.xy) / (pos.z * pos.z), 0.0, maxRadSq);
|
||||
pos.xy *= distortionFactor(r2);
|
||||
}
|
||||
return pos;
|
||||
}
|
|
@ -19,22 +19,22 @@ void main() {
|
|||
vec4 current = texture(tex, texCoord);
|
||||
|
||||
#ifdef _Veloc
|
||||
// Velocity is assumed to be calculated for motion blur, so we need to inverse it for reprojection
|
||||
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
|
||||
// Velocity is assumed to be calculated for motion blur, so we need to inverse it for reprojection
|
||||
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
|
||||
|
||||
// Reproject current coordinates and fetch previous pixel
|
||||
vec4 previous = texture(tex2, texCoord + velocity);
|
||||
// Reproject current coordinates and fetch previous pixel
|
||||
vec4 previous = texture(tex2, texCoord + velocity);
|
||||
|
||||
// Attenuate the previous pixel if the velocity is different
|
||||
#ifdef _SMAA
|
||||
float delta = abs(current.a * current.a - previous.a * previous.a) / 5.0;
|
||||
#else
|
||||
const float delta = 0.0;
|
||||
#endif
|
||||
float weight = 0.5 * clamp(1.0 - sqrt(delta) * SMAA_REPROJECTION_WEIGHT_SCALE, 0.0, 1.0);
|
||||
// Attenuate the previous pixel if the velocity is different
|
||||
#ifdef _SMAA
|
||||
float delta = abs(current.a * current.a - previous.a * previous.a) / 5.0;
|
||||
#else
|
||||
const float delta = 0.0;
|
||||
#endif
|
||||
float weight = 0.5 * clamp(1.0 - sqrt(delta) * SMAA_REPROJECTION_WEIGHT_SCALE, 0.0, 1.0);
|
||||
|
||||
// Blend the pixels according to the calculated weight:
|
||||
fragColor.rgb = mix(current.rgb, previous.rgb, weight);
|
||||
// Blend the pixels according to the calculated weight:
|
||||
fragColor.rgb = mix(current.rgb, previous.rgb, weight);
|
||||
#else
|
||||
vec4 previous = texture(tex2, texCoord);
|
||||
fragColor = mix(current.rgb, previous.rgb, 0.5);
|
||||
|
|
|
@ -17,9 +17,9 @@ void main() {
|
|||
float revealage = accum.a;
|
||||
|
||||
if (revealage == 1.0) {
|
||||
// Save the blending and color texture fetch cost
|
||||
discard;
|
||||
}
|
||||
// Save the blending and color texture fetch cost
|
||||
discard;
|
||||
}
|
||||
|
||||
float accumA = texture(gbuffer1, texCoord).r;
|
||||
// accum.a = texture(gbuffer1, texCoord).r;
|
||||
|
|
|
@ -32,21 +32,14 @@ const float tExt = 0.0; //tScat + tAbs;
|
|||
// const float stepLen = 1.0 / 11.0;
|
||||
const float stepLen = 1.0 / 80; // Temporary..
|
||||
|
||||
vec3 getPos(float depth, vec2 coord) {
|
||||
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
|
||||
pos = invVP * pos;
|
||||
pos.xyz /= pos.w;
|
||||
return pos.xyz;
|
||||
}
|
||||
|
||||
// const float lighting = 0.4;
|
||||
float lighting(vec3 p) {
|
||||
vec3 L = lightPos.xyz - p.xyz;
|
||||
float Ldist = length(lightPos.xyz - p.xyz);
|
||||
vec3 Lnorm = L / Ldist;
|
||||
vec3 L = lightPos.xyz - p.xyz;
|
||||
float Ldist = length(lightPos.xyz - p.xyz);
|
||||
vec3 Lnorm = L / Ldist;
|
||||
|
||||
float linearAtenuation = min(1.0, max(0.0, (lightRadius - Ldist) / lightRadius));
|
||||
return linearAtenuation; //* min(1.0, 1.0 / (Ldist * Ldist));
|
||||
float linearAtenuation = min(1.0, max(0.0, (lightRadius - Ldist) / lightRadius));
|
||||
return linearAtenuation; //* min(1.0, 1.0 / (Ldist * Ldist));
|
||||
}
|
||||
|
||||
void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatteredLightAmount, float stepLenWorld, vec3 viewVecNorm) {
|
||||
|
@ -62,7 +55,7 @@ void rayStep(inout vec3 curPos, inout float curOpticalDepth, inout float scatter
|
|||
vec4 lampPos = LWVP * vec4(curPos, 1.0);
|
||||
if (lampPos.w > 0.0) {
|
||||
lampPos.xyz /= lampPos.w;
|
||||
lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
lampPos.xy = lampPos.xy * 0.5 + 0.5;
|
||||
float distanceFromLight = texture(shadowMap, lampPos.xy).r * 2.0 - 1.0;
|
||||
visibility = float(distanceFromLight > lampPos.z - shadowsBias);
|
||||
}
|
||||
|
@ -75,122 +68,122 @@ void main() {
|
|||
vec2 texCoord = screenPosition * 0.5 + 0.5;
|
||||
// texCoord += vec2(0.5 / screenSize); // Half pixel offset
|
||||
|
||||
float pixelRayMarchNoise = texture(snoise, texCoord).r;
|
||||
float pixelRayMarchNoise = texture(snoise, texCoord).r;
|
||||
|
||||
float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
vec3 worldPos = getPos(depth, texCoord);
|
||||
vec3 worldPos = getPos2(invVP, depth, texCoord);
|
||||
|
||||
vec3 viewVec = worldPos - viewPos;
|
||||
float worldPosDist = length(viewVec);
|
||||
vec3 viewVecNorm = viewVec / worldPosDist;
|
||||
float worldPosDist = length(viewVec);
|
||||
vec3 viewVecNorm = viewVec / worldPosDist;
|
||||
|
||||
float startDepth = 0.1;
|
||||
startDepth = min(worldPosDist, startDepth);
|
||||
float endDepth = 20.0;
|
||||
endDepth = min(worldPosDist, endDepth);
|
||||
float startDepth = 0.1;
|
||||
startDepth = min(worldPosDist, startDepth);
|
||||
float endDepth = 20.0;
|
||||
endDepth = min(worldPosDist, endDepth);
|
||||
|
||||
vec3 curPos = viewPos + viewVecNorm * startDepth;
|
||||
float stepLenWorld = stepLen * (endDepth - startDepth);
|
||||
float curOpticalDepth = exp(-tExt * stepLenWorld);
|
||||
float scatteredLightAmount = 0.0;
|
||||
vec3 curPos = viewPos + viewVecNorm * startDepth;
|
||||
float stepLenWorld = stepLen * (endDepth - startDepth);
|
||||
float curOpticalDepth = exp(-tExt * stepLenWorld);
|
||||
float scatteredLightAmount = 0.0;
|
||||
|
||||
curPos += stepLenWorld * viewVecNorm * (2.0 * pixelRayMarchNoise - 1.0);
|
||||
curPos += stepLenWorld * viewVecNorm * (2.0 * pixelRayMarchNoise - 1.0);
|
||||
|
||||
// for(float l = stepLen; l < 0.99999; l += stepLen) {// Do not do the first and last steps
|
||||
// Raw steps for now..
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
// for(float l = stepLen; l < 0.99999; l += stepLen) {// Do not do the first and last steps
|
||||
// Raw steps for now..
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
// }
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
rayStep(curPos, curOpticalDepth, scatteredLightAmount, stepLenWorld, viewVecNorm);
|
||||
// }
|
||||
|
||||
// curOpticalDepth
|
||||
fragColor = vec4(scatteredLightAmount * lightColor.rgb * volumAirColor * volumAirTurbidity, 0.0);
|
||||
// curOpticalDepth
|
||||
fragColor = vec4(scatteredLightAmount * lightColor.rgb * volumAirColor * volumAirTurbidity, 0.0);
|
||||
// fragColor = vec4(scatteredLightAmount * lightColor.rgb * ((1.0 - depth) * 10.0), 0.0);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#include "../std/gbuffer.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D gbufferD;
|
||||
|
@ -44,7 +45,7 @@ float noise(vec2 p) {
|
|||
// float noise(vec2 xx) {
|
||||
// return -1.0 + 2.0 * texture(snoise, xx / 20.0).r;
|
||||
// }
|
||||
float sea_octave(vec2 uv, float choppy) {
|
||||
float seaOctave(vec2 uv, float choppy) {
|
||||
uv += noise(uv);
|
||||
vec2 wv = 1.0 - abs(sin(uv));
|
||||
vec2 swv = abs(cos(uv));
|
||||
|
@ -61,14 +62,14 @@ float map(vec3 p) {
|
|||
|
||||
float d, h = 0.0;
|
||||
// for(int i = 0; i < 2; i++) {
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq, choppy);
|
||||
d += sea_octave((uv - (time * seaSpeed)) * freq, choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq, choppy);
|
||||
d += seaOctave((uv - (time * seaSpeed)) * freq, choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
//
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq, choppy);
|
||||
d += sea_octave((uv-(time * seaSpeed)) * freq, choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq, choppy);
|
||||
d += seaOctave((uv-(time * seaSpeed)) * freq, choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
|
@ -76,7 +77,7 @@ float map(vec3 p) {
|
|||
// }
|
||||
return p.z - h;
|
||||
}
|
||||
float map_detailed(vec3 p) {
|
||||
float mapDetailed(vec3 p) {
|
||||
float freq = seaFreq;
|
||||
float amp = seaHeight;
|
||||
float choppy = seaChoppy;
|
||||
|
@ -84,29 +85,29 @@ float map_detailed(vec3 p) {
|
|||
|
||||
float d, h = 0.0;
|
||||
// for(int i = 0; i < 4; i++) {
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += sea_octave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += seaOctave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
//
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += sea_octave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += seaOctave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += sea_octave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += seaOctave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += sea_octave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += seaOctave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
d = sea_octave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += sea_octave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
d = seaOctave((uv + (time * seaSpeed)) * freq,choppy);
|
||||
d += seaOctave((uv - (time * seaSpeed)) * freq,choppy);
|
||||
h += d * amp;
|
||||
uv *= octavem; freq *= 1.9; amp *= 0.22;
|
||||
choppy = mix(choppy, 1.0, 0.2);
|
||||
|
@ -115,9 +116,9 @@ float map_detailed(vec3 p) {
|
|||
}
|
||||
vec3 getNormal(vec3 p, float eps) {
|
||||
vec3 n;
|
||||
n.z = map_detailed(p);
|
||||
n.x = map_detailed(vec3(p.x + eps, p.y, p.z)) - n.z;
|
||||
n.y = map_detailed(vec3(p.x, p.y + eps, p.z)) - n.z;
|
||||
n.z = mapDetailed(p);
|
||||
n.x = mapDetailed(vec3(p.x + eps, p.y, p.z)) - n.z;
|
||||
n.y = mapDetailed(vec3(p.x, p.y + eps, p.z)) - n.z;
|
||||
n.z = eps;
|
||||
return normalize(n);
|
||||
}
|
||||
|
@ -125,14 +126,14 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) {
|
|||
vec3 p;
|
||||
float tm = 0.0;
|
||||
float tx = 1000.0;
|
||||
float hx = map_detailed(ori + dir * tx);
|
||||
float hx = mapDetailed(ori + dir * tx);
|
||||
if(hx > 0.0) return p;
|
||||
float hm = map_detailed(ori + dir * tm);
|
||||
float hm = mapDetailed(ori + dir * tm);
|
||||
float tmid = 0.0;
|
||||
// for(int i = 0; i < 5; i++) {
|
||||
tmid = mix(tm, tx, hm / (hm - hx));
|
||||
p = ori + dir * tmid;
|
||||
float hmid = map_detailed(p);
|
||||
float hmid = mapDetailed(p);
|
||||
if (hmid < 0.0) {
|
||||
tx = tmid;
|
||||
hx = hmid;
|
||||
|
@ -144,7 +145,7 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) {
|
|||
//
|
||||
tmid = mix(tm, tx, hm / (hm - hx));
|
||||
p = ori + dir * tmid;
|
||||
hmid = map_detailed(p);
|
||||
hmid = mapDetailed(p);
|
||||
if (hmid < 0.0) {
|
||||
tx = tmid;
|
||||
hx = hmid;
|
||||
|
@ -155,7 +156,7 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) {
|
|||
}
|
||||
tmid = mix(tm, tx, hm / (hm - hx));
|
||||
p = ori + dir * tmid;
|
||||
hmid = map_detailed(p);
|
||||
hmid = mapDetailed(p);
|
||||
if (hmid < 0.0) {
|
||||
tx = tmid;
|
||||
hx = hmid;
|
||||
|
@ -166,7 +167,7 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) {
|
|||
}
|
||||
tmid = mix(tm, tx, hm / (hm - hx));
|
||||
p = ori + dir * tmid;
|
||||
hmid = map_detailed(p);
|
||||
hmid = mapDetailed(p);
|
||||
if (hmid < 0.0) {
|
||||
tx = tmid;
|
||||
hx = hmid;
|
||||
|
@ -177,7 +178,7 @@ vec3 heightMapTracing(vec3 ori, vec3 dir) {
|
|||
}
|
||||
tmid = mix(tm, tx, hm / (hm - hx));
|
||||
p = ori + dir * tmid;
|
||||
hmid = map_detailed(p);
|
||||
hmid = mapDetailed(p);
|
||||
if (hmid < 0.0) {
|
||||
tx = tmid;
|
||||
hx = hmid;
|
||||
|
@ -217,16 +218,6 @@ vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {
|
|||
return color;
|
||||
}
|
||||
|
||||
vec3 getPos(float depth) {
|
||||
vec3 vray = normalize(viewRay);
|
||||
const float projectionA = cameraPlane.y / (cameraPlane.y - cameraPlane.x);
|
||||
const float projectionB = (-cameraPlane.y * cameraPlane.x) / (cameraPlane.y - cameraPlane.x);
|
||||
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
|
||||
float viewZDist = dot(eyeLook, vray);
|
||||
vec3 wposition = eye + vray * (linearDepth / viewZDist);
|
||||
return wposition;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float gdepth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
vec4 colorOriginal = texture(tex, texCoord);
|
||||
|
@ -236,7 +227,7 @@ void main() {
|
|||
// }
|
||||
|
||||
vec3 color = colorOriginal.rgb;
|
||||
vec3 position = getPos(gdepth);
|
||||
vec3 position = getPos(eye, eyeLook, viewRay, gdepth);
|
||||
|
||||
if (position.z <= seaLevel + seaMaxAmplitude) {
|
||||
const vec3 ld = normalize(vec3(0.3, -0.3, 1.0));
|
||||
|
@ -263,7 +254,7 @@ void main() {
|
|||
// vec2 texco = texCoord.xy;
|
||||
// texco.x += sin((time) * 0.002 + 3.0 * abs(position.z)) * (refractionScale * min(depthZ, 1.0));
|
||||
// vec3 refraction = texture(tex, texco).rgb;
|
||||
// vec3 _p = getPos(1.0 - texture(gbuffer0, texco).a);
|
||||
// vec3 _p = getPos(eye, eyeLook, viewRay, 1.0 - texture(gbuffer0, texco).a);
|
||||
// if (_p.z > seaLevel) {
|
||||
// refraction = colorOriginal.rgb;
|
||||
// }
|
||||
|
@ -306,5 +297,4 @@ void main() {
|
|||
}
|
||||
|
||||
fragColor.rgb = color;
|
||||
// gl_FragData[0].rgb = color;
|
||||
}
|
||||
|
|
|
@ -15,10 +15,9 @@ out vec2 texCoord;
|
|||
out vec3 viewRay;
|
||||
out vec3 vecnormal;
|
||||
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
|
||||
void main() {
|
||||
// Scale vertex attribute to [0-1] range
|
||||
const vec2 madd = vec2(0.5, 0.5);
|
||||
texCoord = pos.xy * madd + madd;
|
||||
|
||||
gl_Position = vec4(pos.xy, 0.0, 1.0);
|
||||
|
@ -26,7 +25,7 @@ void main() {
|
|||
vec4 p = vec4(pos.xy, 0.0, 1.0);
|
||||
vec3 unprojected = (invP * p).xyz;
|
||||
vecnormal = mat3(transpV) * unprojected;
|
||||
|
||||
|
||||
// NDC (at the back of cube)
|
||||
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
|
||||
v = vec4(invVP * v);
|
||||
|
|
|
@ -5,6 +5,10 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
#include "../compiled.glsl"
|
||||
#ifdef _EnvTex
|
||||
#include "../std/math.glsl"
|
||||
// envMapEquirect()
|
||||
#endif
|
||||
|
||||
#ifdef _EnvCol
|
||||
uniform vec3 backgroundCol;
|
||||
|
@ -43,15 +47,15 @@ out vec4 fragColor;
|
|||
#ifdef _EnvSky
|
||||
vec3 hosekWilkie(float cos_theta, float gamma, float cos_gamma) {
|
||||
vec3 chi = (1 + cos_gamma * cos_gamma) / pow(1 + H * H - 2 * cos_gamma * H, vec3(1.5));
|
||||
return (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta));
|
||||
return (1 + A * exp(B / (cos_theta + 0.01))) * (C + D * exp(E * gamma) + F * (cos_gamma * cos_gamma) + G * chi + I * sqrt(cos_theta));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EnvClouds
|
||||
// float hash(vec3 p) {
|
||||
// p = fract(p * vec3(0.16532, 0.17369, 0.15787));
|
||||
// p += dot(p.xyz, p.zyx + 19.19);
|
||||
// return fract(p.x * p.y * p.z);
|
||||
// p += dot(p.xyz, p.zyx + 19.19);
|
||||
// return fract(p.x * p.y * p.z);
|
||||
// }
|
||||
float noise(vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
|
@ -69,7 +73,7 @@ float fbm(vec3 p) {
|
|||
f += 0.0625 * noise(p); p = p * 3.0;
|
||||
f += 0.03125 * noise(p); p = p * 3.0;
|
||||
f += 0.015625 * noise(p);
|
||||
return f;
|
||||
return f;
|
||||
}
|
||||
float map(vec3 p) {
|
||||
return fbm(p) - cloudsDensity * 0.6;
|
||||
|
@ -87,7 +91,7 @@ vec2 traceCloud(vec3 pos, vec3 dir) {
|
|||
float beg = ((cloudsLower - pos.z) / dir.z);
|
||||
float end = ((cloudsUpper - pos.z) / dir.z);
|
||||
traceP = vec3(pos.x + dir.x * beg, pos.y + dir.y * beg, 0.0);
|
||||
// beg += hash(traceP) * 150.0; // Noisy
|
||||
// beg += hash(traceP) * 150.0; // Noisy
|
||||
vec3 add = dir * ((end - beg) / steps);
|
||||
|
||||
vec2 shadeSum = vec2(0.0);
|
||||
|
@ -170,14 +174,6 @@ vec3 cloudsColor(vec3 R, vec3 pos, vec3 dir) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EnvTex
|
||||
vec2 envMapEquirect(vec3 normal) {
|
||||
float phi = acos(normal.z);
|
||||
float theta = atan(-normal.y, normal.x) + PI;
|
||||
return vec2(theta / PI2, phi / PI);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
// if (texture(gbufferD, texCoord).r/* * 2.0 - 1.0*/ != 1.0) {
|
||||
// discard;
|
||||
|
@ -199,7 +195,7 @@ void main() {
|
|||
|
||||
#ifdef _EnvSky
|
||||
vec3 n = normalize(normal);
|
||||
vec3 sunDir = vec3(sunDirection.x, -sunDirection.y, sunDirection.z);
|
||||
vec3 sunDir = vec3(sunDirection.x, -sunDirection.y, sunDirection.z);
|
||||
float phi = acos(n.z);
|
||||
float theta = atan(-n.y, n.x) + PI;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
|
|||
if vertex_structure_parsing == True and len(line) > 0 and line.startswith('//') == False and line.startswith('in ') == False:
|
||||
vertex_structure_parsed = True
|
||||
|
||||
if line.startswith('uniform '):
|
||||
if line.startswith('uniform ') or line.startswith('//!uniform'): # Uniforms included from header files
|
||||
s = line.split(' ')
|
||||
# uniform sampler2D myname;
|
||||
# uniform layout(RGBA8) image3D myname;
|
||||
|
|
|
@ -230,7 +230,9 @@ def write_compiledglsl():
|
|||
wrd = bpy.data.worlds['Arm']
|
||||
with open('build/compiled/Shaders/compiled.glsl', 'w') as f:
|
||||
f.write(
|
||||
"""const float PI = 3.1415926535;
|
||||
"""#ifndef _COMPILED_GLSL_
|
||||
#define _COMPILED_GLSL_
|
||||
const float PI = 3.1415926535;
|
||||
const float PI2 = PI * 2.0;
|
||||
const vec2 cameraPlane = vec2(""" + str(round(clip_start * 100) / 100) + """, """ + str(round(clip_end * 100) / 100) + """);
|
||||
const vec2 shadowmapSize = vec2(""" + str(shadowmap_size) + """, """ + str(shadowmap_size) + """);
|
||||
|
@ -333,6 +335,8 @@ const float compoDOFSize = """ + str(round(bpy.data.cameras[0].cycles.aperture_s
|
|||
"""const int skinMaxBones = """ + str(wrd.generate_gpu_skin_max_bones) + """;
|
||||
""")
|
||||
|
||||
f.write("""#endif // _COMPILED_GLSL_""")
|
||||
|
||||
def write_traithx(class_name):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
with open('Sources/' + wrd.arm_project_package + '/' + class_name + '.hx', 'w') as f:
|
||||
|
|
Loading…
Reference in a new issue