diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/draw/engines/workbench/shaders | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders')
26 files changed, 1075 insertions, 1015 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl index fda2fc85460..a6d7c4b393b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl @@ -1,3 +1,5 @@ -vec3 background_color(WorldData world_data, float y) { - return mix(world_data.background_color_low, world_data.background_color_high, y).xyz + bayer_dither_noise(); +vec3 background_color(WorldData world_data, float y) +{ + return mix(world_data.background_color_low, world_data.background_color_high, y).xyz + + bayer_dither_noise(); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl index 769d453bb18..8d66cd7b26c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl @@ -14,64 +14,68 @@ uniform vec4 ssao_settings; uniform vec2 curvature_settings; uniform sampler2D ssao_jitter; -layout(std140) uniform samples_block { - vec4 ssao_samples[500]; +layout(std140) uniform samples_block +{ + vec4 ssao_samples[500]; }; -#define ssao_samples_num ssao_params.x -#define jitter_tilling ssao_params.yz -#define ssao_iteration ssao_params.w +#define ssao_samples_num ssao_params.x +#define jitter_tilling ssao_params.yz +#define ssao_iteration ssao_params.w -#define ssao_distance ssao_settings.x -#define ssao_factor_cavity ssao_settings.y -#define ssao_factor_edge ssao_settings.z -#define ssao_attenuation ssao_settings.w +#define ssao_distance ssao_settings.x +#define ssao_factor_cavity ssao_settings.y +#define ssao_factor_edge ssao_settings.z +#define ssao_attenuation ssao_settings.w vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth) { - if (WinMatrix[3][3] == 0.0) { - /* Perspective */ - float d = 2.0 * depth - 1.0; + if (WinMatrix[3][3] == 0.0) { + /* Perspective */ + float d = 2.0 * depth - 1.0; - float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]); + float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]); - return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz); - } - else { - /* Orthographic */ - vec3 offset = vec3(uvcoords, depth); + return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz); + } + else { + /* Orthographic */ + vec3 offset = vec3(uvcoords, depth); - return viewvecs[0].xyz + offset * viewvecs[1].xyz; - } + return viewvecs[0].xyz + offset * viewvecs[1].xyz; + } } /* forward declartion */ -void ssao_factors( - in float depth, in vec3 normal, in vec3 position, in vec2 screenco, - out float cavities, out float edges); - +void ssao_factors(in float depth, + in vec3 normal, + in vec3 position, + in vec2 screenco, + out float cavities, + out float edges); void main() { - vec2 screenco = vec2(gl_FragCoord.xy) * invertedViewportSize; - ivec2 texel = ivec2(gl_FragCoord.xy); + vec2 screenco = vec2(gl_FragCoord.xy) * invertedViewportSize; + ivec2 texel = ivec2(gl_FragCoord.xy); - float cavity = 0.0, edges = 0.0, curvature = 0.0; + float cavity = 0.0, edges = 0.0, curvature = 0.0; #ifdef USE_CAVITY - float depth = texelFetch(depthBuffer, texel, 0).x; - vec3 position = get_view_space_from_depth(screenco, depth); - vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg); + float depth = texelFetch(depthBuffer, texel, 0).x; + vec3 position = get_view_space_from_depth(screenco, depth); + vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg); - ssao_factors(depth, normal_viewport, position, screenco, cavity, edges); + ssao_factors(depth, normal_viewport, position, screenco, cavity, edges); #endif #ifdef USE_CURVATURE - curvature = calculate_curvature(objectId, normalBuffer, texel, curvature_settings.x, curvature_settings.y); + curvature = calculate_curvature( + objectId, normalBuffer, texel, curvature_settings.x, curvature_settings.y); #endif - float final_cavity_factor = clamp((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0); + float final_cavity_factor = clamp((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0); - /* Using UNORM render target so compress the range. */ - fragColor = vec4(final_cavity_factor / CAVITY_BUFFER_RANGE); + /* Using UNORM render target so compress the range. */ + fragColor = vec4(final_cavity_factor / CAVITY_BUFFER_RANGE); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl index 998517e2e72..1af786b648c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl @@ -3,87 +3,90 @@ /* from The Alchemy screen-space ambient obscurance algorithm * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */ -void ssao_factors( - in float depth, in vec3 normal, in vec3 position, in vec2 screenco, - out float cavities, out float edges) +void ssao_factors(in float depth, + in vec3 normal, + in vec3 position, + in vec2 screenco, + out float cavities, + out float edges) { - cavities = edges = 0.0; - /* early out if there is no need for SSAO */ - if (ssao_factor_cavity == 0.0 && ssao_factor_edge == 0.0) { - return; - } - - /* take the normalized ray direction here */ - vec3 noise = texture(ssao_jitter, screenco.xy * jitter_tilling).rgb; - - /* find the offset in screen space by multiplying a point - * in camera space at the depth of the point by the projection matrix. */ - vec2 offset; - float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3]; - offset.x = WinMatrix[0][0] * ssao_distance / homcoord; - offset.y = WinMatrix[1][1] * ssao_distance / homcoord; - /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */ - offset *= 0.5; - - - int num_samples = int(ssao_samples_num); - - /* Note. Putting noise usage here to put some ALU after texture fetch. */ - vec2 rotX = noise.rg; - vec2 rotY = vec2(-rotX.y, rotX.x); - - for (int x = 0; x < num_samples; x++) { - int sample_index = x + (int(ssao_iteration) * num_samples); - if (sample_index > 500) { - continue; - } - /* ssao_samples[x].xy is sample direction (normalized). - * ssao_samples[x].z is sample distance from disk center. */ - - /* Rotate with random direction to get jittered result. */ - vec2 dir_jittered = vec2(dot(ssao_samples[sample_index].xy, rotX), dot(ssao_samples[sample_index].xy, rotY)); - dir_jittered.xy *= ssao_samples[sample_index].z + noise.b; - - vec2 uvcoords = screenco.xy + dir_jittered * offset; - - if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0) { - continue; - } - - float depth_new = texture(depthBuffer, uvcoords).r; - - /* Handle Background case */ - bool is_background = (depth_new == 1.0); - - /* This trick provide good edge effect even if no neighboor is found. */ - vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new); - - if (is_background) { - pos_new.z -= ssao_distance; - } - - vec3 dir = pos_new - position; - float len = length(dir); - float f_cavities = dot(dir, normal); - float f_edge = -f_cavities; - float f_bias = 0.05 * len + 0.0001; - - float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation)); - - /* use minor bias here to avoid self shadowing */ - if (f_cavities > -f_bias) { - cavities += f_cavities * attenuation; - } - - if (f_edge > f_bias) { - edges += f_edge * attenuation; - } - } - - cavities /= ssao_samples_num; - edges /= ssao_samples_num; - - /* don't let cavity wash out the surface appearance */ - cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0); - edges = edges * ssao_factor_edge; + cavities = edges = 0.0; + /* early out if there is no need for SSAO */ + if (ssao_factor_cavity == 0.0 && ssao_factor_edge == 0.0) { + return; + } + + /* take the normalized ray direction here */ + vec3 noise = texture(ssao_jitter, screenco.xy * jitter_tilling).rgb; + + /* find the offset in screen space by multiplying a point + * in camera space at the depth of the point by the projection matrix. */ + vec2 offset; + float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3]; + offset.x = WinMatrix[0][0] * ssao_distance / homcoord; + offset.y = WinMatrix[1][1] * ssao_distance / homcoord; + /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */ + offset *= 0.5; + + int num_samples = int(ssao_samples_num); + + /* Note. Putting noise usage here to put some ALU after texture fetch. */ + vec2 rotX = noise.rg; + vec2 rotY = vec2(-rotX.y, rotX.x); + + for (int x = 0; x < num_samples; x++) { + int sample_index = x + (int(ssao_iteration) * num_samples); + if (sample_index > 500) { + continue; + } + /* ssao_samples[x].xy is sample direction (normalized). + * ssao_samples[x].z is sample distance from disk center. */ + + /* Rotate with random direction to get jittered result. */ + vec2 dir_jittered = vec2(dot(ssao_samples[sample_index].xy, rotX), + dot(ssao_samples[sample_index].xy, rotY)); + dir_jittered.xy *= ssao_samples[sample_index].z + noise.b; + + vec2 uvcoords = screenco.xy + dir_jittered * offset; + + if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0) { + continue; + } + + float depth_new = texture(depthBuffer, uvcoords).r; + + /* Handle Background case */ + bool is_background = (depth_new == 1.0); + + /* This trick provide good edge effect even if no neighboor is found. */ + vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new); + + if (is_background) { + pos_new.z -= ssao_distance; + } + + vec3 dir = pos_new - position; + float len = length(dir); + float f_cavities = dot(dir, normal); + float f_edge = -f_cavities; + float f_bias = 0.05 * len + 0.0001; + + float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation)); + + /* use minor bias here to avoid self shadowing */ + if (f_cavities > -f_bias) { + cavities += f_cavities * attenuation; + } + + if (f_edge > f_bias) { + edges += f_edge * attenuation; + } + } + + cavities /= ssao_samples_num; + edges /= ssao_samples_num; + + /* don't let cavity wash out the surface appearance */ + cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0); + edges = edges * ssao_factor_edge; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl index 94fa5d51229..c9711e9c7d6 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl @@ -1,12 +1,10 @@ /* 4x4 bayer matrix. */ #define P(x) ((x + 0.5) * (1.0 / 16.0)) -const vec4 dither_mat[4] = vec4[4]( - vec4( P(0.0), P(8.0), P(2.0), P(10.0)), - vec4(P(12.0), P(4.0), P(14.0), P(6.0)), - vec4( P(3.0), P(11.0), P(1.0), P(9.0)), - vec4(P(15.0), P(7.0), P(13.0), P(5.0)) -); +const vec4 dither_mat[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4(P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0))); uniform float threshold = 0.5; uniform float offset = 0.0; @@ -20,19 +18,21 @@ uniform float offset = 0.0; void main() { #if NOISE == 0 - ivec2 tx = ivec2(gl_FragCoord.xy) % 4; - float noise = dither_mat[tx.x][tx.y]; + ivec2 tx = ivec2(gl_FragCoord.xy) % 4; + float noise = dither_mat[tx.x][tx.y]; #elif NOISE == 1 - /* Interlieved gradient noise by Jorge Jimenez - * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */ - float noise = fract(offset + 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y)); + /* Interlieved gradient noise by Jorge Jimenez + * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */ + float noise = fract( + offset + 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y)); #else -#error +# error #endif - if (noise > threshold) { - discard; - } else { - gl_FragDepth = 1.0; - } + if (noise > threshold) { + discard; + } + else { + gl_FragDepth = 1.0; + } } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index 5f3dbd75b15..c76ad8c1d7b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -6,47 +6,46 @@ /* 4x4 bayer matrix prepared for 8bit UNORM precision error. */ #define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0)) -const vec4 dither_mat4x4[4] = vec4[4]( - vec4( P(0.0), P(8.0), P(2.0), P(10.0)), - vec4(P(12.0), P(4.0), P(14.0), P(6.0)), - vec4( P(3.0), P(11.0), P(1.0), P(9.0)), - vec4(P(15.0), P(7.0), P(13.0), P(5.0)) -); - -float bayer_dither_noise() { - ivec2 tx1 = ivec2(gl_FragCoord.xy) % 4; - ivec2 tx2 = ivec2(gl_FragCoord.xy) % 2; - return dither_mat4x4[tx1.x][tx1.y]; +const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4(P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0))); + +float bayer_dither_noise() +{ + ivec2 tx1 = ivec2(gl_FragCoord.xy) % 4; + ivec2 tx2 = ivec2(gl_FragCoord.xy) % 2; + return dither_mat4x4[tx1.x][tx1.y]; } #ifdef WORKBENCH_ENCODE_NORMALS -#define WB_Normal vec2 +# define WB_Normal vec2 /* From http://aras-p.info/texts/CompactNormalStorage.html * Using Method #4: Spheremap Transform */ vec3 workbench_normal_decode(WB_Normal enc) { - vec2 fenc = enc.xy * 4.0 - 2.0; - float f = dot(fenc, fenc); - float g = sqrt(1.0 - f / 4.0); - vec3 n; - n.xy = fenc*g; - n.z = 1 - f / 2; - return n; + vec2 fenc = enc.xy * 4.0 - 2.0; + float f = dot(fenc, fenc); + float g = sqrt(1.0 - f / 4.0); + vec3 n; + n.xy = fenc * g; + n.z = 1 - f / 2; + return n; } /* From http://aras-p.info/texts/CompactNormalStorage.html * Using Method #4: Spheremap Transform */ WB_Normal workbench_normal_encode(vec3 n) { - float p = sqrt(n.z * 8.0 + 8.0); - n.xy = clamp(n.xy / p + 0.5, 0.0, 1.0); - return n.xy; + float p = sqrt(n.z * 8.0 + 8.0); + n.xy = clamp(n.xy / p + 0.5, 0.0, 1.0); + return n.xy; } #else -#define WB_Normal vec3 +# define WB_Normal vec3 /* Well just do nothing... */ # define workbench_normal_encode(a) (a) # define workbench_normal_decode(a) (a) @@ -61,113 +60,112 @@ WB_Normal workbench_normal_encode(vec3 n) /* Encode 2 float into 1 with the desired precision. */ float workbench_float_pair_encode(float v1, float v2) { - // const uint total_mask = ~(0xFFFFFFFFu << TOTAL_BITS); - // const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS); - // const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS); - /* Same as above because some compiler are dumb af. and think we use mediump int. */ - const int total_mask = 0xFF; - const int v1_mask = 0x1F; - const int v2_mask = 0x7; - int iv1 = int(v1 * float(v1_mask)); - int iv2 = int(v2 * float(v2_mask)) << int(ROUGHNESS_BITS); - return float(iv1 | iv2) * (1.0 / float(total_mask)); + // const uint total_mask = ~(0xFFFFFFFFu << TOTAL_BITS); + // const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS); + // const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS); + /* Same as above because some compiler are dumb af. and think we use mediump int. */ + const int total_mask = 0xFF; + const int v1_mask = 0x1F; + const int v2_mask = 0x7; + int iv1 = int(v1 * float(v1_mask)); + int iv2 = int(v2 * float(v2_mask)) << int(ROUGHNESS_BITS); + return float(iv1 | iv2) * (1.0 / float(total_mask)); } void workbench_float_pair_decode(float data, out float v1, out float v2) { - // const uint total_mask = ~(0xFFFFFFFFu << TOTAL_BITS); - // const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS); - // const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS); - /* Same as above because some compiler are dumb af. and think we use mediump int. */ - const int total_mask = 0xFF; - const int v1_mask = 0x1F; - const int v2_mask = 0x7; - int idata = int(data * float(total_mask)); - v1 = float(idata & v1_mask) * (1.0 / float(v1_mask)); - v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask)); + // const uint total_mask = ~(0xFFFFFFFFu << TOTAL_BITS); + // const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS); + // const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS); + /* Same as above because some compiler are dumb af. and think we use mediump int. */ + const int total_mask = 0xFF; + const int v1_mask = 0x1F; + const int v2_mask = 0x7; + int idata = int(data * float(total_mask)); + v1 = float(idata & v1_mask) * (1.0 / float(v1_mask)); + v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask)); } float calculate_transparent_weight(float z, float alpha) { #if 0 - /* Eq 10 : Good for surfaces with varying opacity (like particles) */ - float a = min(1.0, alpha * 10.0) + 0.01; - float b = -gl_FragCoord.z * 0.95 + 1.0; - float w = a * a * a * 3e2 * b * b * b; + /* Eq 10 : Good for surfaces with varying opacity (like particles) */ + float a = min(1.0, alpha * 10.0) + 0.01; + float b = -gl_FragCoord.z * 0.95 + 1.0; + float w = a * a * a * 3e2 * b * b * b; #else - /* Eq 7 put more emphasis on surfaces closer to the view. */ - // float w = 10.0 / (1e-5 + pow(abs(z) / 5.0, 2.0) + pow(abs(z) / 200.0, 6.0)); /* Eq 7 */ - // float w = 10.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0)); /* Eq 8 */ - // float w = 10.0 / (1e-5 + pow(abs(z) / 200.0, 4.0)); /* Eq 9 */ - /* Same as eq 7, but optimized. */ - float a = abs(z) / 5.0; - float b = abs(z) / 200.0; - b *= b; - float w = 10.0 / ((1e-5 + a * a) + b * (b * b)); /* Eq 7 */ + /* Eq 7 put more emphasis on surfaces closer to the view. */ + // float w = 10.0 / (1e-5 + pow(abs(z) / 5.0, 2.0) + pow(abs(z) / 200.0, 6.0)); /* Eq 7 */ + // float w = 10.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0)); /* Eq 8 */ + // float w = 10.0 / (1e-5 + pow(abs(z) / 200.0, 4.0)); /* Eq 9 */ + /* Same as eq 7, but optimized. */ + float a = abs(z) / 5.0; + float b = abs(z) / 200.0; + b *= b; + float w = 10.0 / ((1e-5 + a * a) + b * (b * b)); /* Eq 7 */ #endif - return alpha * clamp(w, 1e-2, 3e2); + return alpha * clamp(w, 1e-2, 3e2); } /* Special function only to be used with calculate_transparent_weight(). */ float linear_zdepth(float depth, vec4 viewvecs[3], mat4 proj_mat) { - if (proj_mat[3][3] == 0.0) { - float d = 2.0 * depth - 1.0; - return -proj_mat[3][2] / (d + proj_mat[2][2]); - } - else { - /* Return depth from near plane. */ - return depth * viewvecs[1].z; - } + if (proj_mat[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -proj_mat[3][2] / (d + proj_mat[2][2]); + } + else { + /* Return depth from near plane. */ + return depth * viewvecs[1].z; + } } vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat) { - return (proj_mat[3][3] == 0.0) - ? normalize(viewvecs[0].xyz + vec3(uv, 0.0) * viewvecs[1].xyz) - : vec3(0.0, 0.0, 1.0); + return (proj_mat[3][3] == 0.0) ? normalize(viewvecs[0].xyz + vec3(uv, 0.0) * viewvecs[1].xyz) : + vec3(0.0, 0.0, 1.0); } vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped) { - /* Quick creation of an orthonormal basis */ - float a = 1.0 / (1.0 + I.z); - float b = -I.x * I.y * a; - vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x); - vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y); - vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N)); - if (flipped) { - matcap_uv.x = -matcap_uv.x; - } - return matcap_uv * 0.496 + 0.5; + /* Quick creation of an orthonormal basis */ + float a = 1.0 / (1.0 + I.z); + float b = -I.x * I.y * a; + vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x); + vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y); + vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N)); + if (flipped) { + matcap_uv.x = -matcap_uv.x; + } + return matcap_uv * 0.496 + 0.5; } float srgb_to_linearrgb(float c) { - if (c < 0.04045) { - return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); - } - else { - return pow((c + 0.055) * (1.0 / 1.055), 2.4); - } + if (c < 0.04045) { + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); + } + else { + return pow((c + 0.055) * (1.0 / 1.055), 2.4); + } } vec4 srgb_to_linearrgb(vec4 col_from) { - vec4 col_to; - col_to.r = srgb_to_linearrgb(col_from.r); - col_to.g = srgb_to_linearrgb(col_from.g); - col_to.b = srgb_to_linearrgb(col_from.b); - col_to.a = col_from.a; - return col_to; + vec4 col_to; + col_to.r = srgb_to_linearrgb(col_from.r); + col_to.g = srgb_to_linearrgb(col_from.g); + col_to.b = srgb_to_linearrgb(col_from.b); + col_to.a = col_from.a; + return col_to; } vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool srgb, bool nearest_sampling) { - vec2 tex_size = vec2(textureSize(image, 0).xy); - /* TODO(fclem) We could do the same with sampler objects. - * But this is a quick workaround instead of messing with the GPUTexture itself. */ - vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord; - vec4 color = texture(image, uv); - return (srgb) ? srgb_to_linearrgb(color) : color; + vec2 tex_size = vec2(textureSize(image, 0).xy); + /* TODO(fclem) We could do the same with sampler objects. + * But this is a quick workaround instead of messing with the GPUTexture itself. */ + vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord; + vec4 color = texture(image, uv); + return (srgb) ? srgb_to_linearrgb(color) : color; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl index d0281f6c85c..22dc906be83 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl @@ -4,38 +4,39 @@ float curvature_soft_clamp(float curvature, float control) { - if (curvature < 0.5 / control) { - return curvature * (1.0 - curvature * control); - } - return 0.25 / control; + if (curvature < 0.5 / control) { + return curvature * (1.0 - curvature * control); + } + return 0.25 / control; } -float calculate_curvature(usampler2D objectId, sampler2D normalBuffer, ivec2 texel, float ridge, float valley) +float calculate_curvature( + usampler2D objectId, sampler2D normalBuffer, ivec2 texel, float ridge, float valley) { - uint object_up = texelFetchOffset(objectId, texel, 0, ivec2(0, CURVATURE_OFFSET)).r; - uint object_down = texelFetchOffset(objectId, texel, 0, ivec2(0, -CURVATURE_OFFSET)).r; - uint object_left = texelFetchOffset(objectId, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).r; - uint object_right = texelFetchOffset(objectId, texel, 0, ivec2( CURVATURE_OFFSET, 0)).r; + uint object_up = texelFetchOffset(objectId, texel, 0, ivec2(0, CURVATURE_OFFSET)).r; + uint object_down = texelFetchOffset(objectId, texel, 0, ivec2(0, -CURVATURE_OFFSET)).r; + uint object_left = texelFetchOffset(objectId, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).r; + uint object_right = texelFetchOffset(objectId, texel, 0, ivec2(CURVATURE_OFFSET, 0)).r; - if((object_up != object_down) || (object_right != object_left)) { - return 0.0; - } + if ((object_up != object_down) || (object_right != object_left)) { + return 0.0; + } - vec2 normal_up = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, CURVATURE_OFFSET)).rg; - vec2 normal_down = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, -CURVATURE_OFFSET)).rg; - vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg; - vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2( CURVATURE_OFFSET, 0)).rg; + vec2 normal_up = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, CURVATURE_OFFSET)).rg; + vec2 normal_down = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, -CURVATURE_OFFSET)).rg; + vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg; + vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2(CURVATURE_OFFSET, 0)).rg; - normal_up = workbench_normal_decode(normal_up ).rg; - normal_down = workbench_normal_decode(normal_down ).rg; - normal_left = workbench_normal_decode(normal_left ).rg; - normal_right = workbench_normal_decode(normal_right).rg; + normal_up = workbench_normal_decode(normal_up).rg; + normal_down = workbench_normal_decode(normal_down).rg; + normal_left = workbench_normal_decode(normal_left).rg; + normal_right = workbench_normal_decode(normal_right).rg; - float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r)); + float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r)); - if (normal_diff < 0) { - return -2.0 * curvature_soft_clamp(-normal_diff, valley); - } + if (normal_diff < 0) { + return -2.0 * curvature_soft_clamp(-normal_diff, valley); + } - return 2.0 * curvature_soft_clamp(normal_diff, ridge); + return 2.0 * curvature_soft_clamp(normal_diff, ridge); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl index 6deb29f6bca..16df56b393a 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -1,20 +1,20 @@ struct LightData { - vec4 direction; - vec4 specular_color; - vec4 diffuse_color_wrap; /* rgb: diffuse col a: wrapped lighting factor */ + vec4 direction; + vec4 specular_color; + vec4 diffuse_color_wrap; /* rgb: diffuse col a: wrapped lighting factor */ }; struct WorldData { - vec4 background_color_low; - vec4 background_color_high; - vec4 object_outline_color; - vec4 shadow_direction_vs; - LightData lights[4]; - vec4 ambient_color; - int num_lights; - int matcap_orientation; - float background_alpha; - float curvature_ridge; - float curvature_valley; - int pad[3]; + vec4 background_color_low; + vec4 background_color_high; + vec4 object_outline_color; + vec4 shadow_direction_vs; + LightData lights[4]; + vec4 ambient_color; + int num_lights; + int matcap_orientation; + float background_alpha; + float curvature_ridge; + float curvature_valley; + int pad[3]; }; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl index 9e4394238ff..45ebf09d623 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl @@ -5,35 +5,36 @@ uniform vec2 invertedViewportSize; out vec4 fragColor; -layout(std140) uniform world_block { - WorldData world_data; +layout(std140) uniform world_block +{ + WorldData world_data; }; void main() { - vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; - vec3 background = background_color(world_data, uv_viewport.y); + vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; + vec3 background = background_color(world_data, uv_viewport.y); #ifndef V3D_SHADING_OBJECT_OUTLINE - fragColor = vec4(background, world_data.background_alpha); + fragColor = vec4(background, world_data.background_alpha); #else /* !V3D_SHADING_OBJECT_OUTLINE */ - ivec2 texel = ivec2(gl_FragCoord.xy); - uint object_id = texelFetch(objectId, texel, 0).r; - float object_outline = calculate_object_outline(objectId, texel, object_id); - - if (object_outline == 0.0) { - fragColor = vec4(background, world_data.background_alpha); - } - else { - /* Do correct alpha blending. */ - vec4 background_color = vec4(background, 1.0) * world_data.background_alpha; - vec4 outline_color = vec4(world_data.object_outline_color.rgb, 1.0); - fragColor = mix(outline_color, background_color, object_outline); - fragColor = vec4(fragColor.rgb / max(1e-8, fragColor.a), fragColor.a); - } + ivec2 texel = ivec2(gl_FragCoord.xy); + uint object_id = texelFetch(objectId, texel, 0).r; + float object_outline = calculate_object_outline(objectId, texel, object_id); + + if (object_outline == 0.0) { + fragColor = vec4(background, world_data.background_alpha); + } + else { + /* Do correct alpha blending. */ + vec4 background_color = vec4(background, 1.0) * world_data.background_alpha; + vec4 outline_color = vec4(world_data.object_outline_color.rgb, 1.0); + fragColor = mix(outline_color, background_color, object_outline); + fragColor = vec4(fragColor.rgb / max(1e-8, fragColor.a), fragColor.a); + } #endif /* !V3D_SHADING_OBJECT_OUTLINE */ } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl index 40e166bc7ac..65196c1a836 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl @@ -19,80 +19,80 @@ uniform float shadowFocus = 1.0; uniform vec3 materialSingleColor; -layout(std140) uniform world_block { - WorldData world_data; +layout(std140) uniform world_block +{ + WorldData world_data; }; void main() { - ivec2 texel = ivec2(gl_FragCoord.xy); - vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; + ivec2 texel = ivec2(gl_FragCoord.xy); + vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; - float roughness, metallic; - vec3 base_color; + float roughness, metallic; + vec3 base_color; #ifndef MATDATA_PASS_ENABLED - base_color = materialSingleColor; - metallic = 0.0; - roughness = 0.5; + base_color = materialSingleColor; + metallic = 0.0; + roughness = 0.5; #else - vec4 material_data = texelFetch(materialBuffer, texel, 0); - base_color = material_data.rgb; - workbench_float_pair_decode(material_data.a, roughness, metallic); + vec4 material_data = texelFetch(materialBuffer, texel, 0); + base_color = material_data.rgb; + workbench_float_pair_decode(material_data.a, roughness, metallic); #endif /* Do we need normals */ #ifdef NORMAL_VIEWPORT_PASS_ENABLED - vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg); + vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg); #endif - vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix); + vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix); - /* -------- SHADING --------- */ + /* -------- SHADING --------- */ #ifdef V3D_LIGHTING_FLAT - vec3 shaded_color = base_color; + vec3 shaded_color = base_color; #elif defined(V3D_LIGHTING_MATCAP) - /* When using matcaps, the metallic is the backface sign. */ - normal_viewport = (metallic > 0.0) ? normal_viewport : -normal_viewport; - bool flipped = world_data.matcap_orientation != 0; - vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped); - vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb; - vec3 shaded_color = matcap * base_color; + /* When using matcaps, the metallic is the backface sign. */ + normal_viewport = (metallic > 0.0) ? normal_viewport : -normal_viewport; + bool flipped = world_data.matcap_orientation != 0; + vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped); + vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb; + vec3 shaded_color = matcap * base_color; #elif defined(V3D_LIGHTING_STUDIO) # ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - vec3 specular_color = mix(vec3(0.05), base_color, metallic); - vec3 diffuse_color = mix(base_color, vec3(0.0), metallic); + vec3 specular_color = mix(vec3(0.05), base_color, metallic); + vec3 diffuse_color = mix(base_color, vec3(0.0), metallic); # else - roughness = 0.0; - vec3 specular_color = vec3(0.0); - vec3 diffuse_color = base_color; + roughness = 0.0; + vec3 specular_color = vec3(0.0); + vec3 diffuse_color = base_color; # endif - vec3 shaded_color = get_world_lighting(world_data, - diffuse_color, specular_color, roughness, - normal_viewport, I_vs); + vec3 shaded_color = get_world_lighting( + world_data, diffuse_color, specular_color, roughness, normal_viewport, I_vs); #endif - /* -------- POST EFFECTS --------- */ + /* -------- POST EFFECTS --------- */ #ifdef WB_CAVITY - /* Using UNORM texture so decompress the range */ - shaded_color *= texelFetch(cavityBuffer, texel, 0).r * CAVITY_BUFFER_RANGE; + /* Using UNORM texture so decompress the range */ + shaded_color *= texelFetch(cavityBuffer, texel, 0).r * CAVITY_BUFFER_RANGE; #endif #ifdef V3D_SHADING_SHADOW - float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz); - float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor); - shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix); + float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz); + float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor); + shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix); #endif #ifdef V3D_SHADING_OBJECT_OUTLINE - uint object_id = texelFetch(objectId, texel, 0).r; - float object_outline = calculate_object_outline(objectId, texel, object_id); - shaded_color = mix(world_data.object_outline_color.rgb, shaded_color, object_outline); + uint object_id = texelFetch(objectId, texel, 0).r; + float object_outline = calculate_object_outline(objectId, texel, object_id); + shaded_color = mix(world_data.object_outline_color.rgb, shaded_color, object_outline); #endif - fragColor = vec4(shaded_color, 1.0); + fragColor = vec4(shaded_color, 1.0); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl index 1fb7a9cec46..54440f7b120 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl @@ -18,29 +18,42 @@ uniform sampler2D halfResColorTex; uniform sampler2D blurTex; uniform sampler2D noiseTex; -#define dof_aperturesize dofParams.x -#define dof_distance dofParams.y -#define dof_invsensorsize dofParams.z +#define dof_aperturesize dofParams.x +#define dof_distance dofParams.y +#define dof_invsensorsize dofParams.z -#define M_PI 3.1415926535897932 /* pi */ +#define M_PI 3.1415926535897932 /* pi */ -float max_v4(vec4 v) { return max(max(v.x, v.y), max(v.z, v.w)); } +float max_v4(vec4 v) +{ + return max(max(v.x, v.y), max(v.z, v.w)); +} -#define weighted_sum(a, b, c, d, e, e_sum) ((a) * e.x + (b) * e.y + (c) * e.z + (d) * e.w) / max(1e-6, e_sum); +#define weighted_sum(a, b, c, d, e, e_sum) \ + ((a)*e.x + (b)*e.y + (c)*e.z + (d)*e.w) / max(1e-6, e_sum); /* divide by sensor size to get the normalized size */ -#define calculate_coc(zdepth) (dof_aperturesize * (dof_distance / zdepth - 1.0) * dof_invsensorsize) +#define calculate_coc(zdepth) \ + (dof_aperturesize * (dof_distance / zdepth - 1.0) * dof_invsensorsize) #define linear_depth(z) \ - ((ProjectionMatrix[3][3] == 0.0) ? \ - (nearFar.x * nearFar.y) / (z * (nearFar.x - nearFar.y) + nearFar.y) : \ - (z * 2.0 - 1.0) * nearFar.y) - + ((ProjectionMatrix[3][3] == 0.0) ? \ + (nearFar.x * nearFar.y) / (z * (nearFar.x - nearFar.y) + nearFar.y) : \ + (z * 2.0 - 1.0) * nearFar.y) const float MAX_COC_SIZE = 100.0; -vec2 encode_coc(float near, float far) { return vec2(near, far) / MAX_COC_SIZE; } -float decode_coc(vec2 cocs) { return max(cocs.x, cocs.y) * MAX_COC_SIZE; } -float decode_signed_coc(vec2 cocs) { return ((cocs.x > cocs.y) ? cocs.x : -cocs.y) * MAX_COC_SIZE; } +vec2 encode_coc(float near, float far) +{ + return vec2(near, far) / MAX_COC_SIZE; +} +float decode_coc(vec2 cocs) +{ + return max(cocs.x, cocs.y) * MAX_COC_SIZE; +} +float decode_signed_coc(vec2 cocs) +{ + return ((cocs.x > cocs.y) ? cocs.x : -cocs.y) * MAX_COC_SIZE; +} /** * ----------------- STEP 0 ------------------ @@ -53,39 +66,39 @@ layout(location = 1) out vec2 normalizedCoc; void main() { - ivec4 texel = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1); - - vec4 color1 = texelFetch(sceneColorTex, texel.xy, 0); - vec4 color2 = texelFetch(sceneColorTex, texel.zw, 0); - vec4 color3 = texelFetch(sceneColorTex, texel.zy, 0); - vec4 color4 = texelFetch(sceneColorTex, texel.xw, 0); - - vec4 depths; - depths.x = texelFetch(sceneDepthTex, texel.xy, 0).x; - depths.y = texelFetch(sceneDepthTex, texel.zw, 0).x; - depths.z = texelFetch(sceneDepthTex, texel.zy, 0).x; - depths.w = texelFetch(sceneDepthTex, texel.xw, 0).x; - - vec4 zdepths = linear_depth(depths); - vec4 cocs_near = calculate_coc(zdepths); - vec4 cocs_far = -cocs_near; - - float coc_near = max(max_v4(cocs_near), 0.0); - float coc_far = max(max_v4(cocs_far), 0.0); - - /* now we need to write the near-far fields premultiplied by the coc - * also use bilateral weighting by each coc values to avoid bleeding. */ - vec4 near_weights = step(0.0, cocs_near) * clamp(1.0 - abs(coc_near - cocs_near), 0.0, 1.0); - vec4 far_weights = step(0.0, cocs_far) * clamp(1.0 - abs(coc_far - cocs_far), 0.0, 1.0); - - /* now write output to weighted buffers. */ - /* Take far plane pixels in priority. */ - vec4 w = any(notEqual(far_weights, vec4(0.0))) ? far_weights : near_weights; - float tot_weight = dot(w, vec4(1.0)); - halfResColor = weighted_sum(color1, color2, color3, color4, w, tot_weight); - halfResColor = clamp(halfResColor, 0.0, 3.0); - - normalizedCoc = encode_coc(coc_near, coc_far); + ivec4 texel = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1); + + vec4 color1 = texelFetch(sceneColorTex, texel.xy, 0); + vec4 color2 = texelFetch(sceneColorTex, texel.zw, 0); + vec4 color3 = texelFetch(sceneColorTex, texel.zy, 0); + vec4 color4 = texelFetch(sceneColorTex, texel.xw, 0); + + vec4 depths; + depths.x = texelFetch(sceneDepthTex, texel.xy, 0).x; + depths.y = texelFetch(sceneDepthTex, texel.zw, 0).x; + depths.z = texelFetch(sceneDepthTex, texel.zy, 0).x; + depths.w = texelFetch(sceneDepthTex, texel.xw, 0).x; + + vec4 zdepths = linear_depth(depths); + vec4 cocs_near = calculate_coc(zdepths); + vec4 cocs_far = -cocs_near; + + float coc_near = max(max_v4(cocs_near), 0.0); + float coc_far = max(max_v4(cocs_far), 0.0); + + /* now we need to write the near-far fields premultiplied by the coc + * also use bilateral weighting by each coc values to avoid bleeding. */ + vec4 near_weights = step(0.0, cocs_near) * clamp(1.0 - abs(coc_near - cocs_near), 0.0, 1.0); + vec4 far_weights = step(0.0, cocs_far) * clamp(1.0 - abs(coc_far - cocs_far), 0.0, 1.0); + + /* now write output to weighted buffers. */ + /* Take far plane pixels in priority. */ + vec4 w = any(notEqual(far_weights, vec4(0.0))) ? far_weights : near_weights; + float tot_weight = dot(w, vec4(1.0)); + halfResColor = weighted_sum(color1, color2, color3, color4, w, tot_weight); + halfResColor = clamp(halfResColor, 0.0, 3.0); + + normalizedCoc = encode_coc(coc_near, coc_far); } #endif @@ -100,36 +113,36 @@ layout(location = 1) out vec2 outCocs; void main() { - ivec4 texel = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1); + ivec4 texel = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1); - vec4 color1 = texelFetch(sceneColorTex, texel.xy, 0); - vec4 color2 = texelFetch(sceneColorTex, texel.zw, 0); - vec4 color3 = texelFetch(sceneColorTex, texel.zy, 0); - vec4 color4 = texelFetch(sceneColorTex, texel.xw, 0); + vec4 color1 = texelFetch(sceneColorTex, texel.xy, 0); + vec4 color2 = texelFetch(sceneColorTex, texel.zw, 0); + vec4 color3 = texelFetch(sceneColorTex, texel.zy, 0); + vec4 color4 = texelFetch(sceneColorTex, texel.xw, 0); - vec4 depths; - vec2 cocs1 = texelFetch(inputCocTex, texel.xy, 0).rg; - vec2 cocs2 = texelFetch(inputCocTex, texel.zw, 0).rg; - vec2 cocs3 = texelFetch(inputCocTex, texel.zy, 0).rg; - vec2 cocs4 = texelFetch(inputCocTex, texel.xw, 0).rg; + vec4 depths; + vec2 cocs1 = texelFetch(inputCocTex, texel.xy, 0).rg; + vec2 cocs2 = texelFetch(inputCocTex, texel.zw, 0).rg; + vec2 cocs3 = texelFetch(inputCocTex, texel.zy, 0).rg; + vec2 cocs4 = texelFetch(inputCocTex, texel.xw, 0).rg; - vec4 cocs_near = vec4(cocs1.r, cocs2.r, cocs3.r, cocs4.r) * MAX_COC_SIZE; - vec4 cocs_far = vec4(cocs1.g, cocs2.g, cocs3.g, cocs4.g) * MAX_COC_SIZE; + vec4 cocs_near = vec4(cocs1.r, cocs2.r, cocs3.r, cocs4.r) * MAX_COC_SIZE; + vec4 cocs_far = vec4(cocs1.g, cocs2.g, cocs3.g, cocs4.g) * MAX_COC_SIZE; - float coc_near = max_v4(cocs_near); - float coc_far = max_v4(cocs_far); + float coc_near = max_v4(cocs_near); + float coc_far = max_v4(cocs_far); - /* now we need to write the near-far fields premultiplied by the coc - * also use bilateral weighting by each coc values to avoid bleeding. */ - vec4 near_weights = step(0.0, cocs_near) * clamp(1.0 - abs(coc_near - cocs_near), 0.0, 1.0); - vec4 far_weights = step(0.0, cocs_far) * clamp(1.0 - abs(coc_far - cocs_far), 0.0, 1.0); + /* now we need to write the near-far fields premultiplied by the coc + * also use bilateral weighting by each coc values to avoid bleeding. */ + vec4 near_weights = step(0.0, cocs_near) * clamp(1.0 - abs(coc_near - cocs_near), 0.0, 1.0); + vec4 far_weights = step(0.0, cocs_far) * clamp(1.0 - abs(coc_far - cocs_far), 0.0, 1.0); - /* now write output to weighted buffers. */ - vec4 w = any(notEqual(far_weights, vec4(0.0))) ? far_weights : near_weights; - float tot_weight = dot(w, vec4(1.0)); - outColor = weighted_sum(color1, color2, color3, color4, w, tot_weight); + /* now write output to weighted buffers. */ + vec4 w = any(notEqual(far_weights, vec4(0.0))) ? far_weights : near_weights; + float tot_weight = dot(w, vec4(1.0)); + outColor = weighted_sum(color1, color2, color3, color4, w, tot_weight); - outCocs = encode_coc(coc_near, coc_far); + outCocs = encode_coc(coc_near, coc_far); } #endif @@ -143,28 +156,29 @@ layout(location = 0) out vec2 flattenedCoc; void main() { -#ifdef FLATTEN_HORIZONTAL - ivec2 texel = ivec2(gl_FragCoord.xy) * ivec2(8, 1); - vec2 cocs1 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 0)).rg; - vec2 cocs2 = texelFetchOffset(inputCocTex, texel, 0, ivec2(1, 0)).rg; - vec2 cocs3 = texelFetchOffset(inputCocTex, texel, 0, ivec2(2, 0)).rg; - vec2 cocs4 = texelFetchOffset(inputCocTex, texel, 0, ivec2(3, 0)).rg; - vec2 cocs5 = texelFetchOffset(inputCocTex, texel, 0, ivec2(4, 0)).rg; - vec2 cocs6 = texelFetchOffset(inputCocTex, texel, 0, ivec2(5, 0)).rg; - vec2 cocs7 = texelFetchOffset(inputCocTex, texel, 0, ivec2(6, 0)).rg; - vec2 cocs8 = texelFetchOffset(inputCocTex, texel, 0, ivec2(7, 0)).rg; -#else /* FLATTEN_VERTICAL */ - ivec2 texel = ivec2(gl_FragCoord.xy) * ivec2(1, 8); - vec2 cocs1 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 0)).rg; - vec2 cocs2 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 1)).rg; - vec2 cocs3 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 2)).rg; - vec2 cocs4 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 3)).rg; - vec2 cocs5 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 4)).rg; - vec2 cocs6 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 5)).rg; - vec2 cocs7 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 6)).rg; - vec2 cocs8 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 7)).rg; -#endif - flattenedCoc = max(max(max(cocs1, cocs2), max(cocs3, cocs4)), max(max(cocs5, cocs6), max(cocs7, cocs8))); +# ifdef FLATTEN_HORIZONTAL + ivec2 texel = ivec2(gl_FragCoord.xy) * ivec2(8, 1); + vec2 cocs1 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 0)).rg; + vec2 cocs2 = texelFetchOffset(inputCocTex, texel, 0, ivec2(1, 0)).rg; + vec2 cocs3 = texelFetchOffset(inputCocTex, texel, 0, ivec2(2, 0)).rg; + vec2 cocs4 = texelFetchOffset(inputCocTex, texel, 0, ivec2(3, 0)).rg; + vec2 cocs5 = texelFetchOffset(inputCocTex, texel, 0, ivec2(4, 0)).rg; + vec2 cocs6 = texelFetchOffset(inputCocTex, texel, 0, ivec2(5, 0)).rg; + vec2 cocs7 = texelFetchOffset(inputCocTex, texel, 0, ivec2(6, 0)).rg; + vec2 cocs8 = texelFetchOffset(inputCocTex, texel, 0, ivec2(7, 0)).rg; +# else /* FLATTEN_VERTICAL */ + ivec2 texel = ivec2(gl_FragCoord.xy) * ivec2(1, 8); + vec2 cocs1 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 0)).rg; + vec2 cocs2 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 1)).rg; + vec2 cocs3 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 2)).rg; + vec2 cocs4 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 3)).rg; + vec2 cocs5 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 4)).rg; + vec2 cocs6 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 5)).rg; + vec2 cocs7 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 6)).rg; + vec2 cocs8 = texelFetchOffset(inputCocTex, texel, 0, ivec2(0, 7)).rg; +# endif + flattenedCoc = max(max(max(cocs1, cocs2), max(cocs3, cocs4)), + max(max(cocs5, cocs6), max(cocs7, cocs8))); } #endif @@ -178,27 +192,27 @@ layout(location = 0) out vec2 dilatedCoc; void main() { - vec2 texel_size = 1.0 / vec2(textureSize(inputCocTex, 0)); - vec2 uv = gl_FragCoord.xy * texel_size; -#ifdef DILATE_VERTICAL - vec2 cocs1 = texture(inputCocTex, uv + texel_size * vec2(-3, 0)).rg; - vec2 cocs2 = texture(inputCocTex, uv + texel_size * vec2(-2, 0)).rg; - vec2 cocs3 = texture(inputCocTex, uv + texel_size * vec2(-1, 0)).rg; - vec2 cocs4 = texture(inputCocTex, uv + texel_size * vec2( 0, 0)).rg; - vec2 cocs5 = texture(inputCocTex, uv + texel_size * vec2( 1, 0)).rg; - vec2 cocs6 = texture(inputCocTex, uv + texel_size * vec2( 2, 0)).rg; - vec2 cocs7 = texture(inputCocTex, uv + texel_size * vec2( 3, 0)).rg; -#else /* DILATE_HORIZONTAL */ - vec2 cocs1 = texture(inputCocTex, uv + texel_size * vec2(0, -3)).rg; - vec2 cocs2 = texture(inputCocTex, uv + texel_size * vec2(0, -2)).rg; - vec2 cocs3 = texture(inputCocTex, uv + texel_size * vec2(0, -1)).rg; - vec2 cocs4 = texture(inputCocTex, uv + texel_size * vec2(0, 0)).rg; - vec2 cocs5 = texture(inputCocTex, uv + texel_size * vec2(0, 1)).rg; - vec2 cocs6 = texture(inputCocTex, uv + texel_size * vec2(0, 2)).rg; - vec2 cocs7 = texture(inputCocTex, uv + texel_size * vec2(0, 3)).rg; -#endif - // dilatedCoc = max(max(cocs3, cocs4), max(max(cocs5, cocs6), cocs2)); - dilatedCoc = max(max(max(cocs1, cocs2), max(cocs3, cocs4)), max(max(cocs5, cocs6), cocs7)); + vec2 texel_size = 1.0 / vec2(textureSize(inputCocTex, 0)); + vec2 uv = gl_FragCoord.xy * texel_size; +# ifdef DILATE_VERTICAL + vec2 cocs1 = texture(inputCocTex, uv + texel_size * vec2(-3, 0)).rg; + vec2 cocs2 = texture(inputCocTex, uv + texel_size * vec2(-2, 0)).rg; + vec2 cocs3 = texture(inputCocTex, uv + texel_size * vec2(-1, 0)).rg; + vec2 cocs4 = texture(inputCocTex, uv + texel_size * vec2(0, 0)).rg; + vec2 cocs5 = texture(inputCocTex, uv + texel_size * vec2(1, 0)).rg; + vec2 cocs6 = texture(inputCocTex, uv + texel_size * vec2(2, 0)).rg; + vec2 cocs7 = texture(inputCocTex, uv + texel_size * vec2(3, 0)).rg; +# else /* DILATE_HORIZONTAL */ + vec2 cocs1 = texture(inputCocTex, uv + texel_size * vec2(0, -3)).rg; + vec2 cocs2 = texture(inputCocTex, uv + texel_size * vec2(0, -2)).rg; + vec2 cocs3 = texture(inputCocTex, uv + texel_size * vec2(0, -1)).rg; + vec2 cocs4 = texture(inputCocTex, uv + texel_size * vec2(0, 0)).rg; + vec2 cocs5 = texture(inputCocTex, uv + texel_size * vec2(0, 1)).rg; + vec2 cocs6 = texture(inputCocTex, uv + texel_size * vec2(0, 2)).rg; + vec2 cocs7 = texture(inputCocTex, uv + texel_size * vec2(0, 3)).rg; +# endif + // dilatedCoc = max(max(cocs3, cocs4), max(max(cocs5, cocs6), cocs2)); + dilatedCoc = max(max(max(cocs1, cocs2), max(cocs3, cocs4)), max(max(cocs5, cocs6), cocs7)); } #endif @@ -210,53 +224,55 @@ void main() #ifdef BLUR1 layout(location = 0) out vec4 blurColor; -#define NUM_SAMPLES 49 +# define NUM_SAMPLES 49 -layout(std140) uniform dofSamplesBlock { - vec4 samples[NUM_SAMPLES]; +layout(std140) uniform dofSamplesBlock +{ + vec4 samples[NUM_SAMPLES]; }; vec2 get_random_vector(float offset) { - /* Interlieved gradient noise by Jorge Jimenez - * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */ - float ign = fract(offset + 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y)); - float bn = texelFetch(noiseTex, ivec2(gl_FragCoord.xy) % 64, 0).a; - float ang = M_PI * 2.0 * fract(bn + offset); - return vec2(cos(ang), sin(ang)) * sqrt(ign); - // return noise.rg * sqrt(ign); + /* Interlieved gradient noise by Jorge Jimenez + * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */ + float ign = fract(offset + + 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y)); + float bn = texelFetch(noiseTex, ivec2(gl_FragCoord.xy) % 64, 0).a; + float ang = M_PI * 2.0 * fract(bn + offset); + return vec2(cos(ang), sin(ang)) * sqrt(ign); + // return noise.rg * sqrt(ign); } void main() { - vec2 uv = gl_FragCoord.xy * invertedViewportSize * 2.0; + vec2 uv = gl_FragCoord.xy * invertedViewportSize * 2.0; - vec2 size = vec2(textureSize(halfResColorTex, 0).xy); - ivec2 texel = ivec2(uv * size); + vec2 size = vec2(textureSize(halfResColorTex, 0).xy); + ivec2 texel = ivec2(uv * size); - vec4 color = vec4(0.0); - float tot = 1e-4; + vec4 color = vec4(0.0); + float tot = 1e-4; - float coc = decode_coc(texelFetch(inputCocTex, texel, 0).rg); - float max_radius = coc; - vec2 noise = get_random_vector(noiseOffset) * 0.2 * clamp(max_radius * 0.2 - 4.0, 0.0, 1.0); - for (int i = 0; i < NUM_SAMPLES; ++i) { - vec2 tc = uv + (noise + samples[i].xy) * invertedViewportSize * max_radius; + float coc = decode_coc(texelFetch(inputCocTex, texel, 0).rg); + float max_radius = coc; + vec2 noise = get_random_vector(noiseOffset) * 0.2 * clamp(max_radius * 0.2 - 4.0, 0.0, 1.0); + for (int i = 0; i < NUM_SAMPLES; ++i) { + vec2 tc = uv + (noise + samples[i].xy) * invertedViewportSize * max_radius; - /* decode_signed_coc return biggest coc. */ - coc = abs(decode_signed_coc(texture(inputCocTex, tc).rg)); + /* decode_signed_coc return biggest coc. */ + coc = abs(decode_signed_coc(texture(inputCocTex, tc).rg)); - float lod = log2(clamp((coc + min(coc, max_radius)) * 0.5 - 21.0, 0.0, 16.0) * 0.25); - vec4 samp = textureLod(halfResColorTex, tc, lod); + float lod = log2(clamp((coc + min(coc, max_radius)) * 0.5 - 21.0, 0.0, 16.0) * 0.25); + vec4 samp = textureLod(halfResColorTex, tc, lod); - float radius = samples[i].z * max_radius; - float weight = abs(coc) * smoothstep(radius - 0.5, radius + 0.5, abs(coc)); + float radius = samples[i].z * max_radius; + float weight = abs(coc) * smoothstep(radius - 0.5, radius + 0.5, abs(coc)); - color += samp * weight; - tot += weight; - } + color += samp * weight; + tot += weight; + } - blurColor = color / tot; + blurColor = color / tot; } #endif @@ -297,48 +313,70 @@ out vec4 finalColor; void main() { - /* Half Res pass */ - vec2 pixel_size = 1.0 / vec2(textureSize(blurTex, 0).xy); - vec2 uv = gl_FragCoord.xy * pixel_size.xy; - float coc = decode_coc(texture(inputCocTex, uv).rg); - /* Only use this filter if coc is > 9.0 - * since this filter is not weighted by CoC - * and can bleed a bit. */ - float rad = clamp(coc - 9.0, 0.0, 1.0); - -#define vec vec4 -#define toVec(x) x.rgba - -#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); -#define mn3(a, b, c) s2(a, b); s2(a, c); -#define mx3(a, b, c) s2(b, c); s2(a, c); - -#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges -#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges -#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges -#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges - - vec v[9]; - - /* Add the pixels which make up our window to the pixel array. */ - for(int dX = -1; dX <= 1; ++dX) { - for(int dY = -1; dY <= 1; ++dY) { - vec2 offset = vec2(float(dX), float(dY)); - /* If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the - * pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the - * bottom right pixel of the window at pixel[N-1]. */ - v[(dX + 1) * 3 + (dY + 1)] = toVec(texture(blurTex, uv + offset * pixel_size * rad)); - } - } - - vec temp; - - /* Starting with a subset of size 6, remove the min and max each time */ - mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]); - mnmx5(v[1], v[2], v[3], v[4], v[6]); - mnmx4(v[2], v[3], v[4], v[7]); - mnmx3(v[3], v[4], v[8]); - toVec(finalColor) = v[4]; + /* Half Res pass */ + vec2 pixel_size = 1.0 / vec2(textureSize(blurTex, 0).xy); + vec2 uv = gl_FragCoord.xy * pixel_size.xy; + float coc = decode_coc(texture(inputCocTex, uv).rg); + /* Only use this filter if coc is > 9.0 + * since this filter is not weighted by CoC + * and can bleed a bit. */ + float rad = clamp(coc - 9.0, 0.0, 1.0); + +# define vec vec4 +# define toVec(x) x.rgba + +# define s2(a, b) \ + temp = a; \ + a = min(a, b); \ + b = max(temp, b); +# define mn3(a, b, c) \ + s2(a, b); \ + s2(a, c); +# define mx3(a, b, c) \ + s2(b, c); \ + s2(a, c); + +# define mnmx3(a, b, c) \ + mx3(a, b, c); \ + s2(a, b); // 3 exchanges +# define mnmx4(a, b, c, d) \ + s2(a, b); \ + s2(c, d); \ + s2(a, c); \ + s2(b, d); // 4 exchanges +# define mnmx5(a, b, c, d, e) \ + s2(a, b); \ + s2(c, d); \ + mn3(a, c, e); \ + mx3(b, d, e); // 6 exchanges +# define mnmx6(a, b, c, d, e, f) \ + s2(a, d); \ + s2(b, e); \ + s2(c, f); \ + mn3(a, b, c); \ + mx3(d, e, f); // 7 exchanges + + vec v[9]; + + /* Add the pixels which make up our window to the pixel array. */ + for (int dX = -1; dX <= 1; ++dX) { + for (int dY = -1; dY <= 1; ++dY) { + vec2 offset = vec2(float(dX), float(dY)); + /* If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the + * pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the + * bottom right pixel of the window at pixel[N-1]. */ + v[(dX + 1) * 3 + (dY + 1)] = toVec(texture(blurTex, uv + offset * pixel_size * rad)); + } + } + + vec temp; + + /* Starting with a subset of size 6, remove the min and max each time */ + mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]); + mnmx5(v[1], v[2], v[3], v[4], v[6]); + mnmx4(v[2], v[3], v[4], v[7]); + mnmx3(v[3], v[4], v[8]); + toVec(finalColor) = v[4]; } #endif @@ -351,16 +389,16 @@ out vec4 finalColor; void main() { - /* Fullscreen pass */ - vec2 pixel_size = 0.5 / vec2(textureSize(halfResColorTex, 0).xy); - vec2 uv = gl_FragCoord.xy * pixel_size; + /* Fullscreen pass */ + vec2 pixel_size = 0.5 / vec2(textureSize(halfResColorTex, 0).xy); + vec2 uv = gl_FragCoord.xy * pixel_size; - /* TODO MAKE SURE TO ALIGN SAMPLE POSITION TO AVOID OFFSET IN THE BOKEH */ - float depth = texelFetch(sceneDepthTex, ivec2(gl_FragCoord.xy), 0).r; - float zdepth = linear_depth(depth); - float coc = calculate_coc(zdepth); + /* TODO MAKE SURE TO ALIGN SAMPLE POSITION TO AVOID OFFSET IN THE BOKEH */ + float depth = texelFetch(sceneDepthTex, ivec2(gl_FragCoord.xy), 0).r; + float zdepth = linear_depth(depth); + float coc = calculate_coc(zdepth); - finalColor = texture(halfResColorTex, uv); - finalColor.a = smoothstep(1.0, 3.0, abs(coc)); + finalColor = texture(halfResColorTex, uv); + finalColor.a = smoothstep(1.0, 3.0, abs(coc)); } #endif diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_fxaa_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_fxaa_frag.glsl index 4ffd20c2839..46b0361245b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_fxaa_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_fxaa_frag.glsl @@ -8,12 +8,6 @@ uniform vec2 invertedViewportSize; void main() { - FragColor = FxaaPixelShader( - uvcoordsvar.st, - colorBuffer, - invertedViewportSize, - 1.0, - 0.166, - 0.0833 - ); + FragColor = FxaaPixelShader( + uvcoordsvar.st, colorBuffer, invertedViewportSize, 1.0, 0.166, 0.0833); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl index 1da1b2ad13c..5795268f794 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl @@ -7,8 +7,8 @@ uniform float mixFactor; void main() { - ivec2 texel = ivec2(gl_FragCoord.xy); - vec4 color_buffer = texelFetch(colorBuffer, texel, 0); - vec4 history_buffer = texelFetch(historyBuffer, texel, 0); - colorOutput = mix(history_buffer, color_buffer, mixFactor); + ivec2 texel = ivec2(gl_FragCoord.xy); + vec4 color_buffer = texelFetch(colorBuffer, texel, 0); + vec4 history_buffer = texelFetch(historyBuffer, texel, 0); + colorOutput = mix(history_buffer, color_buffer, mixFactor); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl index 576a5e81c0d..6915055e356 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl @@ -6,38 +6,40 @@ uniform sampler2D transparentRevealage; uniform vec2 invertedViewportSize; #ifndef ALPHA_COMPOSITE -layout(std140) uniform world_block { - WorldData world_data; +layout(std140) uniform world_block +{ + WorldData world_data; }; #endif /* TODO: Bypass the whole shader if there is no xray pass and no outline pass. */ void main() { - ivec2 texel = ivec2(gl_FragCoord.xy); - vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; + ivec2 texel = ivec2(gl_FragCoord.xy); + vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; - /* Listing 4 */ - vec4 trans_accum = texelFetch(transparentAccum, texel, 0); - float trans_revealage = trans_accum.a; - trans_accum.a = texelFetch(transparentRevealage, texel, 0).r; + /* Listing 4 */ + vec4 trans_accum = texelFetch(transparentAccum, texel, 0); + float trans_revealage = trans_accum.a; + trans_accum.a = texelFetch(transparentRevealage, texel, 0).r; - vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4); + vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4); #ifndef ALPHA_COMPOSITE - vec3 bg_color = background_color(world_data, uv_viewport.y); + vec3 bg_color = background_color(world_data, uv_viewport.y); - bg_color = (world_data.background_alpha == 0.0) ? trans_color : bg_color; - vec4 color = mix(vec4(trans_color, 1.0), vec4(bg_color, world_data.background_alpha), trans_revealage); + bg_color = (world_data.background_alpha == 0.0) ? trans_color : bg_color; + vec4 color = mix( + vec4(trans_color, 1.0), vec4(bg_color, world_data.background_alpha), trans_revealage); # ifdef V3D_SHADING_OBJECT_OUTLINE - uint object_id = texelFetch(objectId, texel, 0).r; - float outline = calculate_object_outline(objectId, texel, object_id); - color = mix(vec4(world_data.object_outline_color.rgb, 1.0), color, outline); + uint object_id = texelFetch(objectId, texel, 0).r; + float outline = calculate_object_outline(objectId, texel, object_id); + color = mix(vec4(world_data.object_outline_color.rgb, 1.0), color, outline); # endif - fragColor = color; + fragColor = color; #else - fragColor = vec4(trans_color, 1.0 - trans_revealage); + fragColor = vec4(trans_color, 1.0 - trans_revealage); #endif } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl index 9380044f2b9..505b4822ad6 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl @@ -1,5 +1,5 @@ uniform int object_id = 0; -layout(location=0) out uint objectId; +layout(location = 0) out uint objectId; uniform float ImageTransparencyCutoff = 0.1; #ifdef V3D_SHADING_TEXTURE_COLOR uniform sampler2D image; @@ -10,11 +10,11 @@ in vec2 uv_interp; void main() { #ifdef V3D_SHADING_TEXTURE_COLOR - vec4 diffuse_color = texture(image, uv_interp); - if (diffuse_color.a < ImageTransparencyCutoff) { - discard; - } + vec4 diffuse_color = texture(image, uv_interp); + if (diffuse_color.a < ImageTransparencyCutoff) { + discard; + } #endif - objectId = uint(object_id); + objectId = uint(object_id); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index b3642b7beb3..e654141df5c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -29,62 +29,63 @@ in vec2 uv_interp; uniform sampler2D matcapImage; #endif -layout(std140) uniform world_block { - WorldData world_data; +layout(std140) uniform world_block +{ + WorldData world_data; }; -layout(location=0) out vec4 transparentAccum; -layout(location=1) out float revealageAccum; /* revealage actually stored in transparentAccum.a */ +layout(location = 0) out vec4 transparentAccum; +layout(location = 1) out + float revealageAccum; /* revealage actually stored in transparentAccum.a */ void main() { - vec4 diffuse_color; + vec4 diffuse_color; #ifdef V3D_SHADING_TEXTURE_COLOR - diffuse_color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest); - if (diffuse_color.a < ImageTransparencyCutoff) { - discard; - } + diffuse_color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest); + if (diffuse_color.a < ImageTransparencyCutoff) { + discard; + } #else - diffuse_color = vec4(materialDiffuseColor, 1.0); + diffuse_color = vec4(materialDiffuseColor, 1.0); #endif /* V3D_SHADING_TEXTURE_COLOR */ - vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; - vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix); + vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; + vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix); #ifdef NORMAL_VIEWPORT_PASS_ENABLED - vec3 nor = normalize(normal_viewport); + vec3 nor = normalize(normal_viewport); #endif - /* -------- SHADING --------- */ + /* -------- SHADING --------- */ #ifdef V3D_LIGHTING_FLAT - vec3 shaded_color = diffuse_color.rgb; + vec3 shaded_color = diffuse_color.rgb; #elif defined(V3D_LIGHTING_MATCAP) - bool flipped = world_data.matcap_orientation != 0; - vec2 matcap_uv = matcap_uv_compute(I_vs, nor, flipped); - vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb; - vec3 shaded_color = matcap * diffuse_color.rgb; + bool flipped = world_data.matcap_orientation != 0; + vec2 matcap_uv = matcap_uv_compute(I_vs, nor, flipped); + vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb; + vec3 shaded_color = matcap * diffuse_color.rgb; #elif defined(V3D_LIGHTING_STUDIO) - vec3 shaded_color = get_world_lighting(world_data, - diffuse_color.rgb, materialSpecularColor, materialRoughness, - nor, I_vs); + vec3 shaded_color = get_world_lighting( + world_data, diffuse_color.rgb, materialSpecularColor, materialRoughness, nor, I_vs); #endif #ifdef V3D_SHADING_SHADOW - float light_factor = -dot(nor, world_data.shadow_direction_vs.xyz); - float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor); - shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix); + float light_factor = -dot(nor, world_data.shadow_direction_vs.xyz); + float shadow_mix = smoothstep(shadowFocus, shadowShift, light_factor); + shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix); #endif - /* Based on : - * McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of - * Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013 - */ - /* Listing 4 */ - float z = linear_zdepth(gl_FragCoord.z, viewvecs, ProjectionMatrix); - float weight = calculate_transparent_weight(z, alpha); - transparentAccum = vec4(shaded_color * weight, alpha); - revealageAccum = weight; + /* Based on : + * McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of + * Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013 + */ + /* Listing 4 */ + float z = linear_zdepth(gl_FragCoord.z, viewvecs, ProjectionMatrix); + float weight = calculate_transparent_weight(z, alpha); + transparentAccum = vec4(shaded_color * weight, alpha); + revealageAccum = weight; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_ghost_resolve_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_ghost_resolve_frag.glsl index 59f2df11086..d223a7650c5 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_ghost_resolve_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_ghost_resolve_frag.glsl @@ -2,12 +2,12 @@ uniform sampler2D depthBuffer; void main(void) { - float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; + float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; - /* background, discard */ - if (depth >= 1.0) { - discard; - } + /* background, discard */ + if (depth >= 1.0) { + discard; + } - gl_FragDepth = depth; + gl_FragDepth = depth; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_object_outline_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_object_outline_lib.glsl index 3e925ba023f..a4a5d9c31a3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_object_outline_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_object_outline_lib.glsl @@ -2,11 +2,11 @@ float calculate_object_outline(usampler2D objectId, ivec2 texel, uint object_id) { - uvec4 oid_offset = uvec4( - texelFetchOffset(objectId, texel, 0, ivec2(0, OBJECT_OUTLINE_OFFSET)).r, - texelFetchOffset(objectId, texel, 0, ivec2(0, -OBJECT_OUTLINE_OFFSET)).r, - texelFetchOffset(objectId, texel, 0, ivec2(-OBJECT_OUTLINE_OFFSET, 0)).r, - texelFetchOffset(objectId, texel, 0, ivec2( OBJECT_OUTLINE_OFFSET, 0)).r); + uvec4 oid_offset = uvec4( + texelFetchOffset(objectId, texel, 0, ivec2(0, OBJECT_OUTLINE_OFFSET)).r, + texelFetchOffset(objectId, texel, 0, ivec2(0, -OBJECT_OUTLINE_OFFSET)).r, + texelFetchOffset(objectId, texel, 0, ivec2(-OBJECT_OUTLINE_OFFSET, 0)).r, + texelFetchOffset(objectId, texel, 0, ivec2(OBJECT_OUTLINE_OFFSET, 0)).r); - return dot(vec4(equal(uvec4(object_id), oid_offset)), vec4(0.25)); + return dot(vec4(equal(uvec4(object_id), oid_offset)), vec4(0.25)); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl index db51d3da15f..6b2962a66da 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -22,58 +22,58 @@ flat in float hair_rand; #endif #ifdef MATDATA_PASS_ENABLED -layout(location=0) out vec4 materialData; +layout(location = 0) out vec4 materialData; #endif #ifdef OBJECT_ID_PASS_ENABLED -layout(location=1) out uint objectId; +layout(location = 1) out uint objectId; #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED -layout(location=2) out WB_Normal normalViewport; +layout(location = 2) out WB_Normal normalViewport; #endif void main() { #ifdef MATDATA_PASS_ENABLED - float metallic, roughness; - vec4 color; + float metallic, roughness; + vec4 color; # ifdef V3D_SHADING_TEXTURE_COLOR - color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest); - if (color.a < ImageTransparencyCutoff) { - discard; - } + color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest); + if (color.a < ImageTransparencyCutoff) { + discard; + } # else - color.rgb = materialDiffuseColor; + color.rgb = materialDiffuseColor; # endif # ifdef V3D_LIGHTING_MATCAP - /* Encode front facing in metallic channel. */ - metallic = float(gl_FrontFacing); - roughness = 0.0; + /* Encode front facing in metallic channel. */ + metallic = float(gl_FrontFacing); + roughness = 0.0; # else - metallic = materialMetallic; - roughness = materialRoughness; + metallic = materialMetallic; + roughness = materialRoughness; # endif # ifdef HAIR_SHADER - /* Add some variation to the hairs to avoid uniform look. */ - float hair_variation = hair_rand * 0.1; - color = clamp(color - hair_variation, 0.0, 1.0); - metallic = clamp(materialMetallic - hair_variation, 0.0, 1.0); - roughness = clamp(materialRoughness - hair_variation, 0.0, 1.0); + /* Add some variation to the hairs to avoid uniform look. */ + float hair_variation = hair_rand * 0.1; + color = clamp(color - hair_variation, 0.0, 1.0); + metallic = clamp(materialMetallic - hair_variation, 0.0, 1.0); + roughness = clamp(materialRoughness - hair_variation, 0.0, 1.0); # endif - materialData.rgb = color.rgb; - materialData.a = workbench_float_pair_encode(roughness, metallic); + materialData.rgb = color.rgb; + materialData.a = workbench_float_pair_encode(roughness, metallic); #endif /* MATDATA_PASS_ENABLED */ #ifdef OBJECT_ID_PASS_ENABLED - objectId = uint(object_id); + objectId = uint(object_id); #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED - vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport; - n = normalize(n); - normalViewport = workbench_normal_encode(n); + vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport; + n = normalize(n); + normalViewport = workbench_normal_encode(n); #endif } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl index 66372f82b89..dd737063f61 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl @@ -10,7 +10,7 @@ uniform mat3 NormalMatrix; in vec3 pos; in vec3 nor; in vec2 u; /* active texture layer */ -#define uv u +# define uv u #else /* HAIR_SHADER */ # ifdef V3D_SHADING_TEXTURE_COLOR uniform samplerBuffer u; /* active texture layer */ @@ -29,49 +29,53 @@ out vec2 uv_interp; /* From http://libnoise.sourceforge.net/noisegen/index.html */ float integer_noise(int n) { - n = (n >> 13) ^ n; - int nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; - return (float(nn) / 1073741824.0); + n = (n >> 13) ^ n; + int nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return (float(nn) / 1073741824.0); } void main() { #ifdef HAIR_SHADER # ifdef V3D_SHADING_TEXTURE_COLOR - vec2 uv = hair_get_customdata_vec2(u); + vec2 uv = hair_get_customdata_vec2(u); # endif - float time, thick_time, thickness; - vec3 pos, tan, binor; - hair_get_pos_tan_binor_time( - (ProjectionMatrix[3][3] == 0.0), - ModelMatrixInverse, - ViewMatrixInverse[3].xyz, ViewMatrixInverse[2].xyz, - pos, tan, binor, time, thickness, thick_time); - /* To "simulate" anisotropic shading, randomize hair normal per strand. */ - hair_rand = integer_noise(hair_get_strand_id()); - tan = normalize(tan); - vec3 nor = normalize(cross(binor, tan)); - nor = normalize(mix(nor, -tan, hair_rand * 0.10)); - float cos_theta = (hair_rand*2.0 - 1.0) * 0.20; - float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta)); - nor = nor * sin_theta + binor * cos_theta; - gl_Position = ViewProjectionMatrix * vec4(pos, 1.0); + float time, thick_time, thickness; + vec3 pos, tan, binor; + hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0), + ModelMatrixInverse, + ViewMatrixInverse[3].xyz, + ViewMatrixInverse[2].xyz, + pos, + tan, + binor, + time, + thickness, + thick_time); + /* To "simulate" anisotropic shading, randomize hair normal per strand. */ + hair_rand = integer_noise(hair_get_strand_id()); + tan = normalize(tan); + vec3 nor = normalize(cross(binor, tan)); + nor = normalize(mix(nor, -tan, hair_rand * 0.10)); + float cos_theta = (hair_rand * 2.0 - 1.0) * 0.20; + float sin_theta = sqrt(max(0.0, 1.0f - cos_theta * cos_theta)); + nor = nor * sin_theta + binor * cos_theta; + gl_Position = ViewProjectionMatrix * vec4(pos, 1.0); #else - gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); #endif #ifdef V3D_SHADING_TEXTURE_COLOR - uv_interp = uv; + uv_interp = uv; #endif #ifdef NORMAL_VIEWPORT_PASS_ENABLED - normal_viewport = NormalMatrix * nor; + normal_viewport = NormalMatrix * nor; # ifndef HAIR_SHADER - normal_viewport = normalize(normal_viewport); + normal_viewport = normalize(normal_viewport); # endif #endif #ifdef USE_WORLD_CLIP_PLANES - world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); + world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); #endif - } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl index d8c8f22ed1c..09bafb8ff11 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl @@ -1,7 +1,7 @@ #extension GL_ARB_gpu_shader5 : enable #ifdef GL_ARB_gpu_shader5 -#define USE_INVOC_EXT +# define USE_INVOC_EXT #endif #ifdef DOUBLE_MANIFOLD @@ -28,58 +28,66 @@ layout(triangle_strip, max_vertices = vert_len) out; uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57); -in VertexData { - vec3 pos; /* local position */ - vec4 frontPosition; /* final ndc position */ - vec4 backPosition; -} vData[]; +in VertexData +{ + vec3 pos; /* local position */ + vec4 frontPosition; /* final ndc position */ + vec4 backPosition; +} +vData[]; vec4 get_pos(int v, bool backface) { - return (backface) ? vData[v].backPosition : vData[v].frontPosition; + return (backface) ? vData[v].backPosition : vData[v].frontPosition; } void emit_cap(const bool front, bool reversed) { - if (front) { - gl_Position = vData[0].frontPosition; EmitVertex(); - gl_Position = vData[reversed ? 2 : 1].frontPosition; EmitVertex(); - gl_Position = vData[reversed ? 1 : 2].frontPosition; EmitVertex(); - } - else { - gl_Position = vData[0].backPosition; EmitVertex(); - gl_Position = vData[reversed ? 1 : 2].backPosition; EmitVertex(); - gl_Position = vData[reversed ? 2 : 1].backPosition; EmitVertex(); - } - EndPrimitive(); + if (front) { + gl_Position = vData[0].frontPosition; + EmitVertex(); + gl_Position = vData[reversed ? 2 : 1].frontPosition; + EmitVertex(); + gl_Position = vData[reversed ? 1 : 2].frontPosition; + EmitVertex(); + } + else { + gl_Position = vData[0].backPosition; + EmitVertex(); + gl_Position = vData[reversed ? 1 : 2].backPosition; + EmitVertex(); + gl_Position = vData[reversed ? 2 : 1].backPosition; + EmitVertex(); + } + EndPrimitive(); } void main() { - vec3 v10 = vData[0].pos - vData[1].pos; - vec3 v12 = vData[2].pos - vData[1].pos; + vec3 v10 = vData[0].pos - vData[1].pos; + vec3 v12 = vData[2].pos - vData[1].pos; - vec3 n = cross(v12, v10); - float facing = dot(n, lightDirection); + vec3 n = cross(v12, v10); + float facing = dot(n, lightDirection); - bool backface = facing > 0.0; + bool backface = facing > 0.0; #ifdef DOUBLE_MANIFOLD - /* In case of non manifold geom, we only increase/decrease - * the stencil buffer by one but do every faces as they were facing the light. */ - bool invert = backface; + /* In case of non manifold geom, we only increase/decrease + * the stencil buffer by one but do every faces as they were facing the light. */ + bool invert = backface; #else - const bool invert = false; - if (!backface) { + const bool invert = false; + if (!backface) { #endif #ifdef USE_INVOC_EXT - bool do_front = (gl_InvocationID & 1) == 0; - emit_cap(do_front, invert); + bool do_front = (gl_InvocationID & 1) == 0; + emit_cap(do_front, invert); #else - emit_cap(true, invert); - emit_cap(false, invert); + emit_cap(true, invert); + emit_cap(false, invert); #endif #ifndef DOUBLE_MANIFOLD - } +} #endif } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl index ceb33e77f2b..6b0741b6d1b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl @@ -3,12 +3,13 @@ out vec4 fragColor; void main() { - const float intensity = 0.25; + const float intensity = 0.25; #ifdef SHADOW_PASS - fragColor = vec4((gl_FrontFacing) ? vec3(intensity, -intensity, 0.0) - : vec3(-intensity, intensity, 0.0), 1.0); + fragColor = vec4( + (gl_FrontFacing) ? vec3(intensity, -intensity, 0.0) : vec3(-intensity, intensity, 0.0), 1.0); #else - fragColor = vec4((gl_FrontFacing) ? vec3(intensity, intensity, -intensity) - : vec3(-intensity, -intensity, intensity), 1.0); + fragColor = vec4((gl_FrontFacing) ? vec3(intensity, intensity, -intensity) : + vec3(-intensity, -intensity, intensity), + 1.0); #endif } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl index 00213260df0..5373648d4e4 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl @@ -1,7 +1,7 @@ #extension GL_ARB_gpu_shader5 : enable #ifdef GL_ARB_gpu_shader5 -#define USE_INVOC_EXT +# define USE_INVOC_EXT #endif #ifdef DOUBLE_MANIFOLD @@ -28,11 +28,13 @@ layout(triangle_strip, max_vertices = vert_len) out; uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57); -in VertexData { - vec3 pos; /* local position */ - vec4 frontPosition; /* final ndc position */ - vec4 backPosition; -} vData[]; +in VertexData +{ + vec3 pos; /* local position */ + vec4 frontPosition; /* final ndc position */ + vec4 backPosition; +} +vData[]; #define DEGENERATE_TRIS_WORKAROUND @@ -40,80 +42,82 @@ in VertexData { void extrude_edge(bool invert) { - /* Reverse order if backfacing the light. */ - ivec2 idx = (invert) ? ivec2(1, 2) : ivec2(2, 1); - gl_Position = vData[idx.x].frontPosition; EmitVertex(); - gl_Position = vData[idx.y].frontPosition; EmitVertex(); - gl_Position = vData[idx.x].backPosition; EmitVertex(); - gl_Position = vData[idx.y].backPosition; EmitVertex(); - EndPrimitive(); + /* Reverse order if backfacing the light. */ + ivec2 idx = (invert) ? ivec2(1, 2) : ivec2(2, 1); + gl_Position = vData[idx.x].frontPosition; + EmitVertex(); + gl_Position = vData[idx.y].frontPosition; + EmitVertex(); + gl_Position = vData[idx.x].backPosition; + EmitVertex(); + gl_Position = vData[idx.y].backPosition; + EmitVertex(); + EndPrimitive(); } void main() { - vec3 v10 = vData[0].pos - vData[1].pos; - vec3 v12 = vData[2].pos - vData[1].pos; - vec3 v13 = vData[3].pos - vData[1].pos; + vec3 v10 = vData[0].pos - vData[1].pos; + vec3 v12 = vData[2].pos - vData[1].pos; + vec3 v13 = vData[3].pos - vData[1].pos; - vec3 n1 = cross(v12, v10); - vec3 n2 = cross(v13, v12); + vec3 n1 = cross(v12, v10); + vec3 n2 = cross(v13, v12); #ifdef DEGENERATE_TRIS_WORKAROUND - /* Check if area is null */ - vec2 faces_area = vec2(len_sqr(n1), len_sqr(n2)); - bvec2 degen_faces = equal(abs(faces_area), vec2(0.0)); - - /* Both triangles are degenerate, abort. */ - if (all(degen_faces)) { - return; - } + /* Check if area is null */ + vec2 faces_area = vec2(len_sqr(n1), len_sqr(n2)); + bvec2 degen_faces = equal(abs(faces_area), vec2(0.0)); + + /* Both triangles are degenerate, abort. */ + if (all(degen_faces)) { + return; + } #endif - vec2 facing = vec2(dot(n1, lightDirection), - dot(n2, lightDirection)); + vec2 facing = vec2(dot(n1, lightDirection), dot(n2, lightDirection)); - /* WATCH: maybe unpredictable in some cases. */ - bool is_manifold = any(notEqual(vData[0].pos, vData[3].pos)); + /* WATCH: maybe unpredictable in some cases. */ + bool is_manifold = any(notEqual(vData[0].pos, vData[3].pos)); - bvec2 backface = greaterThan(facing, vec2(0.0)); + bvec2 backface = greaterThan(facing, vec2(0.0)); #ifdef DEGENERATE_TRIS_WORKAROUND # ifndef DOUBLE_MANIFOLD - /* If the mesh is known to be manifold and we don't use double count, - * only create an quad if the we encounter a facing geom. */ - if ((degen_faces.x && backface.y) || - (degen_faces.y && backface.x)) - return; + /* If the mesh is known to be manifold and we don't use double count, + * only create an quad if the we encounter a facing geom. */ + if ((degen_faces.x && backface.y) || (degen_faces.y && backface.x)) + return; # endif - /* If one of the 2 triangles is degenerate, replace edge by a non-manifold one. */ - backface.x = (degen_faces.x) ? !backface.y : backface.x; - backface.y = (degen_faces.y) ? !backface.x : backface.y; - is_manifold = (any(degen_faces)) ? false : is_manifold; + /* If one of the 2 triangles is degenerate, replace edge by a non-manifold one. */ + backface.x = (degen_faces.x) ? !backface.y : backface.x; + backface.y = (degen_faces.y) ? !backface.x : backface.y; + is_manifold = (any(degen_faces)) ? false : is_manifold; #endif - /* If both faces face the same direction it's not an outline edge. */ - if (backface.x == backface.y) { - return; - } + /* If both faces face the same direction it's not an outline edge. */ + if (backface.x == backface.y) { + return; + } #ifdef USE_INVOC_EXT - if (gl_InvocationID == 0) { - extrude_edge(backface.x); - } - else if (is_manifold) { + if (gl_InvocationID == 0) { + extrude_edge(backface.x); + } + else if (is_manifold) { # ifdef DOUBLE_MANIFOLD - /* Increment/Decrement twice for manifold edges. */ - extrude_edge(backface.x); + /* Increment/Decrement twice for manifold edges. */ + extrude_edge(backface.x); # endif - } + } #else - extrude_edge(backface.x); - if (is_manifold) { + extrude_edge(backface.x); + if (is_manifold) { # ifdef DOUBLE_MANIFOLD - /* Increment/Decrement twice for manifold edges. */ - extrude_edge(backface.x); + /* Increment/Decrement twice for manifold edges. */ + extrude_edge(backface.x); # endif - } + } #endif } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl index 50a721f948f..afd704a7d3a 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl @@ -7,15 +7,17 @@ uniform float lightDistance = 1e4; in vec3 pos; -out VertexData { - vec3 pos; /* local position */ - vec4 frontPosition; /* final ndc position */ - vec4 backPosition; -} vData; +out VertexData +{ + vec3 pos; /* local position */ + vec4 frontPosition; /* final ndc position */ + vec4 backPosition; +} +vData; void main() { - vData.pos = pos; - vData.frontPosition = ModelViewProjectionMatrix * vec4(pos, 1.0); - vData.backPosition = ModelViewProjectionMatrix * vec4(pos + lightDirection * lightDistance, 1.0); + vData.pos = pos; + vData.frontPosition = ModelViewProjectionMatrix * vec4(pos, 1.0); + vData.backPosition = ModelViewProjectionMatrix * vec4(pos + lightDirection * lightDistance, 1.0); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index c99787eaee8..26ebe7a4553 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -15,7 +15,7 @@ uniform sampler1D transferTexture; uniform int samplesLen = 256; uniform float noiseOfs = 0.0f; -uniform float stepLength; /* Step length in local space. */ +uniform float stepLength; /* Step length in local space. */ uniform float densityScale; /* Simple Opacity multiplicator. */ uniform vec4 viewvecs[3]; uniform vec3 activeColor; @@ -29,90 +29,93 @@ in vec3 localPos; out vec4 fragColor; -#define M_PI 3.1415926535897932 /* pi */ +#define M_PI 3.1415926535897932 /* pi */ float phase_function_isotropic() { - return 1.0 / (4.0 * M_PI); + return 1.0 / (4.0 * M_PI); } float get_view_z_from_depth(float depth) { - if (ProjectionMatrix[3][3] == 0.0) { - float d = 2.0 * depth - 1.0; - return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); - } - else { - return viewvecs[0].z + depth * viewvecs[1].z; - } + if (ProjectionMatrix[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); + } + else { + return viewvecs[0].z + depth * viewvecs[1].z; + } } vec3 get_view_space_from_depth(vec2 uvcoords, float depth) { - if (ProjectionMatrix[3][3] == 0.0) { - return vec3(viewvecs[0].xy + uvcoords * viewvecs[1].xy, 1.0) * get_view_z_from_depth(depth); - } - else { - return viewvecs[0].xyz + vec3(uvcoords, depth) * viewvecs[1].xyz; - } + if (ProjectionMatrix[3][3] == 0.0) { + return vec3(viewvecs[0].xy + uvcoords * viewvecs[1].xy, 1.0) * get_view_z_from_depth(depth); + } + else { + return viewvecs[0].xyz + vec3(uvcoords, depth) * viewvecs[1].xyz; + } } -float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); } +float max_v3(vec3 v) +{ + return max(v.x, max(v.y, v.z)); +} float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) { - /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */ - vec3 firstplane = (vec3( 1.0) - lineorigin) / linedirection; - vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; - vec3 furthestplane = min(firstplane, secondplane); - return max_v3(furthestplane); + /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */ + vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection; + vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; + vec3 furthestplane = min(firstplane, secondplane); + return max_v3(furthestplane); } #define sample_trilinear(ima, co) texture(ima, co) vec4 sample_tricubic(sampler3D ima, vec3 co) { - vec3 tex_size = vec3(textureSize(ima, 0).xyz); - - co *= tex_size; - /* texel center */ - vec3 tc = floor(co - 0.5) + 0.5; - vec3 f = co - tc; - vec3 f2 = f * f; - vec3 f3 = f2 * f; - /* Bspline coefs (optimized) */ - vec3 w3 = f3 / 6.0; - vec3 w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0; - vec3 w1 = f3 * 0.5 - f2 + 2.0 / 3.0; - vec3 w2 = 1.0 - w0 - w1 - w3; - - vec3 s0 = w0 + w1; - vec3 s1 = w2 + w3; - - vec3 f0 = w1 / (w0 + w1); - vec3 f1 = w3 / (w2 + w3); - - vec2 final_z; - vec4 final_co; - final_co.xy = tc.xy - 1.0 + f0.xy; - final_co.zw = tc.xy + 1.0 + f1.xy; - final_z = tc.zz + vec2(-1.0, 1.0) + vec2(f0.z, f1.z); - - final_co /= tex_size.xyxy; - final_z /= tex_size.zz; - - vec4 color; - color = texture(ima, vec3(final_co.xy, final_z.x)) * s0.x * s0.y * s0.z; - color += texture(ima, vec3(final_co.zy, final_z.x)) * s1.x * s0.y * s0.z; - color += texture(ima, vec3(final_co.xw, final_z.x)) * s0.x * s1.y * s0.z; - color += texture(ima, vec3(final_co.zw, final_z.x)) * s1.x * s1.y * s0.z; - - color += texture(ima, vec3(final_co.xy, final_z.y)) * s0.x * s0.y * s1.z; - color += texture(ima, vec3(final_co.zy, final_z.y)) * s1.x * s0.y * s1.z; - color += texture(ima, vec3(final_co.xw, final_z.y)) * s0.x * s1.y * s1.z; - color += texture(ima, vec3(final_co.zw, final_z.y)) * s1.x * s1.y * s1.z; - - return color; + vec3 tex_size = vec3(textureSize(ima, 0).xyz); + + co *= tex_size; + /* texel center */ + vec3 tc = floor(co - 0.5) + 0.5; + vec3 f = co - tc; + vec3 f2 = f * f; + vec3 f3 = f2 * f; + /* Bspline coefs (optimized) */ + vec3 w3 = f3 / 6.0; + vec3 w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0; + vec3 w1 = f3 * 0.5 - f2 + 2.0 / 3.0; + vec3 w2 = 1.0 - w0 - w1 - w3; + + vec3 s0 = w0 + w1; + vec3 s1 = w2 + w3; + + vec3 f0 = w1 / (w0 + w1); + vec3 f1 = w3 / (w2 + w3); + + vec2 final_z; + vec4 final_co; + final_co.xy = tc.xy - 1.0 + f0.xy; + final_co.zw = tc.xy + 1.0 + f1.xy; + final_z = tc.zz + vec2(-1.0, 1.0) + vec2(f0.z, f1.z); + + final_co /= tex_size.xyxy; + final_z /= tex_size.zz; + + vec4 color; + color = texture(ima, vec3(final_co.xy, final_z.x)) * s0.x * s0.y * s0.z; + color += texture(ima, vec3(final_co.zy, final_z.x)) * s1.x * s0.y * s0.z; + color += texture(ima, vec3(final_co.xw, final_z.x)) * s0.x * s1.y * s0.z; + color += texture(ima, vec3(final_co.zw, final_z.x)) * s1.x * s1.y * s0.z; + + color += texture(ima, vec3(final_co.xy, final_z.y)) * s0.x * s0.y * s1.z; + color += texture(ima, vec3(final_co.zy, final_z.y)) * s1.x * s0.y * s1.z; + color += texture(ima, vec3(final_co.xw, final_z.y)) * s0.x * s1.y * s1.z; + color += texture(ima, vec3(final_co.zw, final_z.y)) * s1.x * s1.y * s1.z; + + return color; } #ifdef USE_TRICUBIC @@ -123,127 +126,126 @@ vec4 sample_tricubic(sampler3D ima, vec3 co) void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction) { - vec3 co = ls_pos * 0.5 + 0.5; + vec3 co = ls_pos * 0.5 + 0.5; #ifdef USE_COBA - float val = sample_volume_texture(densityTexture, co).r; - vec4 tval = texture(transferTexture, val) * densityScale; - tval.rgb = pow(tval.rgb, vec3(2.2)); - scattering = tval.rgb * 1500.0; - extinction = max(1e-4, tval.a * 50.0); + float val = sample_volume_texture(densityTexture, co).r; + vec4 tval = texture(transferTexture, val) * densityScale; + tval.rgb = pow(tval.rgb, vec3(2.2)); + scattering = tval.rgb * 1500.0; + extinction = max(1e-4, tval.a * 50.0); #else - float flame = sample_volume_texture(flameTexture, co).r; - vec4 emission = texture(flameColorTexture, flame); - float shadows = sample_volume_texture(shadowTexture, co).r; - vec4 density = sample_volume_texture(densityTexture, co); /* rgb: color, a: density */ + float flame = sample_volume_texture(flameTexture, co).r; + vec4 emission = texture(flameColorTexture, flame); + float shadows = sample_volume_texture(shadowTexture, co).r; + vec4 density = sample_volume_texture(densityTexture, co); /* rgb: color, a: density */ - scattering = density.rgb * (density.a * densityScale) * activeColor; - extinction = max(1e-4, dot(scattering, vec3(0.33333))); + scattering = density.rgb * (density.a * densityScale) * activeColor; + extinction = max(1e-4, dot(scattering, vec3(0.33333))); - /* Scale shadows in log space and clamp them to avoid completely black shadows. */ - scattering *= exp(clamp(log(shadows) * densityScale * 0.1, -2.5, 0.0)) * M_PI; + /* Scale shadows in log space and clamp them to avoid completely black shadows. */ + scattering *= exp(clamp(log(shadows) * densityScale * 0.1, -2.5, 0.0)) * M_PI; - /* 800 is arbitrary and here to mimic old viewport. TODO make it a parameter */ - scattering += pow(emission.rgb, vec3(2.2)) * emission.a * 800.0; + /* 800 is arbitrary and here to mimic old viewport. TODO make it a parameter */ + scattering += pow(emission.rgb, vec3(2.2)) * emission.a * 800.0; #endif } void eval_volume_step(inout vec3 Lscat, float extinction, float step_len, out float Tr) { - Lscat *= phase_function_isotropic(); - /* Evaluate Scattering */ - Tr = exp(-extinction * step_len); - /* integrate along the current step segment */ - Lscat = (Lscat - Lscat * Tr) / extinction; + Lscat *= phase_function_isotropic(); + /* Evaluate Scattering */ + Tr = exp(-extinction * step_len); + /* integrate along the current step segment */ + Lscat = (Lscat - Lscat * Tr) / extinction; } #define P(x) ((x + 0.5) * (1.0 / 16.0)) -const vec4 dither_mat[4] = vec4[4]( - vec4( P(0.0), P(8.0), P(2.0), P(10.0)), - vec4(P(12.0), P(4.0), P(14.0), P(6.0)), - vec4( P(3.0), P(11.0), P(1.0), P(9.0)), - vec4(P(15.0), P(7.0), P(13.0), P(5.0)) -); - -vec4 volume_integration( - vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max, float step_len) +const vec4 dither_mat[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4(P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0))); + +vec4 volume_integration(vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max, float step_len) { - /* Start with full transmittance and no scattered light. */ - vec3 final_scattering = vec3(0.0); - float final_transmittance = 1.0; - - ivec2 tx = ivec2(gl_FragCoord.xy) % 4; - float noise = fract(dither_mat[tx.x][tx.y] + noiseOfs); - - float ray_len = noise * ray_inc; - for (int i = 0; i < samplesLen && ray_len < ray_max; ++i, ray_len += ray_inc) { - vec3 ls_pos = ray_ori + ray_dir * ray_len; - - vec3 Lscat; - float s_extinction, Tr; - volume_properties(ls_pos, Lscat, s_extinction); - eval_volume_step(Lscat, s_extinction, step_len, Tr); - /* accumulate and also take into account the transmittance from previous steps */ - final_scattering += final_transmittance * Lscat; - final_transmittance *= Tr; - } - - return vec4(final_scattering, final_transmittance); + /* Start with full transmittance and no scattered light. */ + vec3 final_scattering = vec3(0.0); + float final_transmittance = 1.0; + + ivec2 tx = ivec2(gl_FragCoord.xy) % 4; + float noise = fract(dither_mat[tx.x][tx.y] + noiseOfs); + + float ray_len = noise * ray_inc; + for (int i = 0; i < samplesLen && ray_len < ray_max; ++i, ray_len += ray_inc) { + vec3 ls_pos = ray_ori + ray_dir * ray_len; + + vec3 Lscat; + float s_extinction, Tr; + volume_properties(ls_pos, Lscat, s_extinction); + eval_volume_step(Lscat, s_extinction, step_len, Tr); + /* accumulate and also take into account the transmittance from previous steps */ + final_scattering += final_transmittance * Lscat; + final_transmittance *= Tr; + } + + return vec4(final_scattering, final_transmittance); } void main() { #ifdef VOLUME_SLICE - /* Manual depth test. TODO remove. */ - float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; - if (gl_FragCoord.z >= depth) { - discard; - } - - vec3 Lscat; - float s_extinction, Tr; - volume_properties(localPos, Lscat, s_extinction); - eval_volume_step(Lscat, s_extinction, stepLength, Tr); - - fragColor = vec4(Lscat, Tr); + /* Manual depth test. TODO remove. */ + float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; + if (gl_FragCoord.z >= depth) { + discard; + } + + vec3 Lscat; + float s_extinction, Tr; + volume_properties(localPos, Lscat, s_extinction); + eval_volume_step(Lscat, s_extinction, stepLength, Tr); + + fragColor = vec4(Lscat, Tr); #else - vec2 screen_uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy); - bool is_persp = ProjectionMatrix[3][3] == 0.0; - - vec3 volume_center = ModelMatrix[3].xyz; - - float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; - float depth_end = min(depth, gl_FragCoord.z); - vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end); - vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0); - vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0); - vs_ray_dir /= abs(vs_ray_dir.z); - - vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0; - vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz; - vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz; - - ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0; - ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0; - - /* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */ - - float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir); - if (dist > 0.0) { - ls_ray_ori = ls_ray_dir * dist + ls_ray_ori; - } - - vec3 ls_vol_isect = ls_ray_end - ls_ray_ori; - if (dot(ls_ray_dir, ls_vol_isect) < 0.0) { - /* Start is further away than the end. - * That means no volume is intersected. */ - discard; - } - - fragColor = volume_integration(ls_ray_ori, ls_ray_dir, stepLength, - length(ls_vol_isect) / length(ls_ray_dir), - length(vs_ray_dir) * stepLength); + vec2 screen_uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy); + bool is_persp = ProjectionMatrix[3][3] == 0.0; + + vec3 volume_center = ModelMatrix[3].xyz; + + float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; + float depth_end = min(depth, gl_FragCoord.z); + vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end); + vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0); + vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0); + vs_ray_dir /= abs(vs_ray_dir.z); + + vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0; + vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz; + vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz; + + ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0; + ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0; + + /* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */ + + float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir); + if (dist > 0.0) { + ls_ray_ori = ls_ray_dir * dist + ls_ray_ori; + } + + vec3 ls_vol_isect = ls_ray_end - ls_ray_ori; + if (dot(ls_ray_dir, ls_vol_isect) < 0.0) { + /* Start is further away than the end. + * That means no volume is intersected. */ + discard; + } + + fragColor = volume_integration(ls_ray_ori, + ls_ray_dir, + stepLength, + length(ls_vol_isect) / length(ls_ray_dir), + length(vs_ray_dir) * stepLength); #endif - /* Convert transmitance to alpha so we can use premul blending. */ - fragColor.a = 1.0 - fragColor.a; + /* Convert transmitance to alpha so we can use premul blending. */ + fragColor.a = 1.0 - fragColor.a; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl index 7ce21c3d5ca..7a418243fd3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl @@ -15,19 +15,19 @@ out vec3 localPos; void main() { #ifdef VOLUME_SLICE - if (sliceAxis == 0) { - localPos = vec3(slicePosition * 2.0 - 1.0, pos.xy); - } - else if (sliceAxis == 1) { - localPos = vec3(pos.x, slicePosition * 2.0 - 1.0, pos.y); - } - else { - localPos = vec3(pos.xy, slicePosition * 2.0 - 1.0); - } - vec3 final_pos = localPos; + if (sliceAxis == 0) { + localPos = vec3(slicePosition * 2.0 - 1.0, pos.xy); + } + else if (sliceAxis == 1) { + localPos = vec3(pos.x, slicePosition * 2.0 - 1.0, pos.y); + } + else { + localPos = vec3(pos.xy, slicePosition * 2.0 - 1.0); + } + vec3 final_pos = localPos; #else - vec3 final_pos = pos; + vec3 final_pos = pos; #endif - final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1]; - gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 1.0); + final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1]; + gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 1.0); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index 8792c646ec1..690ce5d527f 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -2,113 +2,108 @@ /* [Drobot2014a] Low Level Optimizations for GCN */ vec4 fast_rcp(vec4 v) { - return intBitsToFloat(0x7eef370b - floatBitsToInt(v)); + return intBitsToFloat(0x7eef370b - floatBitsToInt(v)); } vec3 brdf_approx(vec3 spec_color, float roughness, float NV) { - /* Very rough own approx. We don't need it to be correct, just fast. - * Just simulate fresnel effect with roughness attenuation. */ - float fresnel = exp2(-8.35 * NV) * (1.0 - roughness); - return mix(spec_color, vec3(1.0), fresnel); + /* Very rough own approx. We don't need it to be correct, just fast. + * Just simulate fresnel effect with roughness attenuation. */ + float fresnel = exp2(-8.35 * NV) * (1.0 - roughness); + return mix(spec_color, vec3(1.0), fresnel); } void prep_specular( - vec3 L, vec3 I, vec3 N, vec3 R, - out float NL, out float wrapped_NL, out float spec_angle) + vec3 L, vec3 I, vec3 N, vec3 R, out float NL, out float wrapped_NL, out float spec_angle) { - wrapped_NL = dot(L, R); - vec3 half_dir = normalize(L + I); - spec_angle = clamp(dot(half_dir, N), 0.0, 1.0); - NL = clamp(dot(L, N), 0.0, 1.0); + wrapped_NL = dot(L, R); + vec3 half_dir = normalize(L + I); + spec_angle = clamp(dot(half_dir, N), 0.0, 1.0); + NL = clamp(dot(L, N), 0.0, 1.0); } /* Normalized Blinn shading */ vec4 blinn_specular(vec4 shininess, vec4 spec_angle, vec4 NL) { - /* Pi is already divided in the light power. - * normalization_factor = (shininess + 8.0) / (8.0 * M_PI) */ - vec4 normalization_factor = shininess * 0.125 + 1.0; - vec4 spec_light = pow(spec_angle, shininess) * NL * normalization_factor; + /* Pi is already divided in the light power. + * normalization_factor = (shininess + 8.0) / (8.0 * M_PI) */ + vec4 normalization_factor = shininess * 0.125 + 1.0; + vec4 spec_light = pow(spec_angle, shininess) * NL * normalization_factor; - return spec_light; + return spec_light; } /* NL need to be unclamped. w in [0..1] range. */ vec4 wrapped_lighting(vec4 NL, vec4 w) { - vec4 w_1 = w + 1.0; - vec4 denom = fast_rcp(w_1 * w_1); - return clamp((NL + w) * denom, 0.0, 1.0); + vec4 w_1 = w + 1.0; + vec4 denom = fast_rcp(w_1 * w_1); + return clamp((NL + w) * denom, 0.0, 1.0); } vec3 get_world_lighting( - WorldData world_data, - vec3 diffuse_color, vec3 specular_color, float roughness, - vec3 N, vec3 I) + WorldData world_data, vec3 diffuse_color, vec3 specular_color, float roughness, vec3 N, vec3 I) { - vec3 specular_light = world_data.ambient_color.rgb; - vec3 diffuse_light = world_data.ambient_color.rgb; - vec4 wrap = vec4( - world_data.lights[0].diffuse_color_wrap.a, - world_data.lights[1].diffuse_color_wrap.a, - world_data.lights[2].diffuse_color_wrap.a, - world_data.lights[3].diffuse_color_wrap.a - ); + vec3 specular_light = world_data.ambient_color.rgb; + vec3 diffuse_light = world_data.ambient_color.rgb; + vec4 wrap = vec4(world_data.lights[0].diffuse_color_wrap.a, + world_data.lights[1].diffuse_color_wrap.a, + world_data.lights[2].diffuse_color_wrap.a, + world_data.lights[3].diffuse_color_wrap.a); #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - /* Prepare Specular computation. Eval 4 lights at once. */ - vec3 R = -reflect(I, N); - vec4 spec_angle, spec_NL, wrap_NL; - prep_specular(world_data.lights[0].direction.xyz, I, N, R, spec_NL.x, wrap_NL.x, spec_angle.x); - prep_specular(world_data.lights[1].direction.xyz, I, N, R, spec_NL.y, wrap_NL.y, spec_angle.y); - prep_specular(world_data.lights[2].direction.xyz, I, N, R, spec_NL.z, wrap_NL.z, spec_angle.z); - prep_specular(world_data.lights[3].direction.xyz, I, N, R, spec_NL.w, wrap_NL.w, spec_angle.w); - - vec4 gloss = vec4(1.0 - roughness); - /* Reduce gloss for smooth light. (simulate bigger light) */ - gloss *= 1.0 - wrap; - vec4 shininess = exp2(10.0 * gloss + 1.0); - - vec4 spec_light = blinn_specular(shininess, spec_angle, spec_NL); - - /* Simulate Env. light. */ - vec4 w = mix(wrap, vec4(1.0), roughness); - vec4 spec_env = wrapped_lighting(wrap_NL, w); - - spec_light = mix(spec_light, spec_env, wrap * wrap); - - /* Multiply result by lights specular colors. */ - specular_light += spec_light.x * world_data.lights[0].specular_color.rgb; - specular_light += spec_light.y * world_data.lights[1].specular_color.rgb; - specular_light += spec_light.z * world_data.lights[2].specular_color.rgb; - specular_light += spec_light.w * world_data.lights[3].specular_color.rgb; - - float NV = clamp(dot(N, I), 0.0, 1.0); - specular_color = brdf_approx(specular_color, roughness, NV); + /* Prepare Specular computation. Eval 4 lights at once. */ + vec3 R = -reflect(I, N); + vec4 spec_angle, spec_NL, wrap_NL; + prep_specular(world_data.lights[0].direction.xyz, I, N, R, spec_NL.x, wrap_NL.x, spec_angle.x); + prep_specular(world_data.lights[1].direction.xyz, I, N, R, spec_NL.y, wrap_NL.y, spec_angle.y); + prep_specular(world_data.lights[2].direction.xyz, I, N, R, spec_NL.z, wrap_NL.z, spec_angle.z); + prep_specular(world_data.lights[3].direction.xyz, I, N, R, spec_NL.w, wrap_NL.w, spec_angle.w); + + vec4 gloss = vec4(1.0 - roughness); + /* Reduce gloss for smooth light. (simulate bigger light) */ + gloss *= 1.0 - wrap; + vec4 shininess = exp2(10.0 * gloss + 1.0); + + vec4 spec_light = blinn_specular(shininess, spec_angle, spec_NL); + + /* Simulate Env. light. */ + vec4 w = mix(wrap, vec4(1.0), roughness); + vec4 spec_env = wrapped_lighting(wrap_NL, w); + + spec_light = mix(spec_light, spec_env, wrap * wrap); + + /* Multiply result by lights specular colors. */ + specular_light += spec_light.x * world_data.lights[0].specular_color.rgb; + specular_light += spec_light.y * world_data.lights[1].specular_color.rgb; + specular_light += spec_light.z * world_data.lights[2].specular_color.rgb; + specular_light += spec_light.w * world_data.lights[3].specular_color.rgb; + + float NV = clamp(dot(N, I), 0.0, 1.0); + specular_color = brdf_approx(specular_color, roughness, NV); #endif - specular_light *= specular_color; + specular_light *= specular_color; - /* Prepare diffuse computation. Eval 4 lights at once. */ - vec4 diff_NL; - diff_NL.x = dot(world_data.lights[0].direction.xyz, N); - diff_NL.y = dot(world_data.lights[1].direction.xyz, N); - diff_NL.z = dot(world_data.lights[2].direction.xyz, N); - diff_NL.w = dot(world_data.lights[3].direction.xyz, N); + /* Prepare diffuse computation. Eval 4 lights at once. */ + vec4 diff_NL; + diff_NL.x = dot(world_data.lights[0].direction.xyz, N); + diff_NL.y = dot(world_data.lights[1].direction.xyz, N); + diff_NL.z = dot(world_data.lights[2].direction.xyz, N); + diff_NL.w = dot(world_data.lights[3].direction.xyz, N); - vec4 diff_light = wrapped_lighting(diff_NL, wrap); + vec4 diff_light = wrapped_lighting(diff_NL, wrap); - /* Multiply result by lights diffuse colors. */ - diffuse_light += diff_light.x * world_data.lights[0].diffuse_color_wrap.rgb; - diffuse_light += diff_light.y * world_data.lights[1].diffuse_color_wrap.rgb; - diffuse_light += diff_light.z * world_data.lights[2].diffuse_color_wrap.rgb; - diffuse_light += diff_light.w * world_data.lights[3].diffuse_color_wrap.rgb; + /* Multiply result by lights diffuse colors. */ + diffuse_light += diff_light.x * world_data.lights[0].diffuse_color_wrap.rgb; + diffuse_light += diff_light.y * world_data.lights[1].diffuse_color_wrap.rgb; + diffuse_light += diff_light.z * world_data.lights[2].diffuse_color_wrap.rgb; + diffuse_light += diff_light.w * world_data.lights[3].diffuse_color_wrap.rgb; - /* Energy conservation with colored specular look strange. - * Limit this strangeness by using mono-chromatic specular intensity. */ - float spec_energy = dot(specular_color, vec3(0.33333)); + /* Energy conservation with colored specular look strange. + * Limit this strangeness by using mono-chromatic specular intensity. */ + float spec_energy = dot(specular_color, vec3(0.33333)); - diffuse_light *= diffuse_color * (1.0 - spec_energy); + diffuse_light *= diffuse_color * (1.0 - spec_energy); - return diffuse_light + specular_light; + return diffuse_light + specular_light; } |