Shaders overhaul.

This commit is contained in:
Lubos Lenco 2016-10-17 17:39:40 +02:00
parent 73e67e3c1e
commit 9edb0b0fa9
76 changed files with 2425 additions and 4061 deletions

View file

@ -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"
}
]
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -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"
}
]
}

View file

@ -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;
}

View file

@ -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"
}
]

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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
}

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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)));

View file

@ -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

View file

@ -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..

View file

@ -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
}

View file

@ -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)));

View file

@ -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);
}

View file

@ -7,7 +7,7 @@
"cull_mode": "none",
"links": [
{
"name": "texStep",
"name": "screenSizeInv",
"link": "_screenSizeInv"
}
],

View file

@ -9,5 +9,5 @@ in vec4 color;
out vec4 fragColor;
void main() {
fragColor = color;
fragColor = color;
}

View file

@ -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"
}
]
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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)));

View file

@ -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));

View file

@ -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)));

View file

@ -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

View file

@ -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));
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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++;
}
// }

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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*/);
}

View file

@ -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

View file

@ -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*/);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}

View file

@ -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
View 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
View 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
View 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
View 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
View 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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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: