diff --git a/armorpaint/shaders/dilate_map.vert.glsl b/armorpaint/shaders/dilate_map.vert.glsl index f88a85cc..64c1a7a9 100644 --- a/armorpaint/shaders/dilate_map.vert.glsl +++ b/armorpaint/shaders/dilate_map.vert.glsl @@ -6,13 +6,13 @@ in vec2 tex; out float dummy; void main() { - #if defined(HLSL) || defined(METAL) || defined(SPIRV) - vec2 tex_coord = vec2(tex.x * 2.0 - 1.0, (1.0 - tex.y) * 2.0 - 1.0); - #else +#ifdef GLSL vec2 tex_coord = tex * 2.0 - 1.0; - #endif +#else + vec2 tex_coord = vec2(tex.x * 2.0 - 1.0, (1.0 - tex.y) * 2.0 - 1.0); +#endif gl_Position = vec4(tex_coord, 0.0, 1.0); - #ifdef HLSL +#ifdef HLSL float keep = pos.x + nor.x; - #endif +#endif } diff --git a/base/shaders/cursor.vert.glsl b/base/shaders/cursor.vert.glsl index 428a569d..ef1cd4af 100644 --- a/base/shaders/cursor.vert.glsl +++ b/base/shaders/cursor.vert.glsl @@ -12,21 +12,25 @@ uniform sampler2D gbufferD; uniform sampler2D texa; #endif +#ifdef HLSL in vec4 pos; in vec2 nor; +#endif in vec2 tex; out vec2 tex_coord; vec3 get_pos(vec2 uv) { - #ifdef HLSL +#ifdef HLSL float keep = textureLod(texa, vec2(0.0, 0.0), 0.0).r; // direct3d12 unit align float keep2 = pos.x + nor.x; - #endif - #if defined(HLSL) || defined(METAL) || defined(SPIRV) - float depth = textureLod(gbufferD, vec2(uv.x, 1.0 - uv.y), 0.0).r; - #else +#endif + +#ifdef GLSL float depth = textureLod(gbufferD, uv, 0.0).r; - #endif +#else + float depth = textureLod(gbufferD, vec2(uv.x, 1.0 - uv.y), 0.0).r; +#endif + vec4 wpos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); wpos = mul(wpos, invVP); return wpos.xyz / wpos.w; @@ -38,7 +42,7 @@ vec3 get_normal(vec3 p0, vec2 uv) { return normalize(cross(p2 - p0, p1 - p0)); } -void create_basis(vec3 normal, out vec3 tangent, out vec3 binormal) { +void create_basis(vec3 normal, OUT(vec3, tangent), OUT(vec3, binormal)) { tangent = normalize(camera_right - normal * dot(camera_right, normal)); binormal = cross(tangent, normal); } diff --git a/base/shaders/pass.vert.glsl b/base/shaders/pass.vert.glsl index 6f71dfbe..9d6e43e6 100644 --- a/base/shaders/pass.vert.glsl +++ b/base/shaders/pass.vert.glsl @@ -7,9 +7,11 @@ void main() { // Scale vertex attribute to [0-1] range const vec2 madd = vec2(0.5, 0.5); tex_coord = pos.xy * madd + madd; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) + +#ifdef GLSL +#else tex_coord.y = 1.0 - tex_coord.y; - #endif +#endif gl_Position = vec4(pos.xy, 0.0, 1.0); } diff --git a/base/shaders/pass_viewray.vert.glsl b/base/shaders/pass_viewray.vert.glsl index 5760db04..de8ab595 100644 --- a/base/shaders/pass_viewray.vert.glsl +++ b/base/shaders/pass_viewray.vert.glsl @@ -12,9 +12,11 @@ void main() { // Scale vertex attribute to [0-1] range const vec2 madd = vec2(0.5, 0.5); tex_coord = pos.xy * madd + madd; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) + +#ifdef GLSL +#else tex_coord.y = 1.0 - tex_coord.y; - #endif +#endif gl_Position = vec4(pos.xy, 0.0, 1.0); diff --git a/base/shaders/pass_viewray2.vert.glsl b/base/shaders/pass_viewray2.vert.glsl index a747e49a..a375f3d5 100644 --- a/base/shaders/pass_viewray2.vert.glsl +++ b/base/shaders/pass_viewray2.vert.glsl @@ -11,9 +11,11 @@ void main() { // Scale vertex attribute to [0-1] range const vec2 madd = vec2(0.5, 0.5); tex_coord = pos.xy * madd + madd; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) + +#ifdef GLSL +#else tex_coord.y = 1.0 - tex_coord.y; - #endif +#endif gl_Position = vec4(pos.xy, 0.0, 1.0); diff --git a/base/shaders/smaa_blend_weight.frag.glsl b/base/shaders/smaa_blend_weight.frag.glsl index 8bb8ebe1..a2bee364 100644 --- a/base/shaders/smaa_blend_weight.frag.glsl +++ b/base/shaders/smaa_blend_weight.frag.glsl @@ -28,36 +28,19 @@ in vec4 offset1; in vec4 offset2; out vec4 frag_color; -// Blending Weight Calculation Pixel Shader (Second Pass) vec2 cdw_end; vec4 textureLod_a(sampler2D edges_tex, vec2 coord, float lod) { - #if defined(HLSL) || defined(METAL) || defined(SPIRV) +#ifdef GLSL +#else coord.y = 1.0 - coord.y; - #endif +#endif return textureLod(edges_tex, coord, lod); } #define smaa_sample_level_zero_offset(edges_tex, coord, offset) textureLod_a(edges_tex, coord + offset * screen_size_inv.xy, 0.0) -//----------------------------------------------------------------------------- -// Diagonal Search Functions - -// #if !defined(SMAA_DISABLE_DIAG_DETECTION) vec2 smaa_decode_diag_bilinear_access(vec2 e) { - // Bilinear access for fetching 'e' have a 0.25 offset, and we are - // interested in the R and G edges: - // - // +---G---+-------+ - // | x o R x | - // +-------+-------+ - // - // Then, if one of these edge is enabled: - // Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0 - // Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0 - // - // This function will unpack the values (mad + mul + round): - // wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1 e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75); return round(e); } @@ -67,12 +50,12 @@ vec4 smaa_decode_diag_bilinear_access(vec4 e) { return round(e); } -vec2 smaa_search_diag1(vec2 texcoord, vec2 dir/*, out vec2 e*/) { +vec2 smaa_search_diag1(vec2 texcoord, vec2 dir) { vec4 coord = vec4(texcoord, -1.0, 1.0); vec3 t = vec3(screen_size_inv.xy, 1.0); while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && coord.w > 0.9) { coord.xyz = mad(t, vec3(dir, 1.0), coord.xyz); - cdw_end /*e*/ = textureLod_a(edges_tex, coord.xy, 0.0).rg; + cdw_end = textureLod_a(edges_tex, coord.xy, 0.0).rg; coord.w = dot(cdw_end /*e*/, vec2(0.5, 0.5)); } return coord.zw; @@ -85,10 +68,9 @@ vec2 smaa_search_diag2(vec2 texcoord, vec2 dir) { float cw = coord.w; // TODO: krafix hlsl bug while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && cw > 0.9) { coord.xyz = mad(t, vec3(dir, 1.0), coord.xyz); - // Fetch both edges at once using bilinear filtering: - cdw_end /*e*/ = textureLod_a(edges_tex, coord.xy, 0.0).rg; - cdw_end /*e*/ = smaa_decode_diag_bilinear_access(cdw_end /*e*/); - cw = dot(cdw_end /*e*/, vec2(0.5, 0.5)); + cdw_end = textureLod_a(edges_tex, coord.xy, 0.0).rg; + cdw_end = smaa_decode_diag_bilinear_access(cdw_end); + cw = dot(cdw_end, vec2(0.5, 0.5)); } coord.w = cw; return coord.zw; @@ -96,63 +78,47 @@ vec2 smaa_search_diag2(vec2 texcoord, vec2 dir) { vec2 smaa_area_diag(vec2 dist, vec2 e, float offset) { vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist); - - // We do a scale and bias for mapping to texel space: texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); - - // Diagonal areas are on the second half of the texture: texcoord.x += 0.5; - - // Move to proper place, according to the subpixel offset: texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; - - // Do it! return SMAA_AREATEX_SELECT(textureLod(area_tex, texcoord, 0.0)); } vec2 smaa_calculate_diag_weights(vec2 texcoord, vec2 e, vec4 subsample_indices) { vec2 weights = vec2(0.0, 0.0); - // Search for the line ends: vec4 d; if (e.r > 0.0) { - d.xz = smaa_search_diag1(texcoord, vec2(-1.0, 1.0)/*, cdw_end*/); + d.xz = smaa_search_diag1(texcoord, vec2(-1.0, 1.0)); float dadd = cdw_end.y > 0.9 ? 1.0 : 0.0; d.x += dadd; } else { d.xz = vec2(0.0, 0.0); } - d.yw = smaa_search_diag1(texcoord, vec2(1.0, -1.0)/*, cdw_end*/); + d.yw = smaa_search_diag1(texcoord, vec2(1.0, -1.0)); - //SMAA_BRANCH - if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 - // Fetch the crossing edges: + if (d.x + d.y > 2.0) { vec4 coords = mad(vec4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), screen_size_inv.xyxy, texcoord.xyxy); vec4 c; - c.xy = smaa_sample_level_zero_offset(edges_tex, coords.xy, ivec2(-1, 0)).rg; - c.zw = smaa_sample_level_zero_offset(edges_tex, coords.zw, ivec2( 1, 0)).rg; + c.xy = smaa_sample_level_zero_offset(edges_tex, coords.xy, vec2(-1, 0)).rg; + c.zw = smaa_sample_level_zero_offset(edges_tex, coords.zw, vec2( 1, 0)).rg; c.yxwz = smaa_decode_diag_bilinear_access(c.xyzw); - // Merge crossing edges at each side into a single value: vec2 cc = mad(vec2(2.0, 2.0), c.xz, c.yw); - // Remove the crossing edge if we didn't found the end of the line: - // SMAAMovc(bvec2(step(0.9, d.zw)), cc, vec2(0.0, 0.0)); float a1condx = step(0.9, d.z); float a1condy = step(0.9, d.w); if (a1condx == 1.0) cc.x = 0.0; if (a1condy == 1.0) cc.y = 0.0; - // Fetch the areas for this line: weights += smaa_area_diag(d.xy, cc, subsample_indices.z); } - // Search for the line ends: - d.xz = smaa_search_diag2(texcoord, vec2(-1.0, -1.0)/*, cdw_end*/); - if (smaa_sample_level_zero_offset(edges_tex, texcoord, ivec2(1, 0)).r > 0.0) { - d.yw = smaa_search_diag2(texcoord, vec2(1.0, 1.0)/*, cdw_end*/); + d.xz = smaa_search_diag2(texcoord, vec2(-1.0, -1.0)); + if (smaa_sample_level_zero_offset(edges_tex, texcoord, vec2(1, 0)).r > 0.0) { + d.yw = smaa_search_diag2(texcoord, vec2(1.0, 1.0)); float dadd = cdw_end.y > 0.9 ? 1.0 : 0.0; d.y += dadd; } @@ -160,60 +126,43 @@ vec2 smaa_calculate_diag_weights(vec2 texcoord, vec2 e, vec4 subsample_indices) d.yw = vec2(0.0, 0.0); } - // SMAA_BRANCH - if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 - // Fetch the crossing edges: + if (d.x + d.y > 2.0) { vec4 coords = mad(vec4(-d.x, -d.x, d.y, d.y), screen_size_inv.xyxy, texcoord.xyxy); vec4 c; - c.x = smaa_sample_level_zero_offset(edges_tex, coords.xy, ivec2(-1, 0)).g; - c.y = smaa_sample_level_zero_offset(edges_tex, coords.xy, ivec2( 0, -1)).r; - c.zw = smaa_sample_level_zero_offset(edges_tex, coords.zw, ivec2( 1, 0)).gr; + c.x = smaa_sample_level_zero_offset(edges_tex, coords.xy, vec2(-1, 0)).g; + c.y = smaa_sample_level_zero_offset(edges_tex, coords.xy, vec2( 0, -1)).r; + c.zw = smaa_sample_level_zero_offset(edges_tex, coords.zw, vec2( 1, 0)).gr; vec2 cc = mad(vec2(2.0, 2.0), c.xz, c.yw); - // Remove the crossing edge if we didn't found the end of the line: - // SMAAMovc(bvec2(step(0.9, d.zw)), cc, vec2(0.0, 0.0)); float a1condx = step(0.9, d.z); float a1condy = step(0.9, d.w); if (a1condx == 1.0) cc.x = 0.0; if (a1condy == 1.0) cc.y = 0.0; - // Fetch the areas for this line: weights += smaa_area_diag(d.xy, cc, subsample_indices.w).gr; } return weights; } -// #endif - -//----------------------------------------------------------------------------- -// Horizontal/Vertical Search Functions float smaa_search_length(vec2 e, float offset) { - // The texture is flipped vertically, with left and right cases taking half - // of the space horizontally: vec2 scale = SMAA_SEARCHTEX_SIZE * vec2(0.5, -1.0); vec2 bias = SMAA_SEARCHTEX_SIZE * vec2(offset, 1.0); - // Scale and bias to access texel centers: scale += vec2(-1.0, 1.0); bias += vec2( 0.5, -0.5); - // Convert from pixel coordinates to texcoords: - // (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped) scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; vec2 coord = mad(scale, e, bias); - // Lookup the search texture: return SMAA_SEARCHTEX_SELECT(textureLod(search_tex, coord, 0.0)); } float smaa_search_x_left(vec2 texcoord, float end) { vec2 e = vec2(0.0, 1.0); - while (texcoord.x > end && - e.g > 0.8281 && // Is there some edge not activated? - e.r == 0.0) { // Or is there a crossing edge that breaks the line? + while (texcoord.x > end && e.g > 0.8281 && e.r == 0.0) { e = textureLod_a(edges_tex, texcoord, 0.0).rg; texcoord = mad(-vec2(2.0, 0.0), screen_size_inv.xy, texcoord); } @@ -224,9 +173,7 @@ float smaa_search_x_left(vec2 texcoord, float end) { float smaa_search_x_right(vec2 texcoord, float end) { vec2 e = vec2(0.0, 1.0); - while (texcoord.x < end && - e.g > 0.8281 && // Is there some edge not activated? - e.r == 0.0) { // Or is there a crossing edge that breaks the line? + while (texcoord.x < end && e.g > 0.8281 && e.r == 0.0) { e = textureLod_a(edges_tex, texcoord, 0.0).rg; texcoord = mad(vec2(2.0, 0.0), screen_size_inv.xy, texcoord); } @@ -237,9 +184,7 @@ float smaa_search_x_right(vec2 texcoord, float end) { float smaa_search_y_up(vec2 texcoord, float end) { vec2 e = vec2(1.0, 0.0); - while (texcoord.y > end && - e.r > 0.8281 && // Is there some edge not activated? - e.g == 0.0) { // Or is there a crossing edge that breaks the line? + while (texcoord.y > end && e.r > 0.8281 && e.g == 0.0) { e = textureLod_a(edges_tex, texcoord, 0.0).rg; texcoord = mad(-vec2(0.0, 2.0), screen_size_inv.xy, texcoord); } @@ -249,163 +194,111 @@ float smaa_search_y_up(vec2 texcoord, float end) { float smaa_search_y_down(vec2 texcoord, float end) { vec2 e = vec2(1.0, 0.0); - while (texcoord.y < end && - e.r > 0.8281 && // Is there some edge not activated? - e.g == 0.0) { // Or is there a crossing edge that breaks the line? + while (texcoord.y < end && e.r > 0.8281 && e.g == 0.0) { e = textureLod_a(edges_tex, texcoord, 0.0).rg; texcoord = mad(vec2(0.0, 2.0), screen_size_inv.xy, texcoord); } - float offset = mad(-(255.0 / 127.0), smaa_search_length(/*search_tex,*/ e.gr, 0.5), 3.25); + float offset = mad(-(255.0 / 127.0), smaa_search_length(e.gr, 0.5), 3.25); return mad(-screen_size_inv.y, offset, texcoord.y); } vec2 smaa_area(vec2 dist, float e1, float e2, float offset) { - // Rounding prevents precision errors of bilinear filtering: vec2 texcoord = mad(vec2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * vec2(e1, e2)), dist); - - // We do a scale and bias for mapping to texel space: texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); - - // Move to proper place, according to the subpixel offset: texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); - - // Do it! return SMAA_AREATEX_SELECT(textureLod(area_tex, texcoord, 0.0)); } -//----------------------------------------------------------------------------- -// Corner Detection Functions - vec2 smaa_detect_horizontal_corner_pattern(vec2 weights, vec4 texcoord, vec2 d) { - // #if !defined(SMAA_DISABLE_CORNER_DETECTION) - vec2 left_right = step(d.xy, d.yx); - vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * left_right; - - rounding /= left_right.x + left_right.y; // Reduce blending for pixels in the center of a line. - - vec2 factor = vec2(1.0, 1.0); - factor.x -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, ivec2(0, 1)).r; - factor.x -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, ivec2(1, 1)).r; - factor.y -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, ivec2(0, -2)).r; - factor.y -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, ivec2(1, -2)).r; - - weights *= saturate(factor); - return weights; // - // #endif -} - -vec2 smaa_detect_vertical_corner_pattern(vec2 weights, vec4 texcoord, vec2 d) { - //#if !defined(SMAA_DISABLE_CORNER_DETECTION) vec2 left_right = step(d.xy, d.yx); vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * left_right; rounding /= left_right.x + left_right.y; vec2 factor = vec2(1.0, 1.0); - factor.x -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, ivec2( 1, 0)).g; - factor.x -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, ivec2( 1, 1)).g; - factor.y -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, ivec2(-2, 0)).g; - factor.y -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, ivec2(-2, 1)).g; + factor.x -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, vec2(0, 1)).r; + factor.x -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, vec2(1, 1)).r; + factor.y -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, vec2(0, -2)).r; + factor.y -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, vec2(1, -2)).r; weights *= saturate(factor); - return weights; // - // #endif + return weights; +} + +vec2 smaa_detect_vertical_corner_pattern(vec2 weights, vec4 texcoord, vec2 d) { + vec2 left_right = step(d.xy, d.yx); + vec2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * left_right; + + rounding /= left_right.x + left_right.y; + + vec2 factor = vec2(1.0, 1.0); + factor.x -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, vec2( 1, 0)).g; + factor.x -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, vec2( 1, 1)).g; + factor.y -= rounding.x * smaa_sample_level_zero_offset(edges_tex, texcoord.xy, vec2(-2, 0)).g; + factor.y -= rounding.y * smaa_sample_level_zero_offset(edges_tex, texcoord.zw, vec2(-2, 1)).g; + + weights *= saturate(factor); + return weights; } -vec4 smaa_blending_weight_calculation_ps(vec2 texcoord, vec2 pixcoord, vec4 subsample_indices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. +vec4 smaa_blending_weight_calculation_ps(vec2 texcoord, vec2 pixcoord, vec4 subsample_indices) { vec4 weights = vec4(0.0, 0.0, 0.0, 0.0); vec2 e = textureLod_a(edges_tex, texcoord, 0.0).rg; - //SMAA_BRANCH - if (e.g > 0.0) { // Edge at north - //#if !defined(SMAA_DISABLE_DIAG_DETECTION) - // Diagonals have both north and west edges, so searching for them in - // one of the boundaries is enough. + if (e.g > 0.0) { weights.rg = smaa_calculate_diag_weights(texcoord, e, subsample_indices); + if (weights.r == -weights.g) { + vec2 d; - // We give priority to diagonals, so if we find a diagonal we skip - // horizontal/vertical processing. - //SMAA_BRANCH - if (weights.r == -weights.g) { // weights.r + weights.g == 0.0 - //#endif + vec3 coords; + coords.x = smaa_search_x_left(offset0.xy, offset2.x); + coords.y = offset1.y; + d.x = coords.x; - vec2 d; + float e1 = textureLod_a(edges_tex, coords.xy, 0.0).r; - // Find the distance to the left: - vec3 coords; - coords.x = smaa_search_x_left(offset0.xy, offset2.x); - coords.y = offset1.y; // offset[1].y = texcoord.y - 0.25 * screen_size_inv.y (@CROSSING_OFFSET) - d.x = coords.x; + coords.z = smaa_search_x_right(offset0.zw, offset2.y); + d.y = coords.z; - // Now fetch the left crossing edges, two at a time using bilinear - // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to - // discern what value each edge has: - float e1 = textureLod_a(edges_tex, coords.xy, 0.0).r; + d = abs(round(mad(screen_size.xx, d, -pixcoord.xx))); - // Find the distance to the right: - coords.z = smaa_search_x_right(offset0.zw, offset2.y); - d.y = coords.z; + vec2 sqrt_d = sqrt(d); - // We want the distances to be in pixel units (doing this here allow to - // better interleave arithmetic and memory accesses): - d = abs(round(mad(screen_size.xx, d, -pixcoord.xx))); + float e2 = smaa_sample_level_zero_offset(edges_tex, coords.zy, vec2(1, 0)).r; - // smaa_area below needs a sqrt, as the areas texture is compressed - // quadratically: - vec2 sqrt_d = sqrt(d); + weights.rg = smaa_area(sqrt_d, e1, e2, subsample_indices.y); - // Fetch the right crossing edges: - float e2 = smaa_sample_level_zero_offset(edges_tex, coords.zy, ivec2(1, 0)).r; - - // Ok, we know how this pattern looks like, now it is time for getting - // the actual area: - weights.rg = smaa_area(sqrt_d, e1, e2, subsample_indices.y); - - // Fix corners: - coords.y = texcoord.y; - weights.rg = smaa_detect_horizontal_corner_pattern(weights.rg, coords.xyzy, d); - - //#if !defined(SMAA_DISABLE_DIAG_DETECTION) + coords.y = texcoord.y; + weights.rg = smaa_detect_horizontal_corner_pattern(weights.rg, coords.xyzy, d); } else { - e.r = 0.0; // Skip vertical processing. + e.r = 0.0; } - //#endif } - //SMAA_BRANCH - if (e.r > 0.0) { // Edge at west + if (e.r > 0.0) { vec2 d; - // Find the distance to the top: vec3 coords; - coords.y = smaa_search_y_up(/*edges_tex, search_tex,*/ offset1.xy, offset2.z); - coords.x = offset0.x; // offset[1].x = texcoord.x - 0.25 * screen_size_inv.x; + coords.y = smaa_search_y_up(offset1.xy, offset2.z); + coords.x = offset0.x; d.x = coords.y; - // Fetch the top crossing edges: float e1 = textureLod_a(edges_tex, coords.xy, 0.0).g; - // Find the distance to the bottom: coords.z = smaa_search_y_down(offset1.zw, offset2.w); d.y = coords.z; - // We want the distances to be in pixel units: d = abs(round(mad(screen_size.yy, d, -pixcoord.yy))); - // smaa_area below needs a sqrt, as the areas texture is compressed - // quadratically: vec2 sqrt_d = sqrt(d); - // Fetch the bottom crossing edges: - float e2 = smaa_sample_level_zero_offset(edges_tex, coords.xz, ivec2(0, 1)).g; + float e2 = smaa_sample_level_zero_offset(edges_tex, coords.xz, vec2(0, 1)).g; - // Get the area for this direction: weights.ba = smaa_area(sqrt_d, e1, e2, subsample_indices.x); - // Fix corners: coords.x = texcoord.x; weights.ba = smaa_detect_vertical_corner_pattern(weights.ba, coords.xyxz, d); } diff --git a/base/shaders/smaa_blend_weight.vert.glsl b/base/shaders/smaa_blend_weight.vert.glsl index b38a9fff..a666570e 100644 --- a/base/shaders/smaa_blend_weight.vert.glsl +++ b/base/shaders/smaa_blend_weight.vert.glsl @@ -13,18 +13,14 @@ out vec4 offset2; const int SMAA_MAX_SEARCH_STEPS = 16; void main() { - // Scale vertex attribute to [0-1] range const vec2 madd = vec2(0.5, 0.5); tex_coord = pos.xy * madd + madd; - // Blend Weight Calculation Vertex Shader pixcoord = tex_coord * screen_size; - // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): offset0 = screen_size_inv.xyxy * vec4(-0.25, -0.125, 1.25, -0.125) + tex_coord.xyxy; offset1 = screen_size_inv.xyxy * vec4(-0.125, -0.25, -0.125, 1.25) + tex_coord.xyxy; - // And these for the searches, they indicate the ends of the loops: offset2 = screen_size_inv.xxyy * (vec4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS)) + vec4(offset0.xz, offset1.yw); diff --git a/base/shaders/smaa_edge_detect.frag.glsl b/base/shaders/smaa_edge_detect.frag.glsl index 5ab9f38f..78649088 100644 --- a/base/shaders/smaa_edge_detect.frag.glsl +++ b/base/shaders/smaa_edge_detect.frag.glsl @@ -28,7 +28,7 @@ // http://www.iryoku.com/smaa/ #define SMAA_THRESHOLD 0.1 -#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) // For depth edge detection, depends on the depth range of the scene +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) #define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0 uniform sampler2D color_tex; @@ -39,94 +39,43 @@ in vec4 offset1; in vec4 offset2; out vec4 frag_color; -// Misc functions -// Gathers current pixel, and the top-left neighbors. -// vec3 SMAAGatherNeighbours(vec2 texcoord/*, vec4 offset[3], sampler2D tex*/) { - // float P = textureLod(tex, texcoord, 0.0).r; - // float Pleft = textureLod(tex, offset0.xy, 0.0).r; - // float Ptop = textureLod(tex, offset0.zw, 0.0).r; - // return vec3(P, Pleft, Ptop); -// } - -// Edge Detection Pixel Shaders (First Pass) -// Adjusts the threshold by means of predication. -// vec2 SMAACalculatePredicatedThreshold(vec2 texcoord, vec4 offset[3], sampler2D predicationTex) { -// vec3 neighbours = SMAAGatherNeighbours(texcoord, offset, predicationTex); -// vec2 delta = abs(neighbours.xx - neighbours.yz); -// vec2 edges = step(SMAA_PREDICATION_THRESHOLD, delta); -// return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges); -// } - -// Luma Edge Detection -// IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and -// thus 'color_tex' should be a non-sRGB texture. -vec2 smaa_luma_edge_detection_ps(vec2 texcoord - //#if SMAA_PREDICATION - //, sampler2D predicationTex - //#endif - ) { - // Calculate the threshold: - //#if SMAA_PREDICATION - //vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex)); - //#else +vec2 smaa_luma_edge_detection_ps(vec2 texcoord) { vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD); - //#endif - // Calculate lumas: vec3 weights = vec3(0.2126, 0.7152, 0.0722); float L = dot(textureLod(color_tex, texcoord, 0.0).rgb, weights); float Lleft = dot(textureLod(color_tex, offset0.xy, 0.0).rgb, weights); float Ltop = dot(textureLod(color_tex, offset0.zw, 0.0).rgb, weights); - // 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; - // Calculate right and bottom deltas: float Lright = dot(textureLod(color_tex, offset1.xy, 0.0).rgb, weights); float Lbottom = dot(textureLod(color_tex, offset1.zw, 0.0).rgb, weights); delta.zw = abs(L - vec2(Lright, Lbottom)); - // Calculate the maximum delta in the direct neighborhood: vec2 max_delta = max(delta.xy, delta.zw); - // Calculate left-left and top-top deltas: float Lleftleft = dot(textureLod(color_tex, offset2.xy, 0.0).rgb, weights); float Ltoptop = dot(textureLod(color_tex, offset2.zw, 0.0).rgb, weights); delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop)); - // Calculate the final maximum delta: max_delta = max(max_delta.xy, delta.zw); float final_delta = max(max_delta.x, max_delta.y); - // Local contrast adaptation: edges.xy *= step(final_delta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); return edges; } -// Color Edge Detection -// IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and -// thus 'color_tex' should be a non-sRGB texture. -vec2 smaa_color_edge_detection_ps(vec2 texcoord - //#if SMAA_PREDICATION - //, sampler2D predicationTex - //#endif - ) { - // Calculate the threshold: - //#if SMAA_PREDICATION - //vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex); - //#else +vec2 smaa_color_edge_detection_ps(vec2 texcoord) { vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD); - //#endif - // Calculate color deltas: vec4 delta; vec3 C = textureLod(color_tex, texcoord, 0.0).rgb; @@ -138,14 +87,11 @@ vec2 smaa_color_edge_detection_ps(vec2 texcoord 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); - // 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 = textureLod(color_tex, offset1.xy, 0.0).rgb; t = abs(C - Cright); delta.z = max(max(t.r, t.g), t.b); @@ -154,10 +100,8 @@ vec2 smaa_color_edge_detection_ps(vec2 texcoord t = abs(C - Cbottom); delta.w = max(max(t.r, t.g), t.b); - // Calculate the maximum delta in the direct neighborhood: vec2 max_delta = max(delta.xy, delta.zw); - // Calculate left-left and top-top deltas: vec3 Cleftleft = textureLod(color_tex, offset2.xy, 0.0).rgb; t = abs(C - Cleftleft); delta.z = max(max(t.r, t.g), t.b); @@ -166,28 +110,14 @@ vec2 smaa_color_edge_detection_ps(vec2 texcoord t = abs(C - Ctoptop); delta.w = max(max(t.r, t.g), t.b); - // Calculate the final maximum delta: max_delta = max(max_delta.xy, delta.zw); float final_delta = max(max_delta.x, max_delta.y); - // Local contrast adaptation: edges.xy *= step(final_delta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); 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); - - // if (dot(edges, vec2(1.0, 1.0)) == 0.0) - // discard; - - // return edges; -// } - void main() { frag_color.rg = smaa_color_edge_detection_ps(tex_coord); } diff --git a/base/shaders/smaa_edge_detect.vert.glsl b/base/shaders/smaa_edge_detect.vert.glsl index afebd082..7bac7cc1 100644 --- a/base/shaders/smaa_edge_detect.vert.glsl +++ b/base/shaders/smaa_edge_detect.vert.glsl @@ -8,19 +8,21 @@ out vec4 offset0; out vec4 offset1; out vec4 offset2; -#if defined(HLSL) || defined(METAL) || defined(SPIRV) -#define V_DIR(v) -(v) -#else +#ifdef GLSL #define V_DIR(v) v +#else +#define V_DIR(v) -(v) #endif void main() { // Scale vertex attribute to [0-1] range const vec2 madd = vec2(0.5, 0.5); tex_coord = pos.xy * madd + madd; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) - tex_coord.y = 1.0 - tex_coord.y; - #endif + +#ifdef GLSL +#else +tex_coord.y = 1.0 - tex_coord.y; +#endif offset0 = screen_size_inv.xyxy * vec4(-1.0, 0.0, 0.0, V_DIR(-1.0)) + tex_coord.xyxy; offset1 = screen_size_inv.xyxy * vec4( 1.0, 0.0, 0.0, V_DIR(1.0)) + tex_coord.xyxy; diff --git a/base/shaders/smaa_neighborhood_blend.frag.glsl b/base/shaders/smaa_neighborhood_blend.frag.glsl index b3255626..80e9f1af 100644 --- a/base/shaders/smaa_neighborhood_blend.frag.glsl +++ b/base/shaders/smaa_neighborhood_blend.frag.glsl @@ -13,46 +13,41 @@ in vec2 tex_coord; in vec4 offset; out vec4 frag_color; -//----------------------------------------------------------------------------- -// Neighborhood Blending Pixel Shader (Third Pass) - vec4 textureLodA_color_tex(sampler2D color_tex, vec2 coords, float lod) { - #if defined(HLSL) || defined(METAL) || defined(SPIRV) +#ifdef GLSL +#else coords.y = 1.0 - coords.y; - #endif +#endif return textureLod(color_tex, coords, lod); } vec4 textureLodA_sveloc(sampler2D sveloc, vec2 coords, float lod) { - #if defined(HLSL) || defined(METAL) || defined(SPIRV) +#ifdef GLSL +#else coords.y = 1.0 - coords.y; - #endif +#endif + return textureLod(sveloc, coords, lod); } vec4 smaa_neighborhood_blending_ps(vec2 texcoord, vec4 offset) { - // Fetch the blending weights for current pixel: vec4 a; a.x = textureLod(blend_tex, offset.xy, 0.0).a; // Right a.y = textureLod(blend_tex, offset.zw, 0.0).g; // Top a.wz = textureLod(blend_tex, texcoord, 0.0).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(color_tex, texcoord, 0.0); #ifdef _Veloc vec2 velocity = textureLod(sveloc, tex_coord, 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) + bool h = max(a.x, a.z) > max(a.y, a.w); - // Calculate the blending offsets: vec4 blending_offset = vec4(0.0, a.y, 0.0, a.w); vec2 blending_weight = a.yw; @@ -67,25 +62,20 @@ vec4 smaa_neighborhood_blending_ps(vec2 texcoord, vec4 offset) { blending_weight /= dot(blending_weight, vec2(1.0, 1.0)); - // Calculate the texture coordinates: - #if defined(HLSL) || defined(METAL) || defined(SPIRV) - vec2 tc = vec2(texcoord.x, 1.0 - texcoord.y); - #else +#ifdef GLSL vec2 tc = texcoord; - #endif +#else + vec2 tc = vec2(texcoord.x, 1.0 - texcoord.y); +#endif vec4 blending_coord = blending_offset * vec4(screen_size_inv.xy, -screen_size_inv.xy) + tc.xyxy; - // We exploit bilinear filtering to mix current pixel with the chosen - // neighbor: vec4 color = blending_weight.x * textureLodA_color_tex(color_tex, blending_coord.xy, 0.0); color += blending_weight.y * textureLodA_color_tex(color_tex, blending_coord.zw, 0.0); #ifdef _Veloc - // Antialias velocity for proper reprojection in a later stage: vec2 velocity = blending_weight.x * textureLodA_sveloc(sveloc, blending_coord.xy, 0.0).rg; velocity += blending_weight.y * textureLodA_sveloc(sveloc, blending_coord.zw, 0.0).rg; - // Pack velocity into the alpha channel: color.a = sqrt(5.0 * length(velocity)); #endif return color; diff --git a/base/shaders/smaa_neighborhood_blend.vert.glsl b/base/shaders/smaa_neighborhood_blend.vert.glsl index fbc2c7c5..daf7c891 100644 --- a/base/shaders/smaa_neighborhood_blend.vert.glsl +++ b/base/shaders/smaa_neighborhood_blend.vert.glsl @@ -6,19 +6,21 @@ in vec2 pos; out vec2 tex_coord; out vec4 offset; -#if defined(HLSL) || defined(METAL) || defined(SPIRV) -#define V_DIR(v) -(v) -#else +#ifdef GLSL #define V_DIR(v) v +#else +#define V_DIR(v) -(v) #endif void main() { // Scale vertex attribute to [0-1] range const vec2 madd = vec2(0.5, 0.5); tex_coord = pos.xy * madd + madd; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) + +#ifdef GLSL +#else tex_coord.y = 1.0 - tex_coord.y; - #endif +#endif // Neighborhood Blending Vertex Shader offset = screen_size_inv.xyxy * vec4(1.0, 0.0, 0.0, V_DIR(1.0)) + tex_coord.xyxy; diff --git a/base/shaders/ssao_pass.frag.glsl b/base/shaders/ssao_pass.frag.glsl index 70fe7f36..0d2af4b7 100644 --- a/base/shaders/ssao_pass.frag.glsl +++ b/base/shaders/ssao_pass.frag.glsl @@ -27,9 +27,10 @@ vec2 get_projected_coord(vec3 hit_coord) { vec4 projected_coord = mul(vec4(hit_coord, 1.0), P); projected_coord.xy /= projected_coord.w; projected_coord.xy = projected_coord.xy * 0.5 + 0.5; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) +#ifdef GLSL +#else projected_coord.y = 1.0 - projected_coord.y; - #endif +#endif return projected_coord.xy; } diff --git a/base/shaders/ssr_pass.frag.glsl b/base/shaders/ssr_pass.frag.glsl index 47124db8..287f3ddc 100644 --- a/base/shaders/ssr_pass.frag.glsl +++ b/base/shaders/ssr_pass.frag.glsl @@ -30,9 +30,10 @@ vec2 get_projected_coord(const vec3 hit) { vec4 projected_coord = mul(vec4(hit, 1.0), P); projected_coord.xy /= projected_coord.w; projected_coord.xy = projected_coord.xy * 0.5 + 0.5; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) +#ifdef GLSL +#else projected_coord.y = 1.0 - projected_coord.y; - #endif +#endif return projected_coord.xy; } diff --git a/base/shaders/std/brdf.glsl b/base/shaders/std/brdf.glsl index 683765fb..8839eac0 100644 --- a/base/shaders/std/brdf.glsl +++ b/base/shaders/std/brdf.glsl @@ -1,7 +1,4 @@ -#ifndef _BRDF_GLSL_ -#define _BRDF_GLSL_ - vec3 surface_albedo(const vec3 base_color, const float metalness) { return mix(base_color, vec3(0.0, 0.0, 0.0), metalness); } @@ -14,5 +11,3 @@ float mip_from_roughness(const float roughness, const float num_mipmaps) { // First mipmap level = roughness 0, last = roughness = 1 return roughness * num_mipmaps; } - -#endif diff --git a/base/shaders/std/conetrace.glsl b/base/shaders/std/conetrace.glsl index 70141a99..7a74fced 100644 --- a/base/shaders/std/conetrace.glsl +++ b/base/shaders/std/conetrace.glsl @@ -1,26 +1,11 @@ -#ifndef _CONETRACE_GLSL_ -#define _CONETRACE_GLSL_ - -// References -// https://github.com/Friduric/voxel-cone-tracing -// https://github.com/Cigg/Voxel-Cone-Tracing -// https://github.com/GreatBlambo/voxel_cone_tracing/ -// http://simonstechblog.blogspot.com/2013/01/implementing-voxel-cone-tracing.html -// http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/ -// http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf -// https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf - -uniform float cone_offset; -uniform float cone_aperture; - const int voxelgi_resolution = 256; const vec3 voxelgi_half_extents = vec3(1, 1, 1); const float voxelgi_occ = 1.0; const float voxelgi_step = 1.0; const float voxelgi_range = 2.0; const float MAX_DISTANCE = 1.73205080757 * voxelgi_range; -const float VOXEL_SIZE = (2.0 / voxelgi_resolution.x) * voxelgi_step; +const float VOXEL_SIZE = (2.0 / voxelgi_resolution) * voxelgi_step; vec3 tangent(const vec3 n) { vec3 t1 = cross(n, vec3(0, 0, 1)); @@ -37,7 +22,7 @@ float trace_cone_ao(sampler3D voxels, const vec3 origin, vec3 dir, const float a vec3 sample_pos; while (sample_col < 1.0 && dist < max_dist) { sample_pos = dir * dist + origin; - float mip = max(log2(diam * voxelgi_resolution.x), 0); + float mip = max(log2(diam * voxelgi_resolution), 0.0); float mip_sample = textureLod(voxels, sample_pos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r; sample_col += (1 - sample_col) * mip_sample; dist += max(diam / 2, VOXEL_SIZE); @@ -58,11 +43,11 @@ float trace_ao(const vec3 origin, const vec3 normal, sampler3D voxels) { vec3 c1 = 0.5f * (o1 + o2); vec3 c2 = 0.5f * (o1 - o2); - #ifdef HLSL +#ifdef HLSL const float factor = voxelgi_occ * 0.93; - #else +#else const float factor = voxelgi_occ * 0.90; - #endif +#endif float col = trace_cone_ao(voxels, origin, normal, aperture, MAX_DISTANCE); col += trace_cone_ao(voxels, origin, mix(normal, o1, angle_mix), aperture, MAX_DISTANCE); @@ -73,5 +58,3 @@ float trace_ao(const vec3 origin, const vec3 normal, sampler3D voxels) { return 0.0; } - -#endif diff --git a/base/shaders/std/deferred_light.glsl b/base/shaders/std/deferred_light.glsl index 42a67b1a..c8438ff2 100644 --- a/base/shaders/std/deferred_light.glsl +++ b/base/shaders/std/deferred_light.glsl @@ -20,9 +20,20 @@ uniform vec3 eye; uniform vec3 eye_look; uniform vec3 point_pos; uniform vec3 point_col; +#ifdef _Voxel +uniform float cone_offset; +uniform float cone_aperture; +#endif +uniform vec3 light_area0; +uniform vec3 light_area1; +uniform vec3 light_area2; +uniform vec3 light_area3; +uniform sampler2D sltc_mat; +uniform sampler2D sltc_mag; #include "gbuffer.glsl" -#include "light.glsl" +#include "brdf.glsl" +#include "math.glsl" #include "shirr.glsl" #ifdef _Voxel #include "conetrace.glsl" @@ -32,6 +43,182 @@ in vec2 tex_coord; in vec3 view_ray; out vec4 frag_color; +const float LUT_SIZE = 64.0; +const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE; +const float LUT_BIAS = 0.5 / LUT_SIZE; + +float integrate_edge(vec3 v1, vec3 v2) { + float cos_theta = dot(v1, v2); + float theta = acos(cos_theta); + float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0); + return res; +} + +float ltc_evaluate(vec3 N, vec3 V, float dotnv, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { + // Construct orthonormal basis around N + vec3 T1, T2; + T1 = normalize(V - N * dotnv); + T2 = cross(N, T1); + + // Rotate area light in (T1, T2, R) basis + Minv = mul(transpose(mat3(T1, T2, N)), Minv); + + // Polygon (allocate 5 vertices for clipping) + vec3 L0 = mul((points0 - P), Minv); + vec3 L1 = mul((points1 - P), Minv); + vec3 L2 = mul((points2 - P), Minv); + vec3 L3 = mul((points3 - P), Minv); + vec3 L4 = vec3(0.0, 0.0, 0.0); + + int n = 0; + // 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 + 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 == 0) return 0.0; + if (n == 3) L3 = L0; + if (n == 4) L4 = L0; + + // Project onto sphere + L0 = normalize(L0); + L1 = normalize(L1); + L2 = normalize(L2); + L3 = normalize(L3); + L4 = normalize(L4); + + // Integrate + float sum = 0.0; + + sum += integrate_edge(L0, L1); + sum += integrate_edge(L1, L2); + sum += integrate_edge(L2, L3); + + if (n >= 4) sum += integrate_edge(L3, L4); + if (n == 5) sum += integrate_edge(L4, L0); + + return max(0.0, -sum); +} + +vec3 sample_light(const vec3 p, const vec3 n, const vec3 v, const float dotnv, const vec3 lp, const vec3 light_col, + const vec3 albedo, const float rough, const vec3 f0, const float occ +#ifdef _Voxel + , sampler3D voxels, vec3 voxpos +#endif + ) { + vec3 ld = lp - p; + vec3 l = normalize(ld); + float dotnl = max(0.0, dot(n, l)); + + float theta = acos(dotnv); + vec2 tuv = vec2(rough, theta / (0.5 * PI)); + tuv = tuv * LUT_SCALE + LUT_BIAS; + vec4 t = textureLod(sltc_mat, tuv, 0.0); + mat3 inv = mat3( + vec3(1.0, 0.0, t.y), + vec3(0.0, t.z, 0.0), + vec3(t.w, 0.0, t.x)); + float ltcspec = ltc_evaluate(n, v, dotnv, p, inv, light_area0, light_area1, light_area2, light_area3); + ltcspec *= textureLod(sltc_mag, tuv, 0.0).a; + + mat3 m1 = mat3( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0)); + float ltcdiff = ltc_evaluate(n, v, dotnv, p, m1, light_area0, light_area1, light_area2, light_area3); + vec3 direct = albedo * ltcdiff + ltcspec * 0.05; + + direct *= attenuate(distance(p, lp)); + direct *= light_col; + direct *= clamp(dotnl + 2.0 * occ * occ - 1.0, 0.0, 1.0); // Micro shadowing + +#ifdef _Voxel + direct *= 1.0 - trace_shadow(voxels, voxpos, l); +#endif + + return direct; +} + void main() { vec4 g0 = textureLod(gbuffer0, tex_coord, 0.0); // Normal.xy, roughness, metallic/matid diff --git a/base/shaders/std/gbuffer.glsl b/base/shaders/std/gbuffer.glsl index efddc359..66bc8fcd 100644 --- a/base/shaders/std/gbuffer.glsl +++ b/base/shaders/std/gbuffer.glsl @@ -1,7 +1,4 @@ -#ifndef _GBUFFER_GLSL_ -#define _GBUFFER_GLSL_ - vec2 octahedron_wrap(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)); } @@ -43,7 +40,7 @@ float pack_f32_i16(const float f, const uint i) { return t1 * f + t2 * float(i); } -void unpack_f32_i16(const float val, out float f, out uint i) { +void unpack_f32_i16(const float val, OUT(float, f), OUT(uint, i)) { // Constant optimize by compiler const int num_bit_target = 16; const int num_bit_i = 4; @@ -56,9 +53,7 @@ void unpack_f32_i16(const float val, out float f, out uint i) { // extract integer part // + rcp(prec_minus_one) to deal with precision issue i = int((val / t2) + (1.0 / prec_minus_one)); - // Now that we have i, solve formula in packFloatInt for f + // Now that we have i, solve formula in pack_f32_i16 for f //f = (val - t2 * float(i)) / t1 => convert in mads form f = clamp((-t2 * float(i) + val) / t1, 0.0, 1.0); // Saturate in case of precision issue } - -#endif diff --git a/base/shaders/std/light.glsl b/base/shaders/std/light.glsl deleted file mode 100644 index 89956e11..00000000 --- a/base/shaders/std/light.glsl +++ /dev/null @@ -1,58 +0,0 @@ - -#ifndef _LIGHT_GLSL_ -#define _LIGHT_GLSL_ - -#include "brdf.glsl" -#include "math.glsl" -#include "ltc.glsl" -#ifdef _Voxel -#include "conetrace.glsl" -#endif - -uniform vec3 light_area0; -uniform vec3 light_area1; -uniform vec3 light_area2; -uniform vec3 light_area3; -uniform sampler2D sltc_mat; -uniform sampler2D sltc_mag; - -vec3 sample_light(const vec3 p, const vec3 n, const vec3 v, const float dotnv, const vec3 lp, const vec3 light_col, - const vec3 albedo, const float rough, const vec3 f0, const float occ -#ifdef _Voxel - , sampler3D voxels, vec3 voxpos -#endif - ) { - vec3 ld = lp - p; - vec3 l = normalize(ld); - float dotnl = max(0.0, dot(n, l)); - - float theta = acos(dotnv); - vec2 tuv = vec2(rough, theta / (0.5 * PI)); - tuv = tuv * LUT_SCALE + LUT_BIAS; - vec4 t = textureLod(sltc_mat, tuv, 0.0); - mat3 inv = mat3( - vec3(1.0, 0.0, t.y), - vec3(0.0, t.z, 0.0), - vec3(t.w, 0.0, t.x)); - float ltcspec = ltc_evaluate(n, v, dotnv, p, inv, light_area0, light_area1, light_area2, light_area3); - ltcspec *= textureLod(sltc_mag, tuv, 0.0).a; - - mat3 m1 = mat3( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0)); - float ltcdiff = ltc_evaluate(n, v, dotnv, p, m1, light_area0, light_area1, light_area2, light_area3); - vec3 direct = albedo * ltcdiff + ltcspec * 0.05; - - direct *= attenuate(distance(p, lp)); - direct *= light_col; - direct *= clamp(dotnl + 2.0 * occ * occ - 1.0, 0.0, 1.0); // Micro shadowing - - #ifdef _Voxel - direct *= 1.0 - trace_shadow(voxels, voxpos, l); - #endif - - return direct; -} - -#endif diff --git a/base/shaders/std/ltc.glsl b/base/shaders/std/ltc.glsl deleted file mode 100644 index 0f527563..00000000 --- a/base/shaders/std/ltc.glsl +++ /dev/null @@ -1,144 +0,0 @@ -// Linearly Transformed Cosines -// https://eheitzresearch.wordpress.com/415-2/ - -#ifndef _LTC_GLSL_ -#define _LTC_GLSL_ - -const float LUT_SIZE = 64.0; -const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE; -const float LUT_BIAS = 0.5 / LUT_SIZE; - -float integrate_edge(vec3 v1, vec3 v2) { - float cos_theta = dot(v1, v2); - float theta = acos(cos_theta); - float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0); - return res; -} - -float ltc_evaluate(vec3 N, vec3 V, float dotnv, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { - // Construct orthonormal basis around N - vec3 T1, T2; - T1 = normalize(V - N * dotnv); - T2 = cross(N, T1); - - // Rotate area light in (T1, T2, R) basis - Minv = mul(transpose(mat3(T1, T2, N)), Minv); - - // Polygon (allocate 5 vertices for clipping) - vec3 L0 = mul((points0 - P), Minv); - vec3 L1 = mul((points1 - P), Minv); - vec3 L2 = mul((points2 - P), Minv); - vec3 L3 = mul((points3 - P), Minv); - vec3 L4 = vec3(0.0, 0.0, 0.0); - - int n = 0; - // 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 - 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 == 0) return 0.0; - if (n == 3) L3 = L0; - if (n == 4) L4 = L0; - - // Project onto sphere - L0 = normalize(L0); - L1 = normalize(L1); - L2 = normalize(L2); - L3 = normalize(L3); - L4 = normalize(L4); - - // Integrate - float sum = 0.0; - - sum += integrate_edge(L0, L1); - sum += integrate_edge(L1, L2); - sum += integrate_edge(L2, L3); - - if (n >= 4) sum += integrate_edge(L3, L4); - if (n == 5) sum += integrate_edge(L4, L0); - - return max(0.0, -sum); -} - -#endif diff --git a/base/shaders/std/math.glsl b/base/shaders/std/math.glsl index db9e864c..1f4fd97d 100644 --- a/base/shaders/std/math.glsl +++ b/base/shaders/std/math.glsl @@ -1,7 +1,4 @@ -#ifndef _MATH_GLSL_ -#define _MATH_GLSL_ - const float PI = 3.1415926535; const float PI2 = PI * 2.0; @@ -20,5 +17,3 @@ float rand(const vec2 co) { // Unreliable float attenuate(const float dist) { return 1.0 / (dist * dist); } - -#endif diff --git a/base/shaders/std/shirr.glsl b/base/shaders/std/shirr.glsl index cd5b312e..c92b0968 100644 --- a/base/shaders/std/shirr.glsl +++ b/base/shaders/std/shirr.glsl @@ -1,7 +1,4 @@ -#ifndef _SHIRR_GLSL_ -#define _SHIRR_GLSL_ - vec3 sh_irradiance(const vec3 nor, const vec4 shirr[7]) { const float c1 = 0.429043; const float c2 = 0.511664; @@ -31,5 +28,3 @@ vec3 sh_irradiance(const vec3 nor, const vec4 shirr[7]) { 2.0 * c2 * cl10 * nor.x ); } - -#endif diff --git a/base/shaders/taa_pass.frag.glsl b/base/shaders/taa_pass.frag.glsl index 3e51a231..89dfa689 100644 --- a/base/shaders/taa_pass.frag.glsl +++ b/base/shaders/taa_pass.frag.glsl @@ -15,9 +15,10 @@ void main() { // Velocity is assumed to be calculated for motion blur, so we need to inverse it for reprojection vec2 velocity = -textureLod(sveloc, tex_coord, 0.0).rg; - #if defined(HLSL) || defined(METAL) || defined(SPIRV) +#ifdef GLSL +#else velocity.y = -velocity.y; - #endif +#endif // Reproject current coordinates and fetch previous pixel vec4 previous = textureLod(tex2, tex_coord + velocity, 0.0);