Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/draw/engines/workbench
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (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')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl74
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl167
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl34
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl190
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl51
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl30
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl39
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl80
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl426
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_fxaa_frag.glsl10
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl8
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl36
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_depth_frag.glsl12
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl69
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_ghost_resolve_frag.glsl12
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_object_outline_lib.glsl12
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl52
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl58
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl74
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_debug_frag.glsl11
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl116
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl18
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl330
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl26
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl149
-rw-r--r--source/blender/draw/engines/workbench/solid_mode.c79
-rw-r--r--source/blender/draw/engines/workbench/transparent_mode.c57
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c383
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c2066
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_aa.c131
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c683
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_fxaa.c30
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_taa.c486
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c21
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c1141
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c442
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h516
-rw-r--r--source/blender/draw/engines/workbench/workbench_render.c288
-rw-r--r--source/blender/draw/engines/workbench/workbench_studiolight.c498
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c323
41 files changed, 4738 insertions, 4496 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;
}
diff --git a/source/blender/draw/engines/workbench/solid_mode.c b/source/blender/draw/engines/workbench/solid_mode.c
index 4e69788457a..a01b14f17fb 100644
--- a/source/blender/draw/engines/workbench/solid_mode.c
+++ b/source/blender/draw/engines/workbench/solid_mode.c
@@ -35,78 +35,83 @@
static void workbench_solid_engine_init(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_deferred_engine_init(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_deferred_engine_init(data);
}
static void workbench_solid_cache_init(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_deferred_cache_init(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_deferred_cache_init(data);
}
static void workbench_solid_cache_populate(void *vedata, Object *ob)
{
- WORKBENCH_Data *data = vedata;
- workbench_deferred_solid_cache_populate(data, ob);
+ WORKBENCH_Data *data = vedata;
+ workbench_deferred_solid_cache_populate(data, ob);
}
static void workbench_solid_cache_finish(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_deferred_cache_finish(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_deferred_cache_finish(data);
}
static void workbench_solid_draw_background(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_deferred_draw_background(data);
- workbench_deferred_draw_scene(data);
- workbench_deferred_draw_finish(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_deferred_draw_background(data);
+ workbench_deferred_draw_scene(data);
+ workbench_deferred_draw_finish(data);
}
static void workbench_solid_engine_free(void)
{
- workbench_deferred_engine_free();
+ workbench_deferred_engine_free();
}
static void workbench_solid_view_update(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_taa_view_updated(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_taa_view_updated(data);
}
static void workbench_solid_id_update(void *UNUSED(vedata), struct ID *id)
{
- if (GS(id->name) == ID_OB) {
- WORKBENCH_ObjectData *oed = (WORKBENCH_ObjectData *)DRW_drawdata_get(id, &draw_engine_workbench_solid);
- if (oed != NULL && oed->dd.recalc != 0) {
- oed->shadow_bbox_dirty = (oed->dd.recalc & ID_RECALC_ALL) != 0;
- oed->dd.recalc = 0;
- }
- }
+ if (GS(id->name) == ID_OB) {
+ WORKBENCH_ObjectData *oed = (WORKBENCH_ObjectData *)DRW_drawdata_get(
+ id, &draw_engine_workbench_solid);
+ if (oed != NULL && oed->dd.recalc != 0) {
+ oed->shadow_bbox_dirty = (oed->dd.recalc & ID_RECALC_ALL) != 0;
+ oed->dd.recalc = 0;
+ }
+ }
}
-static void workbench_render_to_image(void *vedata, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
+static void workbench_render_to_image(void *vedata,
+ RenderEngine *engine,
+ RenderLayer *render_layer,
+ const rcti *rect)
{
- workbench_render(vedata, engine, render_layer, rect);
+ workbench_render(vedata, engine, render_layer, rect);
}
static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data);
DrawEngineType draw_engine_workbench_solid = {
- NULL, NULL,
- N_("Workbench"),
- &workbench_data_size,
- &workbench_solid_engine_init,
- &workbench_solid_engine_free,
- &workbench_solid_cache_init,
- &workbench_solid_cache_populate,
- &workbench_solid_cache_finish,
- &workbench_solid_draw_background,
- NULL,
- &workbench_solid_view_update,
- &workbench_solid_id_update,
- &workbench_render_to_image,
+ NULL,
+ NULL,
+ N_("Workbench"),
+ &workbench_data_size,
+ &workbench_solid_engine_init,
+ &workbench_solid_engine_free,
+ &workbench_solid_cache_init,
+ &workbench_solid_cache_populate,
+ &workbench_solid_cache_finish,
+ &workbench_solid_draw_background,
+ NULL,
+ &workbench_solid_view_update,
+ &workbench_solid_id_update,
+ &workbench_render_to_image,
};
diff --git a/source/blender/draw/engines/workbench/transparent_mode.c b/source/blender/draw/engines/workbench/transparent_mode.c
index c3b118d4660..0f4150ff986 100644
--- a/source/blender/draw/engines/workbench/transparent_mode.c
+++ b/source/blender/draw/engines/workbench/transparent_mode.c
@@ -33,62 +33,63 @@
static void workbench_transparent_engine_init(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_forward_engine_init(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_forward_engine_init(data);
}
static void workbench_transparent_cache_init(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_forward_cache_init(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_forward_cache_init(data);
}
static void workbench_transparent_cache_populate(void *vedata, Object *ob)
{
- WORKBENCH_Data *data = vedata;
- workbench_forward_cache_populate(data, ob);
+ WORKBENCH_Data *data = vedata;
+ workbench_forward_cache_populate(data, ob);
}
static void workbench_transparent_cache_finish(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_forward_cache_finish(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_forward_cache_finish(data);
}
static void workbench_transparent_draw_background(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_forward_draw_background(data);
- workbench_forward_draw_scene(data);
- workbench_forward_draw_finish(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_forward_draw_background(data);
+ workbench_forward_draw_scene(data);
+ workbench_forward_draw_finish(data);
}
static void workbench_transparent_engine_free(void)
{
- workbench_forward_engine_free();
+ workbench_forward_engine_free();
}
static void workbench_transparent_view_update(void *vedata)
{
- WORKBENCH_Data *data = vedata;
- workbench_taa_view_updated(data);
+ WORKBENCH_Data *data = vedata;
+ workbench_taa_view_updated(data);
}
static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data);
DrawEngineType draw_engine_workbench_transparent = {
- NULL, NULL,
- N_("Workbench"),
- &workbench_data_size,
- &workbench_transparent_engine_init,
- &workbench_transparent_engine_free,
- &workbench_transparent_cache_init,
- &workbench_transparent_cache_populate,
- &workbench_transparent_cache_finish,
- &workbench_transparent_draw_background,
- NULL,
- &workbench_transparent_view_update,
- NULL,
- NULL,
+ NULL,
+ NULL,
+ N_("Workbench"),
+ &workbench_data_size,
+ &workbench_transparent_engine_init,
+ &workbench_transparent_engine_free,
+ &workbench_transparent_cache_init,
+ &workbench_transparent_cache_populate,
+ &workbench_transparent_cache_finish,
+ &workbench_transparent_draw_background,
+ NULL,
+ &workbench_transparent_view_update,
+ NULL,
+ NULL,
};
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 38b05133487..7728b3f998b 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -28,214 +28,209 @@
#include "GPU_batch.h"
-
void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info)
{
- effect_info->jitter_index = 0;
- effect_info->view_updated = true;
+ effect_info->jitter_index = 0;
+ effect_info->view_updated = true;
}
void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const Scene *scene = draw_ctx->scene;
- wpd->material_hash = BLI_ghash_ptr_new(__func__);
- wpd->material_transp_hash = BLI_ghash_ptr_new(__func__);
- wpd->preferences = &U;
-
- View3D *v3d = draw_ctx->v3d;
- if (!v3d) {
- wpd->shading = scene->display.shading;
- wpd->use_color_render_settings = true;
- }
- else if (v3d->shading.type == OB_RENDER &&
- BKE_scene_uses_blender_workbench(scene))
- {
- wpd->shading = scene->display.shading;
- wpd->use_color_render_settings = true;
- }
- else {
- wpd->shading = v3d->shading;
- wpd->use_color_render_settings = false;
- }
-
- wpd->use_color_management = BKE_scene_check_color_management_enabled(scene);
-
- if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
- wpd->studio_light = BKE_studiolight_find(
- wpd->shading.matcap, STUDIOLIGHT_TYPE_MATCAP);
- }
- else {
- wpd->studio_light = BKE_studiolight_find(
- wpd->shading.studio_light, STUDIOLIGHT_TYPE_STUDIO);
- }
-
- /* If matcaps are missing, use this as fallback. */
- if (UNLIKELY(wpd->studio_light == NULL)) {
- wpd->studio_light = BKE_studiolight_find(
- wpd->shading.studio_light, STUDIOLIGHT_TYPE_STUDIO);
- }
-
-
- float shadow_focus = scene->display.shadow_focus;
- /* Clamp to avoid overshadowing and shading errors. */
- CLAMP(shadow_focus, 0.0001f, 0.99999f);
- wpd->shadow_shift = scene->display.shadow_shift;
- wpd->shadow_focus = 1.0f - shadow_focus * (1.0f - wpd->shadow_shift);
- wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
-
- WORKBENCH_UBO_World *wd = &wpd->world_data;
- wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0;
- wd->background_alpha = (DRW_state_is_image_render() && scene->r.alphamode == R_ALPHAPREMUL) ? 0.0f : 1.0f;
-
- if ((scene->world != NULL) &&
- (!v3d || (v3d && ((v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) ||
- (v3d->shading.type == OB_RENDER)))))
- {
- copy_v3_v3(wd->background_color_low, &scene->world->horr);
- copy_v3_v3(wd->background_color_high, &scene->world->horr);
- }
- else if (v3d && (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT)) {
- copy_v3_v3(wd->background_color_low, v3d->shading.background_color);
- copy_v3_v3(wd->background_color_high, v3d->shading.background_color);
- }
- else if (v3d) {
- UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK, wd->background_color_low);
- UI_GetThemeColor3fv(TH_BACK, wd->background_color_high);
-
- /* XXX: Really quick conversion to avoid washed out background.
- * Needs to be addressed properly (color managed using ocio). */
- if (wpd->use_color_management) {
- srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
- srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
- }
- else {
- copy_v3_v3(wd->background_color_high, wd->background_color_high);
- copy_v3_v3(wd->background_color_low, wd->background_color_low);
- }
- }
- else {
- zero_v3(wd->background_color_low);
- zero_v3(wd->background_color_high);
- }
-
- studiolight_update_world(wpd, wpd->studio_light, wd);
-
- copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color);
- wd->object_outline_color[3] = 1.0f;
-
- wd->curvature_ridge = 0.5f / max_ff(SQUARE(wpd->shading.curvature_ridge_factor), 1e-4f);
- wd->curvature_valley = 0.7f / max_ff(SQUARE(wpd->shading.curvature_valley_factor), 1e-4f);
-
- /* Will be NULL when rendering. */
- if (draw_ctx->rv3d != NULL) {
- RegionView3D *rv3d = draw_ctx->rv3d;
- if (rv3d->rflag & RV3D_CLIPPING) {
- wpd->world_clip_planes = rv3d->clip;
- DRW_state_clip_planes_set_from_rv3d(rv3d);
- UI_GetThemeColor4fv(TH_V3D_CLIPPING_BORDER, wpd->world_clip_planes_color);
- if (wpd->use_color_management) {
- srgb_to_linearrgb_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color);
- }
- else {
- copy_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color);
- }
- }
- else {
- wpd->world_clip_planes = NULL;
- }
- }
-
- wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
-
- /* Cavity settings */
- {
- const int ssao_samples = scene->display.matcap_ssao_samples;
-
- float invproj[4][4];
- const bool is_persp = DRW_viewport_is_persp_get();
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float viewvecs[3][4] = {
- {-1.0f, -1.0f, -1.0f, 1.0f},
- {1.0f, -1.0f, -1.0f, 1.0f},
- {-1.0f, 1.0f, -1.0f, 1.0f},
- };
- int i;
- const float *size = DRW_viewport_size_get();
-
- wpd->ssao_params[0] = ssao_samples;
- wpd->ssao_params[1] = size[0] / 64.0;
- wpd->ssao_params[2] = size[1] / 64.0;
- wpd->ssao_params[3] = 0;
-
- /* distance, factor, factor, attenuation */
- copy_v4_fl4(
- wpd->ssao_settings,
- scene->display.matcap_ssao_distance,
- wpd->shading.cavity_valley_factor,
- wpd->shading.cavity_ridge_factor,
- scene->display.matcap_ssao_attenuation);
-
- /* invert the view matrix */
- DRW_viewport_matrix_get(wpd->winmat, DRW_MAT_WIN);
- invert_m4_m4(invproj, wpd->winmat);
-
- /* convert the view vectors to view space */
- for (i = 0; i < 3; i++) {
- mul_m4_v4(invproj, viewvecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
- if (is_persp) {
- mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
- }
- viewvecs[i][3] = 1.0;
-
- copy_v4_v4(wpd->viewvecs[i], viewvecs[i]);
- }
-
- /* we need to store the differences */
- wpd->viewvecs[1][0] -= wpd->viewvecs[0][0];
- wpd->viewvecs[1][1] = wpd->viewvecs[2][1] - wpd->viewvecs[0][1];
-
- /* calculate a depth offset as well */
- if (!is_persp) {
- float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
- mul_m4_v4(invproj, vec_far);
- mul_v3_fl(vec_far, 1.0f / vec_far[3]);
- wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2];
- }
- }
-
- wpd->volumes_do = false;
- BLI_listbase_clear(&wpd->smoke_domains);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene = draw_ctx->scene;
+ wpd->material_hash = BLI_ghash_ptr_new(__func__);
+ wpd->material_transp_hash = BLI_ghash_ptr_new(__func__);
+ wpd->preferences = &U;
+
+ View3D *v3d = draw_ctx->v3d;
+ if (!v3d) {
+ wpd->shading = scene->display.shading;
+ wpd->use_color_render_settings = true;
+ }
+ else if (v3d->shading.type == OB_RENDER && BKE_scene_uses_blender_workbench(scene)) {
+ wpd->shading = scene->display.shading;
+ wpd->use_color_render_settings = true;
+ }
+ else {
+ wpd->shading = v3d->shading;
+ wpd->use_color_render_settings = false;
+ }
+
+ wpd->use_color_management = BKE_scene_check_color_management_enabled(scene);
+
+ if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
+ wpd->studio_light = BKE_studiolight_find(wpd->shading.matcap, STUDIOLIGHT_TYPE_MATCAP);
+ }
+ else {
+ wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, STUDIOLIGHT_TYPE_STUDIO);
+ }
+
+ /* If matcaps are missing, use this as fallback. */
+ if (UNLIKELY(wpd->studio_light == NULL)) {
+ wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, STUDIOLIGHT_TYPE_STUDIO);
+ }
+
+ float shadow_focus = scene->display.shadow_focus;
+ /* Clamp to avoid overshadowing and shading errors. */
+ CLAMP(shadow_focus, 0.0001f, 0.99999f);
+ wpd->shadow_shift = scene->display.shadow_shift;
+ wpd->shadow_focus = 1.0f - shadow_focus * (1.0f - wpd->shadow_shift);
+ wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
+
+ WORKBENCH_UBO_World *wd = &wpd->world_data;
+ wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0;
+ wd->background_alpha = (DRW_state_is_image_render() && scene->r.alphamode == R_ALPHAPREMUL) ?
+ 0.0f :
+ 1.0f;
+
+ if ((scene->world != NULL) &&
+ (!v3d || (v3d && ((v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) ||
+ (v3d->shading.type == OB_RENDER))))) {
+ copy_v3_v3(wd->background_color_low, &scene->world->horr);
+ copy_v3_v3(wd->background_color_high, &scene->world->horr);
+ }
+ else if (v3d && (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT)) {
+ copy_v3_v3(wd->background_color_low, v3d->shading.background_color);
+ copy_v3_v3(wd->background_color_high, v3d->shading.background_color);
+ }
+ else if (v3d) {
+ UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK,
+ wd->background_color_low);
+ UI_GetThemeColor3fv(TH_BACK, wd->background_color_high);
+
+ /* XXX: Really quick conversion to avoid washed out background.
+ * Needs to be addressed properly (color managed using ocio). */
+ if (wpd->use_color_management) {
+ srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
+ srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
+ }
+ else {
+ copy_v3_v3(wd->background_color_high, wd->background_color_high);
+ copy_v3_v3(wd->background_color_low, wd->background_color_low);
+ }
+ }
+ else {
+ zero_v3(wd->background_color_low);
+ zero_v3(wd->background_color_high);
+ }
+
+ studiolight_update_world(wpd, wpd->studio_light, wd);
+
+ copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color);
+ wd->object_outline_color[3] = 1.0f;
+
+ wd->curvature_ridge = 0.5f / max_ff(SQUARE(wpd->shading.curvature_ridge_factor), 1e-4f);
+ wd->curvature_valley = 0.7f / max_ff(SQUARE(wpd->shading.curvature_valley_factor), 1e-4f);
+
+ /* Will be NULL when rendering. */
+ if (draw_ctx->rv3d != NULL) {
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ wpd->world_clip_planes = rv3d->clip;
+ DRW_state_clip_planes_set_from_rv3d(rv3d);
+ UI_GetThemeColor4fv(TH_V3D_CLIPPING_BORDER, wpd->world_clip_planes_color);
+ if (wpd->use_color_management) {
+ srgb_to_linearrgb_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color);
+ }
+ else {
+ copy_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color);
+ }
+ }
+ else {
+ wpd->world_clip_planes = NULL;
+ }
+ }
+
+ wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
+
+ /* Cavity settings */
+ {
+ const int ssao_samples = scene->display.matcap_ssao_samples;
+
+ float invproj[4][4];
+ const bool is_persp = DRW_viewport_is_persp_get();
+ /* view vectors for the corners of the view frustum.
+ * Can be used to recreate the world space position easily */
+ float viewvecs[3][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f},
+ };
+ int i;
+ const float *size = DRW_viewport_size_get();
+
+ wpd->ssao_params[0] = ssao_samples;
+ wpd->ssao_params[1] = size[0] / 64.0;
+ wpd->ssao_params[2] = size[1] / 64.0;
+ wpd->ssao_params[3] = 0;
+
+ /* distance, factor, factor, attenuation */
+ copy_v4_fl4(wpd->ssao_settings,
+ scene->display.matcap_ssao_distance,
+ wpd->shading.cavity_valley_factor,
+ wpd->shading.cavity_ridge_factor,
+ scene->display.matcap_ssao_attenuation);
+
+ /* invert the view matrix */
+ DRW_viewport_matrix_get(wpd->winmat, DRW_MAT_WIN);
+ invert_m4_m4(invproj, wpd->winmat);
+
+ /* convert the view vectors to view space */
+ for (i = 0; i < 3; i++) {
+ mul_m4_v4(invproj, viewvecs[i]);
+ /* normalized trick see:
+ * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
+ if (is_persp) {
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
+ }
+ viewvecs[i][3] = 1.0;
+
+ copy_v4_v4(wpd->viewvecs[i], viewvecs[i]);
+ }
+
+ /* we need to store the differences */
+ wpd->viewvecs[1][0] -= wpd->viewvecs[0][0];
+ wpd->viewvecs[1][1] = wpd->viewvecs[2][1] - wpd->viewvecs[0][1];
+
+ /* calculate a depth offset as well */
+ if (!is_persp) {
+ float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
+ mul_m4_v4(invproj, vec_far);
+ mul_v3_fl(vec_far, 1.0f / vec_far[3]);
+ wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2];
+ }
+ }
+
+ wpd->volumes_do = false;
+ BLI_listbase_clear(&wpd->smoke_domains);
}
-void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3])
+void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd,
+ float r_light_direction[3])
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- WORKBENCH_UBO_World *wd = &wpd->world_data;
- float view_matrix[4][4];
- DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ WORKBENCH_UBO_World *wd = &wpd->world_data;
+ float view_matrix[4][4];
+ DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
- copy_v3_v3(r_light_direction, scene->display.light_direction);
- SWAP(float, r_light_direction[2], r_light_direction[1]);
- r_light_direction[2] = -r_light_direction[2];
- r_light_direction[0] = -r_light_direction[0];
+ copy_v3_v3(r_light_direction, scene->display.light_direction);
+ SWAP(float, r_light_direction[2], r_light_direction[1]);
+ r_light_direction[2] = -r_light_direction[2];
+ r_light_direction[0] = -r_light_direction[0];
- /* Shadow direction. */
- mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, r_light_direction);
+ /* Shadow direction. */
+ mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, r_light_direction);
- DRW_uniformbuffer_update(wpd->world_ubo, wd);
+ DRW_uniformbuffer_update(wpd->world_ubo, wd);
}
void workbench_private_data_free(WORKBENCH_PrivateData *wpd)
{
- BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
- BLI_ghash_free(wpd->material_transp_hash, NULL, MEM_freeN);
- DRW_UBO_FREE_SAFE(wpd->world_ubo);
- DRW_UBO_FREE_SAFE(wpd->dof_ubo);
- GPU_BATCH_DISCARD_SAFE(wpd->world_clip_planes_batch);
+ BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
+ BLI_ghash_free(wpd->material_transp_hash, NULL, MEM_freeN);
+ DRW_UBO_FREE_SAFE(wpd->world_ubo);
+ DRW_UBO_FREE_SAFE(wpd->dof_ubo);
+ GPU_BATCH_DISCARD_SAFE(wpd->world_clip_planes_batch);
}
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 482d7178cb7..91f4f351c7b 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -22,7 +22,6 @@
#include "workbench_private.h"
-
#include "BLI_alloca.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
@@ -38,7 +37,6 @@
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
-
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "GPU_extensions.h"
@@ -54,41 +52,41 @@
#endif
typedef struct WORKBENCH_DEFERRED_Shaders {
- struct GPUShader *prepass_sh_cache[MAX_PREPASS_SHADERS];
+ struct GPUShader *prepass_sh_cache[MAX_PREPASS_SHADERS];
} WORKBENCH_DEFERRED_Shaders;
static struct {
- WORKBENCH_DEFERRED_Shaders sh_data[GPU_SHADER_CFG_LEN];
-
- struct GPUShader *composite_sh_cache[MAX_COMPOSITE_SHADERS];
- struct GPUShader *cavity_sh[MAX_CAVITY_SHADERS];
- struct GPUShader *background_sh[2];
- struct GPUShader *ghost_resolve_sh;
- struct GPUShader *shadow_fail_sh;
- struct GPUShader *shadow_fail_manifold_sh;
- struct GPUShader *shadow_pass_sh;
- struct GPUShader *shadow_pass_manifold_sh;
- struct GPUShader *shadow_caps_sh;
- struct GPUShader *shadow_caps_manifold_sh;
- struct GPUShader *oit_resolve_sh;
-
- /* TODO(fclem) move everything below to wpd and custom viewlayer data. */
- struct GPUTexture *oit_accum_tx; /* ref only, not alloced */
- struct GPUTexture *oit_revealage_tx; /* ref only, not alloced */
- struct GPUTexture *ghost_depth_tx; /* ref only, not alloced */
- struct GPUTexture *object_id_tx; /* ref only, not alloced */
- struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
- struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */
- struct GPUTexture *metallic_buffer_tx; /* ref only, not alloced */
- struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
- struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
-
- SceneDisplay display; /* world light direction for shadows */
- int next_object_id;
-
- struct GPUUniformBuffer *sampling_ubo;
- struct GPUTexture *jitter_tx;
- int cached_sample_num;
+ WORKBENCH_DEFERRED_Shaders sh_data[GPU_SHADER_CFG_LEN];
+
+ struct GPUShader *composite_sh_cache[MAX_COMPOSITE_SHADERS];
+ struct GPUShader *cavity_sh[MAX_CAVITY_SHADERS];
+ struct GPUShader *background_sh[2];
+ struct GPUShader *ghost_resolve_sh;
+ struct GPUShader *shadow_fail_sh;
+ struct GPUShader *shadow_fail_manifold_sh;
+ struct GPUShader *shadow_pass_sh;
+ struct GPUShader *shadow_pass_manifold_sh;
+ struct GPUShader *shadow_caps_sh;
+ struct GPUShader *shadow_caps_manifold_sh;
+ struct GPUShader *oit_resolve_sh;
+
+ /* TODO(fclem) move everything below to wpd and custom viewlayer data. */
+ struct GPUTexture *oit_accum_tx; /* ref only, not alloced */
+ struct GPUTexture *oit_revealage_tx; /* ref only, not alloced */
+ struct GPUTexture *ghost_depth_tx; /* ref only, not alloced */
+ struct GPUTexture *object_id_tx; /* ref only, not alloced */
+ struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *metallic_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
+
+ SceneDisplay display; /* world light direction for shadows */
+ int next_object_id;
+
+ struct GPUUniformBuffer *sampling_ubo;
+ struct GPUTexture *jitter_tx;
+ int cached_sample_num;
} e_data = {{{{NULL}}}};
/* Shaders */
@@ -119,947 +117,999 @@ extern char datatoc_gpu_shader_depth_only_frag_glsl[];
static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd)
{
- DynStr *ds = BLI_dynstr_new();
-
- BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
-
- if (!FLAT_ENABLED(wpd)) {
- BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
- }
- if (OBJECT_OUTLINE_ENABLED(wpd)) {
- BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl);
- }
- if (CURVATURE_ENABLED(wpd)) {
- BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
- }
-
- BLI_dynstr_append(ds, datatoc_workbench_deferred_composite_frag_glsl);
-
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
+
+ if (!FLAT_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
+ }
+ if (OBJECT_OUTLINE_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl);
+ }
+ if (CURVATURE_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
+ }
+
+ BLI_dynstr_append(ds, datatoc_workbench_deferred_composite_frag_glsl);
+
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static char *workbench_build_prepass_frag(void)
{
- DynStr *ds = BLI_dynstr_new();
+ DynStr *ds = BLI_dynstr_new();
- BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl);
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static char *workbench_build_prepass_vert(bool is_hair)
{
- DynStr *ds = BLI_dynstr_new();
- if (is_hair) {
- BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
- }
- BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ DynStr *ds = BLI_dynstr_new();
+ if (is_hair) {
+ BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
+ }
+ BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static char *workbench_build_cavity_frag(bool cavity, bool curvature, bool high_dpi)
{
- DynStr *ds = BLI_dynstr_new();
-
- if (cavity) {
- BLI_dynstr_append(ds, "#define USE_CAVITY\n");
- }
- if (curvature) {
- BLI_dynstr_append(ds, "#define USE_CURVATURE\n");
- }
- if (high_dpi) {
- BLI_dynstr_append(ds, "#define CURVATURE_OFFSET 2\n");
- }
- if (NORMAL_ENCODING_ENABLED()) {
- BLI_dynstr_append(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
- }
- BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_cavity_frag_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_cavity_lib_glsl);
-
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ DynStr *ds = BLI_dynstr_new();
+
+ if (cavity) {
+ BLI_dynstr_append(ds, "#define USE_CAVITY\n");
+ }
+ if (curvature) {
+ BLI_dynstr_append(ds, "#define USE_CURVATURE\n");
+ }
+ if (high_dpi) {
+ BLI_dynstr_append(ds, "#define CURVATURE_OFFSET 2\n");
+ }
+ if (NORMAL_ENCODING_ENABLED()) {
+ BLI_dynstr_append(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
+ }
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_cavity_frag_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_cavity_lib_glsl);
+
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static GPUShader *workbench_cavity_shader_get(bool cavity, bool curvature)
{
- const bool high_dpi = (U.pixelsize > 1.5f);
- int index = 0;
- SET_FLAG_FROM_TEST(index, cavity, 1 << 0);
- SET_FLAG_FROM_TEST(index, curvature, 1 << 1);
- SET_FLAG_FROM_TEST(index, high_dpi, 1 << 2);
-
- GPUShader **sh = &e_data.cavity_sh[index];
- if (*sh == NULL) {
- char *cavity_frag = workbench_build_cavity_frag(cavity, curvature, high_dpi);
- *sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
- MEM_freeN(cavity_frag);
- }
- return *sh;
+ const bool high_dpi = (U.pixelsize > 1.5f);
+ int index = 0;
+ SET_FLAG_FROM_TEST(index, cavity, 1 << 0);
+ SET_FLAG_FROM_TEST(index, curvature, 1 << 1);
+ SET_FLAG_FROM_TEST(index, high_dpi, 1 << 2);
+
+ GPUShader **sh = &e_data.cavity_sh[index];
+ if (*sh == NULL) {
+ char *cavity_frag = workbench_build_cavity_frag(cavity, curvature, high_dpi);
+ *sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
+ MEM_freeN(cavity_frag);
+ }
+ return *sh;
}
-static GPUShader *ensure_deferred_prepass_shader(
- WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair, eGPUShaderConfig sh_cfg)
+static GPUShader *ensure_deferred_prepass_shader(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair,
+ eGPUShaderConfig sh_cfg)
{
- WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_cfg];
- int index = workbench_material_get_prepass_shader_index(wpd, use_textures, is_hair);
- if (sh_data->prepass_sh_cache[index] == NULL) {
- const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
- char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
- char *prepass_vert = workbench_build_prepass_vert(is_hair);
- char *prepass_frag = workbench_build_prepass_frag();
- sh_data->prepass_sh_cache[index] = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, prepass_vert, NULL},
- .frag = (const char *[]){prepass_frag, NULL},
- .defs = (const char *[]){sh_cfg_data->def, defines, NULL},
- });
- MEM_freeN(prepass_vert);
- MEM_freeN(prepass_frag);
- MEM_freeN(defines);
- }
- return sh_data->prepass_sh_cache[index];
+ WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_cfg];
+ int index = workbench_material_get_prepass_shader_index(wpd, use_textures, is_hair);
+ if (sh_data->prepass_sh_cache[index] == NULL) {
+ const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
+ char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
+ char *prepass_vert = workbench_build_prepass_vert(is_hair);
+ char *prepass_frag = workbench_build_prepass_frag();
+ sh_data->prepass_sh_cache[index] = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib, prepass_vert, NULL},
+ .frag = (const char *[]){prepass_frag, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, defines, NULL},
+ });
+ MEM_freeN(prepass_vert);
+ MEM_freeN(prepass_frag);
+ MEM_freeN(defines);
+ }
+ return sh_data->prepass_sh_cache[index];
}
static GPUShader *ensure_deferred_composite_shader(WORKBENCH_PrivateData *wpd)
{
- int index = workbench_material_get_composite_shader_index(wpd);
- if (e_data.composite_sh_cache[index] == NULL) {
- char *defines = workbench_material_build_defines(wpd, false, false);
- char *composite_frag = workbench_build_composite_frag(wpd);
- e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
- MEM_freeN(composite_frag);
- MEM_freeN(defines);
- }
- return e_data.composite_sh_cache[index];
+ int index = workbench_material_get_composite_shader_index(wpd);
+ if (e_data.composite_sh_cache[index] == NULL) {
+ char *defines = workbench_material_build_defines(wpd, false, false);
+ char *composite_frag = workbench_build_composite_frag(wpd);
+ e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
+ MEM_freeN(composite_frag);
+ MEM_freeN(defines);
+ }
+ return e_data.composite_sh_cache[index];
}
static GPUShader *ensure_background_shader(WORKBENCH_PrivateData *wpd)
{
- const int index = OBJECT_OUTLINE_ENABLED(wpd) ? 1 : 0;
- if (e_data.background_sh[index] == NULL) {
- const char *defines = (index) ? "#define V3D_SHADING_OBJECT_OUTLINE\n" : NULL;
- char *frag = BLI_string_joinN(
- datatoc_workbench_data_lib_glsl,
- datatoc_workbench_common_lib_glsl,
- datatoc_workbench_background_lib_glsl,
- datatoc_workbench_object_outline_lib_glsl,
- datatoc_workbench_deferred_background_frag_glsl);
- e_data.background_sh[index] = DRW_shader_create_fullscreen(frag, defines);
- MEM_freeN(frag);
- }
- return e_data.background_sh[index];
+ const int index = OBJECT_OUTLINE_ENABLED(wpd) ? 1 : 0;
+ if (e_data.background_sh[index] == NULL) {
+ const char *defines = (index) ? "#define V3D_SHADING_OBJECT_OUTLINE\n" : NULL;
+ char *frag = BLI_string_joinN(datatoc_workbench_data_lib_glsl,
+ datatoc_workbench_common_lib_glsl,
+ datatoc_workbench_background_lib_glsl,
+ datatoc_workbench_object_outline_lib_glsl,
+ datatoc_workbench_deferred_background_frag_glsl);
+ e_data.background_sh[index] = DRW_shader_create_fullscreen(frag, defines);
+ MEM_freeN(frag);
+ }
+ return e_data.background_sh[index];
}
static void select_deferred_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg)
{
- wpd->prepass_solid_sh = ensure_deferred_prepass_shader(wpd, false, false, sh_cfg);
- wpd->prepass_solid_hair_sh = ensure_deferred_prepass_shader(wpd, false, true, sh_cfg);
- wpd->prepass_texture_sh = ensure_deferred_prepass_shader(wpd, true, false, sh_cfg);
- wpd->prepass_texture_hair_sh = ensure_deferred_prepass_shader(wpd, true, true, sh_cfg);
- wpd->composite_sh = ensure_deferred_composite_shader(wpd);
- wpd->background_sh = ensure_background_shader(wpd);
+ wpd->prepass_solid_sh = ensure_deferred_prepass_shader(wpd, false, false, sh_cfg);
+ wpd->prepass_solid_hair_sh = ensure_deferred_prepass_shader(wpd, false, true, sh_cfg);
+ wpd->prepass_texture_sh = ensure_deferred_prepass_shader(wpd, true, false, sh_cfg);
+ wpd->prepass_texture_hair_sh = ensure_deferred_prepass_shader(wpd, true, true, sh_cfg);
+ wpd->composite_sh = ensure_deferred_composite_shader(wpd);
+ wpd->background_sh = ensure_background_shader(wpd);
}
/* Using Hammersley distribution */
static float *create_disk_samples(int num_samples, int num_iterations)
{
- /* vec4 to ensure memory alignment. */
- const int total_samples = num_samples * num_iterations;
- float(*texels)[4] = MEM_mallocN(sizeof(float[4]) * total_samples, __func__);
- const float num_samples_inv = 1.0f / num_samples;
-
- for (int i = 0; i < total_samples; i++) {
- float it_add = (i / num_samples) * 0.499f;
- float r = fmodf((i + 0.5f + it_add) * num_samples_inv, 1.0f);
- double dphi;
- BLI_hammersley_1d(i, &dphi);
-
- float phi = (float)dphi * 2.0f * M_PI + it_add;
- texels[i][0] = cosf(phi);
- texels[i][1] = sinf(phi);
- /* This deliberately distribute more samples
- * at the center of the disk (and thus the shadow). */
- texels[i][2] = r;
- }
-
- return (float *)texels;
+ /* vec4 to ensure memory alignment. */
+ const int total_samples = num_samples * num_iterations;
+ float(*texels)[4] = MEM_mallocN(sizeof(float[4]) * total_samples, __func__);
+ const float num_samples_inv = 1.0f / num_samples;
+
+ for (int i = 0; i < total_samples; i++) {
+ float it_add = (i / num_samples) * 0.499f;
+ float r = fmodf((i + 0.5f + it_add) * num_samples_inv, 1.0f);
+ double dphi;
+ BLI_hammersley_1d(i, &dphi);
+
+ float phi = (float)dphi * 2.0f * M_PI + it_add;
+ texels[i][0] = cosf(phi);
+ texels[i][1] = sinf(phi);
+ /* This deliberately distribute more samples
+ * at the center of the disk (and thus the shadow). */
+ texels[i][2] = r;
+ }
+
+ return (float *)texels;
}
static struct GPUTexture *create_jitter_texture(int num_samples)
{
- float jitter[64 * 64][4];
- const float num_samples_inv = 1.0f / num_samples;
-
- for (int i = 0; i < 64 * 64; i++) {
- float phi = blue_noise[i][0] * 2.0f * M_PI;
- /* This rotate the sample per pixels */
- jitter[i][0] = cosf(phi);
- jitter[i][1] = sinf(phi);
- /* This offset the sample along it's direction axis (reduce banding) */
- float bn = blue_noise[i][1] - 0.5f;
- CLAMP(bn, -0.499f, 0.499f); /* fix fireflies */
- jitter[i][2] = bn * num_samples_inv;
- jitter[i][3] = blue_noise[i][1];
- }
-
- UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx, ltc_disk_integral);
-
- return DRW_texture_create_2d(64, 64, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
+ float jitter[64 * 64][4];
+ const float num_samples_inv = 1.0f / num_samples;
+
+ for (int i = 0; i < 64 * 64; i++) {
+ float phi = blue_noise[i][0] * 2.0f * M_PI;
+ /* This rotate the sample per pixels */
+ jitter[i][0] = cosf(phi);
+ jitter[i][1] = sinf(phi);
+ /* This offset the sample along it's direction axis (reduce banding) */
+ float bn = blue_noise[i][1] - 0.5f;
+ CLAMP(bn, -0.499f, 0.499f); /* fix fireflies */
+ jitter[i][2] = bn * num_samples_inv;
+ jitter[i][3] = blue_noise[i][1];
+ }
+
+ UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx, ltc_disk_integral);
+
+ return DRW_texture_create_2d(64, 64, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
}
/* Functions */
-
static void workbench_init_object_data(DrawData *dd)
{
- WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
- data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
- data->shadow_bbox_dirty = true;
+ WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
+ data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
+ data->shadow_bbox_dirty = true;
}
-static void workbench_init_oit_framebuffer(WORKBENCH_FramebufferList *fbl, DefaultTextureList *dtxl)
+static void workbench_init_oit_framebuffer(WORKBENCH_FramebufferList *fbl,
+ DefaultTextureList *dtxl)
{
- const float *size = DRW_viewport_size_get();
- e_data.oit_accum_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
- e_data.oit_revealage_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_R16F, &draw_engine_workbench_solid);
-
- GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb, {
- GPU_ATTACHMENT_TEXTURE(dtxl->depth),
- GPU_ATTACHMENT_TEXTURE(e_data.oit_accum_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.oit_revealage_tx),
- });
+ const float *size = DRW_viewport_size_get();
+ e_data.oit_accum_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
+ e_data.oit_revealage_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_R16F, &draw_engine_workbench_solid);
+
+ GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(e_data.oit_accum_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.oit_revealage_tx),
+ });
}
void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
{
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- RegionView3D *rv3d = draw_ctx->rv3d;
- View3D *v3d = draw_ctx->v3d;
- Scene *scene = draw_ctx->scene;
- Object *camera;
-
- if (v3d && rv3d) {
- camera = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL;
- }
- else {
- camera = scene->camera;
- }
-
- if (!stl->g_data) {
- /* Alloc transient pointers */
- stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
- }
- if (!stl->effects) {
- stl->effects = MEM_callocN(sizeof(*stl->effects), __func__);
- workbench_effect_info_init(stl->effects);
- }
-
- if (!e_data.next_object_id) {
- WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
- memset(sh_data->prepass_sh_cache, 0, sizeof(sh_data->prepass_sh_cache));
- memset(e_data.composite_sh_cache, 0, sizeof(e_data.composite_sh_cache));
- e_data.next_object_id = 1;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ View3D *v3d = draw_ctx->v3d;
+ Scene *scene = draw_ctx->scene;
+ Object *camera;
+
+ if (v3d && rv3d) {
+ camera = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL;
+ }
+ else {
+ camera = scene->camera;
+ }
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
+ }
+ if (!stl->effects) {
+ stl->effects = MEM_callocN(sizeof(*stl->effects), __func__);
+ workbench_effect_info_init(stl->effects);
+ }
+
+ if (!e_data.next_object_id) {
+ WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ memset(sh_data->prepass_sh_cache, 0, sizeof(sh_data->prepass_sh_cache));
+ memset(e_data.composite_sh_cache, 0, sizeof(e_data.composite_sh_cache));
+ e_data.next_object_id = 1;
#ifdef DEBUG_SHADOW_VOLUME
- const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
+ const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
#else
- const char *shadow_frag = datatoc_gpu_shader_depth_only_frag_glsl;
+ const char *shadow_frag = datatoc_gpu_shader_depth_only_frag_glsl;
#endif
- /* TODO only compile on demand */
- e_data.shadow_pass_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_PASS\n"
- "#define DOUBLE_MANIFOLD\n");
- e_data.shadow_pass_manifold_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_PASS\n");
- e_data.shadow_fail_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n"
- "#define DOUBLE_MANIFOLD\n");
- e_data.shadow_fail_manifold_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n");
- e_data.shadow_caps_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_caps_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n"
- "#define DOUBLE_MANIFOLD\n");
- e_data.shadow_caps_manifold_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_caps_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n");
-
- e_data.ghost_resolve_sh = DRW_shader_create_fullscreen(datatoc_workbench_ghost_resolve_frag_glsl, NULL);
- }
- workbench_volume_engine_init();
- workbench_fxaa_engine_init();
- workbench_taa_engine_init(vedata);
-
- WORKBENCH_PrivateData *wpd = stl->g_data;
- workbench_private_data_init(wpd);
-
- workbench_dof_engine_init(vedata, camera);
-
- if (OIT_ENABLED(wpd)) {
- if (e_data.oit_resolve_sh == NULL) {
- e_data.oit_resolve_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_forward_composite_frag_glsl,
- "#define ALPHA_COMPOSITE\n");
- }
-
- workbench_forward_choose_shaders(wpd, draw_ctx->sh_cfg);
- workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
- }
-
- {
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
- const eGPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F;
- const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
- const eGPUTextureFormat col_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_RGBA8;
- const eGPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8;
-
- e_data.object_id_tx = NULL;
- e_data.color_buffer_tx = NULL;
- e_data.composite_buffer_tx = NULL;
- e_data.normal_buffer_tx = NULL;
- e_data.cavity_buffer_tx = NULL;
-
- e_data.composite_buffer_tx = DRW_texture_pool_query_2d(size[0], size[1], comp_tex_format, &draw_engine_workbench_solid);
-
- if (MATDATA_PASS_ENABLED(wpd) || GPU_unused_fb_slot_workaround()) {
- e_data.color_buffer_tx = DRW_texture_pool_query_2d(size[0], size[1], col_tex_format, &draw_engine_workbench_solid);
- }
- if (OBJECT_ID_PASS_ENABLED(wpd) || GPU_unused_fb_slot_workaround()) {
- e_data.object_id_tx = DRW_texture_pool_query_2d(size[0], size[1], id_tex_format, &draw_engine_workbench_solid);
- }
- if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
- e_data.normal_buffer_tx = DRW_texture_pool_query_2d(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid);
- }
- if (CAVITY_ENABLED(wpd)) {
- e_data.cavity_buffer_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_R16, &draw_engine_workbench_solid);
- }
-
- GPU_framebuffer_ensure_config(&fbl->prepass_fb, {
- GPU_ATTACHMENT_TEXTURE(dtxl->depth),
- GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->cavity_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.cavity_buffer_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->composite_fb, {
- GPU_ATTACHMENT_TEXTURE(dtxl->depth),
- GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->color_only_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
- });
-
- if (!MATDATA_PASS_ENABLED(wpd) && !GPU_unused_fb_slot_workaround()) {
- e_data.color_buffer_tx = DRW_texture_pool_query_2d(size[0], size[1], col_tex_format, &draw_engine_workbench_solid);
- }
-
- GPU_framebuffer_ensure_config(&fbl->effect_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
- });
-
- if (OBJECT_ID_PASS_ENABLED(wpd)) {
- GPU_framebuffer_ensure_config(&fbl->id_clear_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
- });
- }
- }
-
- {
- /* AO Samples Tex */
- int num_iterations = workbench_taa_calculate_num_iterations(vedata);
-
- const int ssao_samples_single_iteration = scene->display.matcap_ssao_samples;
- const int ssao_samples = MIN2(num_iterations * ssao_samples_single_iteration, 500);
-
- if (e_data.sampling_ubo && (e_data.cached_sample_num != ssao_samples)) {
- DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
- DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
- }
-
- if (e_data.sampling_ubo == NULL) {
- float *samples = create_disk_samples(ssao_samples_single_iteration, num_iterations);
- e_data.jitter_tx = create_jitter_texture(ssao_samples);
- e_data.sampling_ubo = DRW_uniformbuffer_create(sizeof(float[4]) * ssao_samples, samples);
- e_data.cached_sample_num = ssao_samples;
- MEM_freeN(samples);
- }
- }
-
- /* Prepass */
- {
- DRWShadingGroup *grp;
- const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
-
- int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
- psl->prepass_pass = DRW_pass_create("Prepass", (do_cull) ? state | DRW_STATE_CULL_BACK : state);
- psl->prepass_hair_pass = DRW_pass_create("Prepass", state);
-
- psl->ghost_prepass_pass = DRW_pass_create("Prepass Ghost", (do_cull) ? state | DRW_STATE_CULL_BACK : state);
- psl->ghost_prepass_hair_pass = DRW_pass_create("Prepass Ghost", state);
-
- psl->ghost_resolve_pass = DRW_pass_create("Resolve Ghost Depth", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
- grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.ghost_depth_tx);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
-
- {
- workbench_aa_create_pass(vedata, &e_data.color_buffer_tx);
- }
-
- {
- workbench_dof_create_pass(vedata, &e_data.composite_buffer_tx, e_data.jitter_tx);
- }
-
- if (CAVITY_ENABLED(wpd)) {
- int state = DRW_STATE_WRITE_COLOR;
- GPUShader *shader = workbench_cavity_shader_get(SSAO_ENABLED(wpd), CURVATURE_ENABLED(wpd));
- psl->cavity_pass = DRW_pass_create("Cavity", state);
- DRWShadingGroup *grp = DRW_shgroup_create(shader, psl->cavity_pass);
- DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
- DRW_shgroup_uniform_block(grp, "samples_block", e_data.sampling_ubo);
-
- if (SSAO_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- DRW_shgroup_uniform_vec4(grp, "ssao_params", wpd->ssao_params, 1);
- DRW_shgroup_uniform_vec4(grp, "ssao_settings", wpd->ssao_settings, 1);
- DRW_shgroup_uniform_mat4(grp, "WinMatrix", wpd->winmat);
- DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
- }
-
- if (CURVATURE_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
- DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1);
- }
-
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
+ /* TODO only compile on demand */
+ e_data.shadow_pass_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_PASS\n"
+ "#define DOUBLE_MANIFOLD\n");
+ e_data.shadow_pass_manifold_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_PASS\n");
+ e_data.shadow_fail_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n"
+ "#define DOUBLE_MANIFOLD\n");
+ e_data.shadow_fail_manifold_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n");
+ e_data.shadow_caps_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_caps_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n"
+ "#define DOUBLE_MANIFOLD\n");
+ e_data.shadow_caps_manifold_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_caps_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n");
+
+ e_data.ghost_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_ghost_resolve_frag_glsl, NULL);
+ }
+ workbench_volume_engine_init();
+ workbench_fxaa_engine_init();
+ workbench_taa_engine_init(vedata);
+
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ workbench_private_data_init(wpd);
+
+ workbench_dof_engine_init(vedata, camera);
+
+ if (OIT_ENABLED(wpd)) {
+ if (e_data.oit_resolve_sh == NULL) {
+ e_data.oit_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_forward_composite_frag_glsl, "#define ALPHA_COMPOSITE\n");
+ }
+
+ workbench_forward_choose_shaders(wpd, draw_ctx->sh_cfg);
+ workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
+ }
+
+ {
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+ const eGPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F;
+ const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F :
+ GPU_R11F_G11F_B10F;
+ const eGPUTextureFormat col_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_RGBA8;
+ const eGPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8;
+
+ e_data.object_id_tx = NULL;
+ e_data.color_buffer_tx = NULL;
+ e_data.composite_buffer_tx = NULL;
+ e_data.normal_buffer_tx = NULL;
+ e_data.cavity_buffer_tx = NULL;
+
+ e_data.composite_buffer_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], comp_tex_format, &draw_engine_workbench_solid);
+
+ if (MATDATA_PASS_ENABLED(wpd) || GPU_unused_fb_slot_workaround()) {
+ e_data.color_buffer_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], col_tex_format, &draw_engine_workbench_solid);
+ }
+ if (OBJECT_ID_PASS_ENABLED(wpd) || GPU_unused_fb_slot_workaround()) {
+ e_data.object_id_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], id_tex_format, &draw_engine_workbench_solid);
+ }
+ if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
+ e_data.normal_buffer_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], nor_tex_format, &draw_engine_workbench_solid);
+ }
+ if (CAVITY_ENABLED(wpd)) {
+ e_data.cavity_buffer_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_R16, &draw_engine_workbench_solid);
+ }
+
+ GPU_framebuffer_ensure_config(&fbl->prepass_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->cavity_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.cavity_buffer_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->composite_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->color_only_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
+ });
+
+ if (!MATDATA_PASS_ENABLED(wpd) && !GPU_unused_fb_slot_workaround()) {
+ e_data.color_buffer_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], col_tex_format, &draw_engine_workbench_solid);
+ }
+
+ GPU_framebuffer_ensure_config(&fbl->effect_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
+ });
+
+ if (OBJECT_ID_PASS_ENABLED(wpd)) {
+ GPU_framebuffer_ensure_config(&fbl->id_clear_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
+ });
+ }
+ }
+
+ {
+ /* AO Samples Tex */
+ int num_iterations = workbench_taa_calculate_num_iterations(vedata);
+
+ const int ssao_samples_single_iteration = scene->display.matcap_ssao_samples;
+ const int ssao_samples = MIN2(num_iterations * ssao_samples_single_iteration, 500);
+
+ if (e_data.sampling_ubo && (e_data.cached_sample_num != ssao_samples)) {
+ DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
+ DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
+ }
+
+ if (e_data.sampling_ubo == NULL) {
+ float *samples = create_disk_samples(ssao_samples_single_iteration, num_iterations);
+ e_data.jitter_tx = create_jitter_texture(ssao_samples);
+ e_data.sampling_ubo = DRW_uniformbuffer_create(sizeof(float[4]) * ssao_samples, samples);
+ e_data.cached_sample_num = ssao_samples;
+ MEM_freeN(samples);
+ }
+ }
+
+ /* Prepass */
+ {
+ DRWShadingGroup *grp;
+ const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
+
+ int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
+ psl->prepass_pass = DRW_pass_create("Prepass",
+ (do_cull) ? state | DRW_STATE_CULL_BACK : state);
+ psl->prepass_hair_pass = DRW_pass_create("Prepass", state);
+
+ psl->ghost_prepass_pass = DRW_pass_create("Prepass Ghost",
+ (do_cull) ? state | DRW_STATE_CULL_BACK : state);
+ psl->ghost_prepass_hair_pass = DRW_pass_create("Prepass Ghost", state);
+
+ psl->ghost_resolve_pass = DRW_pass_create("Resolve Ghost Depth",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
+ grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass);
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.ghost_depth_tx);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+
+ {
+ workbench_aa_create_pass(vedata, &e_data.color_buffer_tx);
+ }
+
+ {
+ workbench_dof_create_pass(vedata, &e_data.composite_buffer_tx, e_data.jitter_tx);
+ }
+
+ if (CAVITY_ENABLED(wpd)) {
+ int state = DRW_STATE_WRITE_COLOR;
+ GPUShader *shader = workbench_cavity_shader_get(SSAO_ENABLED(wpd), CURVATURE_ENABLED(wpd));
+ psl->cavity_pass = DRW_pass_create("Cavity", state);
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, psl->cavity_pass);
+ DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
+ DRW_shgroup_uniform_block(grp, "samples_block", e_data.sampling_ubo);
+
+ if (SSAO_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ DRW_shgroup_uniform_vec4(grp, "ssao_params", wpd->ssao_params, 1);
+ DRW_shgroup_uniform_vec4(grp, "ssao_settings", wpd->ssao_settings, 1);
+ DRW_shgroup_uniform_mat4(grp, "WinMatrix", wpd->winmat);
+ DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
+ }
+
+ if (CURVATURE_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
+ DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1);
+ }
+
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
}
static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl)
{
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
-
- e_data.ghost_depth_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_workbench_solid);
-
- GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb, {
- GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
- });
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+
+ e_data.ghost_depth_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_workbench_solid);
+
+ GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
+ });
}
void workbench_deferred_engine_free(void)
{
- for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
- WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_data_index];
- for (int index = 0; index < MAX_PREPASS_SHADERS; index++) {
- DRW_SHADER_FREE_SAFE(sh_data->prepass_sh_cache[index]);
- }
- }
- for (int index = 0; index < MAX_COMPOSITE_SHADERS; index++) {
- DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
- }
- for (int index = 0; index < MAX_CAVITY_SHADERS; ++index) {
- DRW_SHADER_FREE_SAFE(e_data.cavity_sh[index]);
- }
- DRW_SHADER_FREE_SAFE(e_data.ghost_resolve_sh);
- DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
- DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
- DRW_SHADER_FREE_SAFE(e_data.background_sh[0]);
- DRW_SHADER_FREE_SAFE(e_data.background_sh[1]);
-
- DRW_SHADER_FREE_SAFE(e_data.oit_resolve_sh);
-
- DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
- DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
- DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
- DRW_SHADER_FREE_SAFE(e_data.shadow_fail_manifold_sh);
- DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
- DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
-
- workbench_volume_engine_free();
- workbench_fxaa_engine_free();
- workbench_taa_engine_free();
- workbench_dof_engine_free();
+ for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
+ WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_data_index];
+ for (int index = 0; index < MAX_PREPASS_SHADERS; index++) {
+ DRW_SHADER_FREE_SAFE(sh_data->prepass_sh_cache[index]);
+ }
+ }
+ for (int index = 0; index < MAX_COMPOSITE_SHADERS; index++) {
+ DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
+ }
+ for (int index = 0; index < MAX_CAVITY_SHADERS; ++index) {
+ DRW_SHADER_FREE_SAFE(e_data.cavity_sh[index]);
+ }
+ DRW_SHADER_FREE_SAFE(e_data.ghost_resolve_sh);
+ DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
+ DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
+ DRW_SHADER_FREE_SAFE(e_data.background_sh[0]);
+ DRW_SHADER_FREE_SAFE(e_data.background_sh[1]);
+
+ DRW_SHADER_FREE_SAFE(e_data.oit_resolve_sh);
+
+ DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_fail_manifold_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
+
+ workbench_volume_engine_free();
+ workbench_fxaa_engine_free();
+ workbench_taa_engine_free();
+ workbench_dof_engine_free();
}
static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
{
- DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
- if (MATDATA_PASS_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "materialBuffer", &e_data.color_buffer_tx);
- }
- else {
- DRW_shgroup_uniform_vec3(grp, "materialSingleColor", wpd->shading.single_color, 1);
- }
- if (OBJECT_OUTLINE_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
- }
- if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
- }
- if (CAVITY_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "cavityBuffer", &e_data.cavity_buffer_tx);
- }
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
- DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- }
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- }
- if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
- BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
- DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture);
- }
+ DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
+ if (MATDATA_PASS_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "materialBuffer", &e_data.color_buffer_tx);
+ }
+ else {
+ DRW_shgroup_uniform_vec3(grp, "materialSingleColor", wpd->shading.single_color, 1);
+ }
+ if (OBJECT_OUTLINE_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
+ }
+ if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
+ }
+ if (CAVITY_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "cavityBuffer", &e_data.cavity_buffer_tx);
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ }
+ if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
+ BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture(
+ grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture);
+ }
}
void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- DRWShadingGroup *grp;
- const DRWContextState *draw_ctx = DRW_context_state_get();
-
- Scene *scene = draw_ctx->scene;
-
- workbench_volume_cache_init(vedata);
-
- select_deferred_shaders(wpd, draw_ctx->sh_cfg);
-
- /* Background Pass */
- {
- psl->background_pass = DRW_pass_create(
- "Background", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
- grp = DRW_shgroup_create(wpd->background_sh, psl->background_pass);
- DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- if (OBJECT_OUTLINE_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
- }
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
-
- if (draw_ctx->rv3d && (draw_ctx->rv3d->rflag & RV3D_CLIPPING) && draw_ctx->rv3d->clipbb) {
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
- grp = DRW_shgroup_create(shader, psl->background_pass);
- wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
- DRW_shgroup_call_add(grp, wpd->world_clip_planes_batch, NULL);
- DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
- }
- }
-
- /* Deferred Mix Pass */
- {
- workbench_private_data_get_light_direction(wpd, e_data.display.light_direction);
- studiolight_update_light(wpd, e_data.display.light_direction);
-
- if (SHADOW_ENABLED(wpd)) {
- psl->composite_pass = DRW_pass_create(
- "Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL | DRW_STATE_DEPTH_GREATER);
- grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
- workbench_composite_uniforms(wpd, grp);
- DRW_shgroup_stencil_mask(grp, 0x00);
- DRW_shgroup_uniform_float_copy(grp, "lightMultiplier", 1.0f);
- DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
- DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
- DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
-
- /* Stencil Shadow passes. */
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ DRWShadingGroup *grp;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ Scene *scene = draw_ctx->scene;
+
+ workbench_volume_cache_init(vedata);
+
+ select_deferred_shaders(wpd, draw_ctx->sh_cfg);
+
+ /* Background Pass */
+ {
+ psl->background_pass = DRW_pass_create("Background",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ grp = DRW_shgroup_create(wpd->background_sh, psl->background_pass);
+ DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ if (OBJECT_OUTLINE_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
+ }
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+
+ if (draw_ctx->rv3d && (draw_ctx->rv3d->rflag & RV3D_CLIPPING) && draw_ctx->rv3d->clipbb) {
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
+ grp = DRW_shgroup_create(shader, psl->background_pass);
+ wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
+ DRW_shgroup_call_add(grp, wpd->world_clip_planes_batch, NULL);
+ DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
+ }
+ }
+
+ /* Deferred Mix Pass */
+ {
+ workbench_private_data_get_light_direction(wpd, e_data.display.light_direction);
+ studiolight_update_light(wpd, e_data.display.light_direction);
+
+ if (SHADOW_ENABLED(wpd)) {
+ psl->composite_pass = DRW_pass_create(
+ "Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL | DRW_STATE_DEPTH_GREATER);
+ grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
+ workbench_composite_uniforms(wpd, grp);
+ DRW_shgroup_stencil_mask(grp, 0x00);
+ DRW_shgroup_uniform_float_copy(grp, "lightMultiplier", 1.0f);
+ DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
+ DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
+ DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+
+ /* Stencil Shadow passes. */
#ifdef DEBUG_SHADOW_VOLUME
- DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
- DRWState depth_fail_state = DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
+ DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR |
+ DRW_STATE_ADDITIVE;
+ DRWState depth_fail_state = DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR |
+ DRW_STATE_ADDITIVE;
#else
- DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS;
- DRWState depth_fail_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL;
+ DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS;
+ DRWState depth_fail_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL;
#endif
- psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Pass", depth_pass_state);
- psl->shadow_depth_pass_mani_pass = DRW_pass_create("Shadow Pass Mani", depth_pass_state);
- psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Fail", depth_fail_state);
- psl->shadow_depth_fail_mani_pass = DRW_pass_create("Shadow Fail Mani", depth_fail_state);
- psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Fail Caps", depth_fail_state);
- psl->shadow_depth_fail_caps_mani_pass = DRW_pass_create("Shadow Fail Caps Mani", depth_fail_state);
+ psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Pass", depth_pass_state);
+ psl->shadow_depth_pass_mani_pass = DRW_pass_create("Shadow Pass Mani", depth_pass_state);
+ psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Fail", depth_fail_state);
+ psl->shadow_depth_fail_mani_pass = DRW_pass_create("Shadow Fail Mani", depth_fail_state);
+ psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Fail Caps", depth_fail_state);
+ psl->shadow_depth_fail_caps_mani_pass = DRW_pass_create("Shadow Fail Caps Mani",
+ depth_fail_state);
#ifndef DEBUG_SHADOW_VOLUME
- grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
- grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
- grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
- grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
- grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
- grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
-
- psl->composite_shadow_pass = DRW_pass_create(
- "Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL | DRW_STATE_DEPTH_GREATER);
- grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
- DRW_shgroup_stencil_mask(grp, 0x00);
- workbench_composite_uniforms(wpd, grp);
- DRW_shgroup_uniform_float(grp, "lightMultiplier", &wpd->shadow_multiplier, 1);
- DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
- DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
- DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+ grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+ grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+ grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+ grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+ grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh,
+ psl->shadow_depth_fail_caps_mani_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+
+ psl->composite_shadow_pass = DRW_pass_create(
+ "Composite Shadow",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL | DRW_STATE_DEPTH_GREATER);
+ grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
+ DRW_shgroup_stencil_mask(grp, 0x00);
+ workbench_composite_uniforms(wpd, grp);
+ DRW_shgroup_uniform_float(grp, "lightMultiplier", &wpd->shadow_multiplier, 1);
+ DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
+ DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
+ DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
#endif
- }
- else {
- psl->composite_pass = DRW_pass_create(
- "Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER);
- grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
- workbench_composite_uniforms(wpd, grp);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
- }
-
- /**
- * Order Independant Transparency.
- * Similar to workbench forward. Duplicated code to avoid
- * spaghetti with workbench forward. It would be great if we unify
- * this in a clean way.
- */
- if (OIT_ENABLED(wpd)) {
- const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
- const int cull_state = (do_cull) ? DRW_STATE_CULL_BACK : 0;
- /* Transparency Accum */
- {
- /* Same as forward but here we use depth test to
- * not bleed through other solid objects. */
- int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT | DRW_STATE_DEPTH_LESS | cull_state;
- psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
- }
- /* Depth */
- {
- int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | cull_state;
- psl->object_outline_pass = DRW_pass_create("Transparent Depth", state);
- }
- /* OIT Composite */
- {
- int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
- psl->oit_composite_pass = DRW_pass_create("OIT Composite", state);
-
- grp = DRW_shgroup_create(e_data.oit_resolve_sh, psl->oit_composite_pass);
- DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.oit_accum_tx);
- DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.oit_revealage_tx);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
- }
+ }
+ else {
+ psl->composite_pass = DRW_pass_create("Composite",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER);
+ grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
+ workbench_composite_uniforms(wpd, grp);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ }
+
+ /**
+ * Order Independant Transparency.
+ * Similar to workbench forward. Duplicated code to avoid
+ * spaghetti with workbench forward. It would be great if we unify
+ * this in a clean way.
+ */
+ if (OIT_ENABLED(wpd)) {
+ const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
+ const int cull_state = (do_cull) ? DRW_STATE_CULL_BACK : 0;
+ /* Transparency Accum */
+ {
+ /* Same as forward but here we use depth test to
+ * not bleed through other solid objects. */
+ int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT | DRW_STATE_DEPTH_LESS | cull_state;
+ psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
+ }
+ /* Depth */
+ {
+ int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | cull_state;
+ psl->object_outline_pass = DRW_pass_create("Transparent Depth", state);
+ }
+ /* OIT Composite */
+ {
+ int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
+ psl->oit_composite_pass = DRW_pass_create("OIT Composite", state);
+
+ grp = DRW_shgroup_create(e_data.oit_resolve_sh, psl->oit_composite_pass);
+ DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.oit_accum_tx);
+ DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.oit_revealage_tx);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ }
}
-static WORKBENCH_MaterialData *get_or_create_material_data(
- WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, ImageUser *iuser, int color_type, int interp)
+static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedata,
+ Object *ob,
+ Material *mat,
+ Image *ima,
+ ImageUser *iuser,
+ int color_type,
+ int interp)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- WORKBENCH_MaterialData *material;
- WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
- &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
- WORKBENCH_MaterialData material_template;
- const bool is_ghost = (ob->dtx & OB_DRAWXRAY);
-
- /* Solid */
- workbench_material_update_data(wpd, ob, mat, &material_template);
- material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
- material_template.color_type = color_type;
- material_template.ima = ima;
- material_template.iuser = iuser;
- material_template.interp = interp;
- uint hash = workbench_material_get_hash(&material_template, is_ghost);
-
- material = BLI_ghash_lookup(wpd->material_hash, POINTER_FROM_UINT(hash));
- if (material == NULL) {
- material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
- material->shgrp = DRW_shgroup_create(
- (color_type == V3D_SHADING_TEXTURE_COLOR) ? wpd->prepass_texture_sh: wpd->prepass_solid_sh,
- (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_pass : psl->prepass_pass);
- workbench_material_copy(material, &material_template);
- DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
- DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1);
- workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true, interp);
- BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material);
- }
- return material;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_MaterialData *material;
+ WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
+ &ob->id,
+ &draw_engine_workbench_solid,
+ sizeof(WORKBENCH_ObjectData),
+ &workbench_init_object_data,
+ NULL);
+ WORKBENCH_MaterialData material_template;
+ const bool is_ghost = (ob->dtx & OB_DRAWXRAY);
+
+ /* Solid */
+ workbench_material_update_data(wpd, ob, mat, &material_template);
+ material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
+ material_template.color_type = color_type;
+ material_template.ima = ima;
+ material_template.iuser = iuser;
+ material_template.interp = interp;
+ uint hash = workbench_material_get_hash(&material_template, is_ghost);
+
+ material = BLI_ghash_lookup(wpd->material_hash, POINTER_FROM_UINT(hash));
+ if (material == NULL) {
+ material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
+ material->shgrp = DRW_shgroup_create(
+ (color_type == V3D_SHADING_TEXTURE_COLOR) ? wpd->prepass_texture_sh :
+ wpd->prepass_solid_sh,
+ (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_pass : psl->prepass_pass);
+ workbench_material_copy(material, &material_template);
+ DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
+ DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1);
+ workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true, interp);
+ BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material);
+ }
+ return material;
}
static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
-
- for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
- if (md->type != eModifierType_ParticleSystem) {
- continue;
- }
- ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
- if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
- continue;
- }
- ParticleSettings *part = psys->part;
- const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
-
- if (draw_as == PART_DRAW_PATH) {
- Material *mat;
- Image *image;
- ImageUser *iuser;
- int interp;
- workbench_material_get_image_and_mat(ob, part->omat, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
- WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, mat, image, iuser, color_type, interp);
-
- struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
- wpd->prepass_solid_hair_sh :
- wpd->prepass_texture_hair_sh;
- DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
- ob, psys, md,
- (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_hair_pass : psl->prepass_hair_pass,
- shader);
- DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
- DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
- workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true, interp);
- }
- }
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type != eModifierType_ParticleSystem) {
+ continue;
+ }
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+
+ if (draw_as == PART_DRAW_PATH) {
+ Material *mat;
+ Image *image;
+ ImageUser *iuser;
+ int interp;
+ workbench_material_get_image_and_mat(ob, part->omat, &image, &iuser, &interp, &mat);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ WORKBENCH_MaterialData *material = get_or_create_material_data(
+ vedata, ob, mat, image, iuser, color_type, interp);
+
+ struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
+ wpd->prepass_solid_hair_sh :
+ wpd->prepass_texture_hair_sh;
+ DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
+ ob,
+ psys,
+ md,
+ (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_hair_pass : psl->prepass_hair_pass,
+ shader);
+ DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
+ DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
+ workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true, interp);
+ }
+ }
}
void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
-
- if (!DRW_object_is_renderable(ob)) {
- return;
- }
-
- if (ob->type == OB_MESH) {
- workbench_cache_populate_particles(vedata, ob);
- }
-
- ModifierData *md;
- if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
- (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
- (modifier_isEnabled(scene, md, eModifierMode_Realtime)) &&
- (((SmokeModifierData *)md)->domain != NULL))
- {
- workbench_volume_cache_populate(vedata, scene, ob, md);
- return; /* Do not draw solid in this case. */
- }
-
- if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
- return;
- }
- if ((ob->dt < OB_SOLID) && !DRW_state_is_image_render()) {
- return;
- }
-
- WORKBENCH_MaterialData *material;
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
- const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
- const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
- const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
- const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
- bool has_transp_mat = false;
-
- if (!is_sculpt_mode && me && me->mloopuv && TEXTURE_DRAWING_ENABLED(wpd)) {
- /* Draw textured */
- struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
- for (int i = 0; i < materials_len; i++) {
- if (geom_array != NULL && geom_array[i] != NULL) {
- Material *mat;
- Image *image;
- ImageUser *iuser;
- int interp;
- workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
- if (color_type == V3D_SHADING_MATERIAL_COLOR && mat && mat->a < 1.0) {
- material = workbench_forward_get_or_create_material_data(vedata, ob, mat, image, iuser, color_type, 0);
- has_transp_mat = true;
- }
- else {
- material = get_or_create_material_data(vedata, ob, mat, image, iuser, color_type, interp);
- }
- DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
- }
- }
- }
- else if (ELEM(wpd->shading.color_type,
- V3D_SHADING_SINGLE_COLOR, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR))
- {
- if ((ob->color[3] < 1.0f) &&
- (wpd->shading.color_type == V3D_SHADING_OBJECT_COLOR))
- {
- /* Hack */
- wpd->shading.xray_alpha = ob->color[3];
- material = workbench_forward_get_or_create_material_data(vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
- has_transp_mat = true;
- }
- else {
- /* Draw solid color */
- material = get_or_create_material_data(vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
- }
- if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
- }
- else {
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- DRW_shgroup_call_object_add(material->shgrp, geom, ob);
- }
- }
- }
- else {
- /* Draw material color */
- if (is_sculpt_mode) {
- /* Multiple materials are not supported in sculpt mode yet. */
- Material *mat = give_current_material(ob, 1);
- material = get_or_create_material_data(vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
- DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
- }
- else {
- struct GPUBatch **geoms;
- struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
- memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
-
- geoms = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len, NULL, NULL, NULL);
- for (int i = 0; i < materials_len; ++i) {
- if (geoms != NULL && geoms[i] != NULL) {
- Material *mat = give_current_material(ob, i + 1);
- if (mat != NULL && mat->a < 1.0f) {
- /* Hack */
- wpd->shading.xray_alpha = mat->a;
- material = workbench_forward_get_or_create_material_data(vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
- has_transp_mat = true;
- }
- else {
- material = get_or_create_material_data(vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
- }
- DRW_shgroup_call_object_add(material->shgrp, geoms[i], ob);
- }
- }
- }
- }
-
- if (SHADOW_ENABLED(wpd) && !(ob->dtx & OB_DRAW_NO_SHADOW_CAST)) {
- bool is_manifold;
- struct GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold);
- if (geom_shadow) {
- if (is_sculpt_mode || use_hide) {
- /* Currently unsupported in sculpt mode. We could revert to the slow
- * method in this case but I'm not sure if it's a good idea given that
- * sculpted meshes are heavy to begin with. */
- // DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
- }
- else {
- WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
- &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
-
- if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
-
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
-
- DRWShadingGroup *grp;
- bool use_shadow_pass_technique = !studiolight_camera_in_object_shadow(wpd, ob, engine_object_data);
-
- if (use_shadow_pass_technique && !has_transp_mat) {
- if (is_manifold) {
- grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
- }
- else {
- grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
- }
- DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
- DRW_shgroup_uniform_float_copy(grp, "lightDistance", 1e5f);
- DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+
+ if (!DRW_object_is_renderable(ob)) {
+ return;
+ }
+
+ if (ob->type == OB_MESH) {
+ workbench_cache_populate_particles(vedata, ob);
+ }
+
+ ModifierData *md;
+ if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
+ (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
+ (modifier_isEnabled(scene, md, eModifierMode_Realtime)) &&
+ (((SmokeModifierData *)md)->domain != NULL)) {
+ workbench_volume_cache_populate(vedata, scene, ob, md);
+ return; /* Do not draw solid in this case. */
+ }
+
+ if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+ return;
+ }
+ if ((ob->dt < OB_SOLID) && !DRW_state_is_image_render()) {
+ return;
+ }
+
+ WORKBENCH_MaterialData *material;
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
+ const bool is_active = (ob == draw_ctx->obact);
+ const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
+ const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
+ const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
+ const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
+ bool has_transp_mat = false;
+
+ if (!is_sculpt_mode && me && me->mloopuv && TEXTURE_DRAWING_ENABLED(wpd)) {
+ /* Draw textured */
+ struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
+ for (int i = 0; i < materials_len; i++) {
+ if (geom_array != NULL && geom_array[i] != NULL) {
+ Material *mat;
+ Image *image;
+ ImageUser *iuser;
+ int interp;
+ workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ if (color_type == V3D_SHADING_MATERIAL_COLOR && mat && mat->a < 1.0) {
+ material = workbench_forward_get_or_create_material_data(
+ vedata, ob, mat, image, iuser, color_type, 0);
+ has_transp_mat = true;
+ }
+ else {
+ material = get_or_create_material_data(
+ vedata, ob, mat, image, iuser, color_type, interp);
+ }
+ DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
+ }
+ }
+ }
+ else if (ELEM(wpd->shading.color_type,
+ V3D_SHADING_SINGLE_COLOR,
+ V3D_SHADING_OBJECT_COLOR,
+ V3D_SHADING_RANDOM_COLOR)) {
+ if ((ob->color[3] < 1.0f) && (wpd->shading.color_type == V3D_SHADING_OBJECT_COLOR)) {
+ /* Hack */
+ wpd->shading.xray_alpha = ob->color[3];
+ material = workbench_forward_get_or_create_material_data(
+ vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
+ has_transp_mat = true;
+ }
+ else {
+ /* Draw solid color */
+ material = get_or_create_material_data(
+ vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
+ }
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
+ }
+ else {
+ struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ DRW_shgroup_call_object_add(material->shgrp, geom, ob);
+ }
+ }
+ }
+ else {
+ /* Draw material color */
+ if (is_sculpt_mode) {
+ /* Multiple materials are not supported in sculpt mode yet. */
+ Material *mat = give_current_material(ob, 1);
+ material = get_or_create_material_data(
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
+ }
+ else {
+ struct GPUBatch **geoms;
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
+
+ geoms = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len, NULL, NULL, NULL);
+ for (int i = 0; i < materials_len; ++i) {
+ if (geoms != NULL && geoms[i] != NULL) {
+ Material *mat = give_current_material(ob, i + 1);
+ if (mat != NULL && mat->a < 1.0f) {
+ /* Hack */
+ wpd->shading.xray_alpha = mat->a;
+ material = workbench_forward_get_or_create_material_data(
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ has_transp_mat = true;
+ }
+ else {
+ material = get_or_create_material_data(
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ }
+ DRW_shgroup_call_object_add(material->shgrp, geoms[i], ob);
+ }
+ }
+ }
+ }
+
+ if (SHADOW_ENABLED(wpd) && !(ob->dtx & OB_DRAW_NO_SHADOW_CAST)) {
+ bool is_manifold;
+ struct GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold);
+ if (geom_shadow) {
+ if (is_sculpt_mode || use_hide) {
+ /* Currently unsupported in sculpt mode. We could revert to the slow
+ * method in this case but I'm not sure if it's a good idea given that
+ * sculpted meshes are heavy to begin with. */
+ // DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
+ }
+ else {
+ WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
+ &ob->id,
+ &draw_engine_workbench_solid,
+ sizeof(WORKBENCH_ObjectData),
+ &workbench_init_object_data,
+ NULL);
+
+ if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
+
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_v3_mat3_m4v3(
+ engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
+
+ DRWShadingGroup *grp;
+ bool use_shadow_pass_technique = !studiolight_camera_in_object_shadow(
+ wpd, ob, engine_object_data);
+
+ if (use_shadow_pass_technique && !has_transp_mat) {
+ if (is_manifold) {
+ grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh,
+ psl->shadow_depth_pass_mani_pass);
+ }
+ else {
+ grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
+ }
+ DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_uniform_float_copy(grp, "lightDistance", 1e5f);
+ DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
#ifdef DEBUG_SHADOW_VOLUME
- DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
+ DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
#endif
- }
- else {
- float extrude_distance = studiolight_object_shadow_distance(wpd, ob, engine_object_data);
-
- /* TODO(fclem): only use caps if they are in the view frustum. */
- const bool need_caps = true;
- if (need_caps) {
- if (is_manifold) {
- grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
- }
- else {
- grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
- }
- DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
- DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
- DRW_shgroup_call_add(grp, DRW_cache_object_surface_get(ob), ob->obmat);
- }
-
- if (is_manifold) {
- grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
- }
- else {
- grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
- }
- DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
- DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
- DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
+ }
+ else {
+ float extrude_distance = studiolight_object_shadow_distance(
+ wpd, ob, engine_object_data);
+
+ /* TODO(fclem): only use caps if they are in the view frustum. */
+ const bool need_caps = true;
+ if (need_caps) {
+ if (is_manifold) {
+ grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh,
+ psl->shadow_depth_fail_caps_mani_pass);
+ }
+ else {
+ grp = DRW_shgroup_create(e_data.shadow_caps_sh,
+ psl->shadow_depth_fail_caps_pass);
+ }
+ DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
+ DRW_shgroup_call_add(grp, DRW_cache_object_surface_get(ob), ob->obmat);
+ }
+
+ if (is_manifold) {
+ grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh,
+ psl->shadow_depth_fail_mani_pass);
+ }
+ else {
+ grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
+ }
+ DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
+ DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
#ifdef DEBUG_SHADOW_VOLUME
- DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
+ DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
#endif
- }
- }
- }
- }
- }
- }
+ }
+ }
+ }
+ }
+ }
+ }
}
void workbench_deferred_cache_finish(WORKBENCH_Data *UNUSED(vedata))
@@ -1068,144 +1118,146 @@ void workbench_deferred_cache_finish(WORKBENCH_Data *UNUSED(vedata))
void workbench_deferred_draw_background(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- const float clear_depth = 1.0f;
- const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- uint clear_stencil = 0x00;
-
- DRW_stats_group_start("Clear Background");
-
- if (OBJECT_ID_PASS_ENABLED(wpd)) {
- /* From all the color buffers, only object id needs to be cleared. */
- GPU_framebuffer_bind(fbl->id_clear_fb);
- GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_color);
- }
-
- GPU_framebuffer_bind(fbl->prepass_fb);
- int clear_bits = GPU_DEPTH_BIT;
- SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT);
- GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_color, clear_depth, clear_stencil);
- DRW_stats_group_end();
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ const float clear_depth = 1.0f;
+ const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ uint clear_stencil = 0x00;
+
+ DRW_stats_group_start("Clear Background");
+
+ if (OBJECT_ID_PASS_ENABLED(wpd)) {
+ /* From all the color buffers, only object id needs to be cleared. */
+ GPU_framebuffer_bind(fbl->id_clear_fb);
+ GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_color);
+ }
+
+ GPU_framebuffer_bind(fbl->prepass_fb);
+ int clear_bits = GPU_DEPTH_BIT;
+ SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT);
+ GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_color, clear_depth, clear_stencil);
+ DRW_stats_group_end();
}
void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
{
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
-
- if (TAA_ENABLED(wpd)) {
- workbench_taa_draw_scene_start(vedata);
- }
-
- /* clear in background */
- GPU_framebuffer_bind(fbl->prepass_fb);
- DRW_draw_pass(psl->prepass_pass);
- DRW_draw_pass(psl->prepass_hair_pass);
-
- if (GHOST_ENABLED(psl)) {
- /* meh, late init to not request a depth buffer we won't use. */
- workbench_setup_ghost_framebuffer(fbl);
-
- GPU_framebuffer_bind(fbl->ghost_prepass_fb);
- GPU_framebuffer_clear_depth(fbl->ghost_prepass_fb, 1.0f);
- DRW_draw_pass(psl->ghost_prepass_pass);
- DRW_draw_pass(psl->ghost_prepass_hair_pass);
-
- GPU_framebuffer_bind(dfbl->depth_only_fb);
- DRW_draw_pass(psl->ghost_resolve_pass);
- }
-
- if (CAVITY_ENABLED(wpd)) {
- GPU_framebuffer_bind(fbl->cavity_fb);
- DRW_draw_pass(psl->cavity_pass);
- }
-
- if (SHADOW_ENABLED(wpd)) {
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ if (TAA_ENABLED(wpd)) {
+ workbench_taa_draw_scene_start(vedata);
+ }
+
+ /* clear in background */
+ GPU_framebuffer_bind(fbl->prepass_fb);
+ DRW_draw_pass(psl->prepass_pass);
+ DRW_draw_pass(psl->prepass_hair_pass);
+
+ if (GHOST_ENABLED(psl)) {
+ /* meh, late init to not request a depth buffer we won't use. */
+ workbench_setup_ghost_framebuffer(fbl);
+
+ GPU_framebuffer_bind(fbl->ghost_prepass_fb);
+ GPU_framebuffer_clear_depth(fbl->ghost_prepass_fb, 1.0f);
+ DRW_draw_pass(psl->ghost_prepass_pass);
+ DRW_draw_pass(psl->ghost_prepass_hair_pass);
+
+ GPU_framebuffer_bind(dfbl->depth_only_fb);
+ DRW_draw_pass(psl->ghost_resolve_pass);
+ }
+
+ if (CAVITY_ENABLED(wpd)) {
+ GPU_framebuffer_bind(fbl->cavity_fb);
+ DRW_draw_pass(psl->cavity_pass);
+ }
+
+ if (SHADOW_ENABLED(wpd)) {
#ifdef DEBUG_SHADOW_VOLUME
- GPU_framebuffer_bind(fbl->composite_fb);
- DRW_draw_pass(psl->composite_pass);
+ GPU_framebuffer_bind(fbl->composite_fb);
+ DRW_draw_pass(psl->composite_pass);
#else
- GPU_framebuffer_bind(dfbl->depth_only_fb);
+ GPU_framebuffer_bind(dfbl->depth_only_fb);
#endif
- DRW_draw_pass(psl->shadow_depth_pass_pass);
- DRW_draw_pass(psl->shadow_depth_pass_mani_pass);
- DRW_draw_pass(psl->shadow_depth_fail_pass);
- DRW_draw_pass(psl->shadow_depth_fail_mani_pass);
- DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
- DRW_draw_pass(psl->shadow_depth_fail_caps_mani_pass);
-
- if (GHOST_ENABLED(psl)) {
- /* We need to set the stencil buffer to 0 where Ghost objects
- * else they will get shadow and even badly shadowed. */
- DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
- DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
-
- DRW_draw_pass(psl->ghost_prepass_pass);
- DRW_draw_pass(psl->ghost_prepass_hair_pass);
- }
+ DRW_draw_pass(psl->shadow_depth_pass_pass);
+ DRW_draw_pass(psl->shadow_depth_pass_mani_pass);
+ DRW_draw_pass(psl->shadow_depth_fail_pass);
+ DRW_draw_pass(psl->shadow_depth_fail_mani_pass);
+ DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
+ DRW_draw_pass(psl->shadow_depth_fail_caps_mani_pass);
+
+ if (GHOST_ENABLED(psl)) {
+ /* We need to set the stencil buffer to 0 where Ghost objects
+ * else they will get shadow and even badly shadowed. */
+ DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
+ DRW_pass_state_set(psl->ghost_prepass_hair_pass,
+ DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
+
+ DRW_draw_pass(psl->ghost_prepass_pass);
+ DRW_draw_pass(psl->ghost_prepass_hair_pass);
+ }
#ifndef DEBUG_SHADOW_VOLUME
- GPU_framebuffer_bind(fbl->composite_fb);
- DRW_draw_pass(psl->composite_pass);
- DRW_draw_pass(psl->composite_shadow_pass);
+ GPU_framebuffer_bind(fbl->composite_fb);
+ DRW_draw_pass(psl->composite_pass);
+ DRW_draw_pass(psl->composite_shadow_pass);
#endif
- }
- else {
- GPU_framebuffer_bind(fbl->composite_fb);
- DRW_draw_pass(psl->composite_pass);
- }
-
- /* TODO(fclem): only enable when needed (when there is overlays). */
- if (GHOST_ENABLED(psl)) {
- /* In order to not draw on top of ghost objects, we clear the stencil
- * to 0xFF and the ghost object to 0x00 and only draw overlays on top if
- * stencil is not 0. */
- GPU_framebuffer_bind(dfbl->depth_only_fb);
- GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF);
-
- DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
- DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
-
- DRW_draw_pass(psl->ghost_prepass_pass);
- DRW_draw_pass(psl->ghost_prepass_hair_pass);
- }
-
- GPU_framebuffer_bind(fbl->composite_fb);
- DRW_draw_pass(psl->background_pass);
-
- if (OIT_ENABLED(wpd) && !DRW_pass_is_empty(psl->transparent_accum_pass)) {
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- /* meh, late init to not request buffers we won't use. */
- workbench_init_oit_framebuffer(fbl, dtxl);
-
- const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- GPU_framebuffer_bind(fbl->transparent_accum_fb);
- GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
- DRW_draw_pass(psl->transparent_accum_pass);
-
- GPU_framebuffer_bind(fbl->composite_fb);
- DRW_draw_pass(psl->oit_composite_pass);
- }
-
- if (wpd->volumes_do) {
- GPU_framebuffer_bind(fbl->color_only_fb);
- DRW_draw_pass(psl->volume_pass);
- }
-
- workbench_dof_draw_pass(vedata);
- workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx);
+ }
+ else {
+ GPU_framebuffer_bind(fbl->composite_fb);
+ DRW_draw_pass(psl->composite_pass);
+ }
+
+ /* TODO(fclem): only enable when needed (when there is overlays). */
+ if (GHOST_ENABLED(psl)) {
+ /* In order to not draw on top of ghost objects, we clear the stencil
+ * to 0xFF and the ghost object to 0x00 and only draw overlays on top if
+ * stencil is not 0. */
+ GPU_framebuffer_bind(dfbl->depth_only_fb);
+ GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF);
+
+ DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
+ DRW_pass_state_set(psl->ghost_prepass_hair_pass,
+ DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
+
+ DRW_draw_pass(psl->ghost_prepass_pass);
+ DRW_draw_pass(psl->ghost_prepass_hair_pass);
+ }
+
+ GPU_framebuffer_bind(fbl->composite_fb);
+ DRW_draw_pass(psl->background_pass);
+
+ if (OIT_ENABLED(wpd) && !DRW_pass_is_empty(psl->transparent_accum_pass)) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ /* meh, late init to not request buffers we won't use. */
+ workbench_init_oit_framebuffer(fbl, dtxl);
+
+ const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ GPU_framebuffer_bind(fbl->transparent_accum_fb);
+ GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
+ DRW_draw_pass(psl->transparent_accum_pass);
+
+ GPU_framebuffer_bind(fbl->composite_fb);
+ DRW_draw_pass(psl->oit_composite_pass);
+ }
+
+ if (wpd->volumes_do) {
+ GPU_framebuffer_bind(fbl->color_only_fb);
+ DRW_draw_pass(psl->volume_pass);
+ }
+
+ workbench_dof_draw_pass(vedata);
+ workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx);
}
void workbench_deferred_draw_finish(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
- /* XXX TODO(fclem) do not discard UBOS after drawing! Store them per viewport. */
- workbench_private_data_free(wpd);
- workbench_volume_smoke_textures_free(wpd);
+ /* XXX TODO(fclem) do not discard UBOS after drawing! Store them per viewport. */
+ workbench_private_data_free(wpd);
+ workbench_volume_smoke_textures_free(wpd);
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c
index 226f1746e50..a80f6ce338b 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_aa.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c
@@ -24,83 +24,82 @@
#include "workbench_private.h"
-
void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_EffectInfo *effect_info = stl->effects;
- const DRWContextState *draw_ctx = DRW_context_state_get();
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
- if (draw_ctx->evil_C != NULL) {
- struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
- wpd->is_playback = ED_screen_animation_playing(wm) != NULL;
- }
- else {
- wpd->is_playback = false;
- }
+ if (draw_ctx->evil_C != NULL) {
+ struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
+ wpd->is_playback = ED_screen_animation_playing(wm) != NULL;
+ }
+ else {
+ wpd->is_playback = false;
+ }
- if (TAA_ENABLED(wpd)) {
- psl->effect_aa_pass = workbench_taa_create_pass(vedata, tx);
- }
- else if (FXAA_ENABLED(wpd)) {
- psl->effect_aa_pass = workbench_fxaa_create_pass(tx);
- effect_info->jitter_index = 0;
- }
- else {
- psl->effect_aa_pass = NULL;
- }
+ if (TAA_ENABLED(wpd)) {
+ psl->effect_aa_pass = workbench_taa_create_pass(vedata, tx);
+ }
+ else if (FXAA_ENABLED(wpd)) {
+ psl->effect_aa_pass = workbench_fxaa_create_pass(tx);
+ effect_info->jitter_index = 0;
+ }
+ else {
+ psl->effect_aa_pass = NULL;
+ }
}
static void workspace_aa_draw_transform(GPUTexture *tx, WORKBENCH_PrivateData *wpd)
{
- if (DRW_state_is_image_render()) {
- /* Linear result for render. */
- DRW_transform_none(tx);
- }
- else {
- /* Display space result for viewport. */
- DRW_transform_to_display(tx, wpd->use_color_render_settings, wpd->use_color_render_settings);
- }
+ if (DRW_state_is_image_render()) {
+ /* Linear result for render. */
+ DRW_transform_none(tx);
+ }
+ else {
+ /* Display space result for viewport. */
+ DRW_transform_to_display(tx, wpd->use_color_render_settings, wpd->use_color_render_settings);
+ }
}
void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_EffectInfo *effect_info = stl->effects;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- if (FXAA_ENABLED(wpd)) {
- GPU_framebuffer_bind(fbl->effect_fb);
- workspace_aa_draw_transform(tx, wpd);
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_draw_pass(psl->effect_aa_pass);
- }
- else if (TAA_ENABLED(wpd)) {
- /*
- * when drawing the first TAA frame, we transform directly to the
- * color_only_fb as the TAA shader is just performing a direct copy.
- * the workbench_taa_draw_screen_end will fill the history buffer
- * for the other iterations.
- */
- if (effect_info->jitter_index == 1) {
- GPU_framebuffer_bind(dfbl->color_only_fb);
- workspace_aa_draw_transform(tx, wpd);
- }
- else {
- GPU_framebuffer_bind(fbl->effect_fb);
- workspace_aa_draw_transform(tx, wpd);
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_draw_pass(psl->effect_aa_pass);
- }
- workbench_taa_draw_scene_end(vedata);
- }
- else {
- GPU_framebuffer_bind(dfbl->color_only_fb);
- workspace_aa_draw_transform(tx, wpd);
- }
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ if (FXAA_ENABLED(wpd)) {
+ GPU_framebuffer_bind(fbl->effect_fb);
+ workspace_aa_draw_transform(tx, wpd);
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->effect_aa_pass);
+ }
+ else if (TAA_ENABLED(wpd)) {
+ /*
+ * when drawing the first TAA frame, we transform directly to the
+ * color_only_fb as the TAA shader is just performing a direct copy.
+ * the workbench_taa_draw_screen_end will fill the history buffer
+ * for the other iterations.
+ */
+ if (effect_info->jitter_index == 1) {
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ workspace_aa_draw_transform(tx, wpd);
+ }
+ else {
+ GPU_framebuffer_bind(fbl->effect_fb);
+ workspace_aa_draw_transform(tx, wpd);
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(psl->effect_aa_pass);
+ }
+ workbench_taa_draw_scene_end(vedata);
+ }
+ else {
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ workspace_aa_draw_transform(tx, wpd);
+ }
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index dca65355c8f..3e35f8120d7 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -29,15 +29,15 @@
/* *********** STATIC *********** */
static struct {
- struct GPUShader *effect_dof_prepare_sh;
- struct GPUShader *effect_dof_downsample_sh;
- struct GPUShader *effect_dof_flatten_v_sh;
- struct GPUShader *effect_dof_flatten_h_sh;
- struct GPUShader *effect_dof_dilate_v_sh;
- struct GPUShader *effect_dof_dilate_h_sh;
- struct GPUShader *effect_dof_blur1_sh;
- struct GPUShader *effect_dof_blur2_sh;
- struct GPUShader *effect_dof_resolve_sh;
+ struct GPUShader *effect_dof_prepare_sh;
+ struct GPUShader *effect_dof_downsample_sh;
+ struct GPUShader *effect_dof_flatten_v_sh;
+ struct GPUShader *effect_dof_flatten_h_sh;
+ struct GPUShader *effect_dof_dilate_v_sh;
+ struct GPUShader *effect_dof_dilate_h_sh;
+ struct GPUShader *effect_dof_blur1_sh;
+ struct GPUShader *effect_dof_blur2_sh;
+ struct GPUShader *effect_dof_resolve_sh;
} e_data = {NULL};
/* Shaders */
@@ -50,385 +50,384 @@ extern char datatoc_workbench_effect_dof_frag_glsl[];
*/
static void square_to_circle(float x, float y, float *r, float *T)
{
- if (x > -y) {
- if (x > y) {
- *r = x;
- *T = (M_PI / 4.0f) * (y / x);
- }
- else {
- *r = y;
- *T = (M_PI / 4.0f) * (2 - (x / y));
- }
- }
- else {
- if (x < y) {
- *r = -x;
- *T = (M_PI / 4.0f) * (4 + (y / x));
- }
- else {
- *r = -y;
- if (y != 0) {
- *T = (M_PI / 4.0f) * (6 - (x / y));
- }
- else {
- *T = 0.0f;
- }
- }
- }
+ if (x > -y) {
+ if (x > y) {
+ *r = x;
+ *T = (M_PI / 4.0f) * (y / x);
+ }
+ else {
+ *r = y;
+ *T = (M_PI / 4.0f) * (2 - (x / y));
+ }
+ }
+ else {
+ if (x < y) {
+ *r = -x;
+ *T = (M_PI / 4.0f) * (4 + (y / x));
+ }
+ else {
+ *r = -y;
+ if (y != 0) {
+ *T = (M_PI / 4.0f) * (6 - (x / y));
+ }
+ else {
+ *T = 0.0f;
+ }
+ }
+ }
}
#define KERNEL_RAD 3
-#define SAMP_LEN SQUARE(KERNEL_RAD * 2 + 1)
+#define SAMP_LEN SQUARE(KERNEL_RAD * 2 + 1)
-static void workbench_dof_setup_samples(
- struct GPUUniformBuffer **ubo, float **data,
- float bokeh_sides, float bokeh_rotation, float bokeh_ratio)
+static void workbench_dof_setup_samples(struct GPUUniformBuffer **ubo,
+ float **data,
+ float bokeh_sides,
+ float bokeh_rotation,
+ float bokeh_ratio)
{
- if (*data == NULL) {
- *data = MEM_callocN(sizeof(float) * 4 * SAMP_LEN, "workbench dof samples");
- }
- if (*ubo == NULL) {
- *ubo = DRW_uniformbuffer_create(sizeof(float) * 4 * SAMP_LEN, NULL);
- }
-
- float *samp = *data;
- for (int i = 0; i <= KERNEL_RAD; ++i) {
- for (int j = -KERNEL_RAD; j <= KERNEL_RAD; ++j) {
- for (int k = -KERNEL_RAD; k <= KERNEL_RAD; ++k) {
- if (abs(j) > i || abs(k) > i) {
- continue;
- }
- if (abs(j) < i && abs(k) < i) {
- continue;
- }
- float x = ((float)j) / KERNEL_RAD;
- float y = ((float)k) / KERNEL_RAD;
-
- float r, T;
- square_to_circle(x, y, &r, &T);
- samp[2] = r;
-
- /* Bokeh shape parametrisation */
- if (bokeh_sides > 1.0f) {
- float denom = T - (2.0 * M_PI / bokeh_sides) * floorf((bokeh_sides * T + M_PI) / (2.0 * M_PI));
- r *= cosf(M_PI / bokeh_sides) / cosf(denom);
- }
-
- T += bokeh_rotation;
-
- samp[0] = r * cosf(T) * bokeh_ratio;
- samp[1] = r * sinf(T);
- samp += 4;
- }
- }
- }
-
- DRW_uniformbuffer_update(*ubo, *data);
+ if (*data == NULL) {
+ *data = MEM_callocN(sizeof(float) * 4 * SAMP_LEN, "workbench dof samples");
+ }
+ if (*ubo == NULL) {
+ *ubo = DRW_uniformbuffer_create(sizeof(float) * 4 * SAMP_LEN, NULL);
+ }
+
+ float *samp = *data;
+ for (int i = 0; i <= KERNEL_RAD; ++i) {
+ for (int j = -KERNEL_RAD; j <= KERNEL_RAD; ++j) {
+ for (int k = -KERNEL_RAD; k <= KERNEL_RAD; ++k) {
+ if (abs(j) > i || abs(k) > i) {
+ continue;
+ }
+ if (abs(j) < i && abs(k) < i) {
+ continue;
+ }
+ float x = ((float)j) / KERNEL_RAD;
+ float y = ((float)k) / KERNEL_RAD;
+
+ float r, T;
+ square_to_circle(x, y, &r, &T);
+ samp[2] = r;
+
+ /* Bokeh shape parametrisation */
+ if (bokeh_sides > 1.0f) {
+ float denom = T - (2.0 * M_PI / bokeh_sides) *
+ floorf((bokeh_sides * T + M_PI) / (2.0 * M_PI));
+ r *= cosf(M_PI / bokeh_sides) / cosf(denom);
+ }
+
+ T += bokeh_rotation;
+
+ samp[0] = r * cosf(T) * bokeh_ratio;
+ samp[1] = r * sinf(T);
+ samp += 4;
+ }
+ }
+ }
+
+ DRW_uniformbuffer_update(*ubo, *data);
}
void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
{
- WORKBENCH_TextureList *txl = vedata->txl;
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
-
- if ((wpd->shading.flag & V3D_SHADING_DEPTH_OF_FIELD) == 0 ||
- (camera == NULL))
- {
- wpd->dof_enabled = false;
- return;
- }
-
- if (e_data.effect_dof_prepare_sh == NULL) {
- e_data.effect_dof_prepare_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define PREPARE\n");
-
- e_data.effect_dof_downsample_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define DOWNSAMPLE\n");
-
- e_data.effect_dof_flatten_v_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define FLATTEN_VERTICAL\n");
-
- e_data.effect_dof_flatten_h_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define FLATTEN_HORIZONTAL\n");
-
- e_data.effect_dof_dilate_v_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define DILATE_VERTICAL\n");
-
- e_data.effect_dof_dilate_h_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define DILATE_HORIZONTAL\n");
-
- e_data.effect_dof_blur1_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define BLUR1\n");
-
- e_data.effect_dof_blur2_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define BLUR2\n");
-
- e_data.effect_dof_resolve_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_effect_dof_frag_glsl,
- "#define RESOLVE\n");
- }
-
- const float *full_size = DRW_viewport_size_get();
- int size[2] = {full_size[0] / 2, full_size[1] / 2};
+ WORKBENCH_TextureList *txl = vedata->txl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+
+ if ((wpd->shading.flag & V3D_SHADING_DEPTH_OF_FIELD) == 0 || (camera == NULL)) {
+ wpd->dof_enabled = false;
+ return;
+ }
+
+ if (e_data.effect_dof_prepare_sh == NULL) {
+ e_data.effect_dof_prepare_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define PREPARE\n");
+
+ e_data.effect_dof_downsample_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define DOWNSAMPLE\n");
+
+ e_data.effect_dof_flatten_v_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define FLATTEN_VERTICAL\n");
+
+ e_data.effect_dof_flatten_h_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define FLATTEN_HORIZONTAL\n");
+
+ e_data.effect_dof_dilate_v_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define DILATE_VERTICAL\n");
+
+ e_data.effect_dof_dilate_h_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define DILATE_HORIZONTAL\n");
+
+ e_data.effect_dof_blur1_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define BLUR1\n");
+
+ e_data.effect_dof_blur2_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define BLUR2\n");
+
+ e_data.effect_dof_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl, "#define RESOLVE\n");
+ }
+
+ const float *full_size = DRW_viewport_size_get();
+ int size[2] = {full_size[0] / 2, full_size[1] / 2};
#if 0
- /* NOTE: We Ceil here in order to not miss any edge texel if using a NPO2 texture. */
- int shrink_h_size[2] = {ceilf(size[0] / 8.0f), size[1]};
- int shrink_w_size[2] = {shrink_h_size[0], ceilf(size[1] / 8.0f)};
+ /* NOTE: We Ceil here in order to not miss any edge texel if using a NPO2 texture. */
+ int shrink_h_size[2] = {ceilf(size[0] / 8.0f), size[1]};
+ int shrink_w_size[2] = {shrink_h_size[0], ceilf(size[1] / 8.0f)};
#endif
- DRW_texture_ensure_2d(&txl->dof_source_tx, size[0], size[1], GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
- DRW_texture_ensure_2d(&txl->coc_halfres_tx, size[0], size[1], GPU_RG8, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
- wpd->dof_blur_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_workbench_solid);
+ DRW_texture_ensure_2d(
+ &txl->dof_source_tx, size[0], size[1], GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
+ DRW_texture_ensure_2d(
+ &txl->coc_halfres_tx, size[0], size[1], GPU_RG8, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
+ wpd->dof_blur_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_workbench_solid);
#if 0
- wpd->coc_temp_tx = DRW_texture_pool_query_2d(shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench_solid);
- wpd->coc_tiles_tx[0] = DRW_texture_pool_query_2d(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
- wpd->coc_tiles_tx[1] = DRW_texture_pool_query_2d(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
+ wpd->coc_temp_tx = DRW_texture_pool_query_2d(shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench_solid);
+ wpd->coc_tiles_tx[0] = DRW_texture_pool_query_2d(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
+ wpd->coc_tiles_tx[1] = DRW_texture_pool_query_2d(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
#endif
- GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx),
- GPU_ATTACHMENT_TEXTURE(txl->coc_halfres_tx),
- });
+ GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx),
+ GPU_ATTACHMENT_TEXTURE(txl->coc_halfres_tx),
+ });
#if 0
- GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_h_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->coc_temp_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_v_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[0]),
- });
- GPU_framebuffer_ensure_config(&fbl->dof_coc_dilate_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[1]),
- });
+ GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_h_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->coc_temp_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_v_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[0]),
+ });
+ GPU_framebuffer_ensure_config(&fbl->dof_coc_dilate_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[1]),
+ });
#endif
- GPU_framebuffer_ensure_config(&fbl->dof_blur1_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->dof_blur_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->dof_blur2_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx),
- });
-
- {
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- RegionView3D *rv3d = draw_ctx->rv3d;
- Camera *cam = (Camera *)camera->data;
-
- /* Parameters */
- /* TODO UI Options */
- float fstop = cam->gpu_dof.fstop;
- float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
- float focus_dist = BKE_camera_object_dof_distance(camera);
- float focal_len = cam->lens;
-
- /* TODO(fclem) deduplicate with eevee */
-
- /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
- * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
- * because the shader reads coordinates in world space, which is in blender units.
- * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
- float scale = (scene_eval->unit.system) ? scene_eval->unit.scale_length : 1.0f;
- float scale_camera = 0.001f / scale;
- /* we want radius here for the aperture number */
- float aperture = 0.5f * scale_camera * focal_len / fstop;
- float focal_len_scaled = scale_camera * focal_len;
- float sensor_scaled = scale_camera * sensor;
-
- if (rv3d != NULL) {
- sensor_scaled *= rv3d->viewcamtexcofac[0];
- }
-
- wpd->dof_aperturesize = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
- wpd->dof_distance = -focus_dist;
- wpd->dof_invsensorsize = full_size[0] / sensor_scaled;
-
- wpd->dof_near_far[0] = -cam->clip_start;
- wpd->dof_near_far[1] = -cam->clip_end;
-
- float blades = cam->gpu_dof.num_blades;
- float rotation = cam->gpu_dof.rotation;
- float ratio = 1.0f / cam->gpu_dof.ratio;
-
- if (wpd->dof_ubo == NULL ||
- blades != wpd->dof_blades ||
- rotation != wpd->dof_rotation ||
- ratio != wpd->dof_ratio)
- {
- wpd->dof_blades = blades;
- wpd->dof_rotation = rotation;
- wpd->dof_ratio = ratio;
- workbench_dof_setup_samples(&wpd->dof_ubo, &stl->dof_ubo_data, blades, rotation, ratio);
- }
- }
-
- wpd->dof_enabled = true;
+ GPU_framebuffer_ensure_config(&fbl->dof_blur1_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->dof_blur_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->dof_blur2_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx),
+ });
+
+ {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ Camera *cam = (Camera *)camera->data;
+
+ /* Parameters */
+ /* TODO UI Options */
+ float fstop = cam->gpu_dof.fstop;
+ float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
+ float focus_dist = BKE_camera_object_dof_distance(camera);
+ float focal_len = cam->lens;
+
+ /* TODO(fclem) deduplicate with eevee */
+
+ /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
+ * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
+ * because the shader reads coordinates in world space, which is in blender units.
+ * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
+ float scale = (scene_eval->unit.system) ? scene_eval->unit.scale_length : 1.0f;
+ float scale_camera = 0.001f / scale;
+ /* we want radius here for the aperture number */
+ float aperture = 0.5f * scale_camera * focal_len / fstop;
+ float focal_len_scaled = scale_camera * focal_len;
+ float sensor_scaled = scale_camera * sensor;
+
+ if (rv3d != NULL) {
+ sensor_scaled *= rv3d->viewcamtexcofac[0];
+ }
+
+ wpd->dof_aperturesize = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
+ wpd->dof_distance = -focus_dist;
+ wpd->dof_invsensorsize = full_size[0] / sensor_scaled;
+
+ wpd->dof_near_far[0] = -cam->clip_start;
+ wpd->dof_near_far[1] = -cam->clip_end;
+
+ float blades = cam->gpu_dof.num_blades;
+ float rotation = cam->gpu_dof.rotation;
+ float ratio = 1.0f / cam->gpu_dof.ratio;
+
+ if (wpd->dof_ubo == NULL || blades != wpd->dof_blades || rotation != wpd->dof_rotation ||
+ ratio != wpd->dof_ratio) {
+ wpd->dof_blades = blades;
+ wpd->dof_rotation = rotation;
+ wpd->dof_ratio = ratio;
+ workbench_dof_setup_samples(&wpd->dof_ubo, &stl->dof_ubo_data, blades, rotation, ratio);
+ }
+ }
+
+ wpd->dof_enabled = true;
}
-void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input, GPUTexture *noise_tex)
+void workbench_dof_create_pass(WORKBENCH_Data *vedata,
+ GPUTexture **dof_input,
+ GPUTexture *noise_tex)
{
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_TextureList *txl = vedata->txl;
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
-
- if (!wpd->dof_enabled) {
- return;
- }
-
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
-
- psl->dof_down_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR);
- psl->dof_down2_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR);
- psl->dof_flatten_h_ps = DRW_pass_create("DoF Flatten Coc H", DRW_STATE_WRITE_COLOR);
- psl->dof_flatten_v_ps = DRW_pass_create("DoF Flatten Coc V", DRW_STATE_WRITE_COLOR);
- psl->dof_dilate_h_ps = DRW_pass_create("DoF Dilate Coc H", DRW_STATE_WRITE_COLOR);
- psl->dof_dilate_v_ps = DRW_pass_create("DoF Dilate Coc V", DRW_STATE_WRITE_COLOR);
- psl->dof_blur1_ps = DRW_pass_create("DoF Blur 1", DRW_STATE_WRITE_COLOR);
- psl->dof_blur2_ps = DRW_pass_create("DoF Blur 2", DRW_STATE_WRITE_COLOR);
- psl->dof_resolve_ps = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
-
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_prepare_sh, psl->dof_down_ps);
- DRW_shgroup_uniform_texture_ref(grp, "sceneColorTex", dof_input);
- DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
- DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
-
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_downsample_sh, psl->dof_down2_ps);
- DRW_shgroup_uniform_texture(grp, "sceneColorTex", txl->dof_source_tx);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_TextureList *txl = vedata->txl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
+
+ if (!wpd->dof_enabled) {
+ return;
+ }
+
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ psl->dof_down_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR);
+ psl->dof_down2_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR);
+ psl->dof_flatten_h_ps = DRW_pass_create("DoF Flatten Coc H", DRW_STATE_WRITE_COLOR);
+ psl->dof_flatten_v_ps = DRW_pass_create("DoF Flatten Coc V", DRW_STATE_WRITE_COLOR);
+ psl->dof_dilate_h_ps = DRW_pass_create("DoF Dilate Coc H", DRW_STATE_WRITE_COLOR);
+ psl->dof_dilate_v_ps = DRW_pass_create("DoF Dilate Coc V", DRW_STATE_WRITE_COLOR);
+ psl->dof_blur1_ps = DRW_pass_create("DoF Blur 1", DRW_STATE_WRITE_COLOR);
+ psl->dof_blur2_ps = DRW_pass_create("DoF Blur 2", DRW_STATE_WRITE_COLOR);
+ psl->dof_resolve_ps = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
+
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_prepare_sh, psl->dof_down_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "sceneColorTex", dof_input);
+ DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
+ DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_downsample_sh, psl->dof_down2_ps);
+ DRW_shgroup_uniform_texture(grp, "sceneColorTex", txl->dof_source_tx);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
#if 0
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh, psl->dof_flatten_h_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_v_sh, psl->dof_flatten_v_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_temp_tx);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_v_sh, psl->dof_dilate_v_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[0]);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_h_sh, psl->dof_dilate_h_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[1]);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh, psl->dof_flatten_h_ps);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_v_sh, psl->dof_flatten_v_ps);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_temp_tx);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_v_sh, psl->dof_dilate_v_ps);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[0]);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_h_sh, psl->dof_dilate_h_ps);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[1]);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
#endif
- {
- float offset = stl->effects->jitter_index / (float)workbench_taa_calculate_num_iterations(vedata);
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur1_sh, psl->dof_blur1_ps);
- DRW_shgroup_uniform_block(grp, "dofSamplesBlock", wpd->dof_ubo);
- DRW_shgroup_uniform_texture(grp, "noiseTex", noise_tex);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
- DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_uniform_float_copy(grp, "noiseOffset", offset);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur2_sh, psl->dof_blur2_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
- DRW_shgroup_uniform_texture(grp, "blurTex", wpd->dof_blur_tx);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
- {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_resolve_sh, psl->dof_resolve_ps);
- DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
- DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
- DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
- DRW_shgroup_call_add(grp, quad, NULL);
- }
+ {
+ float offset = stl->effects->jitter_index /
+ (float)workbench_taa_calculate_num_iterations(vedata);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur1_sh, psl->dof_blur1_ps);
+ DRW_shgroup_uniform_block(grp, "dofSamplesBlock", wpd->dof_ubo);
+ DRW_shgroup_uniform_texture(grp, "noiseTex", noise_tex);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
+ DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_float_copy(grp, "noiseOffset", offset);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur2_sh, psl->dof_blur2_ps);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
+ DRW_shgroup_uniform_texture(grp, "blurTex", wpd->dof_blur_tx);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_resolve_sh, psl->dof_resolve_ps);
+ DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
+ DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
+ DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
}
void workbench_dof_engine_free(void)
{
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_prepare_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_downsample_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_v_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_h_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_v_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_h_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_blur1_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_blur2_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_dof_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_prepare_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_downsample_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_v_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_h_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_v_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_h_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_blur1_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_blur2_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_resolve_sh);
}
static void workbench_dof_downsample_level(void *userData, int UNUSED(level))
{
- WORKBENCH_PassList *psl = (WORKBENCH_PassList *)userData;
- DRW_draw_pass(psl->dof_down2_ps);
+ WORKBENCH_PassList *psl = (WORKBENCH_PassList *)userData;
+ DRW_draw_pass(psl->dof_down2_ps);
}
void workbench_dof_draw_pass(WORKBENCH_Data *vedata)
{
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
- if (!wpd->dof_enabled) {
- return;
- }
+ if (!wpd->dof_enabled) {
+ return;
+ }
- DRW_stats_group_start("Depth Of Field");
+ DRW_stats_group_start("Depth Of Field");
- GPU_framebuffer_bind(fbl->dof_downsample_fb);
- DRW_draw_pass(psl->dof_down_ps);
+ GPU_framebuffer_bind(fbl->dof_downsample_fb);
+ DRW_draw_pass(psl->dof_down_ps);
- GPU_framebuffer_recursive_downsample(fbl->dof_downsample_fb, 2, workbench_dof_downsample_level, psl);
+ GPU_framebuffer_recursive_downsample(
+ fbl->dof_downsample_fb, 2, workbench_dof_downsample_level, psl);
#if 0
- GPU_framebuffer_bind(fbl->dof_coc_tile_h_fb);
- DRW_draw_pass(psl->dof_flatten_h_ps);
+ GPU_framebuffer_bind(fbl->dof_coc_tile_h_fb);
+ DRW_draw_pass(psl->dof_flatten_h_ps);
- GPU_framebuffer_bind(fbl->dof_coc_tile_v_fb);
- DRW_draw_pass(psl->dof_flatten_v_ps);
+ GPU_framebuffer_bind(fbl->dof_coc_tile_v_fb);
+ DRW_draw_pass(psl->dof_flatten_v_ps);
- GPU_framebuffer_bind(fbl->dof_coc_dilate_fb);
- DRW_draw_pass(psl->dof_dilate_v_ps);
+ GPU_framebuffer_bind(fbl->dof_coc_dilate_fb);
+ DRW_draw_pass(psl->dof_dilate_v_ps);
- GPU_framebuffer_bind(fbl->dof_coc_tile_v_fb);
- DRW_draw_pass(psl->dof_dilate_h_ps);
+ GPU_framebuffer_bind(fbl->dof_coc_tile_v_fb);
+ DRW_draw_pass(psl->dof_dilate_h_ps);
#endif
- GPU_framebuffer_bind(fbl->dof_blur1_fb);
- DRW_draw_pass(psl->dof_blur1_ps);
+ GPU_framebuffer_bind(fbl->dof_blur1_fb);
+ DRW_draw_pass(psl->dof_blur1_ps);
- GPU_framebuffer_bind(fbl->dof_blur2_fb);
- DRW_draw_pass(psl->dof_blur2_ps);
+ GPU_framebuffer_bind(fbl->dof_blur2_fb);
+ DRW_draw_pass(psl->dof_blur2_ps);
- GPU_framebuffer_bind(fbl->color_only_fb);
- DRW_draw_pass(psl->dof_resolve_ps);
+ GPU_framebuffer_bind(fbl->color_only_fb);
+ DRW_draw_pass(psl->dof_resolve_ps);
- DRW_stats_group_end();
+ DRW_stats_group_end();
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
index 6e2ebff854e..47355f324a8 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
@@ -23,7 +23,7 @@
/* *********** STATIC *********** */
static struct {
- struct GPUShader *effect_fxaa_sh;
+ struct GPUShader *effect_fxaa_sh;
} e_data = {NULL};
/* Shaders */
@@ -34,26 +34,26 @@ extern char datatoc_workbench_effect_fxaa_frag_glsl[];
/* *********** Functions *********** */
void workbench_fxaa_engine_init(void)
{
- if (e_data.effect_fxaa_sh == NULL) {
- e_data.effect_fxaa_sh = DRW_shader_create_with_lib(
- datatoc_common_fullscreen_vert_glsl, NULL,
- datatoc_workbench_effect_fxaa_frag_glsl,
- datatoc_common_fxaa_lib_glsl,
- NULL);
- }
+ if (e_data.effect_fxaa_sh == NULL) {
+ e_data.effect_fxaa_sh = DRW_shader_create_with_lib(datatoc_common_fullscreen_vert_glsl,
+ NULL,
+ datatoc_workbench_effect_fxaa_frag_glsl,
+ datatoc_common_fxaa_lib_glsl,
+ NULL);
+ }
}
DRWPass *workbench_fxaa_create_pass(GPUTexture **color_buffer_tx)
{
- DRWPass *pass = DRW_pass_create("Effect FXAA", DRW_STATE_WRITE_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_fxaa_sh, pass);
- DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- return pass;
+ DRWPass *pass = DRW_pass_create("Effect FXAA", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_fxaa_sh, pass);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ return pass;
}
void workbench_fxaa_engine_free(void)
{
- DRW_SHADER_FREE_SAFE(e_data.effect_fxaa_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_fxaa_sh);
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c
index cbc0e347d7d..0435a804fab 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_taa.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c
@@ -20,290 +20,288 @@
* \ingroup draw_engine
*/
-
#include "workbench_private.h"
#include "BLI_jitter_2d.h"
static struct {
- struct GPUShader *effect_taa_sh;
- float jitter_5[5][2];
- float jitter_8[8][2];
- float jitter_11[11][2];
- float jitter_16[16][2];
- float jitter_32[32][2];
+ struct GPUShader *effect_taa_sh;
+ float jitter_5[5][2];
+ float jitter_8[8][2];
+ float jitter_11[11][2];
+ float jitter_16[16][2];
+ float jitter_32[32][2];
} e_data = {NULL};
extern char datatoc_workbench_effect_taa_frag_glsl[];
-
static void workbench_taa_jitter_init_order(float (*table)[2], int num)
{
- BLI_jitter_init(table, num);
-
- /* find closest element to center */
- int closest_index = 0;
- float closest_squared_distance = 1.0f;
-
- for (int index = 0; index < num; index++) {
- const float squared_dist = SQUARE(table[index][0]) + SQUARE(table[index][1]);
- if (squared_dist < closest_squared_distance) {
- closest_squared_distance = squared_dist;
- closest_index = index;
- }
- }
-
- /* move jitter table so that closest sample is in center */
- for (int index = 0; index < num; index++) {
- sub_v2_v2(table[index], table[closest_index]);
- mul_v2_fl(table[index], 2.0f);
- }
-
- /* swap center sample to the start of the table */
- if (closest_index != 0) {
- swap_v2_v2(table[0], table[closest_index]);
- }
-
- /* sort list based on furtest distance with previous */
- for (int i = 0; i < num - 2; i++) {
- float f_squared_dist = 0.0;
- int f_index = i;
- for (int j = i + 1; j < num; j++) {
- const float squared_dist = SQUARE(table[i][0] - table[j][0]) + SQUARE(table[i][1] - table[j][1]);
- if (squared_dist > f_squared_dist) {
- f_squared_dist = squared_dist;
- f_index = j;
- }
- }
- swap_v2_v2(table[i + 1], table[f_index]);
- }
+ BLI_jitter_init(table, num);
+
+ /* find closest element to center */
+ int closest_index = 0;
+ float closest_squared_distance = 1.0f;
+
+ for (int index = 0; index < num; index++) {
+ const float squared_dist = SQUARE(table[index][0]) + SQUARE(table[index][1]);
+ if (squared_dist < closest_squared_distance) {
+ closest_squared_distance = squared_dist;
+ closest_index = index;
+ }
+ }
+
+ /* move jitter table so that closest sample is in center */
+ for (int index = 0; index < num; index++) {
+ sub_v2_v2(table[index], table[closest_index]);
+ mul_v2_fl(table[index], 2.0f);
+ }
+
+ /* swap center sample to the start of the table */
+ if (closest_index != 0) {
+ swap_v2_v2(table[0], table[closest_index]);
+ }
+
+ /* sort list based on furtest distance with previous */
+ for (int i = 0; i < num - 2; i++) {
+ float f_squared_dist = 0.0;
+ int f_index = i;
+ for (int j = i + 1; j < num; j++) {
+ const float squared_dist = SQUARE(table[i][0] - table[j][0]) +
+ SQUARE(table[i][1] - table[j][1]);
+ if (squared_dist > f_squared_dist) {
+ f_squared_dist = squared_dist;
+ f_index = j;
+ }
+ }
+ swap_v2_v2(table[i + 1], table[f_index]);
+ }
}
-
static void workbench_taa_jitter_init(void)
{
- workbench_taa_jitter_init_order(e_data.jitter_5, 5);
- workbench_taa_jitter_init_order(e_data.jitter_8, 8);
- workbench_taa_jitter_init_order(e_data.jitter_11, 11);
- workbench_taa_jitter_init_order(e_data.jitter_16, 16);
- workbench_taa_jitter_init_order(e_data.jitter_32, 32);
+ workbench_taa_jitter_init_order(e_data.jitter_5, 5);
+ workbench_taa_jitter_init_order(e_data.jitter_8, 8);
+ workbench_taa_jitter_init_order(e_data.jitter_11, 11);
+ workbench_taa_jitter_init_order(e_data.jitter_16, 16);
+ workbench_taa_jitter_init_order(e_data.jitter_32, 32);
}
int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- int result = 1;
- if (TAA_ENABLED(wpd)) {
- if (DRW_state_is_image_render()) {
- const Scene *scene = DRW_context_state_get()->scene;
- result = (scene->r.mode & R_OSA) ? scene->r.osa : 1;
- }
- else if (IN_RANGE_INCL(
- wpd->preferences->gpu_viewport_quality,
- GPU_VIEWPORT_QUALITY_TAA8, GPU_VIEWPORT_QUALITY_TAA16))
- {
- result = 8;
- }
- else if (IN_RANGE_INCL(
- wpd->preferences->gpu_viewport_quality,
- GPU_VIEWPORT_QUALITY_TAA16, GPU_VIEWPORT_QUALITY_TAA32))
- {
- result = 16;
- }
- else {
- result = 32;
- }
- }
- return result;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ int result = 1;
+ if (TAA_ENABLED(wpd)) {
+ if (DRW_state_is_image_render()) {
+ const Scene *scene = DRW_context_state_get()->scene;
+ result = (scene->r.mode & R_OSA) ? scene->r.osa : 1;
+ }
+ else if (IN_RANGE_INCL(wpd->preferences->gpu_viewport_quality,
+ GPU_VIEWPORT_QUALITY_TAA8,
+ GPU_VIEWPORT_QUALITY_TAA16)) {
+ result = 8;
+ }
+ else if (IN_RANGE_INCL(wpd->preferences->gpu_viewport_quality,
+ GPU_VIEWPORT_QUALITY_TAA16,
+ GPU_VIEWPORT_QUALITY_TAA32)) {
+ result = 16;
+ }
+ else {
+ result = 32;
+ }
+ }
+ return result;
}
void workbench_taa_engine_init(WORKBENCH_Data *vedata)
{
- WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- RegionView3D *rv3d = draw_ctx->rv3d;
-
- if (e_data.effect_taa_sh == NULL) {
- e_data.effect_taa_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_taa_frag_glsl, NULL);
- workbench_taa_jitter_init();
- }
-
- /* reset complete drawing when navigating. */
- if (effect_info->jitter_index != 0) {
- if (rv3d && rv3d->rflag & RV3D_NAVIGATING) {
- effect_info->jitter_index = 0;
- }
- }
-
- if (effect_info->view_updated) {
- effect_info->jitter_index = 0;
- effect_info->view_updated = false;
- }
-
- {
- float view[4][4];
- float win[4][4];
- DRW_viewport_matrix_get(view, DRW_MAT_VIEW);
- DRW_viewport_matrix_get(win, DRW_MAT_WIN);
- mul_m4_m4m4(effect_info->curr_mat, view, win);
- if (!equals_m4m4(effect_info->curr_mat, effect_info->last_mat)) {
- effect_info->jitter_index = 0;
- }
- }
+ WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ RegionView3D *rv3d = draw_ctx->rv3d;
+
+ if (e_data.effect_taa_sh == NULL) {
+ e_data.effect_taa_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_taa_frag_glsl,
+ NULL);
+ workbench_taa_jitter_init();
+ }
+
+ /* reset complete drawing when navigating. */
+ if (effect_info->jitter_index != 0) {
+ if (rv3d && rv3d->rflag & RV3D_NAVIGATING) {
+ effect_info->jitter_index = 0;
+ }
+ }
+
+ if (effect_info->view_updated) {
+ effect_info->jitter_index = 0;
+ effect_info->view_updated = false;
+ }
+
+ {
+ float view[4][4];
+ float win[4][4];
+ DRW_viewport_matrix_get(view, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(win, DRW_MAT_WIN);
+ mul_m4_m4m4(effect_info->curr_mat, view, win);
+ if (!equals_m4m4(effect_info->curr_mat, effect_info->last_mat)) {
+ effect_info->jitter_index = 0;
+ }
+ }
}
void workbench_taa_engine_free(void)
{
- DRW_SHADER_FREE_SAFE(e_data.effect_taa_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_taa_sh);
}
-
DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_buffer_tx)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_TextureList *txl = vedata->txl;
- WORKBENCH_EffectInfo *effect_info = stl->effects;
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- /*
- * jitter_index is not updated yet. This will be done in during draw phase.
- * so for now it is inversed.
- */
- int previous_jitter_index = effect_info->jitter_index;
-
- {
- const eGPUTextureFormat hist_buffer_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_RGBA8;
- DRW_texture_ensure_fullscreen_2d(&txl->history_buffer_tx, hist_buffer_format, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
- }
-
- {
- GPU_framebuffer_ensure_config(&fbl->effect_taa_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->history_buffer_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb, {
- GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx),
- });
- }
-
-
- DRWPass *pass = DRW_pass_create("Effect TAA", DRW_STATE_WRITE_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_taa_sh, pass);
- DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
- DRW_shgroup_uniform_texture_ref(grp, "historyBuffer", &txl->history_buffer_tx);
- DRW_shgroup_uniform_float(grp, "mixFactor", &effect_info->taa_mix_factor, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
-
- /*
- * Set the offset for the cavity shader so every iteration different
- * samples will be selected
- */
- wpd->ssao_params[3] = previous_jitter_index;
-
- return pass;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_TextureList *txl = vedata->txl;
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ /*
+ * jitter_index is not updated yet. This will be done in during draw phase.
+ * so for now it is inversed.
+ */
+ int previous_jitter_index = effect_info->jitter_index;
+
+ {
+ const eGPUTextureFormat hist_buffer_format = DRW_state_is_image_render() ? GPU_RGBA16F :
+ GPU_RGBA8;
+ DRW_texture_ensure_fullscreen_2d(&txl->history_buffer_tx, hist_buffer_format, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
+ }
+
+ {
+ GPU_framebuffer_ensure_config(&fbl->effect_taa_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->history_buffer_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx),
+ });
+ }
+
+ DRWPass *pass = DRW_pass_create("Effect TAA", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_taa_sh, pass);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
+ DRW_shgroup_uniform_texture_ref(grp, "historyBuffer", &txl->history_buffer_tx);
+ DRW_shgroup_uniform_float(grp, "mixFactor", &effect_info->taa_mix_factor, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+
+ /*
+ * Set the offset for the cavity shader so every iteration different
+ * samples will be selected
+ */
+ wpd->ssao_params[3] = previous_jitter_index;
+
+ return pass;
}
void workbench_taa_draw_scene_start(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_EffectInfo *effect_info = stl->effects;
- const float *viewport_size = DRW_viewport_size_get();
- int num_samples = 8;
- float (*samples)[2];
- float mix_factor;
-
- num_samples = workbench_taa_calculate_num_iterations(vedata);
- switch (num_samples) {
- default:
- case 5:
- samples = e_data.jitter_5;
- break;
- case 8:
- samples = e_data.jitter_8;
- break;
- case 11:
- samples = e_data.jitter_11;
- break;
- case 16:
- samples = e_data.jitter_16;
- break;
- case 32:
- samples = e_data.jitter_32;
- break;
- }
-
- mix_factor = 1.0f / (effect_info->jitter_index + 1);
-
- const int jitter_index = effect_info->jitter_index;
- const float *transform_offset = samples[jitter_index];
- effect_info->jitter_index = (jitter_index + 1) % num_samples;
-
- /* construct new matrices from transform delta */
- float viewmat[4][4];
- float persmat[4][4];
- DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
- DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
- DRW_viewport_matrix_get(effect_info->override_winmat, DRW_MAT_WIN);
-
- window_translate_m4(
- effect_info->override_winmat, persmat,
- transform_offset[0] / viewport_size[0],
- transform_offset[1] / viewport_size[1]);
-
- mul_m4_m4m4(effect_info->override_persmat, effect_info->override_winmat, viewmat);
- invert_m4_m4(effect_info->override_persinv, effect_info->override_persmat);
- invert_m4_m4(effect_info->override_wininv, effect_info->override_winmat);
-
- DRW_viewport_matrix_override_set(effect_info->override_persmat, DRW_MAT_PERS);
- DRW_viewport_matrix_override_set(effect_info->override_persinv, DRW_MAT_PERSINV);
- DRW_viewport_matrix_override_set(effect_info->override_winmat, DRW_MAT_WIN);
- DRW_viewport_matrix_override_set(effect_info->override_wininv, DRW_MAT_WININV);
-
- /* weight the mix factor by the jitter index */
- effect_info->taa_mix_factor = mix_factor;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
+ const float *viewport_size = DRW_viewport_size_get();
+ int num_samples = 8;
+ float(*samples)[2];
+ float mix_factor;
+
+ num_samples = workbench_taa_calculate_num_iterations(vedata);
+ switch (num_samples) {
+ default:
+ case 5:
+ samples = e_data.jitter_5;
+ break;
+ case 8:
+ samples = e_data.jitter_8;
+ break;
+ case 11:
+ samples = e_data.jitter_11;
+ break;
+ case 16:
+ samples = e_data.jitter_16;
+ break;
+ case 32:
+ samples = e_data.jitter_32;
+ break;
+ }
+
+ mix_factor = 1.0f / (effect_info->jitter_index + 1);
+
+ const int jitter_index = effect_info->jitter_index;
+ const float *transform_offset = samples[jitter_index];
+ effect_info->jitter_index = (jitter_index + 1) % num_samples;
+
+ /* construct new matrices from transform delta */
+ float viewmat[4][4];
+ float persmat[4][4];
+ DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_get(effect_info->override_winmat, DRW_MAT_WIN);
+
+ window_translate_m4(effect_info->override_winmat,
+ persmat,
+ transform_offset[0] / viewport_size[0],
+ transform_offset[1] / viewport_size[1]);
+
+ mul_m4_m4m4(effect_info->override_persmat, effect_info->override_winmat, viewmat);
+ invert_m4_m4(effect_info->override_persinv, effect_info->override_persmat);
+ invert_m4_m4(effect_info->override_wininv, effect_info->override_winmat);
+
+ DRW_viewport_matrix_override_set(effect_info->override_persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_override_set(effect_info->override_persinv, DRW_MAT_PERSINV);
+ DRW_viewport_matrix_override_set(effect_info->override_winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_override_set(effect_info->override_wininv, DRW_MAT_WININV);
+
+ /* weight the mix factor by the jitter index */
+ effect_info->taa_mix_factor = mix_factor;
}
void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata)
{
- /*
- * If first frame than the offset is 0.0 and its depth is the depth buffer to use
- * for the rest of the draw engines. We store it in a persistent buffer.
- *
- * If it is not the first frame we copy the persistent buffer back to the
- * default depth buffer
- */
- const WORKBENCH_StorageList *stl = vedata->stl;
- const WORKBENCH_FramebufferList *fbl = vedata->fbl;
- const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- WORKBENCH_EffectInfo *effect_info = stl->effects;
-
- if (effect_info->jitter_index == 1) {
- GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->depth_buffer_fb, 0, GPU_DEPTH_BIT);
- }
- else {
- GPU_framebuffer_blit(fbl->depth_buffer_fb, 0, dfbl->depth_only_fb, 0, GPU_DEPTH_BIT);
- }
-
- GPU_framebuffer_blit(dfbl->color_only_fb, 0, fbl->effect_taa_fb, 0, GPU_COLOR_BIT);
-
- if (!DRW_state_is_image_render()) {
- DRW_viewport_matrix_override_unset_all();
- }
-
- copy_m4_m4(effect_info->last_mat, effect_info->curr_mat);
- if (effect_info->jitter_index != 0 && !DRW_state_is_image_render()) {
- DRW_viewport_request_redraw();
- }
+ /*
+ * If first frame than the offset is 0.0 and its depth is the depth buffer to use
+ * for the rest of the draw engines. We store it in a persistent buffer.
+ *
+ * If it is not the first frame we copy the persistent buffer back to the
+ * default depth buffer
+ */
+ const WORKBENCH_StorageList *stl = vedata->stl;
+ const WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
+
+ if (effect_info->jitter_index == 1) {
+ GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->depth_buffer_fb, 0, GPU_DEPTH_BIT);
+ }
+ else {
+ GPU_framebuffer_blit(fbl->depth_buffer_fb, 0, dfbl->depth_only_fb, 0, GPU_DEPTH_BIT);
+ }
+
+ GPU_framebuffer_blit(dfbl->color_only_fb, 0, fbl->effect_taa_fb, 0, GPU_COLOR_BIT);
+
+ if (!DRW_state_is_image_render()) {
+ DRW_viewport_matrix_override_unset_all();
+ }
+
+ copy_m4_m4(effect_info->last_mat, effect_info->curr_mat);
+ if (effect_info->jitter_index != 0 && !DRW_state_is_image_render()) {
+ DRW_viewport_request_redraw();
+ }
}
void workbench_taa_view_updated(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- if (stl) {
- WORKBENCH_EffectInfo *effect_info = stl->effects;
- if (effect_info) {
- effect_info->view_updated = true;
- }
- }
+ WORKBENCH_StorageList *stl = vedata->stl;
+ if (stl) {
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
+ if (effect_info) {
+ effect_info->view_updated = true;
+ }
+ }
}
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 8aa21e92082..62a192bbb25 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -32,13 +32,20 @@
/* Note: currently unused, we may want to register so we can see this when debugging the view. */
RenderEngineType DRW_engine_viewport_workbench_type = {
- NULL, NULL,
- WORKBENCH_ENGINE, N_("Workbench"), RE_INTERNAL,
- NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL,
- &workbench_render_update_passes,
- &draw_engine_workbench_solid,
- {NULL, NULL, NULL},
+ NULL,
+ NULL,
+ WORKBENCH_ENGINE,
+ N_("Workbench"),
+ RE_INTERNAL,
+ NULL,
+ &DRW_render_to_image,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &workbench_render_update_passes,
+ &draw_engine_workbench_solid,
+ {NULL, NULL, NULL},
};
-
#undef WORKBENCH_ENGINE
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index f86a263406a..782e85597d7 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -43,28 +43,27 @@
#include "GPU_shader.h"
#include "GPU_texture.h"
-
/* *********** STATIC *********** */
typedef struct WORKBENCH_FORWARD_Shaders {
- struct GPUShader *transparent_accum_sh_cache[MAX_ACCUM_SHADERS];
- struct GPUShader *object_outline_sh;
- struct GPUShader *object_outline_texture_sh;
- struct GPUShader *object_outline_hair_sh;
+ struct GPUShader *transparent_accum_sh_cache[MAX_ACCUM_SHADERS];
+ struct GPUShader *object_outline_sh;
+ struct GPUShader *object_outline_texture_sh;
+ struct GPUShader *object_outline_hair_sh;
} WORKBENCH_FORWARD_Shaders;
static struct {
- WORKBENCH_FORWARD_Shaders sh_data[GPU_SHADER_CFG_LEN];
+ WORKBENCH_FORWARD_Shaders sh_data[GPU_SHADER_CFG_LEN];
- struct GPUShader *composite_sh_cache[2];
- struct GPUShader *checker_depth_sh;
+ struct GPUShader *composite_sh_cache[2];
+ struct GPUShader *checker_depth_sh;
- struct GPUTexture *object_id_tx; /* ref only, not alloced */
- struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
- struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */
- struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *object_id_tx; /* ref only, not alloced */
+ struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
+ struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */
+ struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
- int next_object_id;
+ int next_object_id;
} e_data = {{{{NULL}}}};
/* Shaders */
@@ -85,370 +84,389 @@ extern char datatoc_workbench_world_light_lib_glsl[];
/* static functions */
static char *workbench_build_forward_vert(bool is_hair)
{
- DynStr *ds = BLI_dynstr_new();
- if (is_hair) {
- BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
- }
- BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
-
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ DynStr *ds = BLI_dynstr_new();
+ if (is_hair) {
+ BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
+ }
+ BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
+
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static char *workbench_build_forward_transparent_accum_frag(void)
{
- DynStr *ds = BLI_dynstr_new();
+ DynStr *ds = BLI_dynstr_new();
- BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_forward_transparent_accum_frag_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_forward_transparent_accum_frag_glsl);
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static char *workbench_build_forward_composite_frag(void)
{
- DynStr *ds = BLI_dynstr_new();
-
- BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
- BLI_dynstr_append(ds, datatoc_workbench_forward_composite_frag_glsl);
-
- char *str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_forward_composite_frag_glsl);
+
+ char *str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
static void workbench_init_object_data(DrawData *dd)
{
- WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
- data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
+ WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
+ data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
}
-WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(
- WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, ImageUser *iuser, int color_type, int interp)
+WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_Data *vedata,
+ Object *ob,
+ Material *mat,
+ Image *ima,
+ ImageUser *iuser,
+ int color_type,
+ int interp)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- WORKBENCH_MaterialData *material;
- WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
- &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
- WORKBENCH_MaterialData material_template;
- DRWShadingGroup *grp;
-
- /* Solid */
- workbench_material_update_data(wpd, ob, mat, &material_template);
- material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
- material_template.color_type = color_type;
- material_template.ima = ima;
- material_template.iuser = iuser;
- material_template.interp = interp;
- uint hash = workbench_material_get_hash(&material_template, false);
-
- material = BLI_ghash_lookup(wpd->material_transp_hash, POINTER_FROM_UINT(hash));
- if (material == NULL) {
- material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
-
- /* transparent accum */
- grp = DRW_shgroup_create(
- color_type == V3D_SHADING_TEXTURE_COLOR ? wpd->transparent_accum_texture_sh: wpd->transparent_accum_sh,
- psl->transparent_accum_pass);
- DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
- DRW_shgroup_uniform_float_copy(grp, "alpha", wpd->shading.xray_alpha);
- DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- workbench_material_copy(material, &material_template);
- if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
- BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
- DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
- }
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- }
- if (SHADOW_ENABLED(wpd)) {
- DRW_shgroup_uniform_float_copy(grp, "shadowMultiplier", wpd->shadow_multiplier);
- DRW_shgroup_uniform_float_copy(grp, "shadowShift", wpd->shadow_shift);
- DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
- }
-
- workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false, interp);
- material->shgrp = grp;
-
- /* Depth */
- if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) {
- material->shgrp_object_outline = DRW_shgroup_create(
- sh_data->object_outline_texture_sh, psl->object_outline_pass);
- GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D, false);
- DRW_shgroup_uniform_texture(material->shgrp_object_outline, "image", tex);
- }
- else {
- material->shgrp_object_outline = DRW_shgroup_create(
- sh_data->object_outline_sh, psl->object_outline_pass);
- }
- material->object_id = engine_object_data->object_id;
- DRW_shgroup_uniform_int(material->shgrp_object_outline, "object_id", &material->object_id, 1);
- if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
- DRW_shgroup_world_clip_planes_from_rv3d(material->shgrp_object_outline, draw_ctx->rv3d);
- }
- BLI_ghash_insert(wpd->material_transp_hash, POINTER_FROM_UINT(hash), material);
- }
- return material;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_MaterialData *material;
+ WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
+ &ob->id,
+ &draw_engine_workbench_solid,
+ sizeof(WORKBENCH_ObjectData),
+ &workbench_init_object_data,
+ NULL);
+ WORKBENCH_MaterialData material_template;
+ DRWShadingGroup *grp;
+
+ /* Solid */
+ workbench_material_update_data(wpd, ob, mat, &material_template);
+ material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
+ material_template.color_type = color_type;
+ material_template.ima = ima;
+ material_template.iuser = iuser;
+ material_template.interp = interp;
+ uint hash = workbench_material_get_hash(&material_template, false);
+
+ material = BLI_ghash_lookup(wpd->material_transp_hash, POINTER_FROM_UINT(hash));
+ if (material == NULL) {
+ material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
+
+ /* transparent accum */
+ grp = DRW_shgroup_create(color_type == V3D_SHADING_TEXTURE_COLOR ?
+ wpd->transparent_accum_texture_sh :
+ wpd->transparent_accum_sh,
+ psl->transparent_accum_pass);
+ DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
+ DRW_shgroup_uniform_float_copy(grp, "alpha", wpd->shading.xray_alpha);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ workbench_material_copy(material, &material_template);
+ if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
+ BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture(
+ grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture);
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ }
+ if (SHADOW_ENABLED(wpd)) {
+ DRW_shgroup_uniform_float_copy(grp, "shadowMultiplier", wpd->shadow_multiplier);
+ DRW_shgroup_uniform_float_copy(grp, "shadowShift", wpd->shadow_shift);
+ DRW_shgroup_uniform_float_copy(grp, "shadowFocus", wpd->shadow_focus);
+ }
+
+ workbench_material_shgroup_uniform(wpd, grp, material, ob, false, false, interp);
+ material->shgrp = grp;
+
+ /* Depth */
+ if (workbench_material_determine_color_type(wpd, material->ima, ob) ==
+ V3D_SHADING_TEXTURE_COLOR) {
+ material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_texture_sh,
+ psl->object_outline_pass);
+ GPUTexture *tex = GPU_texture_from_blender(
+ material->ima, material->iuser, GL_TEXTURE_2D, false);
+ DRW_shgroup_uniform_texture(material->shgrp_object_outline, "image", tex);
+ }
+ else {
+ material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_sh,
+ psl->object_outline_pass);
+ }
+ material->object_id = engine_object_data->object_id;
+ DRW_shgroup_uniform_int(material->shgrp_object_outline, "object_id", &material->object_id, 1);
+ if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
+ DRW_shgroup_world_clip_planes_from_rv3d(material->shgrp_object_outline, draw_ctx->rv3d);
+ }
+ BLI_ghash_insert(wpd->material_transp_hash, POINTER_FROM_UINT(hash), material);
+ }
+ return material;
}
-static GPUShader *ensure_forward_accum_shaders(
- WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair, eGPUShaderConfig sh_cfg)
+static GPUShader *ensure_forward_accum_shaders(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair,
+ eGPUShaderConfig sh_cfg)
{
- WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
- int index = workbench_material_get_accum_shader_index(wpd, use_textures, is_hair);
- if (sh_data->transparent_accum_sh_cache[index] == NULL) {
- const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
- char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
- char *transparent_accum_vert = workbench_build_forward_vert(is_hair);
- char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
- sh_data->transparent_accum_sh_cache[index] = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, transparent_accum_vert, NULL},
- .frag = (const char *[]){transparent_accum_frag, NULL},
- .defs = (const char *[]){sh_cfg_data->def, defines, NULL},
- });
- MEM_freeN(transparent_accum_vert);
- MEM_freeN(transparent_accum_frag);
- MEM_freeN(defines);
- }
- return sh_data->transparent_accum_sh_cache[index];
+ WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
+ int index = workbench_material_get_accum_shader_index(wpd, use_textures, is_hair);
+ if (sh_data->transparent_accum_sh_cache[index] == NULL) {
+ const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
+ char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
+ char *transparent_accum_vert = workbench_build_forward_vert(is_hair);
+ char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
+ sh_data->transparent_accum_sh_cache[index] = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib, transparent_accum_vert, NULL},
+ .frag = (const char *[]){transparent_accum_frag, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, defines, NULL},
+ });
+ MEM_freeN(transparent_accum_vert);
+ MEM_freeN(transparent_accum_frag);
+ MEM_freeN(defines);
+ }
+ return sh_data->transparent_accum_sh_cache[index];
}
static GPUShader *ensure_forward_composite_shaders(WORKBENCH_PrivateData *wpd)
{
- int index = OBJECT_OUTLINE_ENABLED(wpd) ? 1 : 0;
- if (e_data.composite_sh_cache[index] == NULL) {
- char *defines = workbench_material_build_defines(wpd, false, false);
- char *composite_frag = workbench_build_forward_composite_frag();
- e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
- MEM_freeN(composite_frag);
- MEM_freeN(defines);
- }
- return e_data.composite_sh_cache[index];
+ int index = OBJECT_OUTLINE_ENABLED(wpd) ? 1 : 0;
+ if (e_data.composite_sh_cache[index] == NULL) {
+ char *defines = workbench_material_build_defines(wpd, false, false);
+ char *composite_frag = workbench_build_forward_composite_frag();
+ e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
+ MEM_freeN(composite_frag);
+ MEM_freeN(defines);
+ }
+ return e_data.composite_sh_cache[index];
}
void workbench_forward_choose_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg)
{
- wpd->composite_sh = ensure_forward_composite_shaders(wpd);
- wpd->transparent_accum_sh = ensure_forward_accum_shaders(wpd, false, false, sh_cfg);
- wpd->transparent_accum_hair_sh = ensure_forward_accum_shaders(wpd, false, true, sh_cfg);
- wpd->transparent_accum_texture_sh = ensure_forward_accum_shaders(wpd, true, false, sh_cfg);
- wpd->transparent_accum_texture_hair_sh = ensure_forward_accum_shaders(wpd, true, true, sh_cfg);
+ wpd->composite_sh = ensure_forward_composite_shaders(wpd);
+ wpd->transparent_accum_sh = ensure_forward_accum_shaders(wpd, false, false, sh_cfg);
+ wpd->transparent_accum_hair_sh = ensure_forward_accum_shaders(wpd, false, true, sh_cfg);
+ wpd->transparent_accum_texture_sh = ensure_forward_accum_shaders(wpd, true, false, sh_cfg);
+ wpd->transparent_accum_texture_hair_sh = ensure_forward_accum_shaders(wpd, true, true, sh_cfg);
}
void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg)
{
- WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
-
- if (sh_data->object_outline_sh == NULL) {
- const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
- char *defines = workbench_material_build_defines(wpd, false, false);
- char *defines_texture = workbench_material_build_defines(wpd, true, false);
- char *defines_hair = workbench_material_build_defines(wpd, false, true);
- char *forward_vert = workbench_build_forward_vert(false);
- char *forward_hair_vert = workbench_build_forward_vert(true);
-
- sh_data->object_outline_sh = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
- .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, defines, NULL},
- });
- sh_data->object_outline_texture_sh = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
- .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, defines_texture, NULL},
- });
- sh_data->object_outline_hair_sh = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg_data->lib, forward_hair_vert, NULL},
- .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, defines_hair, NULL},
- });
-
- MEM_freeN(forward_hair_vert);
- MEM_freeN(forward_vert);
- MEM_freeN(defines);
- MEM_freeN(defines_texture);
- MEM_freeN(defines_hair);
- }
+ WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
+
+ if (sh_data->object_outline_sh == NULL) {
+ const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
+ char *defines = workbench_material_build_defines(wpd, false, false);
+ char *defines_texture = workbench_material_build_defines(wpd, true, false);
+ char *defines_hair = workbench_material_build_defines(wpd, false, true);
+ char *forward_vert = workbench_build_forward_vert(false);
+ char *forward_hair_vert = workbench_build_forward_vert(true);
+
+ sh_data->object_outline_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
+ .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, defines, NULL},
+ });
+ sh_data->object_outline_texture_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
+ .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, defines_texture, NULL},
+ });
+ sh_data->object_outline_hair_sh = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib, forward_hair_vert, NULL},
+ .frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, defines_hair, NULL},
+ });
+
+ MEM_freeN(forward_hair_vert);
+ MEM_freeN(forward_vert);
+ MEM_freeN(defines);
+ MEM_freeN(defines_texture);
+ MEM_freeN(defines_hair);
+ }
}
/* public functions */
void workbench_forward_engine_init(WORKBENCH_Data *vedata)
{
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_StorageList *stl = vedata->stl;
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- DRWShadingGroup *grp;
-
- if (!stl->g_data) {
- /* Alloc transient pointers */
- stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
- }
- if (!stl->effects) {
- stl->effects = MEM_callocN(sizeof(*stl->effects), __func__);
- workbench_effect_info_init(stl->effects);
- }
- WORKBENCH_PrivateData *wpd = stl->g_data;
- workbench_private_data_init(wpd);
- float light_direction[3];
- workbench_private_data_get_light_direction(wpd, light_direction);
-
- if (!e_data.checker_depth_sh) {
- e_data.checker_depth_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
- }
-
- workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
-
- workbench_volume_engine_init();
- workbench_fxaa_engine_init();
- workbench_taa_engine_init(vedata);
-
- workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
- workbench_forward_choose_shaders(wpd, draw_ctx->sh_cfg);
-
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
- const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
-
- e_data.object_id_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent);
- e_data.transparent_accum_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
- e_data.transparent_revealage_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_R16F, &draw_engine_workbench_transparent);
- e_data.composite_buffer_tx = DRW_texture_pool_query_2d(
- size[0], size[1], comp_tex_format, &draw_engine_workbench_transparent);
-
- GPU_framebuffer_ensure_config(&fbl->object_outline_fb, {
- GPU_ATTACHMENT_TEXTURE(dtxl->depth),
- GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.transparent_revealage_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->composite_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->effect_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx),
- });
-
- workbench_volume_cache_init(vedata);
- const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
- const int cull_state = (do_cull) ? DRW_STATE_CULL_BACK : 0;
-
- /* Transparency Accum */
- {
- int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT | cull_state;
- psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
- }
- /* Depth */
- {
- int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | cull_state;
- psl->object_outline_pass = DRW_pass_create("Object Outline Pass", state);
- }
- /* Composite */
- {
- int state = DRW_STATE_WRITE_COLOR;
- psl->composite_pass = DRW_pass_create("Composite", state);
-
- grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
- if (OBJECT_ID_PASS_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
- }
- DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.transparent_accum_tx);
- DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.transparent_revealage_tx);
- DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
-
- /* TODO(campbell): displays but masks geometry,
- * only use with wire or solid-without-xray for now. */
- if ((wpd->shading.type != OB_WIRE && !XRAY_FLAG_ENABLED(wpd)) &&
- (draw_ctx->rv3d && (draw_ctx->rv3d->rflag & RV3D_CLIPPING) && draw_ctx->rv3d->clipbb))
- {
- psl->background_pass = DRW_pass_create(
- "Background", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
- grp = DRW_shgroup_create(shader, psl->background_pass);
- wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
- DRW_shgroup_call_add(grp, wpd->world_clip_planes_batch, NULL);
- DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
- }
-
- {
- workbench_aa_create_pass(vedata, &e_data.transparent_accum_tx);
- }
-
- /* Checker Depth */
- {
- static float noise_offset = 0.0f;
- float blend_threshold = 0.0f;
-
- if (DRW_state_is_image_render()) {
- /* TODO: Should be based on the number of samples used for render. */
- noise_offset = fmodf(noise_offset + 1.0f / 8.0f, 1.0f);
- }
-
- if (XRAY_FLAG_ENABLED(wpd)) {
- blend_threshold = 1.0f - XRAY_ALPHA(wpd) * 0.9f;
- }
-
- if (wpd->shading.type == OB_WIRE) {
- wpd->shading.xray_alpha = 0.0f;
- wpd->shading.xray_alpha_wire = 0.0f;
- }
-
- int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
- psl->checker_depth_pass = DRW_pass_create("Checker Depth", state);
- grp = DRW_shgroup_create(e_data.checker_depth_sh, psl->checker_depth_pass);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- DRW_shgroup_uniform_float_copy(grp, "threshold", blend_threshold);
- DRW_shgroup_uniform_float_copy(grp, "offset", noise_offset);
- }
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ DRWShadingGroup *grp;
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
+ }
+ if (!stl->effects) {
+ stl->effects = MEM_callocN(sizeof(*stl->effects), __func__);
+ workbench_effect_info_init(stl->effects);
+ }
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ workbench_private_data_init(wpd);
+ float light_direction[3];
+ workbench_private_data_get_light_direction(wpd, light_direction);
+
+ if (!e_data.checker_depth_sh) {
+ e_data.checker_depth_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
+ }
+
+ workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
+
+ workbench_volume_engine_init();
+ workbench_fxaa_engine_init();
+ workbench_taa_engine_init(vedata);
+
+ workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
+ workbench_forward_choose_shaders(wpd, draw_ctx->sh_cfg);
+
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+ const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F :
+ GPU_R11F_G11F_B10F;
+
+ e_data.object_id_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent);
+ e_data.transparent_accum_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
+ e_data.transparent_revealage_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_R16F, &draw_engine_workbench_transparent);
+ e_data.composite_buffer_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], comp_tex_format, &draw_engine_workbench_transparent);
+
+ GPU_framebuffer_ensure_config(&fbl->object_outline_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.transparent_revealage_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->composite_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->effect_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx),
+ });
+
+ workbench_volume_cache_init(vedata);
+ const bool do_cull = CULL_BACKFACE_ENABLED(wpd);
+ const int cull_state = (do_cull) ? DRW_STATE_CULL_BACK : 0;
+
+ /* Transparency Accum */
+ {
+ int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT | cull_state;
+ psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
+ }
+ /* Depth */
+ {
+ int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | cull_state;
+ psl->object_outline_pass = DRW_pass_create("Object Outline Pass", state);
+ }
+ /* Composite */
+ {
+ int state = DRW_STATE_WRITE_COLOR;
+ psl->composite_pass = DRW_pass_create("Composite", state);
+
+ grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
+ if (OBJECT_ID_PASS_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
+ }
+ DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.transparent_accum_tx);
+ DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.transparent_revealage_tx);
+ DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+
+ /* TODO(campbell): displays but masks geometry,
+ * only use with wire or solid-without-xray for now. */
+ if ((wpd->shading.type != OB_WIRE && !XRAY_FLAG_ENABLED(wpd)) &&
+ (draw_ctx->rv3d && (draw_ctx->rv3d->rflag & RV3D_CLIPPING) && draw_ctx->rv3d->clipbb)) {
+ psl->background_pass = DRW_pass_create("Background",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
+ grp = DRW_shgroup_create(shader, psl->background_pass);
+ wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
+ DRW_shgroup_call_add(grp, wpd->world_clip_planes_batch, NULL);
+ DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
+ }
+
+ {
+ workbench_aa_create_pass(vedata, &e_data.transparent_accum_tx);
+ }
+
+ /* Checker Depth */
+ {
+ static float noise_offset = 0.0f;
+ float blend_threshold = 0.0f;
+
+ if (DRW_state_is_image_render()) {
+ /* TODO: Should be based on the number of samples used for render. */
+ noise_offset = fmodf(noise_offset + 1.0f / 8.0f, 1.0f);
+ }
+
+ if (XRAY_FLAG_ENABLED(wpd)) {
+ blend_threshold = 1.0f - XRAY_ALPHA(wpd) * 0.9f;
+ }
+
+ if (wpd->shading.type == OB_WIRE) {
+ wpd->shading.xray_alpha = 0.0f;
+ wpd->shading.xray_alpha_wire = 0.0f;
+ }
+
+ int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
+ psl->checker_depth_pass = DRW_pass_create("Checker Depth", state);
+ grp = DRW_shgroup_create(e_data.checker_depth_sh, psl->checker_depth_pass);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ DRW_shgroup_uniform_float_copy(grp, "threshold", blend_threshold);
+ DRW_shgroup_uniform_float_copy(grp, "offset", noise_offset);
+ }
}
void workbench_forward_engine_free()
{
- for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
- WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_data_index];
- for (int index = 0; index < MAX_ACCUM_SHADERS; index++) {
- DRW_SHADER_FREE_SAFE(sh_data->transparent_accum_sh_cache[index]);
- }
- DRW_SHADER_FREE_SAFE(sh_data->object_outline_sh);
- DRW_SHADER_FREE_SAFE(sh_data->object_outline_texture_sh);
- DRW_SHADER_FREE_SAFE(sh_data->object_outline_hair_sh);
- }
-
- for (int index = 0; index < 2; index++) {
- DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
- }
- DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh);
-
- workbench_volume_engine_free();
- workbench_fxaa_engine_free();
- workbench_taa_engine_free();
- workbench_dof_engine_free();
+ for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
+ WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_data_index];
+ for (int index = 0; index < MAX_ACCUM_SHADERS; index++) {
+ DRW_SHADER_FREE_SAFE(sh_data->transparent_accum_sh_cache[index]);
+ }
+ DRW_SHADER_FREE_SAFE(sh_data->object_outline_sh);
+ DRW_SHADER_FREE_SAFE(sh_data->object_outline_texture_sh);
+ DRW_SHADER_FREE_SAFE(sh_data->object_outline_hair_sh);
+ }
+
+ for (int index = 0; index < 2; index++) {
+ DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
+ }
+ DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh);
+
+ workbench_volume_engine_free();
+ workbench_fxaa_engine_free();
+ workbench_taa_engine_free();
+ workbench_dof_engine_free();
}
void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata))
@@ -457,179 +475,180 @@ void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata))
static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
-
- for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
- if (md->type != eModifierType_ParticleSystem) {
- continue;
- }
- ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
- if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
- continue;
- }
- ParticleSettings *part = psys->part;
- const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
-
- if (draw_as == PART_DRAW_PATH) {
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Material *mat;
- Image *image;
- ImageUser *iuser;
- int interp;
- workbench_material_get_image_and_mat(ob, part->omat, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
- WORKBENCH_MaterialData *material = workbench_forward_get_or_create_material_data(vedata, ob, mat, image, iuser, color_type, interp);
-
- struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR)
- ? wpd->transparent_accum_hair_sh
- : wpd->transparent_accum_texture_hair_sh;
- DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
- ob, psys, md,
- psl->transparent_accum_pass,
- shader);
- DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
- workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, false, interp);
- DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- /* Hairs have lots of layer and can rapidly become the most prominent surface.
- * So lower their alpha artificially. */
- float hair_alpha = XRAY_ALPHA(wpd) * 0.33f;
- DRW_shgroup_uniform_float_copy(shgrp, "alpha", hair_alpha);
- if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
- BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
- DRW_shgroup_uniform_texture(shgrp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
- }
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
- DRW_shgroup_uniform_vec2(shgrp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- }
-
- WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
- shgrp = DRW_shgroup_hair_create(
- ob, psys, md,
- vedata->psl->object_outline_pass,
- sh_data->object_outline_hair_sh);
- DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
- }
- }
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type != eModifierType_ParticleSystem) {
+ continue;
+ }
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+
+ if (draw_as == PART_DRAW_PATH) {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Material *mat;
+ Image *image;
+ ImageUser *iuser;
+ int interp;
+ workbench_material_get_image_and_mat(ob, part->omat, &image, &iuser, &interp, &mat);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ WORKBENCH_MaterialData *material = workbench_forward_get_or_create_material_data(
+ vedata, ob, mat, image, iuser, color_type, interp);
+
+ struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
+ wpd->transparent_accum_hair_sh :
+ wpd->transparent_accum_texture_hair_sh;
+ DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
+ ob, psys, md, psl->transparent_accum_pass, shader);
+ DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
+ workbench_material_shgroup_uniform(wpd, shgrp, material, ob, false, false, interp);
+ DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ /* Hairs have lots of layer and can rapidly become the most prominent surface.
+ * So lower their alpha artificially. */
+ float hair_alpha = XRAY_ALPHA(wpd) * 0.33f;
+ DRW_shgroup_uniform_float_copy(shgrp, "alpha", hair_alpha);
+ if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
+ BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture(
+ shgrp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture);
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
+ DRW_shgroup_uniform_vec2(shgrp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ }
+
+ WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ shgrp = DRW_shgroup_hair_create(
+ ob, psys, md, vedata->psl->object_outline_pass, sh_data->object_outline_hair_sh);
+ DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
+ }
+ }
}
void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- const bool is_wire = (ob->dt == OB_WIRE);
-
- if (!DRW_object_is_renderable(ob)) {
- return;
- }
-
- if (ob->type == OB_MESH) {
- workbench_forward_cache_populate_particles(vedata, ob);
- }
-
- ModifierData *md;
- if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
- (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
- (modifier_isEnabled(scene, md, eModifierMode_Realtime)) &&
- (((SmokeModifierData *)md)->domain != NULL))
- {
- workbench_volume_cache_populate(vedata, scene, ob, md);
- return; /* Do not draw solid in this case. */
- }
-
- if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
- return;
- }
- if (ob->dt < OB_WIRE) {
- return;
- }
-
- WORKBENCH_MaterialData *material;
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
- const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
- bool is_drawn = false;
-
- if (!is_sculpt_mode && TEXTURE_DRAWING_ENABLED(wpd) && ELEM(ob->type, OB_MESH)) {
- const Mesh *me = ob->data;
- if (me->mloopuv) {
- const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
- struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
- for (int i = 0; i < materials_len; i++) {
- Material *mat;
- Image *image;
- ImageUser *iuser;
- int interp;
- workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
- material = workbench_forward_get_or_create_material_data(vedata, ob, mat, image, iuser, color_type, interp);
- DRW_shgroup_call_object_add(material->shgrp_object_outline, geom_array[i], ob);
- DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
- }
- is_drawn = true;
- }
- }
-
- /* Fallback from not drawn OB_TEXTURE mode or just OB_SOLID mode */
- if (!is_drawn) {
- if (ELEM(wpd->shading.color_type,
- V3D_SHADING_SINGLE_COLOR, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR))
- {
- /* No material split needed */
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- material = workbench_forward_get_or_create_material_data(vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
- if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
- if (!is_wire) {
- DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
- }
- }
- else {
- DRW_shgroup_call_object_add(material->shgrp_object_outline, geom, ob);
- if (!is_wire) {
- DRW_shgroup_call_object_add(material->shgrp, geom, ob);
- }
- }
- }
- }
- else {
- const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
- struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
- for (int i = 0; i < materials_len; i++) {
- gpumat_array[i] = NULL;
- }
-
- struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
- ob, gpumat_array, materials_len, NULL, NULL, NULL);
- if (mat_geom) {
- for (int i = 0; i < materials_len; ++i) {
- if (mat_geom[i] == NULL) {
- continue;
- }
-
- Material *mat = give_current_material(ob, i + 1);
- material = workbench_forward_get_or_create_material_data(vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
- if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
- if (!is_wire) {
- DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
- }
- }
- else {
- DRW_shgroup_call_object_add(material->shgrp_object_outline, mat_geom[i], ob);
- if (!is_wire) {
- DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob);
- }
- }
- }
- }
- }
- }
- }
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ const bool is_wire = (ob->dt == OB_WIRE);
+
+ if (!DRW_object_is_renderable(ob)) {
+ return;
+ }
+
+ if (ob->type == OB_MESH) {
+ workbench_forward_cache_populate_particles(vedata, ob);
+ }
+
+ ModifierData *md;
+ if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
+ (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
+ (modifier_isEnabled(scene, md, eModifierMode_Realtime)) &&
+ (((SmokeModifierData *)md)->domain != NULL)) {
+ workbench_volume_cache_populate(vedata, scene, ob, md);
+ return; /* Do not draw solid in this case. */
+ }
+
+ if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+ return;
+ }
+ if (ob->dt < OB_WIRE) {
+ return;
+ }
+
+ WORKBENCH_MaterialData *material;
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
+ const bool is_active = (ob == draw_ctx->obact);
+ const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
+ bool is_drawn = false;
+
+ if (!is_sculpt_mode && TEXTURE_DRAWING_ENABLED(wpd) && ELEM(ob->type, OB_MESH)) {
+ const Mesh *me = ob->data;
+ if (me->mloopuv) {
+ const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
+ struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
+ for (int i = 0; i < materials_len; i++) {
+ Material *mat;
+ Image *image;
+ ImageUser *iuser;
+ int interp;
+ workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ material = workbench_forward_get_or_create_material_data(
+ vedata, ob, mat, image, iuser, color_type, interp);
+ DRW_shgroup_call_object_add(material->shgrp_object_outline, geom_array[i], ob);
+ DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
+ }
+ is_drawn = true;
+ }
+ }
+
+ /* Fallback from not drawn OB_TEXTURE mode or just OB_SOLID mode */
+ if (!is_drawn) {
+ if (ELEM(wpd->shading.color_type,
+ V3D_SHADING_SINGLE_COLOR,
+ V3D_SHADING_OBJECT_COLOR,
+ V3D_SHADING_RANDOM_COLOR)) {
+ /* No material split needed */
+ struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ material = workbench_forward_get_or_create_material_data(
+ vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
+ if (!is_wire) {
+ DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
+ }
+ }
+ else {
+ DRW_shgroup_call_object_add(material->shgrp_object_outline, geom, ob);
+ if (!is_wire) {
+ DRW_shgroup_call_object_add(material->shgrp, geom, ob);
+ }
+ }
+ }
+ }
+ else {
+ const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ for (int i = 0; i < materials_len; i++) {
+ gpumat_array[i] = NULL;
+ }
+
+ struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len, NULL, NULL, NULL);
+ if (mat_geom) {
+ for (int i = 0; i < materials_len; ++i) {
+ if (mat_geom[i] == NULL) {
+ continue;
+ }
+
+ Material *mat = give_current_material(ob, i + 1);
+ material = workbench_forward_get_or_create_material_data(
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
+ if (!is_wire) {
+ DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
+ }
+ }
+ else {
+ DRW_shgroup_call_object_add(material->shgrp_object_outline, mat_geom[i], ob);
+ if (!is_wire) {
+ DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
void workbench_forward_cache_finish(WORKBENCH_Data *UNUSED(vedata))
@@ -638,69 +657,69 @@ void workbench_forward_cache_finish(WORKBENCH_Data *UNUSED(vedata))
void workbench_forward_draw_background(WORKBENCH_Data *UNUSED(vedata))
{
- const float clear_depth = 1.0f;
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- DRW_stats_group_start("Clear depth");
- GPU_framebuffer_bind(dfbl->default_fb);
- GPU_framebuffer_clear_depth(dfbl->default_fb, clear_depth);
- DRW_stats_group_end();
+ const float clear_depth = 1.0f;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DRW_stats_group_start("Clear depth");
+ GPU_framebuffer_bind(dfbl->default_fb);
+ GPU_framebuffer_clear_depth(dfbl->default_fb, clear_depth);
+ DRW_stats_group_end();
}
void workbench_forward_draw_scene(WORKBENCH_Data *vedata)
{
- WORKBENCH_PassList *psl = vedata->psl;
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_FramebufferList *fbl = vedata->fbl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
-
- if (TAA_ENABLED(wpd)) {
- workbench_taa_draw_scene_start(vedata);
- }
-
- /* Write Depth + Object ID */
- const float clear_outline[4] = {0.0f};
- GPU_framebuffer_bind(fbl->object_outline_fb);
- GPU_framebuffer_clear_color(fbl->object_outline_fb, clear_outline);
- DRW_draw_pass(psl->object_outline_pass);
-
- if (XRAY_ALPHA(wpd) > 0.0) {
- const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- GPU_framebuffer_bind(fbl->transparent_accum_fb);
- GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
- DRW_draw_pass(psl->transparent_accum_pass);
- }
- else {
- /* TODO(fclem): this is unnecessary and takes up perf.
- * Better change the composite frag shader to not use the tx. */
- const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- GPU_framebuffer_bind(fbl->transparent_accum_fb);
- GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
- }
-
- /* Composite */
- GPU_framebuffer_bind(fbl->composite_fb);
- DRW_draw_pass(psl->composite_pass);
- DRW_draw_pass(psl->volume_pass);
-
- /* Only when clipping is enabled. */
- if (psl->background_pass) {
- DRW_draw_pass(psl->background_pass);
- }
-
- /* Color correct and Anti aliasing */
- workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx);
-
- /* Apply checker pattern */
- GPU_framebuffer_bind(dfbl->depth_only_fb);
- DRW_draw_pass(psl->checker_depth_pass);
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ if (TAA_ENABLED(wpd)) {
+ workbench_taa_draw_scene_start(vedata);
+ }
+
+ /* Write Depth + Object ID */
+ const float clear_outline[4] = {0.0f};
+ GPU_framebuffer_bind(fbl->object_outline_fb);
+ GPU_framebuffer_clear_color(fbl->object_outline_fb, clear_outline);
+ DRW_draw_pass(psl->object_outline_pass);
+
+ if (XRAY_ALPHA(wpd) > 0.0) {
+ const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ GPU_framebuffer_bind(fbl->transparent_accum_fb);
+ GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
+ DRW_draw_pass(psl->transparent_accum_pass);
+ }
+ else {
+ /* TODO(fclem): this is unnecessary and takes up perf.
+ * Better change the composite frag shader to not use the tx. */
+ const float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ GPU_framebuffer_bind(fbl->transparent_accum_fb);
+ GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
+ }
+
+ /* Composite */
+ GPU_framebuffer_bind(fbl->composite_fb);
+ DRW_draw_pass(psl->composite_pass);
+ DRW_draw_pass(psl->volume_pass);
+
+ /* Only when clipping is enabled. */
+ if (psl->background_pass) {
+ DRW_draw_pass(psl->background_pass);
+ }
+
+ /* Color correct and Anti aliasing */
+ workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx);
+
+ /* Apply checker pattern */
+ GPU_framebuffer_bind(dfbl->depth_only_fb);
+ DRW_draw_pass(psl->checker_depth_pass);
}
void workbench_forward_draw_finish(WORKBENCH_Data *vedata)
{
- WORKBENCH_StorageList *stl = vedata->stl;
- WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
- workbench_private_data_free(wpd);
- workbench_volume_smoke_textures_free(wpd);
+ workbench_private_data_free(wpd);
+ workbench_volume_smoke_textures_free(wpd);
}
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 2cec691a62f..d73eee37a98 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -37,260 +37,278 @@
#define HSV_SATURATION 0.5
#define HSV_VALUE 0.8
-void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data)
+void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ Material *mat,
+ WORKBENCH_MaterialData *data)
{
- /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
- int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type;
- copy_v3_fl3(data->diffuse_color, 0.8f, 0.8f, 0.8f);
- copy_v3_v3(data->base_color, data->diffuse_color);
- copy_v3_fl3(data->specular_color, 0.05f, 0.05f, 0.05f); /* Dielectric: 5% reflective. */
- data->metallic = 0.0f;
- data->roughness = 0.5f; /* sqrtf(0.25f); */
+ /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
+ int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ?
+ V3D_SHADING_MATERIAL_COLOR :
+ wpd->shading.color_type;
+ copy_v3_fl3(data->diffuse_color, 0.8f, 0.8f, 0.8f);
+ copy_v3_v3(data->base_color, data->diffuse_color);
+ copy_v3_fl3(data->specular_color, 0.05f, 0.05f, 0.05f); /* Dielectric: 5% reflective. */
+ data->metallic = 0.0f;
+ data->roughness = 0.5f; /* sqrtf(0.25f); */
- if (color_type == V3D_SHADING_SINGLE_COLOR) {
- copy_v3_v3(data->diffuse_color, wpd->shading.single_color);
- copy_v3_v3(data->base_color, data->diffuse_color);
- }
- else if (color_type == V3D_SHADING_RANDOM_COLOR) {
- uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
- if (ob->id.lib) {
- hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->name);
- }
+ if (color_type == V3D_SHADING_SINGLE_COLOR) {
+ copy_v3_v3(data->diffuse_color, wpd->shading.single_color);
+ copy_v3_v3(data->base_color, data->diffuse_color);
+ }
+ else if (color_type == V3D_SHADING_RANDOM_COLOR) {
+ uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
+ if (ob->id.lib) {
+ hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->name);
+ }
- float hue = BLI_hash_int_01(hash);
- float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
- hsv_to_rgb_v(hsv, data->diffuse_color);
- copy_v3_v3(data->base_color, data->diffuse_color);
- }
- else if (color_type == V3D_SHADING_OBJECT_COLOR) {
- copy_v3_v3(data->diffuse_color, ob->color);
- copy_v3_v3(data->base_color, data->diffuse_color);
- }
- else {
- /* V3D_SHADING_MATERIAL_COLOR */
- if (mat) {
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
- copy_v3_v3(data->base_color, &mat->r);
- mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic);
- mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic);
- add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic));
- data->metallic = mat->metallic;
- data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
- }
- else {
- copy_v3_v3(data->base_color, &mat->r);
- copy_v3_v3(data->diffuse_color, &mat->r);
- }
- }
- }
+ float hue = BLI_hash_int_01(hash);
+ float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
+ hsv_to_rgb_v(hsv, data->diffuse_color);
+ copy_v3_v3(data->base_color, data->diffuse_color);
+ }
+ else if (color_type == V3D_SHADING_OBJECT_COLOR) {
+ copy_v3_v3(data->diffuse_color, ob->color);
+ copy_v3_v3(data->base_color, data->diffuse_color);
+ }
+ else {
+ /* V3D_SHADING_MATERIAL_COLOR */
+ if (mat) {
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+ copy_v3_v3(data->base_color, &mat->r);
+ mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic);
+ mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic);
+ add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic));
+ data->metallic = mat->metallic;
+ data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
+ }
+ else {
+ copy_v3_v3(data->base_color, &mat->r);
+ copy_v3_v3(data->diffuse_color, &mat->r);
+ }
+ }
+ }
}
char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
{
- char *str = NULL;
+ char *str = NULL;
- DynStr *ds = BLI_dynstr_new();
+ DynStr *ds = BLI_dynstr_new();
- if (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) {
- BLI_dynstr_append(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n");
- }
- if (wpd->shading.flag & V3D_SHADING_SHADOW) {
- BLI_dynstr_append(ds, "#define V3D_SHADING_SHADOW\n");
- }
- if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define WB_CAVITY\n");
- }
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
- }
- if (STUDIOLIGHT_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define V3D_LIGHTING_STUDIO\n");
- }
- if (FLAT_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define V3D_LIGHTING_FLAT\n");
- }
- if (MATCAP_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define V3D_LIGHTING_MATCAP\n");
- }
- if (OBJECT_ID_PASS_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define OBJECT_ID_PASS_ENABLED\n");
- }
- if (MATDATA_PASS_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define MATDATA_PASS_ENABLED\n");
- }
- if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
- BLI_dynstr_append(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
- }
- if (use_textures) {
- BLI_dynstr_append(ds, "#define V3D_SHADING_TEXTURE_COLOR\n");
- }
- if (NORMAL_ENCODING_ENABLED()) {
- BLI_dynstr_append(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
- }
- if (is_hair) {
- BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
- }
+ if (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) {
+ BLI_dynstr_append(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n");
+ }
+ if (wpd->shading.flag & V3D_SHADING_SHADOW) {
+ BLI_dynstr_append(ds, "#define V3D_SHADING_SHADOW\n");
+ }
+ if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define WB_CAVITY\n");
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
+ }
+ if (STUDIOLIGHT_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define V3D_LIGHTING_STUDIO\n");
+ }
+ if (FLAT_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define V3D_LIGHTING_FLAT\n");
+ }
+ if (MATCAP_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define V3D_LIGHTING_MATCAP\n");
+ }
+ if (OBJECT_ID_PASS_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define OBJECT_ID_PASS_ENABLED\n");
+ }
+ if (MATDATA_PASS_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define MATDATA_PASS_ENABLED\n");
+ }
+ if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
+ BLI_dynstr_append(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
+ }
+ if (use_textures) {
+ BLI_dynstr_append(ds, "#define V3D_SHADING_TEXTURE_COLOR\n");
+ }
+ if (NORMAL_ENCODING_ENABLED()) {
+ BLI_dynstr_append(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
+ }
+ if (is_hair) {
+ BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
+ }
- str = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return str;
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
}
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost)
{
- uint input[4];
- uint result;
- float *color = material_template->diffuse_color;
- input[0] = (uint)(color[0] * 512);
- input[1] = (uint)(color[1] * 512);
- input[2] = (uint)(color[2] * 512);
- input[3] = material_template->object_id;
- result = BLI_ghashutil_uinthash_v4_murmur(input);
+ uint input[4];
+ uint result;
+ float *color = material_template->diffuse_color;
+ input[0] = (uint)(color[0] * 512);
+ input[1] = (uint)(color[1] * 512);
+ input[2] = (uint)(color[2] * 512);
+ input[3] = material_template->object_id;
+ result = BLI_ghashutil_uinthash_v4_murmur(input);
- color = material_template->specular_color;
- input[0] = (uint)(color[0] * 512);
- input[1] = (uint)(color[1] * 512);
- input[2] = (uint)(color[2] * 512);
- input[3] = (uint)(material_template->roughness * 512);
- result += BLI_ghashutil_uinthash_v4_murmur(input);
+ color = material_template->specular_color;
+ input[0] = (uint)(color[0] * 512);
+ input[1] = (uint)(color[1] * 512);
+ input[2] = (uint)(color[2] * 512);
+ input[3] = (uint)(material_template->roughness * 512);
+ result += BLI_ghashutil_uinthash_v4_murmur(input);
- result += BLI_ghashutil_uinthash((uint)is_ghost);
+ result += BLI_ghashutil_uinthash((uint)is_ghost);
- /* add texture reference */
- if (material_template->ima) {
- result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
- }
+ /* add texture reference */
+ if (material_template->ima) {
+ result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
+ }
- return result;
+ return result;
}
int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd)
{
- /* NOTE: change MAX_COMPOSITE_SHADERS accordingly when modifying this function. */
- int index = 0;
- /* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
- index = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
- SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 2);
- SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 3);
- SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 4);
- SET_FLAG_FROM_TEST(index, MATDATA_PASS_ENABLED(wpd), 1 << 5);
- BLI_assert(index < MAX_COMPOSITE_SHADERS);
- return index;
+ /* NOTE: change MAX_COMPOSITE_SHADERS accordingly when modifying this function. */
+ int index = 0;
+ /* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
+ index = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 2);
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 3);
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 4);
+ SET_FLAG_FROM_TEST(index, MATDATA_PASS_ENABLED(wpd), 1 << 5);
+ BLI_assert(index < MAX_COMPOSITE_SHADERS);
+ return index;
}
-int workbench_material_get_prepass_shader_index(
- WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
+int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair)
{
- /* NOTE: change MAX_PREPASS_SHADERS accordingly when modifying this function. */
- int index = 0;
- SET_FLAG_FROM_TEST(index, is_hair, 1 << 0);
- SET_FLAG_FROM_TEST(index, MATDATA_PASS_ENABLED(wpd), 1 << 1);
- SET_FLAG_FROM_TEST(index, OBJECT_ID_PASS_ENABLED(wpd), 1 << 2);
- SET_FLAG_FROM_TEST(index, NORMAL_VIEWPORT_PASS_ENABLED(wpd), 1 << 3);
- SET_FLAG_FROM_TEST(index, MATCAP_ENABLED(wpd), 1 << 4);
- SET_FLAG_FROM_TEST(index, use_textures, 1 << 5);
- BLI_assert(index < MAX_PREPASS_SHADERS);
- return index;
+ /* NOTE: change MAX_PREPASS_SHADERS accordingly when modifying this function. */
+ int index = 0;
+ SET_FLAG_FROM_TEST(index, is_hair, 1 << 0);
+ SET_FLAG_FROM_TEST(index, MATDATA_PASS_ENABLED(wpd), 1 << 1);
+ SET_FLAG_FROM_TEST(index, OBJECT_ID_PASS_ENABLED(wpd), 1 << 2);
+ SET_FLAG_FROM_TEST(index, NORMAL_VIEWPORT_PASS_ENABLED(wpd), 1 << 3);
+ SET_FLAG_FROM_TEST(index, MATCAP_ENABLED(wpd), 1 << 4);
+ SET_FLAG_FROM_TEST(index, use_textures, 1 << 5);
+ BLI_assert(index < MAX_PREPASS_SHADERS);
+ return index;
}
-int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
+int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair)
{
- /* NOTE: change MAX_ACCUM_SHADERS accordingly when modifying this function. */
- int index = 0;
- /* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
- index = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
- SET_FLAG_FROM_TEST(index, use_textures, 1 << 2);
- SET_FLAG_FROM_TEST(index, is_hair, 1 << 3);
- /* 1 bits SHADOWS (only facing factor) */
- SET_FLAG_FROM_TEST(index, SHADOW_ENABLED(wpd), 1 << 4);
- BLI_assert(index < MAX_ACCUM_SHADERS);
- return index;
+ /* NOTE: change MAX_ACCUM_SHADERS accordingly when modifying this function. */
+ int index = 0;
+ /* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
+ index = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
+ SET_FLAG_FROM_TEST(index, use_textures, 1 << 2);
+ SET_FLAG_FROM_TEST(index, is_hair, 1 << 3);
+ /* 1 bits SHADOWS (only facing factor) */
+ SET_FLAG_FROM_TEST(index, SHADOW_ENABLED(wpd), 1 << 4);
+ BLI_assert(index < MAX_ACCUM_SHADERS);
+ return index;
}
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob)
{
- int color_type = wpd->shading.color_type;
- if ((color_type == V3D_SHADING_TEXTURE_COLOR && ima == NULL) || (ob->dt < OB_TEXTURE)) {
- color_type = V3D_SHADING_MATERIAL_COLOR;
- }
- return color_type;
+ int color_type = wpd->shading.color_type;
+ if ((color_type == V3D_SHADING_TEXTURE_COLOR && ima == NULL) || (ob->dt < OB_TEXTURE)) {
+ color_type = V3D_SHADING_MATERIAL_COLOR;
+ }
+ return color_type;
}
-void workbench_material_get_image_and_mat(Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat)
+void workbench_material_get_image_and_mat(
+ Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat)
{
- bNode *node;
- *r_mat = give_current_material(ob, mat_nr);
- ED_object_get_active_image(ob, mat_nr, r_image, r_iuser, &node, NULL);
- if (node && *r_image) {
- switch (node->type) {
- case SH_NODE_TEX_IMAGE:
- {
- NodeTexImage *storage = node->storage;
- *r_interp = storage->interpolation;
- break;
- }
- case SH_NODE_TEX_ENVIRONMENT:
- {
- NodeTexEnvironment *storage = node->storage;
- *r_interp = storage->interpolation;
- break;
- }
- default:
- BLI_assert(!"Node type not supported by workbench");
- *r_interp = 0;
- }
- }
- else {
- *r_interp = 0;
- }
+ bNode *node;
+ *r_mat = give_current_material(ob, mat_nr);
+ ED_object_get_active_image(ob, mat_nr, r_image, r_iuser, &node, NULL);
+ if (node && *r_image) {
+ switch (node->type) {
+ case SH_NODE_TEX_IMAGE: {
+ NodeTexImage *storage = node->storage;
+ *r_interp = storage->interpolation;
+ break;
+ }
+ case SH_NODE_TEX_ENVIRONMENT: {
+ NodeTexEnvironment *storage = node->storage;
+ *r_interp = storage->interpolation;
+ break;
+ }
+ default:
+ BLI_assert(!"Node type not supported by workbench");
+ *r_interp = 0;
+ }
+ }
+ else {
+ *r_interp = 0;
+ }
}
-void workbench_material_shgroup_uniform(
- WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob,
- const bool use_metallic, const bool deferred, const int interp)
+void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
+ DRWShadingGroup *grp,
+ WORKBENCH_MaterialData *material,
+ Object *ob,
+ const bool use_metallic,
+ const bool deferred,
+ const int interp)
{
- if (deferred && !MATDATA_PASS_ENABLED(wpd)) {
- return;
- }
+ if (deferred && !MATDATA_PASS_ENABLED(wpd)) {
+ return;
+ }
- if (workbench_material_determine_color_type(wpd, material->ima, ob) == V3D_SHADING_TEXTURE_COLOR) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(material->ima, material->iuser, NULL);
- const bool do_color_correction = wpd->use_color_management &&
- (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0);
- BKE_image_release_ibuf(material->ima, ibuf, NULL);
- GPUTexture *tex = GPU_texture_from_blender(material->ima, material->iuser, GL_TEXTURE_2D, false);
- DRW_shgroup_uniform_texture(grp, "image", tex);
- DRW_shgroup_uniform_bool_copy(grp, "imageSrgb", do_color_correction);
- DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
- }
- else {
- DRW_shgroup_uniform_vec3(grp, "materialDiffuseColor", (use_metallic) ? material->base_color : material->diffuse_color, 1);
- }
+ if (workbench_material_determine_color_type(wpd, material->ima, ob) ==
+ V3D_SHADING_TEXTURE_COLOR) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(material->ima, material->iuser, NULL);
+ const bool do_color_correction = wpd->use_color_management &&
+ (ibuf &&
+ (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0);
+ BKE_image_release_ibuf(material->ima, ibuf, NULL);
+ GPUTexture *tex = GPU_texture_from_blender(
+ material->ima, material->iuser, GL_TEXTURE_2D, false);
+ DRW_shgroup_uniform_texture(grp, "image", tex);
+ DRW_shgroup_uniform_bool_copy(grp, "imageSrgb", do_color_correction);
+ DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
+ }
+ else {
+ DRW_shgroup_uniform_vec3(grp,
+ "materialDiffuseColor",
+ (use_metallic) ? material->base_color : material->diffuse_color,
+ 1);
+ }
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
- if (use_metallic) {
- DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1);
- }
- else {
- DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1);
- }
- DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
- }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+ if (use_metallic) {
+ DRW_shgroup_uniform_float(grp, "materialMetallic", &material->metallic, 1);
+ }
+ else {
+ DRW_shgroup_uniform_vec3(grp, "materialSpecularColor", material->specular_color, 1);
+ }
+ DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
+ }
- if (WORLD_CLIPPING_ENABLED(wpd)) {
- DRW_shgroup_uniform_vec4(grp, "WorldClipPlanes", wpd->world_clip_planes[0], 6);
- DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES);
- }
+ if (WORLD_CLIPPING_ENABLED(wpd)) {
+ DRW_shgroup_uniform_vec4(grp, "WorldClipPlanes", wpd->world_clip_planes[0], 6);
+ DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES);
+ }
}
-void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material)
+void workbench_material_copy(WORKBENCH_MaterialData *dest_material,
+ const WORKBENCH_MaterialData *source_material)
{
- dest_material->object_id = source_material->object_id;
- copy_v3_v3(dest_material->base_color, source_material->base_color);
- copy_v3_v3(dest_material->diffuse_color, source_material->diffuse_color);
- copy_v3_v3(dest_material->specular_color, source_material->specular_color);
- dest_material->metallic = source_material->metallic;
- dest_material->roughness = source_material->roughness;
- dest_material->ima = source_material->ima;
- dest_material->iuser = source_material->iuser;
+ dest_material->object_id = source_material->object_id;
+ copy_v3_v3(dest_material->base_color, source_material->base_color);
+ copy_v3_v3(dest_material->diffuse_color, source_material->diffuse_color);
+ copy_v3_v3(dest_material->specular_color, source_material->specular_color);
+ dest_material->metallic = source_material->metallic;
+ dest_material->roughness = source_material->roughness;
+ dest_material->ima = source_material->ima;
+ dest_material->iuser = source_material->iuser;
}
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 75d72933c8e..0e2ef2f94d2 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -23,7 +23,6 @@
#ifndef __WORKBENCH_PRIVATE_H__
#define __WORKBENCH_PRIVATE_H__
-
#include "BKE_studiolight.h"
#include "DNA_image_types.h"
@@ -47,258 +46,282 @@
#define STUDIOLIGHT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_STUDIO)
#define MATCAP_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_MATCAP)
#define USE_WORLD_ORIENTATION(wpd) ((wpd->shading.flag & V3D_SHADING_WORLD_ORIENTATION) != 0)
-#define STUDIOLIGHT_TYPE_WORLD_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_WORLD))
-#define STUDIOLIGHT_TYPE_STUDIO_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_STUDIO))
-#define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_MATCAP))
-#define SSAO_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_SSAO) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
-#define CURVATURE_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_CURVATURE) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
+#define STUDIOLIGHT_TYPE_WORLD_ENABLED(wpd) \
+ (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_WORLD))
+#define STUDIOLIGHT_TYPE_STUDIO_ENABLED(wpd) \
+ (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_STUDIO))
+#define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd) \
+ (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_MATCAP))
+#define SSAO_ENABLED(wpd) \
+ ((wpd->shading.flag & V3D_SHADING_CAVITY) && \
+ ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_SSAO) || \
+ (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
+#define CURVATURE_ENABLED(wpd) \
+ ((wpd->shading.flag & V3D_SHADING_CAVITY) && \
+ ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_CURVATURE) || \
+ (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
#define CAVITY_ENABLED(wpd) (CURVATURE_ENABLED(wpd) || SSAO_ENABLED(wpd))
#define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
-#define GHOST_ENABLED(psl) (!DRW_pass_is_empty(psl->ghost_prepass_pass) || !DRW_pass_is_empty(psl->ghost_prepass_hair_pass))
+#define GHOST_ENABLED(psl) \
+ (!DRW_pass_is_empty(psl->ghost_prepass_pass) || !DRW_pass_is_empty(psl->ghost_prepass_hair_pass))
#define CULL_BACKFACE_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_BACKFACE_CULLING) != 0)
-#define OIT_ENABLED(wpd) (ELEM(wpd->shading.color_type, V3D_SHADING_MATERIAL_COLOR, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_TEXTURE_COLOR))
-
-#define IS_NAVIGATING(wpd) ((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING))
-#define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && \
- (IN_RANGE(wpd->preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || \
- ((IS_NAVIGATING(wpd) || wpd->is_playback) && (wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8))))
-#define TAA_ENABLED(wpd) ((DRW_state_is_image_render() && DRW_context_state_get()->scene->r.mode & R_OSA) || \
- (!DRW_state_is_image_render() && wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd) && !wpd->is_playback))
-#define SPECULAR_HIGHLIGHT_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)))
+#define OIT_ENABLED(wpd) \
+ (ELEM(wpd->shading.color_type, \
+ V3D_SHADING_MATERIAL_COLOR, \
+ V3D_SHADING_OBJECT_COLOR, \
+ V3D_SHADING_TEXTURE_COLOR))
+
+#define IS_NAVIGATING(wpd) \
+ ((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING))
+#define FXAA_ENABLED(wpd) \
+ ((!DRW_state_is_opengl_render()) && \
+ (IN_RANGE(wpd->preferences->gpu_viewport_quality, \
+ GPU_VIEWPORT_QUALITY_FXAA, \
+ GPU_VIEWPORT_QUALITY_TAA8) || \
+ ((IS_NAVIGATING(wpd) || wpd->is_playback) && \
+ (wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8))))
+#define TAA_ENABLED(wpd) \
+ ((DRW_state_is_image_render() && DRW_context_state_get()->scene->r.mode & R_OSA) || \
+ (!DRW_state_is_image_render() && \
+ wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd) && \
+ !wpd->is_playback))
+#define SPECULAR_HIGHLIGHT_ENABLED(wpd) \
+ (STUDIOLIGHT_ENABLED(wpd) && (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && \
+ (!STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)))
#define OBJECT_OUTLINE_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
#define OBJECT_ID_PASS_ENABLED(wpd) (OBJECT_OUTLINE_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
-#define MATDATA_PASS_ENABLED(wpd) (wpd->shading.color_type != V3D_SHADING_SINGLE_COLOR || MATCAP_ENABLED(wpd))
-#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd))
-#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) || SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
+#define MATDATA_PASS_ENABLED(wpd) \
+ (wpd->shading.color_type != V3D_SHADING_SINGLE_COLOR || MATCAP_ENABLED(wpd))
+#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) \
+ (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd))
+#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) \
+ (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) || SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
#define NORMAL_ENCODING_ENABLED() (true)
#define WORLD_CLIPPING_ENABLED(wpd) (wpd->world_clip_planes != NULL)
-
struct RenderEngine;
struct RenderLayer;
struct rcti;
-
typedef struct WORKBENCH_FramebufferList {
- /* Deferred render buffers */
- struct GPUFrameBuffer *prepass_fb;
- struct GPUFrameBuffer *ghost_prepass_fb;
- struct GPUFrameBuffer *cavity_fb;
- struct GPUFrameBuffer *composite_fb;
- struct GPUFrameBuffer *id_clear_fb;
-
- struct GPUFrameBuffer *effect_fb;
- struct GPUFrameBuffer *effect_taa_fb;
- struct GPUFrameBuffer *depth_buffer_fb;
- struct GPUFrameBuffer *color_only_fb;
-
- struct GPUFrameBuffer *dof_downsample_fb;
- struct GPUFrameBuffer *dof_coc_tile_h_fb;
- struct GPUFrameBuffer *dof_coc_tile_v_fb;
- struct GPUFrameBuffer *dof_coc_dilate_fb;
- struct GPUFrameBuffer *dof_blur1_fb;
- struct GPUFrameBuffer *dof_blur2_fb;
-
- /* Forward render buffers */
- struct GPUFrameBuffer *object_outline_fb;
- struct GPUFrameBuffer *transparent_accum_fb;
- struct GPUFrameBuffer *transparent_revealage_fb;
+ /* Deferred render buffers */
+ struct GPUFrameBuffer *prepass_fb;
+ struct GPUFrameBuffer *ghost_prepass_fb;
+ struct GPUFrameBuffer *cavity_fb;
+ struct GPUFrameBuffer *composite_fb;
+ struct GPUFrameBuffer *id_clear_fb;
+
+ struct GPUFrameBuffer *effect_fb;
+ struct GPUFrameBuffer *effect_taa_fb;
+ struct GPUFrameBuffer *depth_buffer_fb;
+ struct GPUFrameBuffer *color_only_fb;
+
+ struct GPUFrameBuffer *dof_downsample_fb;
+ struct GPUFrameBuffer *dof_coc_tile_h_fb;
+ struct GPUFrameBuffer *dof_coc_tile_v_fb;
+ struct GPUFrameBuffer *dof_coc_dilate_fb;
+ struct GPUFrameBuffer *dof_blur1_fb;
+ struct GPUFrameBuffer *dof_blur2_fb;
+
+ /* Forward render buffers */
+ struct GPUFrameBuffer *object_outline_fb;
+ struct GPUFrameBuffer *transparent_accum_fb;
+ struct GPUFrameBuffer *transparent_revealage_fb;
} WORKBENCH_FramebufferList;
typedef struct WORKBENCH_TextureList {
- struct GPUTexture *dof_source_tx;
- struct GPUTexture *coc_halfres_tx;
- struct GPUTexture *history_buffer_tx;
- struct GPUTexture *depth_buffer_tx;
+ struct GPUTexture *dof_source_tx;
+ struct GPUTexture *coc_halfres_tx;
+ struct GPUTexture *history_buffer_tx;
+ struct GPUTexture *depth_buffer_tx;
} WORKBENCH_TextureList;
typedef struct WORKBENCH_StorageList {
- struct WORKBENCH_PrivateData *g_data;
- struct WORKBENCH_EffectInfo *effects;
- float *dof_ubo_data;
+ struct WORKBENCH_PrivateData *g_data;
+ struct WORKBENCH_EffectInfo *effects;
+ float *dof_ubo_data;
} WORKBENCH_StorageList;
typedef struct WORKBENCH_PassList {
- /* deferred rendering */
- struct DRWPass *prepass_pass;
- struct DRWPass *prepass_hair_pass;
- struct DRWPass *ghost_prepass_pass;
- struct DRWPass *ghost_prepass_hair_pass;
- struct DRWPass *cavity_pass;
- struct DRWPass *shadow_depth_pass_pass;
- struct DRWPass *shadow_depth_pass_mani_pass;
- struct DRWPass *shadow_depth_fail_pass;
- struct DRWPass *shadow_depth_fail_mani_pass;
- struct DRWPass *shadow_depth_fail_caps_pass;
- struct DRWPass *shadow_depth_fail_caps_mani_pass;
- struct DRWPass *composite_pass;
- struct DRWPass *composite_shadow_pass;
- struct DRWPass *oit_composite_pass;
- struct DRWPass *background_pass;
- struct DRWPass *background_pass_clip;
- struct DRWPass *ghost_resolve_pass;
- struct DRWPass *effect_aa_pass;
- struct DRWPass *dof_down_ps;
- struct DRWPass *dof_down2_ps;
- struct DRWPass *dof_flatten_v_ps;
- struct DRWPass *dof_flatten_h_ps;
- struct DRWPass *dof_dilate_h_ps;
- struct DRWPass *dof_dilate_v_ps;
- struct DRWPass *dof_blur1_ps;
- struct DRWPass *dof_blur2_ps;
- struct DRWPass *dof_resolve_ps;
- struct DRWPass *volume_pass;
-
- /* forward rendering */
- struct DRWPass *transparent_accum_pass;
- struct DRWPass *object_outline_pass;
- struct DRWPass *depth_pass;
- struct DRWPass *checker_depth_pass;
+ /* deferred rendering */
+ struct DRWPass *prepass_pass;
+ struct DRWPass *prepass_hair_pass;
+ struct DRWPass *ghost_prepass_pass;
+ struct DRWPass *ghost_prepass_hair_pass;
+ struct DRWPass *cavity_pass;
+ struct DRWPass *shadow_depth_pass_pass;
+ struct DRWPass *shadow_depth_pass_mani_pass;
+ struct DRWPass *shadow_depth_fail_pass;
+ struct DRWPass *shadow_depth_fail_mani_pass;
+ struct DRWPass *shadow_depth_fail_caps_pass;
+ struct DRWPass *shadow_depth_fail_caps_mani_pass;
+ struct DRWPass *composite_pass;
+ struct DRWPass *composite_shadow_pass;
+ struct DRWPass *oit_composite_pass;
+ struct DRWPass *background_pass;
+ struct DRWPass *background_pass_clip;
+ struct DRWPass *ghost_resolve_pass;
+ struct DRWPass *effect_aa_pass;
+ struct DRWPass *dof_down_ps;
+ struct DRWPass *dof_down2_ps;
+ struct DRWPass *dof_flatten_v_ps;
+ struct DRWPass *dof_flatten_h_ps;
+ struct DRWPass *dof_dilate_h_ps;
+ struct DRWPass *dof_dilate_v_ps;
+ struct DRWPass *dof_blur1_ps;
+ struct DRWPass *dof_blur2_ps;
+ struct DRWPass *dof_resolve_ps;
+ struct DRWPass *volume_pass;
+
+ /* forward rendering */
+ struct DRWPass *transparent_accum_pass;
+ struct DRWPass *object_outline_pass;
+ struct DRWPass *depth_pass;
+ struct DRWPass *checker_depth_pass;
} WORKBENCH_PassList;
typedef struct WORKBENCH_Data {
- void *engine_type;
- WORKBENCH_FramebufferList *fbl;
- WORKBENCH_TextureList *txl;
- WORKBENCH_PassList *psl;
- WORKBENCH_StorageList *stl;
+ void *engine_type;
+ WORKBENCH_FramebufferList *fbl;
+ WORKBENCH_TextureList *txl;
+ WORKBENCH_PassList *psl;
+ WORKBENCH_StorageList *stl;
} WORKBENCH_Data;
typedef struct WORKBENCH_UBO_Light {
- float light_direction[4];
- float specular_color[3], pad;
- float diffuse_color[3], wrapped;
+ float light_direction[4];
+ float specular_color[3], pad;
+ float diffuse_color[3], wrapped;
} WORKBENCH_UBO_Light;
typedef struct WORKBENCH_UBO_World {
- float background_color_low[4];
- float background_color_high[4];
- float object_outline_color[4];
- float shadow_direction_vs[4];
- WORKBENCH_UBO_Light lights[4];
- float ambient_color[4];
- int num_lights;
- int matcap_orientation;
- float background_alpha;
- float curvature_ridge;
- float curvature_valley;
- int pad[3];
+ float background_color_low[4];
+ float background_color_high[4];
+ float object_outline_color[4];
+ float shadow_direction_vs[4];
+ WORKBENCH_UBO_Light lights[4];
+ float ambient_color[4];
+ int num_lights;
+ int matcap_orientation;
+ float background_alpha;
+ float curvature_ridge;
+ float curvature_valley;
+ int pad[3];
} WORKBENCH_UBO_World;
BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
-
typedef struct WORKBENCH_PrivateData {
- struct GHash *material_hash;
- struct GHash *material_transp_hash;
- struct GPUShader *prepass_solid_sh;
- struct GPUShader *prepass_solid_hair_sh;
- struct GPUShader *prepass_texture_sh;
- struct GPUShader *prepass_texture_hair_sh;
- struct GPUShader *composite_sh;
- struct GPUShader *background_sh;
- struct GPUShader *transparent_accum_sh;
- struct GPUShader *transparent_accum_hair_sh;
- struct GPUShader *transparent_accum_texture_sh;
- struct GPUShader *transparent_accum_texture_hair_sh;
- View3DShading shading;
- StudioLight *studio_light;
- const UserDef *preferences;
- struct GPUUniformBuffer *world_ubo;
- struct DRWShadingGroup *shadow_shgrp;
- struct DRWShadingGroup *depth_shgrp;
- WORKBENCH_UBO_World world_data;
- float shadow_multiplier;
- float shadow_shift;
- float shadow_focus;
- float cached_shadow_direction[3];
- float shadow_mat[4][4];
- float shadow_inv[4][4];
- /* Far plane of the view frustum. */
- float shadow_far_plane[4];
- /* Near plane corners in shadow space. */
- float shadow_near_corners[4][3];
- /* min and max of shadow_near_corners. allow fast test */
- float shadow_near_min[3];
- float shadow_near_max[3];
- /* This is a parallelogram, so only 2 normal and distance to the edges. */
- float shadow_near_sides[2][4];
- bool shadow_changed;
- bool is_playback;
-
- float (*world_clip_planes)[4];
- struct GPUBatch *world_clip_planes_batch;
- float world_clip_planes_color[4];
-
- /* Volumes */
- bool volumes_do;
- ListBase smoke_domains;
-
- /* Ssao */
- float winmat[4][4];
- float viewvecs[3][4];
- float ssao_params[4];
- float ssao_settings[4];
-
- /* Dof */
- struct GPUTexture *dof_blur_tx;
- struct GPUTexture *coc_temp_tx;
- struct GPUTexture *coc_tiles_tx[2];
- struct GPUUniformBuffer *dof_ubo;
- float dof_aperturesize;
- float dof_distance;
- float dof_invsensorsize;
- float dof_near_far[2];
- float dof_blades;
- float dof_rotation;
- float dof_ratio;
- bool dof_enabled;
-
- /* Color Management */
- bool use_color_management;
- bool use_color_render_settings;
+ struct GHash *material_hash;
+ struct GHash *material_transp_hash;
+ struct GPUShader *prepass_solid_sh;
+ struct GPUShader *prepass_solid_hair_sh;
+ struct GPUShader *prepass_texture_sh;
+ struct GPUShader *prepass_texture_hair_sh;
+ struct GPUShader *composite_sh;
+ struct GPUShader *background_sh;
+ struct GPUShader *transparent_accum_sh;
+ struct GPUShader *transparent_accum_hair_sh;
+ struct GPUShader *transparent_accum_texture_sh;
+ struct GPUShader *transparent_accum_texture_hair_sh;
+ View3DShading shading;
+ StudioLight *studio_light;
+ const UserDef *preferences;
+ struct GPUUniformBuffer *world_ubo;
+ struct DRWShadingGroup *shadow_shgrp;
+ struct DRWShadingGroup *depth_shgrp;
+ WORKBENCH_UBO_World world_data;
+ float shadow_multiplier;
+ float shadow_shift;
+ float shadow_focus;
+ float cached_shadow_direction[3];
+ float shadow_mat[4][4];
+ float shadow_inv[4][4];
+ /* Far plane of the view frustum. */
+ float shadow_far_plane[4];
+ /* Near plane corners in shadow space. */
+ float shadow_near_corners[4][3];
+ /* min and max of shadow_near_corners. allow fast test */
+ float shadow_near_min[3];
+ float shadow_near_max[3];
+ /* This is a parallelogram, so only 2 normal and distance to the edges. */
+ float shadow_near_sides[2][4];
+ bool shadow_changed;
+ bool is_playback;
+
+ float (*world_clip_planes)[4];
+ struct GPUBatch *world_clip_planes_batch;
+ float world_clip_planes_color[4];
+
+ /* Volumes */
+ bool volumes_do;
+ ListBase smoke_domains;
+
+ /* Ssao */
+ float winmat[4][4];
+ float viewvecs[3][4];
+ float ssao_params[4];
+ float ssao_settings[4];
+
+ /* Dof */
+ struct GPUTexture *dof_blur_tx;
+ struct GPUTexture *coc_temp_tx;
+ struct GPUTexture *coc_tiles_tx[2];
+ struct GPUUniformBuffer *dof_ubo;
+ float dof_aperturesize;
+ float dof_distance;
+ float dof_invsensorsize;
+ float dof_near_far[2];
+ float dof_blades;
+ float dof_rotation;
+ float dof_ratio;
+ bool dof_enabled;
+
+ /* Color Management */
+ bool use_color_management;
+ bool use_color_render_settings;
} WORKBENCH_PrivateData; /* Transient data */
typedef struct WORKBENCH_EffectInfo {
- float override_persmat[4][4];
- float override_persinv[4][4];
- float override_winmat[4][4];
- float override_wininv[4][4];
- float last_mat[4][4];
- float curr_mat[4][4];
- int jitter_index;
- float taa_mix_factor;
- bool view_updated;
+ float override_persmat[4][4];
+ float override_persinv[4][4];
+ float override_winmat[4][4];
+ float override_wininv[4][4];
+ float last_mat[4][4];
+ float curr_mat[4][4];
+ int jitter_index;
+ float taa_mix_factor;
+ bool view_updated;
} WORKBENCH_EffectInfo;
typedef struct WORKBENCH_MaterialData {
- float base_color[3];
- float diffuse_color[3];
- float specular_color[3];
- float metallic;
- float roughness;
- int object_id;
- int color_type;
- int interp;
- Image *ima;
- ImageUser *iuser;
-
- /* Linked shgroup for drawing */
- DRWShadingGroup *shgrp;
- /* forward rendering */
- DRWShadingGroup *shgrp_object_outline;
+ float base_color[3];
+ float diffuse_color[3];
+ float specular_color[3];
+ float metallic;
+ float roughness;
+ int object_id;
+ int color_type;
+ int interp;
+ Image *ima;
+ ImageUser *iuser;
+
+ /* Linked shgroup for drawing */
+ DRWShadingGroup *shgrp;
+ /* forward rendering */
+ DRWShadingGroup *shgrp_object_outline;
} WORKBENCH_MaterialData;
typedef struct WORKBENCH_ObjectData {
- DrawData dd;
+ DrawData dd;
- /* Shadow direction in local object space. */
- float shadow_dir[3], shadow_depth;
- /* Min, max in shadow space */
- float shadow_min[3], shadow_max[3];
- BoundBox shadow_bbox;
- bool shadow_bbox_dirty;
+ /* Shadow direction in local object space. */
+ float shadow_dir[3], shadow_depth;
+ /* Min, max in shadow space */
+ float shadow_min[3], shadow_max[3];
+ BoundBox shadow_bbox;
+ bool shadow_bbox_dirty;
- int object_id;
+ int object_id;
} WORKBENCH_ObjectData;
/* workbench_deferred.c */
@@ -324,8 +347,13 @@ void workbench_forward_cache_finish(WORKBENCH_Data *vedata);
/* For OIT in deferred */
void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg);
void workbench_forward_choose_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg);
-WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(
- WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, ImageUser *iuser, int color_type, int interp);
+WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_Data *vedata,
+ Object *ob,
+ Material *mat,
+ Image *ima,
+ ImageUser *iuser,
+ int color_type,
+ int interp);
/* workbench_effect_aa.c */
void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx);
@@ -348,45 +376,79 @@ int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata);
/* workbench_effect_dof.c */
void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera);
void workbench_dof_engine_free(void);
-void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input, GPUTexture *noise_tex);
+void workbench_dof_create_pass(WORKBENCH_Data *vedata,
+ GPUTexture **dof_input,
+ GPUTexture *noise_tex);
void workbench_dof_draw_pass(WORKBENCH_Data *vedata);
/* workbench_materials.c */
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob);
-void workbench_material_get_image_and_mat(Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat);
-char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
-void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data);
+void workbench_material_get_image_and_mat(
+ Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat);
+char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair);
+void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ Material *mat,
+ WORKBENCH_MaterialData *data);
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost);
int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd);
-int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
-int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
-void workbench_material_shgroup_uniform(
- WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob,
- const bool use_metallic, const bool deferred, const int interp);
-void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material);
+int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair);
+int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd,
+ bool use_textures,
+ bool is_hair);
+void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
+ DRWShadingGroup *grp,
+ WORKBENCH_MaterialData *material,
+ Object *ob,
+ const bool use_metallic,
+ const bool deferred,
+ const int interp);
+void workbench_material_copy(WORKBENCH_MaterialData *dest_material,
+ const WORKBENCH_MaterialData *source_material);
/* workbench_studiolight.c */
-void studiolight_update_world(WORKBENCH_PrivateData *wpd, StudioLight *sl, WORKBENCH_UBO_World *wd);
+void studiolight_update_world(WORKBENCH_PrivateData *wpd,
+ StudioLight *sl,
+ WORKBENCH_UBO_World *wd);
void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3]);
-bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
-float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
-bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
+bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed);
+float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed);
+bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed);
/* workbench_data.c */
void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info);
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
void workbench_private_data_free(WORKBENCH_PrivateData *wpd);
-void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3]);
+void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd,
+ float r_light_direction[3]);
/* workbench_volume.c */
void workbench_volume_engine_init(void);
void workbench_volume_engine_free(void);
void workbench_volume_cache_init(WORKBENCH_Data *vedata);
-void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, struct ModifierData *md);
+void workbench_volume_cache_populate(WORKBENCH_Data *vedata,
+ Scene *scene,
+ Object *ob,
+ struct ModifierData *md);
void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd);
/* workbench_render.c */
-void workbench_render(WORKBENCH_Data *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const struct rcti *rect);
-void workbench_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
+void workbench_render(WORKBENCH_Data *vedata,
+ struct RenderEngine *engine,
+ struct RenderLayer *render_layer,
+ const struct rcti *rect);
+void workbench_render_update_passes(struct RenderEngine *engine,
+ struct Scene *scene,
+ struct ViewLayer *view_layer);
#endif
diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c
index 663727285a1..1497ef493cf 100644
--- a/source/blender/draw/engines/workbench/workbench_render.c
+++ b/source/blender/draw/engines/workbench/workbench_render.c
@@ -39,177 +39,181 @@
#include "workbench_private.h"
-static void workbench_render_deferred_cache(
- void *vedata, struct Object *ob,
- struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
+static void workbench_render_deferred_cache(void *vedata,
+ struct Object *ob,
+ struct RenderEngine *UNUSED(engine),
+ struct Depsgraph *UNUSED(depsgraph))
{
- workbench_deferred_solid_cache_populate(vedata, ob);
+ workbench_deferred_solid_cache_populate(vedata, ob);
}
-static void workbench_render_forward_cache(
- void *vedata, struct Object *ob,
- struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
+static void workbench_render_forward_cache(void *vedata,
+ struct Object *ob,
+ struct RenderEngine *UNUSED(engine),
+ struct Depsgraph *UNUSED(depsgraph))
{
- workbench_forward_cache_populate(vedata, ob);
+ workbench_forward_cache_populate(vedata, ob);
}
static void workbench_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph)
{
- /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
- float frame = BKE_scene_frame_get(scene);
-
- /* Set the persective, view and window matrix. */
- float winmat[4][4], wininv[4][4];
- float viewmat[4][4], viewinv[4][4];
- float persmat[4][4], persinv[4][4];
-
- RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat);
- RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
-
- invert_m4_m4(viewmat, viewinv);
- mul_m4_m4m4(persmat, winmat, viewmat);
- invert_m4_m4(persinv, persmat);
- invert_m4_m4(wininv, winmat);
-
- DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
- DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
- DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
- DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV);
- DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
- DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
+ /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
+ float frame = BKE_scene_frame_get(scene);
+
+ /* Set the persective, view and window matrix. */
+ float winmat[4][4], wininv[4][4];
+ float viewmat[4][4], viewinv[4][4];
+ float persmat[4][4], persinv[4][4];
+
+ RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat);
+ RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
+
+ invert_m4_m4(viewmat, viewinv);
+ mul_m4_m4m4(persmat, winmat, viewmat);
+ invert_m4_m4(persinv, persmat);
+ invert_m4_m4(wininv, winmat);
+
+ DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
+ DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV);
+ DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
+ DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
}
static bool workbench_render_framebuffers_init(void)
{
- /* For image render, allocate own buffers because we don't have a viewport. */
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+ /* For image render, allocate own buffers because we don't have a viewport. */
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL);
- dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL);
+ dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
- if (!(dtxl->depth && dtxl->color)) {
- return false;
- }
+ if (!(dtxl->depth && dtxl->color)) {
+ return false;
+ }
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- GPU_framebuffer_ensure_config(&dfbl->default_fb, {
- GPU_ATTACHMENT_TEXTURE(dtxl->depth),
- GPU_ATTACHMENT_TEXTURE(dtxl->color)
- });
+ GPU_framebuffer_ensure_config(
+ &dfbl->default_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
- GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, {
- GPU_ATTACHMENT_TEXTURE(dtxl->depth),
- GPU_ATTACHMENT_NONE
- });
+ GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
- GPU_framebuffer_ensure_config(&dfbl->color_only_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(dtxl->color)
- });
+ GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
- bool ok = true;
- ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL);
- ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL);
- ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL);
+ bool ok = true;
+ ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL);
+ ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL);
+ ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL);
- return ok;
+ return ok;
}
static void workbench_render_framebuffers_finish(void)
{
}
-void workbench_render(WORKBENCH_Data *data, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
+void workbench_render(WORKBENCH_Data *data,
+ RenderEngine *engine,
+ RenderLayer *render_layer,
+ const rcti *rect)
{
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const Scene *scene = draw_ctx->scene;
- Depsgraph *depsgraph = draw_ctx->depsgraph;
- workbench_render_matrices_init(engine, depsgraph);
-
- if (!workbench_render_framebuffers_init()) {
- RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers");
- return;
- }
-
- const bool deferred = !XRAY_FLAG_ENABLED(&scene->display);
-
- if (deferred) {
- /* Init engine. */
- workbench_deferred_engine_init(data);
-
- /* Init objects. */
- workbench_deferred_cache_init(data);
- DRW_render_object_iter(data, engine, depsgraph, workbench_render_deferred_cache);
- workbench_deferred_cache_finish(data);
- DRW_render_instance_buffer_finish();
-
- /* Also we weed to have a correct fbo bound for DRW_hair_update */
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_hair_update();
-
- /* Draw. */
- int num_samples = workbench_taa_calculate_num_iterations(data);
- for (int sample = 0; sample < num_samples; sample++) {
- if (RE_engine_test_break(engine)) {
- break;
- }
- /* TODO: Save matrices instead of recomputing them for each samples. */
- workbench_render_matrices_init(engine, depsgraph);
-
- workbench_deferred_draw_background(data);
- workbench_deferred_draw_scene(data);
- }
-
- workbench_deferred_draw_finish(data);
- }
- else {
- /* Init engine. */
- workbench_forward_engine_init(data);
-
- /* Init objects. */
- workbench_forward_cache_init(data);
- DRW_render_object_iter(data, engine, depsgraph, workbench_render_forward_cache);
- workbench_forward_cache_finish(data);
- DRW_render_instance_buffer_finish();
-
- /* Also we weed to have a correct fbo bound for DRW_hair_update */
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_hair_update();
-
- /* Draw. */
- int num_samples = workbench_taa_calculate_num_iterations(data);
- for (int sample = 0; sample < num_samples; sample++) {
- if (RE_engine_test_break(engine)) {
- break;
- }
-
- workbench_forward_draw_background(data);
- workbench_forward_draw_scene(data);
- }
-
- workbench_forward_draw_finish(data);
- }
-
- /* Write render output. */
- const char *viewname = RE_GetActiveRenderView(engine->re);
- RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
-
- GPU_framebuffer_bind(dfbl->color_only_fb);
- GPU_framebuffer_read_color(dfbl->color_only_fb,
- rect->xmin, rect->ymin,
- BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
- 4, 0, rp->rect);
-
- workbench_render_framebuffers_finish();
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene = draw_ctx->scene;
+ Depsgraph *depsgraph = draw_ctx->depsgraph;
+ workbench_render_matrices_init(engine, depsgraph);
+
+ if (!workbench_render_framebuffers_init()) {
+ RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers");
+ return;
+ }
+
+ const bool deferred = !XRAY_FLAG_ENABLED(&scene->display);
+
+ if (deferred) {
+ /* Init engine. */
+ workbench_deferred_engine_init(data);
+
+ /* Init objects. */
+ workbench_deferred_cache_init(data);
+ DRW_render_object_iter(data, engine, depsgraph, workbench_render_deferred_cache);
+ workbench_deferred_cache_finish(data);
+ DRW_render_instance_buffer_finish();
+
+ /* Also we weed to have a correct fbo bound for DRW_hair_update */
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_hair_update();
+
+ /* Draw. */
+ int num_samples = workbench_taa_calculate_num_iterations(data);
+ for (int sample = 0; sample < num_samples; sample++) {
+ if (RE_engine_test_break(engine)) {
+ break;
+ }
+ /* TODO: Save matrices instead of recomputing them for each samples. */
+ workbench_render_matrices_init(engine, depsgraph);
+
+ workbench_deferred_draw_background(data);
+ workbench_deferred_draw_scene(data);
+ }
+
+ workbench_deferred_draw_finish(data);
+ }
+ else {
+ /* Init engine. */
+ workbench_forward_engine_init(data);
+
+ /* Init objects. */
+ workbench_forward_cache_init(data);
+ DRW_render_object_iter(data, engine, depsgraph, workbench_render_forward_cache);
+ workbench_forward_cache_finish(data);
+ DRW_render_instance_buffer_finish();
+
+ /* Also we weed to have a correct fbo bound for DRW_hair_update */
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_hair_update();
+
+ /* Draw. */
+ int num_samples = workbench_taa_calculate_num_iterations(data);
+ for (int sample = 0; sample < num_samples; sample++) {
+ if (RE_engine_test_break(engine)) {
+ break;
+ }
+
+ workbench_forward_draw_background(data);
+ workbench_forward_draw_scene(data);
+ }
+
+ workbench_forward_draw_finish(data);
+ }
+
+ /* Write render output. */
+ const char *viewname = RE_GetActiveRenderView(engine->re);
+ RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
+
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ GPU_framebuffer_read_color(dfbl->color_only_fb,
+ rect->xmin,
+ rect->ymin,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect),
+ 4,
+ 0,
+ rp->rect);
+
+ workbench_render_framebuffers_finish();
}
void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
{
- RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+ RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
}
diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c
index f382ad31752..5c95a835adc 100644
--- a/source/blender/draw/engines/workbench/workbench_studiolight.c
+++ b/source/blender/draw/engines/workbench/workbench_studiolight.c
@@ -27,266 +27,286 @@
#include "BLI_math.h"
-void studiolight_update_world(WORKBENCH_PrivateData *wpd, StudioLight *studiolight, WORKBENCH_UBO_World *wd)
+void studiolight_update_world(WORKBENCH_PrivateData *wpd,
+ StudioLight *studiolight,
+ WORKBENCH_UBO_World *wd)
{
- float view_matrix[4][4], rot_matrix[4][4];
- DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
-
- if (USE_WORLD_ORIENTATION(wpd)) {
- axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
- mul_m4_m4m4(rot_matrix, view_matrix, rot_matrix);
- swap_v3_v3(rot_matrix[2], rot_matrix[1]);
- negate_v3(rot_matrix[2]);
- }
- else {
- unit_m4(rot_matrix);
- }
-
- if (U.edit_studio_light) {
- studiolight = BKE_studiolight_studio_edit_get();
- }
-
- /* Studio Lights. */
- for (int i = 0; i < 4; i++) {
- WORKBENCH_UBO_Light *light = &wd->lights[i];
-
- SolidLight *sl = &studiolight->light[i];
- if (sl->flag) {
- copy_v3_v3(light->light_direction, sl->vec);
- mul_mat3_m4_v3(rot_matrix, light->light_direction);
- /* We should predivide the power by PI but that makes the lights really dim. */
- copy_v3_v3(light->specular_color, sl->spec);
- copy_v3_v3(light->diffuse_color, sl->col);
- light->wrapped = sl->smooth;
- }
- else {
- copy_v3_fl3(light->light_direction, 1.0f, 0.0f, 0.0f);
- copy_v3_fl(light->specular_color, 0.0f);
- copy_v3_fl(light->diffuse_color, 0.0f);
- }
- }
-
- copy_v3_v3(wd->ambient_color, studiolight->light_ambient);
+ float view_matrix[4][4], rot_matrix[4][4];
+ DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
+
+ if (USE_WORLD_ORIENTATION(wpd)) {
+ axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
+ mul_m4_m4m4(rot_matrix, view_matrix, rot_matrix);
+ swap_v3_v3(rot_matrix[2], rot_matrix[1]);
+ negate_v3(rot_matrix[2]);
+ }
+ else {
+ unit_m4(rot_matrix);
+ }
+
+ if (U.edit_studio_light) {
+ studiolight = BKE_studiolight_studio_edit_get();
+ }
+
+ /* Studio Lights. */
+ for (int i = 0; i < 4; i++) {
+ WORKBENCH_UBO_Light *light = &wd->lights[i];
+
+ SolidLight *sl = &studiolight->light[i];
+ if (sl->flag) {
+ copy_v3_v3(light->light_direction, sl->vec);
+ mul_mat3_m4_v3(rot_matrix, light->light_direction);
+ /* We should predivide the power by PI but that makes the lights really dim. */
+ copy_v3_v3(light->specular_color, sl->spec);
+ copy_v3_v3(light->diffuse_color, sl->col);
+ light->wrapped = sl->smooth;
+ }
+ else {
+ copy_v3_fl3(light->light_direction, 1.0f, 0.0f, 0.0f);
+ copy_v3_fl(light->specular_color, 0.0f);
+ copy_v3_fl(light->diffuse_color, 0.0f);
+ }
+ }
+
+ copy_v3_v3(wd->ambient_color, studiolight->light_ambient);
#if 0
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED);
-
-#if STUDIOLIGHT_SH_BANDS == 2
- /* Use Geomerics non-linear SH. */
- mul_v3_v3fl(wd->spherical_harmonics_coefs[0], sl->spherical_harmonics_coefs[0], M_1_PI);
- /* Swizzle to make shader code simpler. */
- for (int i = 0; i < 3; ++i) {
- copy_v3_fl3(
- wd->spherical_harmonics_coefs[i + 1],
- -sl->spherical_harmonics_coefs[3][i],
- sl->spherical_harmonics_coefs[2][i],
- -sl->spherical_harmonics_coefs[1][i]);
- mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], M_1_PI * 1.5f); /* 1.5f is to improve the contrast a bit. */
- }
-
- /* Precompute as much as we can. See shader code for derivation. */
- float len_r1[3], lr1_r0[3], p[3], a[3];
- for (int i = 0; i < 3; ++i) {
- mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], 0.5f);
- len_r1[i] = len_v3(wd->spherical_harmonics_coefs[i + 1]);
- mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], 1.0f / len_r1[i]);
- }
- /* lr1_r0 = lenR1 / R0; */
- copy_v3_v3(lr1_r0, wd->spherical_harmonics_coefs[0]);
- invert_v3(lr1_r0);
- mul_v3_v3(lr1_r0, len_r1);
- /* p = 1.0 + 2.0 * lr1_r0; */
- copy_v3_v3(p, lr1_r0);
- mul_v3_fl(p, 2.0f);
- add_v3_fl(p, 1.0f);
- /* a = (1.0 - lr1_r0) / (1.0 + lr1_r0); */
- copy_v3_v3(a, lr1_r0);
- add_v3_fl(a, 1.0f);
- invert_v3(a);
- negate_v3(lr1_r0);
- add_v3_fl(lr1_r0, 1.0f);
- mul_v3_v3(a, lr1_r0);
- /* sh_coefs[4] = p; */
- copy_v3_v3(wd->spherical_harmonics_coefs[4], p);
- /* sh_coefs[5] = R0 * a; */
- mul_v3_v3v3(wd->spherical_harmonics_coefs[5], wd->spherical_harmonics_coefs[0], a);
- /* sh_coefs[0] = R0 * (1.0 - a) * (p + 1.0); */
- negate_v3(a);
- add_v3_fl(a, 1.0f);
- add_v3_fl(p, 1.0f);
- mul_v3_v3(a, p);
- mul_v3_v3(wd->spherical_harmonics_coefs[0], a);
-#else
- for (int i = 0; i < STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN; i++) {
- /* Can't memcpy because of alignment */
- copy_v3_v3(wd->spherical_harmonics_coefs[i], sl->spherical_harmonics_coefs[i]);
- }
-#endif
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED);
+
+# if STUDIOLIGHT_SH_BANDS == 2
+ /* Use Geomerics non-linear SH. */
+ mul_v3_v3fl(wd->spherical_harmonics_coefs[0], sl->spherical_harmonics_coefs[0], M_1_PI);
+ /* Swizzle to make shader code simpler. */
+ for (int i = 0; i < 3; ++i) {
+ copy_v3_fl3(
+ wd->spherical_harmonics_coefs[i + 1],
+ -sl->spherical_harmonics_coefs[3][i],
+ sl->spherical_harmonics_coefs[2][i],
+ -sl->spherical_harmonics_coefs[1][i]);
+ mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], M_1_PI * 1.5f); /* 1.5f is to improve the contrast a bit. */
+ }
+
+ /* Precompute as much as we can. See shader code for derivation. */
+ float len_r1[3], lr1_r0[3], p[3], a[3];
+ for (int i = 0; i < 3; ++i) {
+ mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], 0.5f);
+ len_r1[i] = len_v3(wd->spherical_harmonics_coefs[i + 1]);
+ mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], 1.0f / len_r1[i]);
+ }
+ /* lr1_r0 = lenR1 / R0; */
+ copy_v3_v3(lr1_r0, wd->spherical_harmonics_coefs[0]);
+ invert_v3(lr1_r0);
+ mul_v3_v3(lr1_r0, len_r1);
+ /* p = 1.0 + 2.0 * lr1_r0; */
+ copy_v3_v3(p, lr1_r0);
+ mul_v3_fl(p, 2.0f);
+ add_v3_fl(p, 1.0f);
+ /* a = (1.0 - lr1_r0) / (1.0 + lr1_r0); */
+ copy_v3_v3(a, lr1_r0);
+ add_v3_fl(a, 1.0f);
+ invert_v3(a);
+ negate_v3(lr1_r0);
+ add_v3_fl(lr1_r0, 1.0f);
+ mul_v3_v3(a, lr1_r0);
+ /* sh_coefs[4] = p; */
+ copy_v3_v3(wd->spherical_harmonics_coefs[4], p);
+ /* sh_coefs[5] = R0 * a; */
+ mul_v3_v3v3(wd->spherical_harmonics_coefs[5], wd->spherical_harmonics_coefs[0], a);
+ /* sh_coefs[0] = R0 * (1.0 - a) * (p + 1.0); */
+ negate_v3(a);
+ add_v3_fl(a, 1.0f);
+ add_v3_fl(p, 1.0f);
+ mul_v3_v3(a, p);
+ mul_v3_v3(wd->spherical_harmonics_coefs[0], a);
+# else
+ for (int i = 0; i < STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN; i++) {
+ /* Can't memcpy because of alignment */
+ copy_v3_v3(wd->spherical_harmonics_coefs[i], sl->spherical_harmonics_coefs[i]);
+ }
+# endif
#endif
}
-static void compute_parallel_lines_nor_and_dist(const float v1[2], const float v2[2], const float v3[2], float r_line[2])
+static void compute_parallel_lines_nor_and_dist(const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ float r_line[2])
{
- sub_v2_v2v2(r_line, v2, v1);
- /* Find orthogonal vector. */
- SWAP(float, r_line[0], r_line[1]);
- r_line[0] = -r_line[0];
- /* Edge distances. */
- r_line[2] = dot_v2v2(r_line, v1);
- r_line[3] = dot_v2v2(r_line, v3);
- /* Make sure r_line[2] is the minimum. */
- if (r_line[2] > r_line[3]) {
- SWAP(float, r_line[2], r_line[3]);
- }
+ sub_v2_v2v2(r_line, v2, v1);
+ /* Find orthogonal vector. */
+ SWAP(float, r_line[0], r_line[1]);
+ r_line[0] = -r_line[0];
+ /* Edge distances. */
+ r_line[2] = dot_v2v2(r_line, v1);
+ r_line[3] = dot_v2v2(r_line, v3);
+ /* Make sure r_line[2] is the minimum. */
+ if (r_line[2] > r_line[3]) {
+ SWAP(float, r_line[2], r_line[3]);
+ }
}
void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3])
{
- wpd->shadow_changed = !compare_v3v3(wpd->cached_shadow_direction, light_direction, 1e-5f);
-
- if (wpd->shadow_changed) {
- float up[3] = {0.0f, 0.0f, 1.0f};
- unit_m4(wpd->shadow_mat);
-
- /* TODO fix singularity. */
- copy_v3_v3(wpd->shadow_mat[2], light_direction);
- cross_v3_v3v3(wpd->shadow_mat[0], wpd->shadow_mat[2], up);
- normalize_v3(wpd->shadow_mat[0]);
- cross_v3_v3v3(wpd->shadow_mat[1], wpd->shadow_mat[2], wpd->shadow_mat[0]);
-
- invert_m4_m4(wpd->shadow_inv, wpd->shadow_mat);
-
- copy_v3_v3(wpd->cached_shadow_direction, light_direction);
- }
-
- float planes[6][4];
- DRW_culling_frustum_planes_get(planes);
- /* we only need the far plane. */
- copy_v4_v4(wpd->shadow_far_plane, planes[2]);
-
- BoundBox frustum_corners;
- DRW_culling_frustum_corners_get(&frustum_corners);
-
- mul_v3_mat3_m4v3(wpd->shadow_near_corners[0], wpd->shadow_inv, frustum_corners.vec[0]);
- mul_v3_mat3_m4v3(wpd->shadow_near_corners[1], wpd->shadow_inv, frustum_corners.vec[3]);
- mul_v3_mat3_m4v3(wpd->shadow_near_corners[2], wpd->shadow_inv, frustum_corners.vec[7]);
- mul_v3_mat3_m4v3(wpd->shadow_near_corners[3], wpd->shadow_inv, frustum_corners.vec[4]);
-
- INIT_MINMAX(wpd->shadow_near_min, wpd->shadow_near_max);
- for (int i = 0; i < 4; ++i) {
- minmax_v3v3_v3(wpd->shadow_near_min, wpd->shadow_near_max, wpd->shadow_near_corners[i]);
- }
-
- compute_parallel_lines_nor_and_dist(wpd->shadow_near_corners[0], wpd->shadow_near_corners[1], wpd->shadow_near_corners[2], wpd->shadow_near_sides[0]);
- compute_parallel_lines_nor_and_dist(wpd->shadow_near_corners[1], wpd->shadow_near_corners[2], wpd->shadow_near_corners[0], wpd->shadow_near_sides[1]);
+ wpd->shadow_changed = !compare_v3v3(wpd->cached_shadow_direction, light_direction, 1e-5f);
+
+ if (wpd->shadow_changed) {
+ float up[3] = {0.0f, 0.0f, 1.0f};
+ unit_m4(wpd->shadow_mat);
+
+ /* TODO fix singularity. */
+ copy_v3_v3(wpd->shadow_mat[2], light_direction);
+ cross_v3_v3v3(wpd->shadow_mat[0], wpd->shadow_mat[2], up);
+ normalize_v3(wpd->shadow_mat[0]);
+ cross_v3_v3v3(wpd->shadow_mat[1], wpd->shadow_mat[2], wpd->shadow_mat[0]);
+
+ invert_m4_m4(wpd->shadow_inv, wpd->shadow_mat);
+
+ copy_v3_v3(wpd->cached_shadow_direction, light_direction);
+ }
+
+ float planes[6][4];
+ DRW_culling_frustum_planes_get(planes);
+ /* we only need the far plane. */
+ copy_v4_v4(wpd->shadow_far_plane, planes[2]);
+
+ BoundBox frustum_corners;
+ DRW_culling_frustum_corners_get(&frustum_corners);
+
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[0], wpd->shadow_inv, frustum_corners.vec[0]);
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[1], wpd->shadow_inv, frustum_corners.vec[3]);
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[2], wpd->shadow_inv, frustum_corners.vec[7]);
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[3], wpd->shadow_inv, frustum_corners.vec[4]);
+
+ INIT_MINMAX(wpd->shadow_near_min, wpd->shadow_near_max);
+ for (int i = 0; i < 4; ++i) {
+ minmax_v3v3_v3(wpd->shadow_near_min, wpd->shadow_near_max, wpd->shadow_near_corners[i]);
+ }
+
+ compute_parallel_lines_nor_and_dist(wpd->shadow_near_corners[0],
+ wpd->shadow_near_corners[1],
+ wpd->shadow_near_corners[2],
+ wpd->shadow_near_sides[0]);
+ compute_parallel_lines_nor_and_dist(wpd->shadow_near_corners[1],
+ wpd->shadow_near_corners[2],
+ wpd->shadow_near_corners[0],
+ wpd->shadow_near_sides[1]);
}
-static BoundBox *studiolight_object_shadow_bbox_get(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+static BoundBox *studiolight_object_shadow_bbox_get(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed)
{
- if ((oed->shadow_bbox_dirty) || (wpd->shadow_changed)) {
- float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, wpd->shadow_inv, ob->obmat);
-
- /* Get AABB in shadow space. */
- INIT_MINMAX(oed->shadow_min, oed->shadow_max);
-
- /* From object space to shadow space */
- BoundBox *bbox = BKE_object_boundbox_get(ob);
- for (int i = 0; i < 8; ++i) {
- float corner[3];
- mul_v3_m4v3(corner, tmp_mat, bbox->vec[i]);
- minmax_v3v3_v3(oed->shadow_min, oed->shadow_max, corner);
- }
- oed->shadow_depth = oed->shadow_max[2] - oed->shadow_min[2];
- /* Extend towards infinity. */
- oed->shadow_max[2] += 1e4f;
-
- /* Get extended AABB in world space. */
- BKE_boundbox_init_from_minmax(&oed->shadow_bbox, oed->shadow_min, oed->shadow_max);
- for (int i = 0; i < 8; ++i) {
- mul_m4_v3(wpd->shadow_mat, oed->shadow_bbox.vec[i]);
- }
- oed->shadow_bbox_dirty = false;
- }
-
- return &oed->shadow_bbox;
+ if ((oed->shadow_bbox_dirty) || (wpd->shadow_changed)) {
+ float tmp_mat[4][4];
+ mul_m4_m4m4(tmp_mat, wpd->shadow_inv, ob->obmat);
+
+ /* Get AABB in shadow space. */
+ INIT_MINMAX(oed->shadow_min, oed->shadow_max);
+
+ /* From object space to shadow space */
+ BoundBox *bbox = BKE_object_boundbox_get(ob);
+ for (int i = 0; i < 8; ++i) {
+ float corner[3];
+ mul_v3_m4v3(corner, tmp_mat, bbox->vec[i]);
+ minmax_v3v3_v3(oed->shadow_min, oed->shadow_max, corner);
+ }
+ oed->shadow_depth = oed->shadow_max[2] - oed->shadow_min[2];
+ /* Extend towards infinity. */
+ oed->shadow_max[2] += 1e4f;
+
+ /* Get extended AABB in world space. */
+ BKE_boundbox_init_from_minmax(&oed->shadow_bbox, oed->shadow_min, oed->shadow_max);
+ for (int i = 0; i < 8; ++i) {
+ mul_m4_v3(wpd->shadow_mat, oed->shadow_bbox.vec[i]);
+ }
+ oed->shadow_bbox_dirty = false;
+ }
+
+ return &oed->shadow_bbox;
}
-bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed)
{
- BoundBox *shadow_bbox = studiolight_object_shadow_bbox_get(wpd, ob, oed);
- return DRW_culling_box_test(shadow_bbox);
+ BoundBox *shadow_bbox = studiolight_object_shadow_bbox_get(wpd, ob, oed);
+ return DRW_culling_box_test(shadow_bbox);
}
-float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed)
{
- BoundBox *shadow_bbox = studiolight_object_shadow_bbox_get(wpd, ob, oed);
-
- int corners[4] = {0, 3, 4, 7};
- float dist = 1e4f, dist_isect;
- for (int i = 0; i < 4; ++i) {
- if (isect_ray_plane_v3(shadow_bbox->vec[corners[i]],
- wpd->cached_shadow_direction,
- wpd->shadow_far_plane,
- &dist_isect, true))
- {
- if (dist_isect < dist) {
- dist = dist_isect;
- }
- }
- else {
- /* All rays are parallels. If one fails, the other will too. */
- break;
- }
- }
- return max_ii(dist - oed->shadow_depth, 0);
+ BoundBox *shadow_bbox = studiolight_object_shadow_bbox_get(wpd, ob, oed);
+
+ int corners[4] = {0, 3, 4, 7};
+ float dist = 1e4f, dist_isect;
+ for (int i = 0; i < 4; ++i) {
+ if (isect_ray_plane_v3(shadow_bbox->vec[corners[i]],
+ wpd->cached_shadow_direction,
+ wpd->shadow_far_plane,
+ &dist_isect,
+ true)) {
+ if (dist_isect < dist) {
+ dist = dist_isect;
+ }
+ }
+ else {
+ /* All rays are parallels. If one fails, the other will too. */
+ break;
+ }
+ }
+ return max_ii(dist - oed->shadow_depth, 0);
}
-bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd,
+ Object *ob,
+ WORKBENCH_ObjectData *oed)
{
- /* Just to be sure the min, max are updated. */
- studiolight_object_shadow_bbox_get(wpd, ob, oed);
-
- /* Test if near plane is in front of the shadow. */
- if (oed->shadow_min[2] > wpd->shadow_near_max[2]) {
- return false;
- }
-
- /* Separation Axis Theorem test */
-
- /* Test bbox sides first (faster) */
- if ((oed->shadow_min[0] > wpd->shadow_near_max[0]) ||
- (oed->shadow_max[0] < wpd->shadow_near_min[0]) ||
- (oed->shadow_min[1] > wpd->shadow_near_max[1]) ||
- (oed->shadow_max[1] < wpd->shadow_near_min[1]))
- {
- return false;
- }
-
- /* Test projected near rectangle sides */
- float pts[4][2] = {
- {oed->shadow_min[0], oed->shadow_min[1]},
- {oed->shadow_min[0], oed->shadow_max[1]},
- {oed->shadow_max[0], oed->shadow_min[1]},
- {oed->shadow_max[0], oed->shadow_max[1]},
- };
-
- for (int i = 0; i < 2; ++i) {
- float min_dst = FLT_MAX, max_dst = -FLT_MAX;
- for (int j = 0; j < 4; ++j) {
- float dst = dot_v2v2(wpd->shadow_near_sides[i], pts[j]);
- /* Do min max */
- if (min_dst > dst) { min_dst = dst; }
- if (max_dst < dst) { max_dst = dst; }
- }
-
- if ((wpd->shadow_near_sides[i][2] > max_dst) ||
- (wpd->shadow_near_sides[i][3] < min_dst))
- {
- return false;
- }
- }
-
- /* No separation axis found. Both shape intersect. */
- return true;
+ /* Just to be sure the min, max are updated. */
+ studiolight_object_shadow_bbox_get(wpd, ob, oed);
+
+ /* Test if near plane is in front of the shadow. */
+ if (oed->shadow_min[2] > wpd->shadow_near_max[2]) {
+ return false;
+ }
+
+ /* Separation Axis Theorem test */
+
+ /* Test bbox sides first (faster) */
+ if ((oed->shadow_min[0] > wpd->shadow_near_max[0]) ||
+ (oed->shadow_max[0] < wpd->shadow_near_min[0]) ||
+ (oed->shadow_min[1] > wpd->shadow_near_max[1]) ||
+ (oed->shadow_max[1] < wpd->shadow_near_min[1])) {
+ return false;
+ }
+
+ /* Test projected near rectangle sides */
+ float pts[4][2] = {
+ {oed->shadow_min[0], oed->shadow_min[1]},
+ {oed->shadow_min[0], oed->shadow_max[1]},
+ {oed->shadow_max[0], oed->shadow_min[1]},
+ {oed->shadow_max[0], oed->shadow_max[1]},
+ };
+
+ for (int i = 0; i < 2; ++i) {
+ float min_dst = FLT_MAX, max_dst = -FLT_MAX;
+ for (int j = 0; j < 4; ++j) {
+ float dst = dot_v2v2(wpd->shadow_near_sides[i], pts[j]);
+ /* Do min max */
+ if (min_dst > dst) {
+ min_dst = dst;
+ }
+ if (max_dst < dst) {
+ max_dst = dst;
+ }
+ }
+
+ if ((wpd->shadow_near_sides[i][2] > max_dst) || (wpd->shadow_near_sides[i][3] < min_dst)) {
+ return false;
+ }
+ }
+
+ /* No separation axis found. Both shape intersect. */
+ return true;
}
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index 0f5debc46d8..accc7e91576 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -35,20 +35,20 @@
#include "GPU_draw.h"
enum {
- VOLUME_SH_SLICE = 0,
- VOLUME_SH_COBA,
- VOLUME_SH_CUBIC,
+ VOLUME_SH_SLICE = 0,
+ VOLUME_SH_COBA,
+ VOLUME_SH_CUBIC,
};
#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
static struct {
- struct GPUShader *volume_sh[VOLUME_SH_MAX];
- struct GPUShader *volume_coba_sh;
- struct GPUShader *volume_slice_sh;
- struct GPUShader *volume_slice_coba_sh;
- struct GPUTexture *dummy_tex;
- struct GPUTexture *dummy_coba_tex;
+ struct GPUShader *volume_sh[VOLUME_SH_MAX];
+ struct GPUShader *volume_coba_sh;
+ struct GPUShader *volume_slice_sh;
+ struct GPUShader *volume_slice_coba_sh;
+ struct GPUTexture *dummy_tex;
+ struct GPUTexture *dummy_coba_tex;
} e_data = {{NULL}};
extern char datatoc_workbench_volume_vert_glsl[];
@@ -56,174 +56,177 @@ extern char datatoc_workbench_volume_frag_glsl[];
static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
{
- int id = 0;
- id += (slice) ? (1 << VOLUME_SH_SLICE) : 0;
- id += (coba) ? (1 << VOLUME_SH_COBA) : 0;
- id += (cubic) ? (1 << VOLUME_SH_CUBIC) : 0;
-
- if (!e_data.volume_sh[id]) {
- DynStr *ds = BLI_dynstr_new();
-
- if (slice) {
- BLI_dynstr_append(ds, "#define VOLUME_SLICE\n");
- }
- if (coba) {
- BLI_dynstr_append(ds, "#define USE_COBA\n");
- }
- if (cubic) {
- BLI_dynstr_append(ds, "#define USE_TRICUBIC\n");
- }
-
- char *defines = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
-
- e_data.volume_sh[id] = DRW_shader_create(
- datatoc_workbench_volume_vert_glsl, NULL,
- datatoc_workbench_volume_frag_glsl,
- defines);
-
- MEM_freeN(defines);
- }
-
- return e_data.volume_sh[id];
+ int id = 0;
+ id += (slice) ? (1 << VOLUME_SH_SLICE) : 0;
+ id += (coba) ? (1 << VOLUME_SH_COBA) : 0;
+ id += (cubic) ? (1 << VOLUME_SH_CUBIC) : 0;
+
+ if (!e_data.volume_sh[id]) {
+ DynStr *ds = BLI_dynstr_new();
+
+ if (slice) {
+ BLI_dynstr_append(ds, "#define VOLUME_SLICE\n");
+ }
+ if (coba) {
+ BLI_dynstr_append(ds, "#define USE_COBA\n");
+ }
+ if (cubic) {
+ BLI_dynstr_append(ds, "#define USE_TRICUBIC\n");
+ }
+
+ char *defines = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ e_data.volume_sh[id] = DRW_shader_create(
+ datatoc_workbench_volume_vert_glsl, NULL, datatoc_workbench_volume_frag_glsl, defines);
+
+ MEM_freeN(defines);
+ }
+
+ return e_data.volume_sh[id];
}
void workbench_volume_engine_init(void)
{
- if (!e_data.dummy_tex) {
- float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- e_data.dummy_tex = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, pixel, NULL);
- e_data.dummy_coba_tex = GPU_texture_create_1d(1, GPU_RGBA8, pixel, NULL);
- }
+ if (!e_data.dummy_tex) {
+ float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ e_data.dummy_tex = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, pixel, NULL);
+ e_data.dummy_coba_tex = GPU_texture_create_1d(1, GPU_RGBA8, pixel, NULL);
+ }
}
void workbench_volume_engine_free(void)
{
- for (int i = 0; i < VOLUME_SH_MAX; ++i) {
- DRW_SHADER_FREE_SAFE(e_data.volume_sh[i]);
- }
- DRW_TEXTURE_FREE_SAFE(e_data.dummy_tex);
- DRW_TEXTURE_FREE_SAFE(e_data.dummy_coba_tex);
+ for (int i = 0; i < VOLUME_SH_MAX; ++i) {
+ DRW_SHADER_FREE_SAFE(e_data.volume_sh[i]);
+ }
+ DRW_TEXTURE_FREE_SAFE(e_data.dummy_tex);
+ DRW_TEXTURE_FREE_SAFE(e_data.dummy_coba_tex);
}
void workbench_volume_cache_init(WORKBENCH_Data *vedata)
{
- vedata->psl->volume_pass = DRW_pass_create("Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL | DRW_STATE_CULL_FRONT);
+ vedata->psl->volume_pass = DRW_pass_create(
+ "Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL | DRW_STATE_CULL_FRONT);
}
-void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, ModifierData *md)
+void workbench_volume_cache_populate(WORKBENCH_Data *vedata,
+ Scene *scene,
+ Object *ob,
+ ModifierData *md)
{
- SmokeModifierData *smd = (SmokeModifierData *)md;
- SmokeDomainSettings *sds = smd->domain;
- WORKBENCH_PrivateData *wpd = vedata->stl->g_data;
- WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRWShadingGroup *grp = NULL;
-
- /* Don't show smoke before simulation starts, this could be made an option in the future. */
- if (!sds->fluid || CFRA < sds->point_cache[0]->startframe) {
- return;
- }
-
- wpd->volumes_do = true;
- const bool show_highres = BKE_smoke_show_highres(scene, sds);
- if (sds->use_coba) {
- GPU_create_smoke_coba_field(smd);
- }
- else if (!sds->wt || !show_highres) {
- GPU_create_smoke(smd, 0);
- }
- else if (sds->wt && show_highres) {
- GPU_create_smoke(smd, 1);
- }
-
- if ((!sds->use_coba && sds->tex == NULL) ||
- (sds->use_coba && sds->tex_field == NULL))
- {
- return;
- }
-
- const bool use_slice = (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
- sds->axis_slice_method == AXIS_SLICE_SINGLE);
- const bool cubic_interp = (sds->interp_method == VOLUME_INTERP_CUBIC);
- GPUShader *sh = volume_shader_get(use_slice, sds->use_coba, cubic_interp);
-
- if (use_slice) {
- float invviewmat[4][4];
- DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
-
- const int axis = (sds->slice_axis == SLICE_AXIS_AUTO)
- ? axis_dominant_v3_single(invviewmat[2])
- : sds->slice_axis - 1;
- float dim[3];
- BKE_object_dimensions_get(ob, dim);
- /* 0.05f to acheive somewhat the same opacity as the full view. */
- float step_length = max_ff(1e-16f, dim[axis] * 0.05f);
-
- grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
- DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth);
- DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis);
- DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length);
- DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
- }
- else {
- double noise_ofs;
- BLI_halton_1d(3, 0.0, effect_info->jitter_index, &noise_ofs);
- float dim[3], step_length, max_slice;
- float slice_ct[3] = {sds->res[0], sds->res[1], sds->res[2]};
- mul_v3_fl(slice_ct, max_ff(0.001f, sds->slice_per_voxel));
- max_slice = max_fff(slice_ct[0], slice_ct[1], slice_ct[2]);
- BKE_object_dimensions_get(ob, dim);
- invert_v3(slice_ct);
- mul_v3_v3(dim, slice_ct);
- step_length = len_v3(dim);
-
- grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
- DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slice);
- DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length);
- DRW_shgroup_uniform_float_copy(grp, "noiseOfs", noise_ofs);
- DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
- }
-
- if (sds->use_coba) {
- DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex_field);
- DRW_shgroup_uniform_texture(grp, "transferTexture", sds->tex_coba);
- }
- else {
- static float white[3] = {1.0f, 1.0f, 1.0f};
- bool use_constant_color = ((sds->active_fields & SM_ACTIVE_COLORS) == 0 &&
- (sds->active_fields & SM_ACTIVE_COLOR_SET) != 0);
- DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
- DRW_shgroup_uniform_texture(grp, "shadowTexture", sds->tex_shadow);
- DRW_shgroup_uniform_texture(grp, "flameTexture", (sds->tex_flame) ? sds->tex_flame : e_data.dummy_tex);
- DRW_shgroup_uniform_texture(grp, "flameColorTexture", (sds->tex_flame) ? sds->tex_flame_coba : e_data.dummy_coba_tex);
- DRW_shgroup_uniform_vec3(grp, "activeColor", (use_constant_color) ? sds->active_color : white, 1);
- }
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
-
- if (use_slice) {
- DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
- }
- else {
- DRW_shgroup_call_object_add(grp, DRW_cache_cube_get(), ob);
- }
-
- BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ SmokeDomainSettings *sds = smd->domain;
+ WORKBENCH_PrivateData *wpd = vedata->stl->g_data;
+ WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ DRWShadingGroup *grp = NULL;
+
+ /* Don't show smoke before simulation starts, this could be made an option in the future. */
+ if (!sds->fluid || CFRA < sds->point_cache[0]->startframe) {
+ return;
+ }
+
+ wpd->volumes_do = true;
+ const bool show_highres = BKE_smoke_show_highres(scene, sds);
+ if (sds->use_coba) {
+ GPU_create_smoke_coba_field(smd);
+ }
+ else if (!sds->wt || !show_highres) {
+ GPU_create_smoke(smd, 0);
+ }
+ else if (sds->wt && show_highres) {
+ GPU_create_smoke(smd, 1);
+ }
+
+ if ((!sds->use_coba && sds->tex == NULL) || (sds->use_coba && sds->tex_field == NULL)) {
+ return;
+ }
+
+ const bool use_slice = (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
+ sds->axis_slice_method == AXIS_SLICE_SINGLE);
+ const bool cubic_interp = (sds->interp_method == VOLUME_INTERP_CUBIC);
+ GPUShader *sh = volume_shader_get(use_slice, sds->use_coba, cubic_interp);
+
+ if (use_slice) {
+ float invviewmat[4][4];
+ DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
+
+ const int axis = (sds->slice_axis == SLICE_AXIS_AUTO) ?
+ axis_dominant_v3_single(invviewmat[2]) :
+ sds->slice_axis - 1;
+ float dim[3];
+ BKE_object_dimensions_get(ob, dim);
+ /* 0.05f to acheive somewhat the same opacity as the full view. */
+ float step_length = max_ff(1e-16f, dim[axis] * 0.05f);
+
+ grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
+ DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth);
+ DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis);
+ DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length);
+ DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
+ }
+ else {
+ double noise_ofs;
+ BLI_halton_1d(3, 0.0, effect_info->jitter_index, &noise_ofs);
+ float dim[3], step_length, max_slice;
+ float slice_ct[3] = {sds->res[0], sds->res[1], sds->res[2]};
+ mul_v3_fl(slice_ct, max_ff(0.001f, sds->slice_per_voxel));
+ max_slice = max_fff(slice_ct[0], slice_ct[1], slice_ct[2]);
+ BKE_object_dimensions_get(ob, dim);
+ invert_v3(slice_ct);
+ mul_v3_v3(dim, slice_ct);
+ step_length = len_v3(dim);
+
+ grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slice);
+ DRW_shgroup_uniform_float_copy(grp, "stepLength", step_length);
+ DRW_shgroup_uniform_float_copy(grp, "noiseOfs", noise_ofs);
+ DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
+ }
+
+ if (sds->use_coba) {
+ DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex_field);
+ DRW_shgroup_uniform_texture(grp, "transferTexture", sds->tex_coba);
+ }
+ else {
+ static float white[3] = {1.0f, 1.0f, 1.0f};
+ bool use_constant_color = ((sds->active_fields & SM_ACTIVE_COLORS) == 0 &&
+ (sds->active_fields & SM_ACTIVE_COLOR_SET) != 0);
+ DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
+ DRW_shgroup_uniform_texture(grp, "shadowTexture", sds->tex_shadow);
+ DRW_shgroup_uniform_texture(
+ grp, "flameTexture", (sds->tex_flame) ? sds->tex_flame : e_data.dummy_tex);
+ DRW_shgroup_uniform_texture(
+ grp, "flameColorTexture", (sds->tex_flame) ? sds->tex_flame_coba : e_data.dummy_coba_tex);
+ DRW_shgroup_uniform_vec3(
+ grp, "activeColor", (use_constant_color) ? sds->active_color : white, 1);
+ }
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
+
+ if (use_slice) {
+ DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
+ }
+ else {
+ DRW_shgroup_call_object_add(grp, DRW_cache_cube_get(), ob);
+ }
+
+ BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
}
void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd)
{
- /* Free Smoke Textures after rendering */
- /* XXX This is a waste of processing and GPU bandwidth if nothing
- * is updated. But the problem is since Textures are stored in the
- * modifier we don't want them to take precious VRAM if the
- * modifier is not used for display. We should share them for
- * all viewport in a redraw at least. */
- for (LinkData *link = wpd->smoke_domains.first; link; link = link->next) {
- SmokeModifierData *smd = (SmokeModifierData *)link->data;
- GPU_free_smoke(smd);
- }
- BLI_freelistN(&wpd->smoke_domains);
+ /* Free Smoke Textures after rendering */
+ /* XXX This is a waste of processing and GPU bandwidth if nothing
+ * is updated. But the problem is since Textures are stored in the
+ * modifier we don't want them to take precious VRAM if the
+ * modifier is not used for display. We should share them for
+ * all viewport in a redraw at least. */
+ for (LinkData *link = wpd->smoke_domains.first; link; link = link->next) {
+ SmokeModifierData *smd = (SmokeModifierData *)link->data;
+ GPU_free_smoke(smd);
+ }
+ BLI_freelistN(&wpd->smoke_domains);
}