mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Workbench: Enable BSL 5.3
Contains refactors to use the BSL version of draw and gpu libs. Only leave workbench_shadow_raytrace out because of missing raytrace API in 5.3 compiler. Pull Request: https://projects.blender.org/blender/blender/pulls/164410
This commit is contained in:
parent
5ce66a846e
commit
d50d0205d2
40 changed files with 952 additions and 1460 deletions
|
|
@ -350,12 +350,7 @@ set(GLSL_SRC
|
|||
|
||||
engines/select/shaders/infos/select_id_infos.hh
|
||||
|
||||
engines/workbench/shaders/infos/workbench_depth_infos.hh
|
||||
engines/workbench/shaders/infos/workbench_effect_antialiasing_infos.hh
|
||||
engines/workbench/shaders/infos/workbench_effect_dof_infos.hh
|
||||
engines/workbench/shaders/infos/workbench_effect_outline_infos.hh
|
||||
engines/workbench/shaders/infos/workbench_prepass_infos.hh
|
||||
engines/workbench/shaders/infos/workbench_transparent_resolve_infos.hh
|
||||
|
||||
engines/eevee/shaders/eevee_attributes_curves_lib.bsl.hh
|
||||
engines/eevee/shaders/eevee_attributes_mesh_lib.bsl.hh
|
||||
|
|
@ -512,35 +507,23 @@ set(GLSL_SRC
|
|||
|
||||
engines/workbench/shaders/workbench_cavity.bsl.hh
|
||||
engines/workbench/shaders/workbench_common.bsl.hh
|
||||
engines/workbench/shaders/workbench_common_lib.glsl
|
||||
engines/workbench/shaders/workbench_composite.bsl.hh
|
||||
engines/workbench/shaders/workbench_curvature.bsl.hh
|
||||
engines/workbench/shaders/workbench_effect_dof_prepare_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_dof_downsample_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_dof_blur1_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_dof_blur2_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_dof_resolve_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_dof_lib.glsl
|
||||
engines/workbench/shaders/workbench_effect_outline_frag.glsl
|
||||
engines/workbench/shaders/workbench_fx_dof.bsl.hh
|
||||
engines/workbench/shaders/workbench_fx_outline.bsl.hh
|
||||
engines/workbench/shaders/workbench_effect_smaa_frag.glsl
|
||||
engines/workbench/shaders/workbench_effect_smaa_vert.glsl
|
||||
engines/workbench/shaders/workbench_effect_taa_frag.glsl
|
||||
engines/workbench/shaders/workbench_fullscreen_vert.glsl
|
||||
engines/workbench/shaders/workbench_image_lib.glsl
|
||||
engines/workbench/shaders/workbench_fx_taa.bsl.hh
|
||||
engines/workbench/shaders/workbench_image.bsl.hh
|
||||
engines/workbench/shaders/workbench_matcap_lib.glsl
|
||||
engines/workbench/shaders/workbench_matcap.bsl.hh
|
||||
engines/workbench/shaders/workbench_material.bsl.hh
|
||||
engines/workbench/shaders/workbench_merge_depth_frag.glsl
|
||||
engines/workbench/shaders/workbench_overlay_depth_frag.glsl
|
||||
engines/workbench/shaders/workbench_depth.bsl.hh
|
||||
engines/workbench/shaders/workbench_prepass.bsl.hh
|
||||
engines/workbench/shaders/workbench_shadow.bsl.hh
|
||||
engines/workbench/shaders/workbench_shadow_raytrace.bsl.hh
|
||||
engines/workbench/shaders/workbench_shadow_visibility.bsl.hh
|
||||
engines/workbench/shaders/workbench_transparent_accum_frag.glsl
|
||||
engines/workbench/shaders/workbench_transparent_resolve_frag.glsl
|
||||
engines/workbench/shaders/workbench_transparent_resolve.bsl.hh
|
||||
engines/workbench/shaders/workbench_volume.bsl.hh
|
||||
engines/workbench/shaders/workbench_world_light_lib.glsl
|
||||
engines/workbench/shaders/workbench_world_light.bsl.hh
|
||||
|
||||
engines/workbench/workbench_defines.hh
|
||||
|
|
|
|||
|
|
@ -26,29 +26,10 @@ set(INC_GLSL
|
|||
|
||||
set(SRC_GLSL_VERT
|
||||
workbench_effect_smaa_vert.glsl
|
||||
workbench_fullscreen_vert.glsl
|
||||
)
|
||||
|
||||
set(SRC_GLSL_FRAG
|
||||
workbench_effect_dof_prepare_frag.glsl
|
||||
workbench_effect_dof_downsample_frag.glsl
|
||||
workbench_effect_dof_blur1_frag.glsl
|
||||
workbench_effect_dof_blur2_frag.glsl
|
||||
workbench_effect_dof_resolve_frag.glsl
|
||||
workbench_effect_outline_frag.glsl
|
||||
workbench_effect_smaa_frag.glsl
|
||||
workbench_effect_taa_frag.glsl
|
||||
workbench_merge_depth_frag.glsl
|
||||
workbench_overlay_depth_frag.glsl
|
||||
workbench_transparent_resolve_frag.glsl
|
||||
)
|
||||
|
||||
set(SRC_GLSL_LIB
|
||||
workbench_effect_dof_lib.glsl
|
||||
workbench_common_lib.glsl
|
||||
workbench_image_lib.glsl
|
||||
workbench_matcap_lib.glsl
|
||||
workbench_world_light_lib.glsl
|
||||
)
|
||||
|
||||
set(SRC_BSL
|
||||
|
|
@ -61,7 +42,6 @@ if(WITH_GPU_SHADER_CPP_COMPILATION)
|
|||
add_definitions(-DUSE_GPU_SHADER_CREATE_INFO)
|
||||
|
||||
compile_sources_as_cpp(workbench_cpp_shaders_vert "${SRC_GLSL_VERT}" "GPU_VERTEX_SHADER")
|
||||
compile_sources_as_cpp(workbench_cpp_shaders_frag "${SRC_GLSL_FRAG}" "GPU_FRAGMENT_SHADER")
|
||||
compile_sources_as_cpp(workbench_cpp_shaders_bsl "${SRC_BSL}" "")
|
||||
# Only enable to make sure they compile on their own.
|
||||
# Otherwise it creates a warning about `pragma once`.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
#include "workbench_common.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_composite.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_curvature.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_fx_dof.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_fx_outline.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_fx_taa.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_image.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_matcap.bsl.hh" /* IWYU pragma: export */
|
||||
#include "workbench_material.bsl.hh" /* IWYU pragma: export */
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifdef GPU_SHADER
|
||||
# pragma once
|
||||
# include "gpu_shader_compat.hh"
|
||||
#endif
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_merge_depth)
|
||||
SAMPLER(0, sampler2DDepth, depth_tx)
|
||||
FRAGMENT_SOURCE("workbench_merge_depth_frag.glsl")
|
||||
VERTEX_SOURCE("workbench_fullscreen_vert.glsl")
|
||||
DEPTH_WRITE(DepthWrite::ANY)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_overlay_depth)
|
||||
FRAGMENT_SOURCE("workbench_overlay_depth_frag.glsl")
|
||||
VERTEX_SOURCE("workbench_fullscreen_vert.glsl")
|
||||
DEPTH_WRITE(DepthWrite::ANY)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
@ -18,21 +18,6 @@
|
|||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name TAA
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_taa)
|
||||
SAMPLER(0, sampler2D, color_buffer)
|
||||
PUSH_CONSTANT_ARRAY(float, samplesWeights, 9)
|
||||
FRAGMENT_OUT(0, float4, frag_color)
|
||||
FRAGMENT_SOURCE("workbench_effect_taa_frag.glsl")
|
||||
VERTEX_SOURCE("workbench_fullscreen_vert.glsl")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name SMAA
|
||||
* \{ */
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifdef GPU_SHADER
|
||||
# pragma once
|
||||
# include "gpu_shader_compat.hh"
|
||||
|
||||
# include "workbench_shader_shared.hh"
|
||||
|
||||
# include "draw_view_infos.hh"
|
||||
#endif
|
||||
|
||||
#ifdef GLSL_CPP_STUBS
|
||||
# define PREPARE
|
||||
# define DOWNSAMPLE
|
||||
# define BLUR1
|
||||
# define BLUR2
|
||||
# define RESOLVE
|
||||
# define NUM_SAMPLES 49
|
||||
#endif
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
/*
|
||||
* NOTE: Keep the sampler bind points consistent between the steps.
|
||||
*
|
||||
* SAMPLER(0, sampler2D, input_coc_tx)
|
||||
* SAMPLER(1, sampler2D, scene_color_tx)
|
||||
* SAMPLER(2, sampler2D, scene_depth_tx)
|
||||
* SAMPLER(3, sampler2D, half_res_color_tx)
|
||||
* SAMPLER(4, sampler2D, blur_tx)
|
||||
* SAMPLER(5, sampler2D, noise_tx)
|
||||
*/
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_dof)
|
||||
PUSH_CONSTANT(float2, inverted_viewport_size)
|
||||
PUSH_CONSTANT(float2, near_far)
|
||||
PUSH_CONSTANT(float3, dof_params)
|
||||
PUSH_CONSTANT(float, noise_offset)
|
||||
VERTEX_SOURCE("workbench_fullscreen_vert.glsl")
|
||||
ADDITIONAL_INFO(draw_view)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_dof_prepare)
|
||||
SAMPLER(1, sampler2D, scene_color_tx)
|
||||
SAMPLER(2, sampler2D, scene_depth_tx)
|
||||
FRAGMENT_OUT(0, float4, halfResColor)
|
||||
FRAGMENT_OUT(1, float2, normalizedCoc)
|
||||
FRAGMENT_SOURCE("workbench_effect_dof_prepare_frag.glsl")
|
||||
ADDITIONAL_INFO(workbench_effect_dof)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_dof_downsample)
|
||||
SAMPLER(0, sampler2D, input_coc_tx)
|
||||
SAMPLER(1, sampler2D, scene_color_tx)
|
||||
FRAGMENT_OUT(0, float4, outColor)
|
||||
FRAGMENT_OUT(1, float2, outCocs)
|
||||
FRAGMENT_SOURCE("workbench_effect_dof_downsample_frag.glsl")
|
||||
ADDITIONAL_INFO(workbench_effect_dof)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_dof_blur1)
|
||||
DEFINE_VALUE("NUM_SAMPLES", "49")
|
||||
SAMPLER(0, sampler2D, input_coc_tx)
|
||||
SAMPLER(3, sampler2D, half_res_color_tx)
|
||||
SAMPLER(5, sampler2D, noise_tx)
|
||||
UNIFORM_BUF(1, float4, samples[49])
|
||||
FRAGMENT_OUT(0, float4, blurColor)
|
||||
FRAGMENT_SOURCE("workbench_effect_dof_blur1_frag.glsl")
|
||||
ADDITIONAL_INFO(workbench_effect_dof)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_dof_blur2)
|
||||
SAMPLER(0, sampler2D, input_coc_tx)
|
||||
SAMPLER(4, sampler2D, blur_tx)
|
||||
FRAGMENT_OUT(0, float4, final_color)
|
||||
FRAGMENT_SOURCE("workbench_effect_dof_blur2_frag.glsl")
|
||||
ADDITIONAL_INFO(workbench_effect_dof)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_dof_resolve)
|
||||
SAMPLER(2, sampler2D, scene_depth_tx)
|
||||
SAMPLER(3, sampler2D, half_res_color_tx)
|
||||
FRAGMENT_OUT_DUAL(0, float4, final_colorAdd, SRC_0)
|
||||
FRAGMENT_OUT_DUAL(0, float4, final_colorMul, SRC_1)
|
||||
FRAGMENT_SOURCE("workbench_effect_dof_resolve_frag.glsl")
|
||||
ADDITIONAL_INFO(workbench_effect_dof)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifdef GPU_SHADER
|
||||
# pragma once
|
||||
# include "gpu_shader_compat.hh"
|
||||
|
||||
# include "workbench_shader_shared.hh"
|
||||
#endif
|
||||
|
||||
#include "workbench_defines.hh"
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_effect_outline)
|
||||
TYPEDEF_SOURCE("workbench_shader_shared.hh")
|
||||
FRAGMENT_SOURCE("workbench_effect_outline_frag.glsl")
|
||||
VERTEX_SOURCE("workbench_fullscreen_vert.glsl")
|
||||
SAMPLER(0, usampler2D, object_id_buffer)
|
||||
UNIFORM_BUF(WB_WORLD_SLOT, WorldData, world_data)
|
||||
FRAGMENT_OUT(0, float4, frag_color)
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifdef GPU_SHADER
|
||||
# pragma once
|
||||
|
||||
# include "BLI_utildefines_variadic.hh"
|
||||
|
||||
# include "gpu_shader_compat.hh"
|
||||
|
||||
# include "draw_object_infos_infos.hh"
|
||||
# include "draw_view_infos.hh"
|
||||
|
||||
# include "workbench_shader_shared.hh"
|
||||
#endif
|
||||
|
||||
#ifdef GLSL_CPP_STUBS
|
||||
# define WORKBENCH_COLOR_MATERIAL
|
||||
# define WORKBENCH_COLOR_TEXTURE
|
||||
# define WORKBENCH_TEXTURE_IMAGE_ARRAY
|
||||
# define WORKBENCH_COLOR_MATERIAL
|
||||
# define WORKBENCH_COLOR_VERTEX
|
||||
# define WORKBENCH_LIGHTING_MATCAP 1
|
||||
|
||||
# define CURVES_SHADER
|
||||
# define DRW_HAIR_INFO
|
||||
|
||||
# define POINTCLOUD_SHADER
|
||||
# define DRW_POINTCLOUD_INFO
|
||||
#endif
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
#include "workbench_defines.hh"
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifdef GPU_SHADER
|
||||
# pragma once
|
||||
# include "gpu_shader_compat.hh"
|
||||
#endif
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_transparent_resolve)
|
||||
FRAGMENT_OUT(0, float4, frag_color)
|
||||
SAMPLER(0, sampler2D, transparent_accum)
|
||||
SAMPLER(1, sampler2D, transparent_revealage)
|
||||
FRAGMENT_SOURCE("workbench_transparent_resolve_frag.glsl")
|
||||
VERTEX_SOURCE("workbench_fullscreen_vert.glsl")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "draw_view.bsl.hh"
|
||||
|
||||
#include "workbench_common.bsl.hh"
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ struct Cavity {
|
|||
|
||||
void cavity_compute([[resource_table]] const workbench::Cavity &cavity,
|
||||
[[resource_table]] const workbench::World &world,
|
||||
ViewMatrices view,
|
||||
sampler2DDepth depth_tx,
|
||||
sampler2D normal_tx,
|
||||
float2 screenco,
|
||||
|
|
@ -37,7 +38,7 @@ void cavity_compute([[resource_table]] const workbench::Cavity &cavity,
|
|||
|
||||
const WorldData &world_data = world.world_data;
|
||||
|
||||
float3 position = drw_point_screen_to_view(float3(screenco, depth));
|
||||
float3 position = view.point_screen_to_view(float3(screenco, depth));
|
||||
float3 normal = workbench::normal_decode(texture(normal_tx, screenco));
|
||||
|
||||
float2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale;
|
||||
|
|
@ -46,9 +47,9 @@ void cavity_compute([[resource_table]] const workbench::Cavity &cavity,
|
|||
/* find the offset in screen space by multiplying a point
|
||||
* in camera space at the depth of the point by the projection matrix. */
|
||||
float2 offset;
|
||||
float homcoord = drw_view().winmat[2][3] * position.z + drw_view().winmat[3][3];
|
||||
offset.x = drw_view().winmat[0][0] * world_data.cavity_distance / homcoord;
|
||||
offset.y = drw_view().winmat[1][1] * world_data.cavity_distance / homcoord;
|
||||
float homcoord = view.winmat[2][3] * position.z + view.winmat[3][3];
|
||||
offset.x = view.winmat[0][0] * world_data.cavity_distance / homcoord;
|
||||
offset.y = view.winmat[1][1] * world_data.cavity_distance / homcoord;
|
||||
/* convert from -1...1 range to 0..1 for easy use with texture coordinates */
|
||||
offset *= 0.5f;
|
||||
|
||||
|
|
@ -77,7 +78,7 @@ void cavity_compute([[resource_table]] const workbench::Cavity &cavity,
|
|||
bool is_background = (s_depth == 1.0f);
|
||||
/* This trick provide good edge effect even if no neighbor is found. */
|
||||
s_depth = (is_background) ? depth : s_depth;
|
||||
float3 s_pos = drw_point_screen_to_view(float3(uvcoords, s_depth));
|
||||
float3 s_pos = view.point_screen_to_view(float3(uvcoords, s_depth));
|
||||
|
||||
if (is_background) {
|
||||
s_pos.z -= world_data.cavity_distance;
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2018-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_compat.hh"
|
||||
|
||||
#define EPSILON 0.00001f
|
||||
|
||||
#define CAVITY_BUFFER_RANGE 4.0f
|
||||
|
||||
/* From http://aras-p.info/texts/CompactNormalStorage.html
|
||||
* Using Method #4: Sphere-map Transform */
|
||||
float3 workbench_normal_decode(float4 enc)
|
||||
{
|
||||
float2 fenc = enc.xy * 4.0f - 2.0f;
|
||||
float f = dot(fenc, fenc);
|
||||
float g = sqrt(1.0f - f / 4.0f);
|
||||
float3 n;
|
||||
n.xy = fenc * g;
|
||||
n.z = 1 - f / 2;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* From http://aras-p.info/texts/CompactNormalStorage.html
|
||||
* Using Method #4: Sphere-map Transform */
|
||||
float2 workbench_normal_encode(bool front_face, float3 n)
|
||||
{
|
||||
n = normalize(front_face ? n : -n);
|
||||
float p = sqrt(n.z * 8.0f + 8.0f);
|
||||
n.xy = clamp(n.xy / p + 0.5f, 0.0f, 1.0f);
|
||||
return n.xy;
|
||||
}
|
||||
|
||||
/* Encoding into the alpha of a RGBA16F texture. (10bit mantissa) */
|
||||
#define TARGET_BITCOUNT 8u
|
||||
#define METALLIC_BITS 3u /* Metallic channel is less important. */
|
||||
#define ROUGHNESS_BITS (TARGET_BITCOUNT - METALLIC_BITS)
|
||||
|
||||
/* Encode 2 float into 1 with the desired precision. */
|
||||
float workbench_float_pair_encode(float v1, float v2)
|
||||
{
|
||||
// constexpr uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS);
|
||||
// constexpr uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS);
|
||||
/* Same as above because some compiler are very dumb and think we use medium int. */
|
||||
constexpr int v1_mask = 0x1F;
|
||||
constexpr 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);
|
||||
}
|
||||
|
||||
void workbench_float_pair_decode(float data, float &v1, float &v2)
|
||||
{
|
||||
// constexpr uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS);
|
||||
// constexpr uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS);
|
||||
/* Same as above because some compiler are very dumb and think we use medium int. */
|
||||
constexpr int v1_mask = 0x1F;
|
||||
constexpr int v2_mask = 0x7;
|
||||
int idata = int(data);
|
||||
v1 = float(idata & v1_mask) * (1.0f / float(v1_mask));
|
||||
v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0f / float(v2_mask));
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
#include "workbench_cavity.bsl.hh"
|
||||
#include "workbench_common.bsl.hh"
|
||||
|
|
@ -17,11 +16,6 @@
|
|||
#include "workbench_matcap.bsl.hh"
|
||||
#include "workbench_world_light.bsl.hh"
|
||||
|
||||
/* TODO(fclem): Move to workbench. */
|
||||
#define WORKBENCH_LIGHTING_STUDIO 0
|
||||
#define WORKBENCH_LIGHTING_MATCAP 1
|
||||
#define WORKBENCH_LIGHTING_FLAT 2
|
||||
|
||||
namespace workbench::resolve {
|
||||
|
||||
struct Resources {
|
||||
|
|
@ -30,7 +24,6 @@ struct Resources {
|
|||
[[compilation_constant]] bool use_curvature;
|
||||
[[compilation_constant]] bool use_shadow;
|
||||
|
||||
[[legacy_info]] ShaderCreateInfo draw_view;
|
||||
[[sampler(3)]] sampler2DDepth depth_tx;
|
||||
[[sampler(4)]] sampler2D normal_tx;
|
||||
[[sampler(5)]] sampler2D material_tx;
|
||||
|
|
@ -58,6 +51,7 @@ struct FragOut {
|
|||
|
||||
[[fragment]] void frag([[frag_coord]] const float4 &frag_coord,
|
||||
[[resource_table]] Resources &srt,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[out]] FragOut &frag_out)
|
||||
{
|
||||
float2 uv = frag_coord.xy / float2(textureSize(srt.depth_tx, 0).xy);
|
||||
|
|
@ -69,9 +63,11 @@ struct FragOut {
|
|||
return;
|
||||
}
|
||||
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
/* Normal and Incident vector are in view-space. Lighting is evaluated in view-space. */
|
||||
float3 P = drw_point_screen_to_view(float3(uv, 0.5f));
|
||||
float3 V = drw_view_incident_vector(P);
|
||||
float3 P = view.point_screen_to_view(float3(uv, 0.5f));
|
||||
float3 V = view.view_incident_vector(P);
|
||||
float3 N = workbench::normal_decode(texture(srt.normal_tx, uv));
|
||||
float4 mat_data = texture(srt.material_tx, uv);
|
||||
|
||||
|
|
@ -95,7 +91,7 @@ struct FragOut {
|
|||
float cavity = 0.0f, edges = 0.0f, curvature = 0.0f;
|
||||
if (srt.use_cavity) [[static_branch]] {
|
||||
workbench::cavity_compute(
|
||||
srt.cavity, srt.world, srt.depth_tx, srt.normal_tx, uv, cavity, edges);
|
||||
srt.cavity, srt.world, view, srt.depth_tx, srt.normal_tx, uv, cavity, edges);
|
||||
}
|
||||
|
||||
if (srt.use_curvature) [[static_branch]] {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
|
||||
namespace workbench::depth {
|
||||
|
||||
[[vertex]]
|
||||
void vert([[vertex_id]] const int vert_id, [[position]] float4 &position)
|
||||
{
|
||||
fullscreen_vertex(vert_id, position);
|
||||
}
|
||||
|
||||
struct Merge {
|
||||
[[sampler(0)]] sampler2DDepth depth_tx;
|
||||
};
|
||||
|
||||
/* Merge a depth texture into the current framebuffer. */
|
||||
[[fragment]] void merge([[resource_table]] const Merge &srt,
|
||||
[[frag_coord]] const float4 frag_co,
|
||||
[[frag_depth(any)]] float &out_depth)
|
||||
{
|
||||
float2 screen_uv = frag_co.xy / float2(textureSize(srt.depth_tx, 0));
|
||||
out_depth = texture(srt.depth_tx, screen_uv).r;
|
||||
}
|
||||
|
||||
/* Prepare the Depth Buffer for the Overlay Engine.
|
||||
* Set the depth to 0 for "In Front" objects which have set a specific stencil bit.
|
||||
* This way, the Overlay engine doesn't draw on top of them. */
|
||||
[[fragment]] void overlay([[frag_depth(any)]] float &out_depth)
|
||||
{
|
||||
out_depth = 0.0f;
|
||||
}
|
||||
|
||||
} // namespace workbench::depth
|
||||
|
||||
PipelineGraphic workbench_merge_depth(workbench::depth::vert, workbench::depth::merge);
|
||||
PipelineGraphic workbench_overlay_depth(workbench::depth::vert, workbench::depth::overlay);
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#include "infos/workbench_effect_dof_infos.hh"
|
||||
|
||||
#include "gpu_shader_math_constants.bsl.hh"
|
||||
#include "workbench_effect_dof_lib.glsl"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_effect_dof_blur1)
|
||||
|
||||
/**
|
||||
* ----------------- STEP 2 ------------------
|
||||
* Blur vertically and diagonally.
|
||||
* Outputs vertical blur and combined blur in MRT
|
||||
*/
|
||||
|
||||
float2 get_random_vector(float offset)
|
||||
{
|
||||
/* Interleaved gradient noise by Jorge Jimenez
|
||||
* http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */
|
||||
float ign = fract(
|
||||
offset + 52.9829189f * fract(0.06711056f * gl_FragCoord.x + 0.00583715f * gl_FragCoord.y));
|
||||
float bn = texelFetch(noise_tx, int2(gl_FragCoord.xy) % 64, 0).a;
|
||||
float ang = M_PI * 2.0f * fract(bn + offset);
|
||||
return float2(cos(ang), sin(ang)) * sqrt(ign);
|
||||
// return noise.rg * sqrt(ign);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float2 uv = gl_FragCoord.xy * inverted_viewport_size * 2.0f;
|
||||
|
||||
float2 size = float2(textureSize(half_res_color_tx, 0).xy);
|
||||
int2 texel = int2(uv * size);
|
||||
|
||||
float4 color = float4(0.0f);
|
||||
float tot = 0.0f;
|
||||
|
||||
float coc = dof_decode_coc(texelFetch(input_coc_tx, texel, 0).rg);
|
||||
float max_radius = coc;
|
||||
float2 noise = get_random_vector(noise_offset) * 0.2f *
|
||||
clamp(max_radius * 0.2f - 4.0f, 0.0f, 1.0f);
|
||||
for (int i = 0; i < NUM_SAMPLES; i++) {
|
||||
float2 tc = uv + (noise + samples[i].xy) * inverted_viewport_size * max_radius;
|
||||
|
||||
/* decode_signed_coc return biggest coc. */
|
||||
coc = abs(dof_decode_signed_coc(texture(input_coc_tx, tc).rg));
|
||||
|
||||
float lod = log2(clamp((coc + min(coc, max_radius)) * 0.5f - 21.0f, 0.0f, 16.0f) * 0.25f);
|
||||
float4 samp = textureLod(half_res_color_tx, tc, lod);
|
||||
|
||||
float radius = samples[i].z * max_radius;
|
||||
float weight = abs(coc) * smoothstep(radius - 0.5f, radius + 0.5f, abs(coc));
|
||||
|
||||
color += samp * weight;
|
||||
tot += weight;
|
||||
}
|
||||
|
||||
if (tot > 0.0f) {
|
||||
blurColor = color / tot;
|
||||
}
|
||||
else {
|
||||
blurColor = textureLod(half_res_color_tx, uv, 0.0f);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#include "infos/workbench_effect_dof_infos.hh"
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "gpu_shader_utildefines.bsl.hh"
|
||||
#include "workbench_effect_dof_lib.glsl"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_effect_dof_blur2)
|
||||
|
||||
/**
|
||||
* ----------------- STEP 3 ------------------
|
||||
* 3x3 Median Filter
|
||||
* Morgan McGuire and Kyle Whitson
|
||||
* http://graphics.cs.williams.edu
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
* Copyright 2006 Morgan McGuire and Williams College, All rights reserved.
|
||||
*/
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Half Res pass */
|
||||
float2 pixel_size = 1.0f / float2(textureSize(blur_tx, 0).xy);
|
||||
float2 uv = gl_FragCoord.xy * pixel_size.xy;
|
||||
float coc = dof_decode_coc(texture(input_coc_tx, uv).rg);
|
||||
/* Only use this filter if coc is > 9.0f
|
||||
* since this filter is not weighted by CoC
|
||||
* and can bleed a bit. */
|
||||
float rad = clamp(coc - 9.0f, 0.0f, 1.0f);
|
||||
|
||||
#define vec float4
|
||||
#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++) {
|
||||
float2 offset = float2(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(blur_tx, 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(final_color) = v[4];
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#include "infos/workbench_effect_dof_infos.hh"
|
||||
|
||||
#include "gpu_shader_math_safe.bsl.hh"
|
||||
#include "gpu_shader_math_vector_reduce.bsl.hh"
|
||||
#include "gpu_shader_utildefines.bsl.hh"
|
||||
#include "workbench_effect_dof_lib.glsl"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_effect_dof_downsample)
|
||||
|
||||
/**
|
||||
* ----------------- STEP 0.5 ------------------
|
||||
* Custom COC aware down-sampling. Quarter res pass.
|
||||
*/
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 texel = float4(gl_FragCoord.xyxy) * 2.0f + float4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
texel = (texel - 0.5f) / float4(textureSize(scene_color_tx, 0).xyxy);
|
||||
|
||||
/* Using texelFetch can bypass the mip range setting on some platform.
|
||||
* Using texture LOD fixes this issue. Note that we need to disable filtering to get the right
|
||||
* texel values. */
|
||||
float4 color1 = textureLod(scene_color_tx, texel.xy, 0.0f);
|
||||
float4 color2 = textureLod(scene_color_tx, texel.zw, 0.0f);
|
||||
float4 color3 = textureLod(scene_color_tx, texel.zy, 0.0f);
|
||||
float4 color4 = textureLod(scene_color_tx, texel.xw, 0.0f);
|
||||
|
||||
float2 cocs1 = textureLod(input_coc_tx, texel.xy, 0.0f).rg;
|
||||
float2 cocs2 = textureLod(input_coc_tx, texel.zw, 0.0f).rg;
|
||||
float2 cocs3 = textureLod(input_coc_tx, texel.zy, 0.0f).rg;
|
||||
float2 cocs4 = textureLod(input_coc_tx, texel.xw, 0.0f).rg;
|
||||
|
||||
float4 cocs_near = float4(cocs1.r, cocs2.r, cocs3.r, cocs4.r) * MAX_COC_SIZE;
|
||||
float4 cocs_far = float4(cocs1.g, cocs2.g, cocs3.g, cocs4.g) * MAX_COC_SIZE;
|
||||
|
||||
float coc_near = reduce_max(cocs_near);
|
||||
float coc_far = reduce_max(cocs_far);
|
||||
|
||||
/* Now we need to write the near-far fields pre-multiplied by the COC
|
||||
* also use bilateral weighting by each COC values to avoid bleeding. */
|
||||
float4 near_weights = step(0.0f, cocs_near) *
|
||||
clamp(1.0f - abs(coc_near - cocs_near), 0.0f, 1.0f);
|
||||
float4 far_weights = step(0.0f, cocs_far) * clamp(1.0f - abs(coc_far - cocs_far), 0.0f, 1.0f);
|
||||
|
||||
/* now write output to weighted buffers. */
|
||||
float4 w = any(notEqual(far_weights, float4(0.0f))) ? far_weights : near_weights;
|
||||
outColor = weighted_sum(color1, color2, color3, color4, w);
|
||||
|
||||
outCocs = dof_encode_coc(coc_near, coc_far);
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_math_vector.bsl.hh"
|
||||
|
||||
#define dof_aperturesize dof_params.x
|
||||
#define dof_distance dof_params.y
|
||||
#define dof_invsensorsize dof_params.z
|
||||
|
||||
/* divide by sensor size to get the normalized size */
|
||||
#define dof_calculate_coc(zdepth) \
|
||||
(dof_aperturesize * (dof_distance / zdepth - 1.0f) * dof_invsensorsize)
|
||||
|
||||
#define MAX_COC_SIZE 100.0f
|
||||
float2 dof_encode_coc(float near, float far)
|
||||
{
|
||||
return float2(near, far) / MAX_COC_SIZE;
|
||||
}
|
||||
float dof_decode_coc(float2 cocs)
|
||||
{
|
||||
return max(cocs.x, cocs.y) * MAX_COC_SIZE;
|
||||
}
|
||||
float dof_decode_signed_coc(float2 cocs)
|
||||
{
|
||||
return ((cocs.x > cocs.y) ? cocs.x : -cocs.y) * MAX_COC_SIZE;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#include "infos/workbench_effect_dof_infos.hh"
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "gpu_shader_math_safe.bsl.hh"
|
||||
#include "gpu_shader_math_vector_reduce.bsl.hh"
|
||||
#include "gpu_shader_utildefines.bsl.hh"
|
||||
#include "workbench_effect_dof_lib.glsl"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_effect_dof_prepare)
|
||||
|
||||
/**
|
||||
* ----------------- STEP 0 ------------------
|
||||
* Custom COC aware down-sampling. Half res pass.
|
||||
*/
|
||||
|
||||
void main()
|
||||
{
|
||||
int4 texel = int4(gl_FragCoord.xyxy) * 2 + int4(0, 0, 1, 1);
|
||||
|
||||
float4 color1 = texelFetch(scene_color_tx, texel.xy, 0);
|
||||
float4 color2 = texelFetch(scene_color_tx, texel.zw, 0);
|
||||
float4 color3 = texelFetch(scene_color_tx, texel.zy, 0);
|
||||
float4 color4 = texelFetch(scene_color_tx, texel.xw, 0);
|
||||
|
||||
float4 depths;
|
||||
depths.x = texelFetch(scene_depth_tx, texel.xy, 0).x;
|
||||
depths.y = texelFetch(scene_depth_tx, texel.zw, 0).x;
|
||||
depths.z = texelFetch(scene_depth_tx, texel.zy, 0).x;
|
||||
depths.w = texelFetch(scene_depth_tx, texel.xw, 0).x;
|
||||
|
||||
float4 zdepths = float4(drw_depth_screen_to_view(depths.x),
|
||||
drw_depth_screen_to_view(depths.y),
|
||||
drw_depth_screen_to_view(depths.z),
|
||||
drw_depth_screen_to_view(depths.w));
|
||||
float4 cocs_near = dof_calculate_coc(zdepths);
|
||||
float4 cocs_far = -cocs_near;
|
||||
|
||||
float coc_near = max(reduce_max(cocs_near), 0.0f);
|
||||
float coc_far = max(reduce_max(cocs_far), 0.0f);
|
||||
|
||||
/* now we need to write the near-far fields premultiplied by the coc
|
||||
* also use bilateral weighting by each coc values to avoid bleeding. */
|
||||
float4 near_weights = step(0.0f, cocs_near) *
|
||||
clamp(1.0f - abs(coc_near - cocs_near), 0.0f, 1.0f);
|
||||
float4 far_weights = step(0.0f, cocs_far) * clamp(1.0f - abs(coc_far - cocs_far), 0.0f, 1.0f);
|
||||
|
||||
/* now write output to weighted buffers. */
|
||||
/* Take far plane pixels in priority. */
|
||||
float4 w = any(notEqual(far_weights, float4(0.0f))) ? far_weights : near_weights;
|
||||
halfResColor = weighted_sum(color1, color2, color3, color4, w);
|
||||
halfResColor = clamp(halfResColor, 0.0f, 3.0f);
|
||||
|
||||
normalizedCoc = dof_encode_coc(coc_near, coc_far);
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#include "infos/workbench_effect_dof_infos.hh"
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "gpu_shader_utildefines.bsl.hh"
|
||||
#include "workbench_effect_dof_lib.glsl"
|
||||
|
||||
/**
|
||||
* ----------------- STEP 4 ------------------
|
||||
*/
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_effect_dof_resolve)
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Full-screen pass. */
|
||||
float2 pixel_size = 0.5f / float2(textureSize(half_res_color_tx, 0).xy);
|
||||
float2 uv = gl_FragCoord.xy * pixel_size;
|
||||
|
||||
/* TODO: MAKE SURE TO ALIGN SAMPLE POSITION TO AVOID OFFSET IN THE BOKEH. */
|
||||
float depth = texelFetch(scene_depth_tx, int2(gl_FragCoord.xy), 0).r;
|
||||
float zdepth = drw_depth_screen_to_view(depth);
|
||||
float coc = dof_calculate_coc(zdepth);
|
||||
|
||||
float blend = smoothstep(1.0f, 3.0f, abs(coc));
|
||||
final_colorAdd = texture(half_res_color_tx, uv) * blend;
|
||||
final_colorMul = float4(1.0f - blend);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "infos/workbench_effect_outline_infos.hh"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_effect_outline)
|
||||
|
||||
void main()
|
||||
{
|
||||
float2 uv = gl_FragCoord.xy / float2(textureSize(object_id_buffer, 0));
|
||||
|
||||
float3 offset = float3(world_data.viewport_size_inv, 0.0f) * world_data.ui_scale;
|
||||
|
||||
uint center_id = texture(object_id_buffer, uv).r;
|
||||
uint4 adjacent_ids = uint4(texture(object_id_buffer, uv + offset.zy).r,
|
||||
texture(object_id_buffer, uv - offset.zy).r,
|
||||
texture(object_id_buffer, uv + offset.xz).r,
|
||||
texture(object_id_buffer, uv - offset.xz).r);
|
||||
|
||||
float outline_opacity = 1.0f - dot(float4(equal(uint4(center_id), adjacent_ids)), float4(0.25f));
|
||||
|
||||
frag_color = world_data.object_outline_color * outline_opacity;
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2018-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "infos/workbench_effect_antialiasing_infos.hh"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_taa)
|
||||
|
||||
void main()
|
||||
{
|
||||
float2 texel_size = 1.0f / float2(textureSize(color_buffer, 0));
|
||||
float2 uv = gl_FragCoord.xy * texel_size;
|
||||
|
||||
frag_color = float4(0.0f);
|
||||
int i = 0;
|
||||
for (int x = -1; x <= 1; x++) [[unroll]] {
|
||||
for (int y = -1; y <= 1; y++, i++) [[unroll]] {
|
||||
float4 color = texture(color_buffer, uv + float2(x, y) * texel_size);
|
||||
/* Clamp infinite inputs (See #112211). */
|
||||
color = clamp(color, float4(0.0f), float4(1e10f));
|
||||
/* Use log2 space to avoid highlights creating too much aliasing. */
|
||||
color.rgb = log2(color.rgb + 1.0f);
|
||||
|
||||
frag_color += color * samplesWeights[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2015-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "infos/workbench_depth_infos.hh"
|
||||
#include "infos/workbench_effect_dof_infos.hh"
|
||||
|
||||
VERTEX_SHADER_CREATE_INFO(workbench_merge_depth)
|
||||
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
|
||||
void main()
|
||||
{
|
||||
fullscreen_vertex(gl_VertexID, gl_Position);
|
||||
}
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
/* SPDX-FileCopyrightText: 2019-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
|
||||
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
|
||||
* Converted and adapted from HLSL to GLSL by Clément Foucault
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view.bsl.hh"
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
#include "gpu_shader_math_safe.bsl.hh"
|
||||
#include "gpu_shader_math_vector_reduce.bsl.hh"
|
||||
|
||||
namespace workbench::dof {
|
||||
|
||||
[[vertex]]
|
||||
void vert([[vertex_id]] const int vert_id, [[position]] float4 &position)
|
||||
{
|
||||
fullscreen_vertex(vert_id, position);
|
||||
}
|
||||
|
||||
#define MAX_COC_SIZE 100.0f
|
||||
|
||||
float2 dof_encode_coc(float near, float far)
|
||||
{
|
||||
return float2(near, far) / MAX_COC_SIZE;
|
||||
}
|
||||
float dof_decode_coc(float2 cocs)
|
||||
{
|
||||
return max(cocs.x, cocs.y) * MAX_COC_SIZE;
|
||||
}
|
||||
float dof_decode_signed_coc(float2 cocs)
|
||||
{
|
||||
return ((cocs.x > cocs.y) ? cocs.x : -cocs.y) * MAX_COC_SIZE;
|
||||
}
|
||||
|
||||
float4 sum_weighted(float4 val0, float4 val1, float4 val2, float4 val3, float4 weights)
|
||||
{
|
||||
return (val0 * weights[0] + val1 * weights[1] + val2 * weights[2] + val3 * weights[3]) *
|
||||
safe_rcp(weights[0] + weights[1] + weights[2] + weights[3]);
|
||||
}
|
||||
|
||||
struct DepthOfField {
|
||||
[[push_constant]] float2 inverted_viewport_size;
|
||||
[[push_constant]] float2 near_far;
|
||||
[[push_constant]] float3 dof_params;
|
||||
[[push_constant]] float noise_offset;
|
||||
|
||||
/* divide by sensor size to get the normalized size */
|
||||
template<typename T> T calculate_coc(T z_depth)
|
||||
{
|
||||
float aperture_size = dof_params.x;
|
||||
float distance = dof_params.y;
|
||||
float invsensor_size = dof_params.z;
|
||||
return aperture_size * (distance / z_depth - 1.0f) * invsensor_size;
|
||||
}
|
||||
};
|
||||
|
||||
template float DepthOfField::calculate_coc<float>(float);
|
||||
template float4 DepthOfField::calculate_coc<float4>(float4);
|
||||
|
||||
/*
|
||||
* NOTE: Keep the sampler bind points consistent between the steps.
|
||||
*
|
||||
* [[sampler(0)]] sampler2D input_coc_tx;
|
||||
* [[sampler(1)]] sampler2D scene_color_tx;
|
||||
* [[sampler(2)]] sampler2D scene_depth_tx;
|
||||
* [[sampler(3)]] sampler2D half_res_color_tx;
|
||||
* [[sampler(4)]] sampler2D blur_tx;
|
||||
* [[sampler(5)]] sampler2D noise_tx;
|
||||
*/
|
||||
|
||||
/**
|
||||
* ----------------- STEP 0 ------------------
|
||||
* Custom COC aware down-sampling. Half res pass.
|
||||
*/
|
||||
|
||||
struct Prepare {
|
||||
[[sampler(1)]] sampler2D scene_color_tx;
|
||||
[[sampler(2)]] sampler2D scene_depth_tx;
|
||||
};
|
||||
|
||||
struct PrepareOut {
|
||||
[[frag_color(0)]] float4 half_res_color;
|
||||
[[frag_color(1)]] float2 normalized_coc;
|
||||
};
|
||||
|
||||
[[fragment]] void prepare([[resource_table]] DepthOfField &dof,
|
||||
[[resource_table]] Prepare &srt,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[out]] PrepareOut &out,
|
||||
[[frag_coord]] const float4 frag_co)
|
||||
{
|
||||
int4 texel = int4(frag_co.xyxy) * 2 + int4(0, 0, 1, 1);
|
||||
|
||||
float4 color1 = texelFetch(srt.scene_color_tx, texel.xy, 0);
|
||||
float4 color2 = texelFetch(srt.scene_color_tx, texel.zw, 0);
|
||||
float4 color3 = texelFetch(srt.scene_color_tx, texel.zy, 0);
|
||||
float4 color4 = texelFetch(srt.scene_color_tx, texel.xw, 0);
|
||||
|
||||
float4 depths;
|
||||
depths.x = texelFetch(srt.scene_depth_tx, texel.xy, 0).x;
|
||||
depths.y = texelFetch(srt.scene_depth_tx, texel.zw, 0).x;
|
||||
depths.z = texelFetch(srt.scene_depth_tx, texel.zy, 0).x;
|
||||
depths.w = texelFetch(srt.scene_depth_tx, texel.xw, 0).x;
|
||||
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
float4 zdepths = float4(view.depth_screen_to_view(depths.x),
|
||||
view.depth_screen_to_view(depths.y),
|
||||
view.depth_screen_to_view(depths.z),
|
||||
view.depth_screen_to_view(depths.w));
|
||||
float4 cocs_near = dof.calculate_coc(zdepths);
|
||||
float4 cocs_far = -cocs_near;
|
||||
|
||||
float coc_near = max(reduce_max(cocs_near), 0.0f);
|
||||
float coc_far = max(reduce_max(cocs_far), 0.0f);
|
||||
|
||||
/* now we need to write the near-far fields premultiplied by the coc
|
||||
* also use bilateral weighting by each coc values to avoid bleeding. */
|
||||
float4 near_weights = step(0.0f, cocs_near) *
|
||||
clamp(1.0f - abs(coc_near - cocs_near), 0.0f, 1.0f);
|
||||
float4 far_weights = step(0.0f, cocs_far) * clamp(1.0f - abs(coc_far - cocs_far), 0.0f, 1.0f);
|
||||
|
||||
/* now write output to weighted buffers. */
|
||||
/* Take far plane pixels in priority. */
|
||||
float4 w = any(notEqual(far_weights, float4(0.0f))) ? far_weights : near_weights;
|
||||
out.half_res_color = sum_weighted(color1, color2, color3, color4, w);
|
||||
out.half_res_color = clamp(out.half_res_color, 0.0f, 3.0f);
|
||||
|
||||
out.normalized_coc = dof_encode_coc(coc_near, coc_far);
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------- STEP 1 ------------------
|
||||
* Custom COC aware down-sampling. Quarter res pass.
|
||||
*/
|
||||
|
||||
struct DownSample {
|
||||
[[sampler(0)]] sampler2D input_coc_tx;
|
||||
[[sampler(1)]] sampler2D scene_color_tx;
|
||||
};
|
||||
|
||||
struct DownSampleOut {
|
||||
[[frag_color(0)]] float4 color;
|
||||
[[frag_color(1)]] float2 cocs;
|
||||
};
|
||||
|
||||
[[fragment]] void downsample([[resource_table]] DownSample &srt,
|
||||
[[out]] DownSampleOut &out,
|
||||
[[frag_coord]] const float4 frag_co)
|
||||
{
|
||||
float4 texel = float4(frag_co.xyxy) * 2.0f + float4(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
texel = (texel - 0.5f) / float4(textureSize(srt.scene_color_tx, 0).xyxy);
|
||||
|
||||
/* Using texelFetch can bypass the mip range setting on some platform.
|
||||
* Using texture LOD fixes this issue. Note that we need to disable filtering to get the right
|
||||
* texel values. */
|
||||
float4 color1 = textureLod(srt.scene_color_tx, texel.xy, 0.0f);
|
||||
float4 color2 = textureLod(srt.scene_color_tx, texel.zw, 0.0f);
|
||||
float4 color3 = textureLod(srt.scene_color_tx, texel.zy, 0.0f);
|
||||
float4 color4 = textureLod(srt.scene_color_tx, texel.xw, 0.0f);
|
||||
|
||||
float2 cocs1 = textureLod(srt.input_coc_tx, texel.xy, 0.0f).rg;
|
||||
float2 cocs2 = textureLod(srt.input_coc_tx, texel.zw, 0.0f).rg;
|
||||
float2 cocs3 = textureLod(srt.input_coc_tx, texel.zy, 0.0f).rg;
|
||||
float2 cocs4 = textureLod(srt.input_coc_tx, texel.xw, 0.0f).rg;
|
||||
|
||||
float4 cocs_near = float4(cocs1.r, cocs2.r, cocs3.r, cocs4.r) * MAX_COC_SIZE;
|
||||
float4 cocs_far = float4(cocs1.g, cocs2.g, cocs3.g, cocs4.g) * MAX_COC_SIZE;
|
||||
|
||||
float coc_near = reduce_max(cocs_near);
|
||||
float coc_far = reduce_max(cocs_far);
|
||||
|
||||
/* Now we need to write the near-far fields pre-multiplied by the COC
|
||||
* also use bilateral weighting by each COC values to avoid bleeding. */
|
||||
float4 near_weights = step(0.0f, cocs_near) *
|
||||
clamp(1.0f - abs(coc_near - cocs_near), 0.0f, 1.0f);
|
||||
float4 far_weights = step(0.0f, cocs_far) * clamp(1.0f - abs(coc_far - cocs_far), 0.0f, 1.0f);
|
||||
|
||||
/* now write output to weighted buffers. */
|
||||
float4 w = any(notEqual(far_weights, float4(0.0f))) ? far_weights : near_weights;
|
||||
out.color = sum_weighted(color1, color2, color3, color4, w);
|
||||
|
||||
out.cocs = dof_encode_coc(coc_near, coc_far);
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------- STEP 2 ------------------
|
||||
* Blur vertically and diagonally.
|
||||
* Outputs vertical blur and combined blur in MRT
|
||||
*/
|
||||
|
||||
static constexpr int dof_sample_count = 49;
|
||||
|
||||
struct Blur1 {
|
||||
[[sampler(0)]] sampler2D input_coc_tx;
|
||||
[[sampler(3)]] sampler2D half_res_color_tx;
|
||||
[[sampler(5)]] sampler2D noise_tx;
|
||||
[[uniform(1)]] float4 samples[dof_sample_count];
|
||||
|
||||
float2 get_random_vector(float2 frag_co, float offset) const
|
||||
{
|
||||
/* Interleaved gradient noise by Jorge Jimenez
|
||||
* http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */
|
||||
float ign = fract(offset +
|
||||
52.9829189f * fract(0.06711056f * frag_co.x + 0.00583715f * frag_co.y));
|
||||
float bn = texelFetch(noise_tx, int2(frag_co.xy) % 64, 0).a;
|
||||
float ang = M_PI * 2.0f * fract(bn + offset);
|
||||
return float2(cos(ang), sin(ang)) * sqrt(ign);
|
||||
}
|
||||
};
|
||||
|
||||
struct Blur1Out {
|
||||
[[frag_color(0)]] float4 color;
|
||||
};
|
||||
|
||||
[[fragment]] void blur1([[resource_table]] DepthOfField &dof,
|
||||
[[resource_table]] Blur1 &srt,
|
||||
[[out]] Blur1Out &out,
|
||||
[[frag_coord]] const float4 frag_co)
|
||||
{
|
||||
float2 uv = frag_co.xy * dof.inverted_viewport_size * 2.0f;
|
||||
|
||||
float2 size = float2(textureSize(srt.half_res_color_tx, 0).xy);
|
||||
int2 texel = int2(uv * size);
|
||||
|
||||
float4 color = float4(0.0f);
|
||||
float tot = 0.0f;
|
||||
|
||||
float coc = dof_decode_coc(texelFetch(srt.input_coc_tx, texel, 0).rg);
|
||||
float max_radius = coc;
|
||||
float2 noise = srt.get_random_vector(frag_co.xy, dof.noise_offset) * 0.2f *
|
||||
clamp(max_radius * 0.2f - 4.0f, 0.0f, 1.0f);
|
||||
for (int i = 0; i < dof_sample_count; i++) {
|
||||
float2 tc = uv + (noise + srt.samples[i].xy) * dof.inverted_viewport_size * max_radius;
|
||||
|
||||
/* decode_signed_coc return biggest coc. */
|
||||
coc = abs(dof_decode_signed_coc(texture(srt.input_coc_tx, tc).rg));
|
||||
|
||||
float lod = log2(clamp((coc + min(coc, max_radius)) * 0.5f - 21.0f, 0.0f, 16.0f) * 0.25f);
|
||||
float4 samp = textureLod(srt.half_res_color_tx, tc, lod);
|
||||
|
||||
float radius = srt.samples[i].z * max_radius;
|
||||
float weight = abs(coc) * smoothstep(radius - 0.5f, radius + 0.5f, abs(coc));
|
||||
|
||||
color += samp * weight;
|
||||
tot += weight;
|
||||
}
|
||||
|
||||
if (tot > 0.0f) {
|
||||
out.color = color / tot;
|
||||
}
|
||||
else {
|
||||
out.color = textureLod(srt.half_res_color_tx, uv, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------- STEP 3 ------------------
|
||||
* 3x3 Median Filter
|
||||
* Morgan McGuire and Kyle Whitson
|
||||
* http://graphics.cs.williams.edu
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
* Copyright 2006 Morgan McGuire and Williams College, All rights reserved.
|
||||
*/
|
||||
|
||||
struct Blur2 {
|
||||
[[sampler(0)]] sampler2D input_coc_tx;
|
||||
[[sampler(4)]] sampler2D blur_tx;
|
||||
};
|
||||
|
||||
struct Blur2Out {
|
||||
[[frag_color(0)]] float4 color;
|
||||
};
|
||||
|
||||
[[force_inline]] void s2(float4 &a, float4 &b)
|
||||
{
|
||||
float4 temp = a;
|
||||
a = min(a, b);
|
||||
b = max(temp, b);
|
||||
}
|
||||
|
||||
[[force_inline]] void mn3(float4 &a, float4 &b, float4 &c)
|
||||
{
|
||||
s2(a, b);
|
||||
s2(a, c);
|
||||
}
|
||||
|
||||
[[force_inline]] void mx3(float4 &a, float4 &b, float4 &c)
|
||||
{
|
||||
s2(b, c);
|
||||
s2(a, c);
|
||||
}
|
||||
|
||||
[[force_inline]] void mnmx3(float4 &a, float4 &b, float4 &c)
|
||||
{
|
||||
mx3(a, b, c);
|
||||
s2(a, b); /* 3 exchanges */
|
||||
}
|
||||
|
||||
[[force_inline]] void mnmx4(float4 &a, float4 &b, float4 &c, float4 &d)
|
||||
{
|
||||
s2(a, b);
|
||||
s2(c, d);
|
||||
s2(a, c);
|
||||
s2(b, d); /* 4 exchanges */
|
||||
}
|
||||
|
||||
[[force_inline]] void mnmx5(float4 &a, float4 &b, float4 &c, float4 &d, float4 &e)
|
||||
{
|
||||
s2(a, b);
|
||||
s2(c, d);
|
||||
mn3(a, c, e);
|
||||
mx3(b, d, e); /* 6 exchanges */
|
||||
}
|
||||
|
||||
[[force_inline]] void mnmx6(float4 &a, float4 &b, float4 &c, float4 &d, float4 &e, float4 &f)
|
||||
{
|
||||
s2(a, d);
|
||||
s2(b, e);
|
||||
s2(c, f);
|
||||
mn3(a, b, c);
|
||||
mx3(d, e, f); /* 7 exchanges */
|
||||
}
|
||||
|
||||
[[fragment]] void blur2([[resource_table]] Blur2 &srt,
|
||||
[[out]] Blur2Out &out,
|
||||
[[frag_coord]] const float4 frag_co)
|
||||
{
|
||||
/* Half Res pass */
|
||||
float2 pixel_size = 1.0f / float2(textureSize(srt.blur_tx, 0).xy);
|
||||
float2 uv = frag_co.xy * pixel_size.xy;
|
||||
float coc = dof_decode_coc(texture(srt.input_coc_tx, uv).rg);
|
||||
/* Only use this filter if coc is > 9.0f
|
||||
* since this filter is not weighted by CoC
|
||||
* and can bleed a bit. */
|
||||
float rad = clamp(coc - 9.0f, 0.0f, 1.0f);
|
||||
|
||||
float4 v[9];
|
||||
|
||||
/* Add the pixels which make up our window to the pixel array. */
|
||||
for (int dX = -1; dX <= 1; dX++) [[unroll]] {
|
||||
for (int dY = -1; dY <= 1; dY++) [[unroll]] {
|
||||
float2 offset = float2(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)] = texture(srt.blur_tx, uv + offset * pixel_size * rad);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
out.color = v[4];
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------- STEP 4 ------------------
|
||||
*/
|
||||
|
||||
struct Resolve {
|
||||
[[sampler(2)]] sampler2D scene_depth_tx;
|
||||
[[sampler(3)]] sampler2D half_res_color_tx;
|
||||
};
|
||||
|
||||
struct ResolveOut {
|
||||
[[frag_color(0), index(0)]] float4 color_add;
|
||||
[[frag_color(0), index(1)]] float4 color_mul;
|
||||
};
|
||||
|
||||
[[fragment]] void resolve([[resource_table]] DepthOfField &dof,
|
||||
[[resource_table]] Resolve &srt,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[out]] ResolveOut &out,
|
||||
[[frag_coord]] const float4 frag_co)
|
||||
{
|
||||
/* Full-screen pass. */
|
||||
float2 pixel_size = 0.5f / float2(textureSize(srt.half_res_color_tx, 0).xy);
|
||||
float2 uv = frag_co.xy * pixel_size;
|
||||
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
/* TODO: MAKE SURE TO ALIGN SAMPLE POSITION TO AVOID OFFSET IN THE BOKEH. */
|
||||
float depth = texelFetch(srt.scene_depth_tx, int2(frag_co.xy), 0).r;
|
||||
float zdepth = view.depth_screen_to_view(depth);
|
||||
float coc = dof.calculate_coc(zdepth);
|
||||
|
||||
float blend = smoothstep(1.0f, 3.0f, abs(coc));
|
||||
out.color_add = texture(srt.half_res_color_tx, uv) * blend;
|
||||
out.color_mul = float4(1.0f - blend);
|
||||
}
|
||||
|
||||
} // namespace workbench::dof
|
||||
|
||||
PipelineGraphic workbench_effect_dof_prepare(workbench::dof::vert, workbench::dof::prepare);
|
||||
PipelineGraphic workbench_effect_dof_downsample(workbench::dof::vert, workbench::dof::downsample);
|
||||
PipelineGraphic workbench_effect_dof_blur1(workbench::dof::vert, workbench::dof::blur1);
|
||||
PipelineGraphic workbench_effect_dof_blur2(workbench::dof::vert, workbench::dof::blur2);
|
||||
PipelineGraphic workbench_effect_dof_resolve(workbench::dof::vert, workbench::dof::resolve);
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
#include "workbench_shader_shared.hh"
|
||||
|
||||
namespace workbench::outline {
|
||||
|
||||
[[vertex]]
|
||||
void vert([[vertex_id]] const int vert_id, [[position]] float4 &position)
|
||||
{
|
||||
fullscreen_vertex(vert_id, position);
|
||||
}
|
||||
|
||||
struct Outlines {
|
||||
[[sampler(0)]] usampler2D object_id_buffer;
|
||||
[[uniform(WB_WORLD_SLOT)]] WorldData &world_data;
|
||||
};
|
||||
|
||||
struct FragOut {
|
||||
[[frag_color(0)]] float4 color;
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
void frag([[resource_table]] const Outlines &srt,
|
||||
[[frag_coord]] const float4 frag_co,
|
||||
[[out]] FragOut &frag_out)
|
||||
{
|
||||
float2 uv = frag_co.xy / float2(textureSize(srt.object_id_buffer, 0));
|
||||
|
||||
float3 offset = float3(srt.world_data.viewport_size_inv, 0.0f) * srt.world_data.ui_scale;
|
||||
|
||||
uint center_id = texture(srt.object_id_buffer, uv).r;
|
||||
uint4 adjacent_ids = uint4(texture(srt.object_id_buffer, uv + offset.zy).r,
|
||||
texture(srt.object_id_buffer, uv - offset.zy).r,
|
||||
texture(srt.object_id_buffer, uv + offset.xz).r,
|
||||
texture(srt.object_id_buffer, uv - offset.xz).r);
|
||||
|
||||
float outline_opacity = 1.0f - dot(float4(equal(uint4(center_id), adjacent_ids)), float4(0.25f));
|
||||
|
||||
frag_out.color = srt.world_data.object_outline_color * outline_opacity;
|
||||
}
|
||||
|
||||
} // namespace workbench::outline
|
||||
|
||||
PipelineGraphic workbench_effect_outline(workbench::outline::vert, workbench::outline::frag);
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-FileCopyrightText: 2018-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
|
||||
namespace workbench::taa {
|
||||
|
||||
[[vertex]]
|
||||
void vert([[vertex_id]] const int vert_id, [[position]] float4 &position)
|
||||
{
|
||||
fullscreen_vertex(vert_id, position);
|
||||
}
|
||||
|
||||
struct FragOut {
|
||||
[[frag_color(0)]] float4 color;
|
||||
};
|
||||
|
||||
struct TemporalAA {
|
||||
[[push_constant]] float samplesWeights[9];
|
||||
|
||||
[[sampler(0)]] sampler2D color_buffer;
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
void frag([[resource_table]] const TemporalAA &srt,
|
||||
[[frag_coord]] const float4 frag_co,
|
||||
[[out]] FragOut &frag_out)
|
||||
{
|
||||
float2 texel_size = 1.0f / float2(textureSize(srt.color_buffer, 0));
|
||||
float2 uv = frag_co.xy * texel_size;
|
||||
|
||||
frag_out.color = float4(0.0f);
|
||||
int i = 0;
|
||||
for (int x = -1; x <= 1; x++) [[unroll]] {
|
||||
for (int y = -1; y <= 1; y++) [[unroll]] {
|
||||
float4 color = texture(srt.color_buffer, uv + float2(x, y) * texel_size);
|
||||
/* Clamp infinite inputs (See #112211). */
|
||||
color = clamp(color, float4(0.0f), float4(1e10f));
|
||||
/* Use log2 space to avoid highlights creating too much aliasing. */
|
||||
color.rgb = log2(color.rgb + 1.0f);
|
||||
|
||||
frag_out.color += color * srt.samplesWeights[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace workbench::taa
|
||||
|
||||
PipelineGraphic workbench_taa(workbench::taa::vert, workbench::taa::frag);
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "infos/workbench_prepass_infos.hh"
|
||||
|
||||
SHADER_LIBRARY_CREATE_INFO(workbench_color_texture)
|
||||
|
||||
/* TODO(fclem): deduplicate code. */
|
||||
bool node_tex_tile_lookup(float3 &co, sampler1DArray map)
|
||||
{
|
||||
float2 tile_pos = floor(co.xy);
|
||||
|
||||
if (tile_pos.x < 0 || tile_pos.y < 0 || tile_pos.x >= 10) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float tile = 10.0f * tile_pos.y + tile_pos.x;
|
||||
if (tile >= textureSize(map, 0).x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Fetch tile information. */
|
||||
float tile_layer = texelFetch(map, int2(int(tile), 0), 0).x;
|
||||
if (tile_layer < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float4 tile_info = texelFetch(map, int2(int(tile), 1), 0);
|
||||
|
||||
co = float3(((co.xy - tile_pos) * tile_info.zw) + tile_info.xy, tile_layer);
|
||||
return true;
|
||||
}
|
||||
|
||||
float3 workbench_image_color(float2 uvs)
|
||||
{
|
||||
#ifdef WORKBENCH_COLOR_TEXTURE
|
||||
float4 color;
|
||||
|
||||
float3 co = float3(uvs, 0.0f);
|
||||
if (is_image_tile) {
|
||||
if (node_tex_tile_lookup(co, imageTileData)) {
|
||||
color = texture(imageTileArray, co);
|
||||
}
|
||||
else {
|
||||
color = float4(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
color = texture(imageTexture, uvs);
|
||||
}
|
||||
|
||||
/* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */
|
||||
if (image_premult && !(color.a == 0.0f || color.a == 1.0f)) {
|
||||
color.rgb /= color.a;
|
||||
}
|
||||
|
||||
# ifdef GPU_FRAGMENT_SHADER
|
||||
if (color.a < image_transparency_cutoff) {
|
||||
gpu_discard_fragment();
|
||||
}
|
||||
# endif
|
||||
|
||||
return color.rgb;
|
||||
#else
|
||||
|
||||
return float3(1.0f);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "infos/workbench_prepass_infos.hh"
|
||||
|
||||
#ifdef GPU_LIBRARY_SHADER
|
||||
SHADER_LIBRARY_CREATE_INFO(workbench_prepass)
|
||||
#endif
|
||||
|
||||
float2 matcap_uv_compute(float3 I, float3 N, bool flipped)
|
||||
{
|
||||
/* Quick creation of an orthonormal basis */
|
||||
float a = 1.0f / (1.0f + I.z);
|
||||
float b = -I.x * I.y * a;
|
||||
float3 b1 = float3(1.0f - I.x * I.x * a, b, -I.x);
|
||||
float3 b2 = float3(b, 1.0f - I.y * I.y * a, -I.y);
|
||||
float2 matcap_uv = float2(dot(b1, N), dot(b2, N));
|
||||
if (flipped) {
|
||||
matcap_uv.x = -matcap_uv.x;
|
||||
}
|
||||
return matcap_uv * 0.496f + 0.5f;
|
||||
}
|
||||
|
||||
float3 get_matcap_lighting(
|
||||
sampler2D diffuse_matcap, sampler2D specular_matcap, float3 base_color, float3 N, float3 I)
|
||||
{
|
||||
bool flipped = world_data.matcap_orientation != 0;
|
||||
float2 uv = matcap_uv_compute(I, N, flipped);
|
||||
|
||||
float3 diffuse = textureLod(diffuse_matcap, uv, 0.0f).rgb;
|
||||
float3 specular = textureLod(specular_matcap, uv, 0.0f).rgb;
|
||||
|
||||
return diffuse * base_color + specular * float(world_data.use_specular);
|
||||
}
|
||||
|
||||
float3 get_matcap_lighting(sampler2DArray matcap, float3 base_color, float3 N, float3 I)
|
||||
{
|
||||
bool flipped = world_data.matcap_orientation != 0;
|
||||
float2 uv = matcap_uv_compute(I, N, flipped);
|
||||
|
||||
float3 diffuse = textureLod(matcap, float3(uv, 0.0f), 0.0f).rgb;
|
||||
float3 specular = textureLod(matcap, float3(uv, 1.0f), 0.0f).rgb;
|
||||
|
||||
return diffuse * base_color + specular * float(world_data.use_specular);
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "infos/workbench_depth_infos.hh"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_merge_depth)
|
||||
|
||||
void main()
|
||||
{
|
||||
float2 screen_uv = gl_FragCoord.xy / float2(textureSize(depth_tx, 0));
|
||||
gl_FragDepth = texture(depth_tx, screen_uv).r;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Prepare the Depth Buffer for the Overlay Engine. */
|
||||
|
||||
#include "infos/workbench_depth_infos.hh"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_overlay_depth)
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Set the depth to 0 for "In Front" objects,
|
||||
* so the Overlay engine doesn't draw on top of them. */
|
||||
gl_FragDepth = 0.0f;
|
||||
}
|
||||
|
|
@ -4,14 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view_infos.hh" // IWYU pragma: export
|
||||
|
||||
#include "draw_curves_lib.glsl"
|
||||
#include "draw_curves.bsl.hh"
|
||||
#include "draw_gsplat_lib.bsl.hh"
|
||||
#include "draw_model.bsl.hh"
|
||||
#include "draw_pointcloud_lib.glsl"
|
||||
#include "draw_pointcloud.bsl.hh"
|
||||
#include "draw_view.bsl.hh"
|
||||
#include "draw_view_clipping_lib.glsl"
|
||||
#include "gpu_shader_common_hash.bsl.hh"
|
||||
#include "gpu_shader_math_base.bsl.hh"
|
||||
#include "workbench_common.bsl.hh"
|
||||
|
|
@ -27,6 +24,33 @@ namespace workbench::prepass {
|
|||
#define WORKBENCH_LIGHTING_MATCAP 1
|
||||
#define WORKBENCH_LIGHTING_FLAT 2
|
||||
|
||||
struct ClippingConstant {
|
||||
[[compilation_constant]] const bool use_clipping;
|
||||
};
|
||||
|
||||
struct Clipping {
|
||||
[[resource_table]] ClippingConstant constants;
|
||||
|
||||
[[uniform(DRW_CLIPPING_UBO_SLOT)]] const float4 (&drw_clipping_)[6];
|
||||
|
||||
void set_clipping_distances(float3 ws_P,
|
||||
float &dist0,
|
||||
float &dist1,
|
||||
float &dist2,
|
||||
float &dist3,
|
||||
float &dist4,
|
||||
float &dist5) const
|
||||
{
|
||||
float4 pos_4d = float4(ws_P, 1.0f);
|
||||
dist0 = dot(drw_clipping_[0], pos_4d);
|
||||
dist1 = dot(drw_clipping_[1], pos_4d);
|
||||
dist2 = dot(drw_clipping_[2], pos_4d);
|
||||
dist3 = dot(drw_clipping_[3], pos_4d);
|
||||
dist4 = dot(drw_clipping_[4], pos_4d);
|
||||
dist5 = dot(drw_clipping_[5], pos_4d);
|
||||
}
|
||||
};
|
||||
|
||||
/* Special function only to be used with calculate_transparent_weight(). */
|
||||
float linear_zdepth(float depth, float4x4 proj_mat)
|
||||
{
|
||||
|
|
@ -114,21 +138,12 @@ struct MeshIn {
|
|||
[[attribute(3)]] float2 au;
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
[[legacy_info]] ShaderCreateInfo drw_clipped;
|
||||
|
||||
/**
|
||||
* WORKAROUND: This exact compilation constant is checked in Metal backend to enable clip
|
||||
* distances.
|
||||
*/
|
||||
[[compilation_constant]] const bool use_clipping;
|
||||
};
|
||||
|
||||
[[vertex]] void vert_mesh([[resource_table]] Mesh &mesh,
|
||||
[[resource_table]] color::Materials &materials,
|
||||
[[vertex]] void vert_mesh([[resource_table]] color::Materials &materials,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table]] draw::ResourceCustomID &resources,
|
||||
[[resource_table]] const Clipping &clip,
|
||||
[[clip_distance]] [[condition(use_clipping)]] float (&clip_distances)[6],
|
||||
[[instance_index]] const int inst_id,
|
||||
[[in]] const MeshIn &v_in,
|
||||
[[out]] VertOut &v_out,
|
||||
|
|
@ -143,8 +158,14 @@ struct Mesh {
|
|||
float3 world_pos = obj.point_object_to_world(v_in.pos);
|
||||
out_position = view.point_world_to_homogenous(world_pos);
|
||||
|
||||
if (mesh.use_clipping) [[static_branch]] {
|
||||
view_clipping_distances(world_pos);
|
||||
if (clip.constants.use_clipping) [[static_branch]] {
|
||||
clip.set_clipping_distances(world_pos,
|
||||
clip_distances[0],
|
||||
clip_distances[1],
|
||||
clip_distances[2],
|
||||
clip_distances[3],
|
||||
clip_distances[4],
|
||||
clip_distances[5]);
|
||||
}
|
||||
|
||||
v_out.uv = v_in.au;
|
||||
|
|
@ -158,30 +179,24 @@ struct Mesh {
|
|||
}
|
||||
|
||||
struct Curves {
|
||||
[[legacy_info]] ShaderCreateInfo draw_curves;
|
||||
[[legacy_info]] ShaderCreateInfo draw_curves_infos;
|
||||
[[legacy_info]] ShaderCreateInfo drw_clipped;
|
||||
|
||||
/**
|
||||
* WORKAROUND: This exact compilation constant is checked in Metal backend to enable clip
|
||||
* distances.
|
||||
*/
|
||||
[[compilation_constant]] const bool use_clipping;
|
||||
|
||||
[[sampler(WB_CURVES_COLOR_SLOT) /*, frequency(batch)*/]] samplerBuffer ac;
|
||||
[[sampler(WB_CURVES_UV_SLOT) /*, frequency(batch)*/]] samplerBuffer au;
|
||||
[[sampler(WB_CURVES_COLOR_SLOT), frequency(BATCH)]] samplerBuffer ac;
|
||||
[[sampler(WB_CURVES_UV_SLOT), frequency(BATCH)]] samplerBuffer au;
|
||||
[[push_constant]] const int emitter_object_id;
|
||||
};
|
||||
|
||||
[[vertex]] void vert_curves([[resource_table]] Curves &curves,
|
||||
[[resource_table]] color::Materials &materials,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table]] draw::ResourceCustomID &resources,
|
||||
[[instance_index]] const int inst_id,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[out]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
[[vertex]] void vert_curves(
|
||||
[[resource_table]] Curves &srt,
|
||||
[[resource_table]] color::Materials &materials,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table]] draw::ResourceCustomID &resources,
|
||||
[[resource_table]] draw::Curves &curves,
|
||||
[[instance_index]] const int inst_id,
|
||||
[[resource_table]] const Clipping &clip,
|
||||
[[clip_distance]] [[condition(use_clipping)]] float (&clip_distances)[6],
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[out]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
{
|
||||
int custom_id = int(resources.get_custom_id(inst_id));
|
||||
|
||||
|
|
@ -189,12 +204,10 @@ struct Curves {
|
|||
ViewMatrices view = views.get(id.view_id<1>());
|
||||
ObjectMatrices obj = models.get(id.resource_id<1>());
|
||||
|
||||
const auto &drw_curves = buffer_get(draw_curves_infos, drw_curves);
|
||||
|
||||
const curves::Point ls_pt = curves::point_get(uint(vert_id));
|
||||
const curves::Point ws_pt = curves::object_to_world(ls_pt, obj.model);
|
||||
const curves::ShapePoint pt = curves::shape_point_get(ws_pt,
|
||||
view.world_incident_vector(ws_pt.P));
|
||||
const draw::curves::Point ls_pt = curves.point_get(uint(vert_id));
|
||||
const draw::curves::Point ws_pt = curves.object_to_world(ls_pt, obj.model);
|
||||
const draw::curves::ShapePoint pt = curves.shape_point_get(ws_pt,
|
||||
view.world_incident_vector(ws_pt.P));
|
||||
float3 world_pos = pt.P;
|
||||
|
||||
out_position = view.point_world_to_homogenous(world_pos);
|
||||
|
|
@ -202,26 +215,32 @@ struct Curves {
|
|||
float hair_rand = workbench::prepass::integer_noise(ws_pt.curve_id);
|
||||
|
||||
float3 nor = pt.N;
|
||||
if (drw_curves.half_cylinder_face_count == 1) {
|
||||
if (curves.drw_curves.half_cylinder_face_count == 1) {
|
||||
/* Very cheap smooth normal using attribute interpolator.
|
||||
* Using the correct normals over the cylinder (-1..1) leads to unwanted result as the
|
||||
* interpolation is not spherical but linear. So we use a smaller range (-SQRT2..SQRT2) in
|
||||
* which the linear interpolation is close enough to the desired result. */
|
||||
nor = pt.N + pt.curve_N;
|
||||
}
|
||||
else if (drw_curves.half_cylinder_face_count == 0) {
|
||||
else if (curves.drw_curves.half_cylinder_face_count == 0) {
|
||||
nor = hair_random_normal(pt.curve_T, pt.curve_B, pt.curve_N, hair_rand);
|
||||
}
|
||||
|
||||
if (curves.use_clipping) [[static_branch]] {
|
||||
view_clipping_distances(world_pos);
|
||||
if (clip.constants.use_clipping) [[static_branch]] {
|
||||
clip.set_clipping_distances(world_pos,
|
||||
clip_distances[0],
|
||||
clip_distances[1],
|
||||
clip_distances[2],
|
||||
clip_distances[3],
|
||||
clip_distances[4],
|
||||
clip_distances[5]);
|
||||
}
|
||||
|
||||
v_out.uv = curves::get_customdata_vec2(ws_pt.curve_id, curves.au);
|
||||
v_out.uv = draw::curves::get_customdata_vec2(ws_pt.curve_id, srt.au);
|
||||
|
||||
v_out.normal = normalize(view.normal_world_to_view(nor));
|
||||
|
||||
float3 vert_col = curves::get_customdata_vec3(ws_pt.curve_id, curves.ac);
|
||||
float3 vert_col = draw::curves::get_customdata_vec3(ws_pt.curve_id, srt.ac);
|
||||
materials.material_data_get(
|
||||
custom_id, vert_col, v_out.color, v_out.alpha, v_out.roughness, v_out.metallic);
|
||||
|
||||
|
|
@ -233,31 +252,24 @@ struct Curves {
|
|||
|
||||
v_out.object_id = int(id.resource_id<1>() & 0xFFFFu) + 1;
|
||||
|
||||
if (curves.emitter_object_id != 0) {
|
||||
v_out.object_id = int(uint(curves.emitter_object_id) & 0xFFFFu) + 1;
|
||||
if (srt.emitter_object_id != 0) {
|
||||
v_out.object_id = int(uint(srt.emitter_object_id) & 0xFFFFu) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct PointCloud {
|
||||
[[legacy_info]] ShaderCreateInfo draw_pointcloud;
|
||||
[[legacy_info]] ShaderCreateInfo drw_clipped;
|
||||
|
||||
/**
|
||||
* WORKAROUND: This exact compilation constant is checked in Metal backend to enable clip
|
||||
* distances.
|
||||
*/
|
||||
[[compilation_constant]] const bool use_clipping;
|
||||
};
|
||||
|
||||
[[vertex]] void vert_pointcloud([[resource_table]] PointCloud &point_cloud,
|
||||
[[resource_table]] color::Materials &materials,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table]] draw::ResourceCustomID &resources,
|
||||
[[instance_index]] const int inst_id,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[out]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
[[vertex]] void vert_pointcloud(
|
||||
[[resource_table]] color::Materials &materials,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Infos &infos,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table]] draw::PointCloud &pt_cloud,
|
||||
[[resource_table]] draw::ResourceCustomID &resources,
|
||||
[[resource_table]] const Clipping &clip,
|
||||
[[clip_distance]] [[condition(use_clipping)]] float (&clip_distances)[6],
|
||||
[[instance_index]] const int inst_id,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[out]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
{
|
||||
int custom_id = int(resources.get_custom_id(inst_id));
|
||||
|
||||
|
|
@ -266,20 +278,26 @@ struct PointCloud {
|
|||
|
||||
ViewMatrices view = views.get(id.view_id<1>());
|
||||
ObjectMatrices obj = models.get(res_id);
|
||||
const ObjectInfos ob_infos = infos.get(res_id);
|
||||
const eObjectInfoFlag ob_flag = ob_infos.flag;
|
||||
|
||||
const eObjectInfoFlag ob_flag = buffer_get(draw_object_infos, drw_infos)[res_id].flag;
|
||||
|
||||
const pointcloud::Point ls_pt = pointcloud::point_get(uint(vert_id));
|
||||
const pointcloud::Point ws_pt = pointcloud::object_to_world(ls_pt, obj.model);
|
||||
const pointcloud::ShapePoint pt = pointcloud::shape_point_get(
|
||||
const draw::pointcloud::Point ls_pt = pt_cloud.point_get(uint(vert_id));
|
||||
const draw::pointcloud::Point ws_pt = draw::pointcloud::object_to_world(ls_pt, obj.model);
|
||||
const draw::pointcloud::ShapePoint pt = draw::pointcloud::shape_point_get(
|
||||
ws_pt, view.world_incident_vector(ws_pt.P), view.up(), ob_flag);
|
||||
|
||||
v_out.normal = normalize(view.normal_world_to_view(pt.N));
|
||||
|
||||
out_position = view.point_world_to_homogenous(pt.P);
|
||||
|
||||
if (point_cloud.use_clipping) [[static_branch]] {
|
||||
view_clipping_distances(pt.P);
|
||||
if (clip.constants.use_clipping) [[static_branch]] {
|
||||
clip.set_clipping_distances(pt.P,
|
||||
clip_distances[0],
|
||||
clip_distances[1],
|
||||
clip_distances[2],
|
||||
clip_distances[3],
|
||||
clip_distances[4],
|
||||
clip_distances[5]);
|
||||
}
|
||||
|
||||
v_out.uv = float2(0.0f);
|
||||
|
|
@ -290,24 +308,18 @@ struct PointCloud {
|
|||
v_out.object_id = int(id.resource_id<1>() & 0xFFFFu) + 1;
|
||||
}
|
||||
|
||||
struct GSplat {
|
||||
[[legacy_info]] ShaderCreateInfo drw_clipped;
|
||||
|
||||
/** WORKAROUND: This exact compilation constant is checked in Metal backend to enable clip
|
||||
* distances. */
|
||||
[[compilation_constant]] const bool use_clipping;
|
||||
};
|
||||
|
||||
[[vertex]] void vert_gsplat([[resource_table]] GSplat &gsplat,
|
||||
[[resource_table]] const color::Materials &materials,
|
||||
[[resource_table]] const draw::gsplat::ShapeResource &shape,
|
||||
[[resource_table]] const draw::View &views,
|
||||
[[resource_table]] const draw::Model &models,
|
||||
[[resource_table]] const draw::ResourceCustomID &resources,
|
||||
[[instance_index]] const int inst_id,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[out]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
[[vertex]] void vert_gsplat(
|
||||
[[resource_table]] const color::Materials &materials,
|
||||
[[resource_table]] const draw::gsplat::ShapeResource &shape,
|
||||
[[resource_table]] const draw::View &views,
|
||||
[[resource_table]] const draw::Model &models,
|
||||
[[resource_table]] const draw::ResourceCustomID &resources,
|
||||
[[resource_table]] const Clipping &clip,
|
||||
[[clip_distance]] [[condition(use_clipping)]] float (&clip_distances)[6],
|
||||
[[instance_index]] const int inst_id,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[out]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
{
|
||||
int custom_id = int(resources.get_custom_id(inst_id));
|
||||
|
||||
|
|
@ -329,8 +341,14 @@ struct GSplat {
|
|||
|
||||
out_position = gs.hP;
|
||||
|
||||
if (gsplat.use_clipping) [[static_branch]] {
|
||||
view_clipping_distances(gs.wP);
|
||||
if (clip.constants.use_clipping) [[static_branch]] {
|
||||
clip.set_clipping_distances(gs.wP,
|
||||
clip_distances[0],
|
||||
clip_distances[1],
|
||||
clip_distances[2],
|
||||
clip_distances[3],
|
||||
clip_distances[4],
|
||||
clip_distances[5]);
|
||||
}
|
||||
|
||||
materials.material_data_get(
|
||||
|
|
@ -447,102 +465,102 @@ struct TransparentOut {
|
|||
}
|
||||
|
||||
/* clang-format off */
|
||||
PipelineGraphic mesh_opaque_studio_material_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_studio_material_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_studio_texture_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_studio_texture_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_matcap_material_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_matcap_material_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_matcap_texture_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_matcap_texture_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_flat_material_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_flat_material_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_flat_texture_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_flat_texture_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_studio_material_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_studio_material_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_studio_texture_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_studio_texture_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_matcap_material_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_matcap_material_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_matcap_texture_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_matcap_texture_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_flat_material_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_flat_material_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_flat_texture_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_flat_texture_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_studio_material_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_studio_material_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_studio_texture_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_studio_texture_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_matcap_material_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_matcap_material_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_matcap_texture_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_matcap_texture_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_flat_material_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_flat_material_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_flat_texture_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_flat_texture_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_studio_material_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_studio_material_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_studio_texture_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_studio_texture_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_matcap_material_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_matcap_material_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_matcap_texture_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_matcap_texture_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_flat_material_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_flat_material_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_flat_texture_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_flat_texture_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_studio_material_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_studio_material_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_studio_texture_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_studio_texture_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_matcap_material_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_matcap_material_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_matcap_texture_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_matcap_texture_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_flat_material_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_flat_material_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_flat_texture_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_flat_texture_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Mesh{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_studio_material_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_studio_material_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_studio_texture_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_studio_texture_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_matcap_material_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_matcap_material_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_matcap_texture_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_matcap_texture_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_flat_material_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_flat_material_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_flat_texture_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_flat_texture_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, Curves{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_studio_material_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_studio_material_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_studio_texture_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_studio_texture_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_matcap_material_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_matcap_material_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_matcap_texture_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_matcap_texture_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_flat_material_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_flat_material_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_flat_texture_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_flat_texture_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, PointCloud{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_studio_material_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_studio_material_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_studio_texture_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_studio_texture_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_matcap_material_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_matcap_material_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_matcap_texture_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_matcap_texture_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_flat_material_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_flat_material_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_flat_texture_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_flat_texture_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, GSplat{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_studio_material_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_studio_material_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_studio_texture_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_studio_texture_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_matcap_material_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_matcap_material_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_matcap_texture_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_matcap_texture_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_flat_material_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_flat_material_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_opaque_flat_texture_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_opaque_flat_texture_no_clip( vert_mesh, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_studio_material_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_studio_material_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_studio_texture_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_studio_texture_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_matcap_material_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_matcap_material_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_matcap_texture_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_matcap_texture_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_flat_material_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_flat_material_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_opaque_flat_texture_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_opaque_flat_texture_no_clip( vert_curves, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_studio_material_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_studio_material_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_studio_texture_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_studio_texture_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_matcap_material_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_matcap_material_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_matcap_texture_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_matcap_texture_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_flat_material_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_flat_material_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_opaque_flat_texture_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_opaque_flat_texture_no_clip( vert_pointcloud, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_studio_material_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_studio_material_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_studio_texture_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_studio_texture_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_matcap_material_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_matcap_material_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_matcap_texture_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_matcap_texture_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_flat_material_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_flat_material_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_opaque_flat_texture_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_opaque_flat_texture_no_clip( vert_gsplat, frag_opaque, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_studio_material_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_studio_material_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_studio_texture_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_studio_texture_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_matcap_material_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_matcap_material_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_matcap_texture_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_matcap_texture_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_flat_material_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_flat_material_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic mesh_transparent_flat_texture_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic mesh_transparent_flat_texture_no_clip( vert_mesh, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_studio_material_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_studio_material_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_studio_texture_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_studio_texture_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_matcap_material_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_matcap_material_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_matcap_texture_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_matcap_texture_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_flat_material_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_flat_material_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic curves_transparent_flat_texture_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic curves_transparent_flat_texture_no_clip( vert_curves, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_studio_material_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_studio_material_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_studio_texture_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_studio_texture_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_matcap_material_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_matcap_material_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_matcap_texture_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_matcap_texture_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_flat_material_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_flat_material_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic ptcloud_transparent_flat_texture_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic ptcloud_transparent_flat_texture_no_clip( vert_pointcloud, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = false}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_studio_material_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_studio_material_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_studio_texture_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_studio_texture_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 0 /* WORKBENCH_LIGHTING_STUDIO */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_matcap_material_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_matcap_material_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_matcap_texture_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_matcap_texture_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 1 /* WORKBENCH_LIGHTING_MATCAP */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_flat_material_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_flat_material_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = false, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
PipelineGraphic gsplat_transparent_flat_texture_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = true });
|
||||
PipelineGraphic gsplat_transparent_flat_texture_no_clip( vert_gsplat, frag_transparent, Resources{.lighting_mode = 2 /* WORKBENCH_LIGHTING_FLAT */, .use_texture = true, .use_gsplat = true}, ClippingConstant{.use_clipping = false});
|
||||
/* clang-format on */
|
||||
|
||||
} // namespace workbench::prepass
|
||||
|
|
|
|||
|
|
@ -19,13 +19,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view_infos.hh"
|
||||
#include "gpu_index_load_infos.hh"
|
||||
|
||||
#include "draw_model_lib.glsl"
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "draw_model.bsl.hh"
|
||||
#include "draw_view.bsl.hh"
|
||||
#include "gpu_shader_attribute_load_lib.glsl"
|
||||
#include "gpu_shader_index_load_lib.glsl"
|
||||
#include "gpu_shader_index_load.bsl.hh"
|
||||
#include "gpu_shader_utildefines.bsl.hh"
|
||||
#include "workbench_shader_shared.hh"
|
||||
|
||||
|
|
@ -49,9 +46,10 @@ struct GeomOut {
|
|||
};
|
||||
|
||||
struct Resources {
|
||||
[[legacy_info]] ShaderCreateInfo gpu_index_buffer_load;
|
||||
[[legacy_info]] ShaderCreateInfo draw_view;
|
||||
[[legacy_info]] ShaderCreateInfo draw_modelmat;
|
||||
[[resource_table]] IndexLoad index_load;
|
||||
|
||||
[[resource_table]] draw::View views;
|
||||
[[resource_table]] draw::Model models;
|
||||
|
||||
/* WORKAROUND: Needed to support OpenSubdiv vertex format. Should be removed. */
|
||||
[[push_constant]] const int2 gpu_attr_3;
|
||||
|
|
@ -64,20 +62,25 @@ struct Resources {
|
|||
|
||||
VertIn input_assembly(uint in_vertex_id) const
|
||||
{
|
||||
uint v_i = gpu_index_load(in_vertex_id);
|
||||
uint v_i = index_load.load(in_vertex_id);
|
||||
|
||||
VertIn vert_in;
|
||||
vert_in.lP = gpu_attr_load_float3(this->pos, this->gpu_attr_3, v_i);
|
||||
vert_in.lP = float3(pos[gpu_attr_load_index(v_i, gpu_attr_3) + 0],
|
||||
pos[gpu_attr_load_index(v_i, gpu_attr_3) + 1],
|
||||
pos[gpu_attr_load_index(v_i, gpu_attr_3) + 2]);
|
||||
return vert_in;
|
||||
}
|
||||
|
||||
VertOut vertex_main(VertIn vert_in) const
|
||||
VertOut vertex_main(VertIn vert_in, uint resource_id) const
|
||||
{
|
||||
VertOut vert_out;
|
||||
vert_out.lP = vert_in.lP;
|
||||
float3 L = this->pass_data.light_direction_ws;
|
||||
|
||||
float3 ws_P = drw_point_object_to_world(vert_in.lP);
|
||||
ObjectMatrices model = models.get(resource_id);
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
float3 ws_P = model.point_object_to_world(vert_in.lP);
|
||||
float extrude_distance = 1e5f;
|
||||
float L_FP = dot(L, this->pass_data.far_plane.xyz);
|
||||
if (L_FP > 0.0f) {
|
||||
|
|
@ -87,8 +90,9 @@ struct Resources {
|
|||
/* Ensure we don't overlap the far plane. */
|
||||
extrude_distance -= 1e-3f;
|
||||
}
|
||||
vert_out.backPosition = drw_point_world_to_homogenous(ws_P + L * extrude_distance);
|
||||
vert_out.frontPosition = drw_point_world_to_homogenous(drw_point_object_to_world(vert_in.lP));
|
||||
vert_out.backPosition = view.point_world_to_homogenous(ws_P + L * extrude_distance);
|
||||
vert_out.frontPosition = view.point_world_to_homogenous(
|
||||
model.point_object_to_world(vert_in.lP));
|
||||
return vert_out;
|
||||
}
|
||||
};
|
||||
|
|
@ -176,11 +180,12 @@ struct GeometryShaderEmulator {
|
|||
emit_triangle_vert(2, out_vertex_id, geom_out);
|
||||
}
|
||||
|
||||
void geometry_main([[resource_table]] const Resources &srt,
|
||||
void geometry_main(const Resources &srt,
|
||||
VertOut geom_in[4],
|
||||
uint out_vertex_id,
|
||||
uint out_primitive_id,
|
||||
uint out_invocation_id)
|
||||
uint out_invocation_id,
|
||||
uint resource_id)
|
||||
{
|
||||
float3 v10 = geom_in[0].lP - geom_in[1].lP;
|
||||
float3 v12 = geom_in[2].lP - geom_in[1].lP;
|
||||
|
|
@ -189,7 +194,7 @@ struct GeometryShaderEmulator {
|
|||
float3 n1 = cross(v12, v10);
|
||||
float3 n2 = cross(v13, v12);
|
||||
|
||||
#ifdef DEGENERATE_TRIS_WORKAROUND
|
||||
#if 0 /* DEGENERATE_TRIS_WORKAROUND */
|
||||
/* Check if area is null */
|
||||
float2 faces_area = float2(length_squared(n1), length_squared(n2));
|
||||
bool2 degen_faces = lessThan(abs(faces_area), float2(DEGENERATE_TRIS_AREA_THRESHOLD));
|
||||
|
|
@ -199,8 +204,9 @@ struct GeometryShaderEmulator {
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
ObjectMatrices model = srt.models.get(resource_id);
|
||||
|
||||
float3 ls_light_direction = drw_normal_world_to_object(
|
||||
float3 ls_light_direction = model.normal_world_to_object(
|
||||
float3(srt.pass_data.light_direction_ws));
|
||||
|
||||
float2 facing = float2(dot(n1, ls_light_direction), dot(n2, ls_light_direction));
|
||||
|
|
@ -210,7 +216,7 @@ struct GeometryShaderEmulator {
|
|||
/* WATCH: maybe unpredictable in some cases. */
|
||||
bool is_manifold = any(notEqual(geom_in[0].lP, geom_in[3].lP));
|
||||
|
||||
#ifdef DEGENERATE_TRIS_WORKAROUND
|
||||
#if 0 /* DEGENERATE_TRIS_WORKAROUND */
|
||||
if (srt.double_manifold == false) [[static_branch]] {
|
||||
/* 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. */
|
||||
|
|
@ -243,14 +249,17 @@ struct GeometryShaderEmulator {
|
|||
void geometry_main_caps([[resource_table]] const Resources &srt,
|
||||
VertOut geom_in[3],
|
||||
uint out_vertex_id,
|
||||
uint out_invocation_id)
|
||||
uint out_invocation_id,
|
||||
uint resource_id)
|
||||
{
|
||||
float3 v10 = geom_in[0].lP - geom_in[1].lP;
|
||||
float3 v12 = geom_in[2].lP - geom_in[1].lP;
|
||||
|
||||
float3 Ng = cross(v12, v10);
|
||||
|
||||
float3 ls_light_direction = drw_normal_world_to_object(
|
||||
ObjectMatrices model = srt.models.get(resource_id);
|
||||
|
||||
float3 ls_light_direction = model.normal_world_to_object(
|
||||
float3(srt.pass_data.light_direction_ws));
|
||||
|
||||
float facing = dot(Ng, ls_light_direction);
|
||||
|
|
@ -275,7 +284,9 @@ struct GeometryShaderEmulator {
|
|||
|
||||
[[vertex]]
|
||||
void vert_main([[resource_table]] const Resources &srt,
|
||||
[[resource_table]] const draw::Resource &res,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[instance_index]] const int inst_index,
|
||||
[[position]] float4 &out_position)
|
||||
{
|
||||
/* Line adjacency primitive. */
|
||||
|
|
@ -302,6 +313,8 @@ void vert_main([[resource_table]] const Resources &srt,
|
|||
uint out_invocation_id = (uint(vert_id) / output_vertex_count_per_invocation) %
|
||||
output_invocation_count;
|
||||
|
||||
uint resource_id = res.get(inst_index).resource_id<1>();
|
||||
|
||||
VertIn vert_in[input_primitive_vertex_count];
|
||||
vert_in[0] = srt.input_assembly(in_primitive_first_vertex + 0u);
|
||||
vert_in[1] = srt.input_assembly(in_primitive_first_vertex + 1u);
|
||||
|
|
@ -309,21 +322,23 @@ void vert_main([[resource_table]] const Resources &srt,
|
|||
vert_in[3] = srt.input_assembly(in_primitive_first_vertex + 3u);
|
||||
|
||||
VertOut vert_out[input_primitive_vertex_count];
|
||||
vert_out[0] = srt.vertex_main(vert_in[0]);
|
||||
vert_out[1] = srt.vertex_main(vert_in[1]);
|
||||
vert_out[2] = srt.vertex_main(vert_in[2]);
|
||||
vert_out[3] = srt.vertex_main(vert_in[3]);
|
||||
vert_out[0] = srt.vertex_main(vert_in[0], resource_id);
|
||||
vert_out[1] = srt.vertex_main(vert_in[1], resource_id);
|
||||
vert_out[2] = srt.vertex_main(vert_in[2], resource_id);
|
||||
vert_out[3] = srt.vertex_main(vert_in[3], resource_id);
|
||||
|
||||
GeometryShaderEmulator gs;
|
||||
/* Discard by default. */
|
||||
gs.out_pos = float4(NAN_FLT);
|
||||
gs.geometry_main(srt, vert_out, out_vertex_id, out_primitive_id, out_invocation_id);
|
||||
gs.geometry_main(srt, vert_out, out_vertex_id, out_primitive_id, out_invocation_id, resource_id);
|
||||
out_position = gs.out_pos;
|
||||
}
|
||||
|
||||
[[vertex]]
|
||||
void vert_main_caps([[resource_table]] const Resources &srt,
|
||||
[[resource_table]] const draw::Resource &res,
|
||||
[[vertex_id]] const int vert_id,
|
||||
[[instance_index]] const int inst_index,
|
||||
[[position]] float4 &out_position)
|
||||
{
|
||||
/* Triangle list primitive. */
|
||||
|
|
@ -345,20 +360,22 @@ void vert_main_caps([[resource_table]] const Resources &srt,
|
|||
uint out_invocation_id = (uint(vert_id) / output_vertex_count_per_invocation) %
|
||||
output_invocation_count;
|
||||
|
||||
uint resource_id = res.get(inst_index).resource_id<1>();
|
||||
|
||||
VertIn vert_in[input_primitive_vertex_count];
|
||||
vert_in[0] = srt.input_assembly(in_primitive_first_vertex + 0u);
|
||||
vert_in[1] = srt.input_assembly(in_primitive_first_vertex + 1u);
|
||||
vert_in[2] = srt.input_assembly(in_primitive_first_vertex + 2u);
|
||||
|
||||
VertOut vert_out[input_primitive_vertex_count];
|
||||
vert_out[0] = srt.vertex_main(vert_in[0]);
|
||||
vert_out[1] = srt.vertex_main(vert_in[1]);
|
||||
vert_out[2] = srt.vertex_main(vert_in[2]);
|
||||
vert_out[0] = srt.vertex_main(vert_in[0], resource_id);
|
||||
vert_out[1] = srt.vertex_main(vert_in[1], resource_id);
|
||||
vert_out[2] = srt.vertex_main(vert_in[2], resource_id);
|
||||
|
||||
GeometryShaderEmulator gs;
|
||||
/* Discard by default. */
|
||||
gs.out_pos = float4(NAN_FLT);
|
||||
gs.geometry_main_caps(srt, vert_out, out_vertex_id, out_invocation_id);
|
||||
gs.geometry_main_caps(srt, vert_out, out_vertex_id, out_invocation_id, resource_id);
|
||||
out_position = gs.out_pos;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "draw_view.bsl.hh"
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
#include "gpu_shader_utildefines.bsl.hh"
|
||||
#include "workbench_common.bsl.hh"
|
||||
|
|
@ -13,8 +13,6 @@
|
|||
namespace workbench::shadow::rt {
|
||||
|
||||
struct Resources {
|
||||
[[legacy_info]] ShaderCreateInfo draw_view;
|
||||
|
||||
[[uniform(1)]] const ShadowPassData &pass_data;
|
||||
[[sampler(2)]] const sampler2DDepth depth_tx;
|
||||
[[sampler(3)]] const sampler2D normal_tx;
|
||||
|
|
@ -26,7 +24,9 @@ struct Resources {
|
|||
fullscreen_vertex(vert_id, out_pos);
|
||||
}
|
||||
|
||||
[[fragment]] void frag([[frag_coord]] const float4 &frag_coord, [[resource_table]] Resources &srt)
|
||||
[[fragment]] void frag([[frag_coord]] const float4 &frag_coord,
|
||||
[[resource_table]] Resources &srt,
|
||||
[[resource_table]] const draw::View &views)
|
||||
{
|
||||
const float2 resolution = float2(textureSize(srt.depth_tx, 0).xy);
|
||||
const float2 screen_uv = frag_coord.xy / resolution;
|
||||
|
|
@ -37,7 +37,9 @@ struct Resources {
|
|||
return;
|
||||
}
|
||||
|
||||
const float3 N = drw_normal_view_to_world(
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
const float3 N = view.normal_view_to_world(
|
||||
workbench::normal_decode(texture(srt.normal_tx, screen_uv)));
|
||||
if (dot(N, srt.pass_data.light_direction_ws) >= 0.0f) {
|
||||
/* We already know the fragment is in shadow. No need to query. */
|
||||
|
|
@ -45,11 +47,11 @@ struct Resources {
|
|||
}
|
||||
|
||||
/* Offset depth to compensate for depth buffer precision. */
|
||||
float3 P = drw_point_screen_to_world(
|
||||
float3 P = view.point_screen_to_world(
|
||||
float3(screen_uv, intBitsToFloat(floatBitsToInt(depth) - 2)));
|
||||
|
||||
const float pixel_size = srt.pass_data.pixel_size *
|
||||
(drw_view_is_perspective() ? drw_view_z_distance(P) : 1.0f);
|
||||
(view.is_perspective() ? view.z_distance(P) : 1.0f);
|
||||
|
||||
/* Offset by pixel size to compensate for floating point precision. */
|
||||
const float tMin = pixel_size / max(dot(N, -srt.pass_data.light_direction_ws), 0.1f);
|
||||
|
|
|
|||
|
|
@ -8,10 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "draw_view_infos.hh"
|
||||
#include "gpu_index_load_infos.hh"
|
||||
|
||||
#include "draw_intersect_lib.glsl"
|
||||
#include "draw_intersect.bsl.hh"
|
||||
#include "workbench_shader_shared.hh"
|
||||
|
||||
namespace workbench::shadow::visibility {
|
||||
|
|
@ -19,8 +16,7 @@ namespace workbench::shadow::visibility {
|
|||
struct Resources {
|
||||
[[compilation_constant]] const bool dynamic_pass_selection;
|
||||
|
||||
[[legacy_info]] ShaderCreateInfo draw_view;
|
||||
[[legacy_info]] ShaderCreateInfo draw_view_culling;
|
||||
[[resource_table]] draw::ViewCulling view_culling;
|
||||
[[storage(0, read)]] const ObjectBounds (&bounds_buf)[];
|
||||
|
||||
[[push_constant]] const int resource_len;
|
||||
|
|
@ -57,7 +53,7 @@ struct Resources {
|
|||
|
||||
bool intersects_near_plane(IsectBox box)
|
||||
{
|
||||
float4 near_plane = drw_view_culling().frustum_planes.planes[4];
|
||||
float4 near_plane = view_culling.get(0).frustum_planes.planes[4];
|
||||
bool on_positive_side = false;
|
||||
bool on_negative_side = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "infos/workbench_prepass_infos.hh"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_prepass)
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_transparent_accum)
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_lighting_matcap)
|
||||
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "workbench_common_lib.glsl"
|
||||
#include "workbench_image_lib.glsl"
|
||||
#include "workbench_matcap_lib.glsl"
|
||||
#include "workbench_world_light_lib.glsl"
|
||||
|
||||
/* Special function only to be used with calculate_transparent_weight(). */
|
||||
float linear_zdepth(float depth, float4x4 proj_mat)
|
||||
{
|
||||
if (proj_mat[3][3] == 0.0f) {
|
||||
float d = 2.0f * depth - 1.0f;
|
||||
return -proj_mat[3][2] / (d + proj_mat[2][2]);
|
||||
}
|
||||
else {
|
||||
/* Return depth from near plane. */
|
||||
float z_delta = -2.0f / proj_mat[2][2];
|
||||
return depth * z_delta;
|
||||
}
|
||||
}
|
||||
|
||||
/* Based on :
|
||||
* McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of
|
||||
* Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013
|
||||
*/
|
||||
float calculate_transparent_weight()
|
||||
{
|
||||
float z = linear_zdepth(gl_FragCoord.z, drw_view().winmat);
|
||||
#if 0
|
||||
/* Eq 10 : Good for surfaces with varying opacity (like particles) */
|
||||
float a = min(1.0f, alpha * 10.0f) + 0.01f;
|
||||
float b = -gl_FragCoord.z * 0.95f + 1.0f;
|
||||
float w = a * a * a * 3e2f * b * b * b;
|
||||
#else
|
||||
/* Eq 7 put more emphasis on surfaces closer to the view. */
|
||||
// float w = 10.0f / (1e-5f + pow(abs(z) / 5.0f, 2.0f) + pow(abs(z) / 200.0f, 6.0f)); /* Eq 7 */
|
||||
// float w = 10.0f / (1e-5f + pow(abs(z) / 10.0f, 3.0f) + pow(abs(z) / 200.0f, 6.0f)); /* Eq 8 */
|
||||
// float w = 10.0f / (1e-5f + pow(abs(z) / 200.0f, 4.0f)); /* Eq 9 */
|
||||
/* Same as eq 7, but optimized. */
|
||||
float a = abs(z) / 5.0f;
|
||||
float b = abs(z) / 200.0f;
|
||||
b *= b;
|
||||
float w = 10.0f / ((1e-5f + a * a) + b * (b * b)); /* Eq 7 */
|
||||
#endif
|
||||
return clamp(w, 1e-2f, 3e2f);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Normal and Incident vector are in view-space. Lighting is evaluated in view-space. */
|
||||
float2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv;
|
||||
float3 vP = drw_point_screen_to_view(float3(uv_viewport, 0.5f));
|
||||
float3 I = drw_view_incident_vector(vP);
|
||||
float3 N = normalize(normal_interp);
|
||||
|
||||
float3 color = color_interp;
|
||||
|
||||
#ifdef WORKBENCH_COLOR_TEXTURE
|
||||
color = workbench_image_color(uv_interp);
|
||||
#endif
|
||||
|
||||
float3 shaded_color;
|
||||
#ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
shaded_color = get_matcap_lighting(matcap_tx, color, N, I);
|
||||
#endif
|
||||
|
||||
#ifdef WORKBENCH_LIGHTING_STUDIO
|
||||
shaded_color = get_world_lighting(color, _roughness, metallic, N, I);
|
||||
#endif
|
||||
|
||||
#ifdef WORKBENCH_LIGHTING_FLAT
|
||||
shaded_color = color;
|
||||
#endif
|
||||
|
||||
shaded_color *= get_shadow(N, force_shadowing);
|
||||
|
||||
/* Listing 4 */
|
||||
float alpha = alpha_interp * world_data.xray_alpha;
|
||||
float weight = calculate_transparent_weight() * alpha;
|
||||
out_transparent_accum = float4(shaded_color * weight, alpha);
|
||||
out_revealage_accum = float4(weight);
|
||||
|
||||
out_object_id = uint(object_id);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Based on :
|
||||
* McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of
|
||||
* Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_fullscreen.bsl.hh"
|
||||
|
||||
namespace workbench::transparency {
|
||||
|
||||
[[vertex]]
|
||||
void vert([[vertex_id]] const int vert_id, [[position]] float4 &position)
|
||||
{
|
||||
fullscreen_vertex(vert_id, position);
|
||||
}
|
||||
|
||||
struct Resolve {
|
||||
[[sampler(0)]] sampler2D transparent_accum;
|
||||
[[sampler(1)]] sampler2D transparent_revealage;
|
||||
};
|
||||
|
||||
struct FragOut {
|
||||
[[frag_color(0)]] float4 color;
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
void resolve_weight_blended_order_independant_transparency([[resource_table]] const Resolve &srt,
|
||||
[[frag_coord]] const float4 frag_co,
|
||||
[[out]] FragOut &frag_out)
|
||||
{
|
||||
float2 screen_uv = frag_co.xy / float2(textureSize(srt.transparent_accum, 0).xy);
|
||||
/* Revealage is actually stored in transparent_accum alpha channel.
|
||||
* This is a workaround to older hardware not having separate blend equation per render target.
|
||||
*/
|
||||
float4 trans_accum = texture(srt.transparent_accum, screen_uv);
|
||||
float trans_weight = texture(srt.transparent_revealage, screen_uv).r;
|
||||
float trans_reveal = trans_accum.a;
|
||||
|
||||
/* Listing 4 */
|
||||
frag_out.color.rgb = trans_accum.rgb / clamp(trans_weight, 1e-4f, 5e4f);
|
||||
frag_out.color.a = 1.0f - trans_reveal;
|
||||
}
|
||||
|
||||
} // namespace workbench::transparency
|
||||
|
||||
PipelineGraphic workbench_transparent_resolve(
|
||||
workbench::transparency::vert,
|
||||
workbench::transparency::resolve_weight_blended_order_independant_transparency);
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2020-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Based on :
|
||||
* McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of
|
||||
* Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013
|
||||
*/
|
||||
|
||||
#include "infos/workbench_transparent_resolve_infos.hh"
|
||||
|
||||
FRAGMENT_SHADER_CREATE_INFO(workbench_transparent_resolve)
|
||||
|
||||
void main()
|
||||
{
|
||||
float2 screen_uv = gl_FragCoord.xy / float2(textureSize(transparent_accum, 0).xy);
|
||||
/* Revealage is actually stored in transparent_accum alpha channel.
|
||||
* This is a workaround to older hardware not having separate blend equation per render target.
|
||||
*/
|
||||
float4 trans_accum = texture(transparent_accum, screen_uv);
|
||||
float trans_weight = texture(transparent_revealage, screen_uv).r;
|
||||
float trans_reveal = trans_accum.a;
|
||||
|
||||
/* Listing 4 */
|
||||
frag_color.rgb = trans_accum.rgb / clamp(trans_weight, 1e-4f, 5e4f);
|
||||
frag_color.a = 1.0f - trans_reveal;
|
||||
}
|
||||
|
|
@ -4,13 +4,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_shader_compat.hh"
|
||||
|
||||
#include "draw_object_infos_infos.hh"
|
||||
|
||||
#include "draw_model_lib.glsl"
|
||||
#include "draw_object_infos_lib.glsl"
|
||||
#include "draw_view_lib.glsl"
|
||||
#include "draw_model.bsl.hh"
|
||||
#include "draw_view.bsl.hh"
|
||||
#include "draw_volume.bsl.hh"
|
||||
#include "gpu_shader_math_constants.bsl.hh"
|
||||
#include "gpu_shader_math_vector_compare.bsl.hh"
|
||||
#include "gpu_shader_math_vector_reduce.bsl.hh"
|
||||
|
|
@ -74,7 +70,7 @@ float4 sample_closest(sampler3D ima, float3 co)
|
|||
|
||||
/* Legacy Fluid Simulation Modifier. */
|
||||
struct Smoke {
|
||||
[[legacy_info]] const ShaderCreateInfo draw_modelmat;
|
||||
[[resource_table]] draw::Model model;
|
||||
|
||||
[[sampler(2)]] const sampler3D flame_tx;
|
||||
[[sampler(3)]] const sampler1D flame_color_tx;
|
||||
|
|
@ -82,8 +78,6 @@ struct Smoke {
|
|||
|
||||
/* Volume Objects. */
|
||||
struct Volume {
|
||||
[[legacy_info]] const ShaderCreateInfo draw_volume;
|
||||
|
||||
[[push_constant]] const float4x4 volume_texture_to_object;
|
||||
[[push_constant]] const float4x4 volume_object_to_texture;
|
||||
};
|
||||
|
|
@ -108,10 +102,6 @@ struct ColorUniform {
|
|||
};
|
||||
|
||||
struct Resources {
|
||||
[[legacy_info]] const ShaderCreateInfo draw_view;
|
||||
[[legacy_info]] const ShaderCreateInfo draw_object_infos;
|
||||
[[legacy_info]] const ShaderCreateInfo draw_resource_id_varying;
|
||||
|
||||
[[compilation_constant]] const bool use_slice;
|
||||
[[compilation_constant]] const bool use_color_band;
|
||||
[[compilation_constant]] const bool is_legacy_smoke;
|
||||
|
|
@ -269,8 +259,6 @@ void eval_volume_step(float3 &Lscat, float extinction, float step_len, float &Tr
|
|||
Lscat = (Lscat - Lscat * Tr) / extinction;
|
||||
}
|
||||
|
||||
#define P(x) ((x + 0.5f) * (1.0f / 16.0f))
|
||||
|
||||
float4 volume_integration([[resource_table]] Resources &srt,
|
||||
float4 frag_coord,
|
||||
float3 ray_ori,
|
||||
|
|
@ -281,10 +269,10 @@ float4 volume_integration([[resource_table]] Resources &srt,
|
|||
{
|
||||
/* NOTE: Constant array declared inside function scope to reduce shader core thread memory
|
||||
* pressure on Apple Silicon. */
|
||||
constexpr float4 dither_mat[4] = {float4(P(0.0f), P(8.0f), P(2.0f), P(10.0f)),
|
||||
float4(P(12.0f), P(4.0f), P(14.0f), P(6.0f)),
|
||||
float4(P(3.0f), P(11.0f), P(1.0f), P(9.0f)),
|
||||
float4(P(15.0f), P(7.0f), P(13.0f), P(5.0f))};
|
||||
const float4 dither_mat[4] = {(float4(0.0f, 8.0f, 2.0f, 10.0f) + 0.5f) / 16.0f,
|
||||
(float4(12.0f, 4.0f, 14.0f, 6.0f) + 0.5f) / 16.0f,
|
||||
(float4(3.0f, 11.0f, 1.0f, 9.0f) + 0.5f) / 16.0f,
|
||||
(float4(15.0f, 7.0f, 13.0f, 5.0f) + 0.5f) / 16.0f};
|
||||
/* Start with full transmittance and no scattered light. */
|
||||
float3 final_scattering = float3(0.0f);
|
||||
float final_transmittance = 1.0f;
|
||||
|
|
@ -318,18 +306,29 @@ struct VertIn {
|
|||
[[attribute(0)]] float3 pos;
|
||||
};
|
||||
|
||||
struct ResourceIDOut {
|
||||
[[flat]] uint id;
|
||||
};
|
||||
|
||||
struct VertOut {
|
||||
[[smooth]] float3 local_pos;
|
||||
};
|
||||
|
||||
[[vertex]] void vertex_function([[resource_table]] Resources &srt,
|
||||
[[resource_table]] draw::Resource &ids,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table, condition(is_legacy_smoke)]] draw::Infos &infos,
|
||||
[[instance_index]] const int inst_index,
|
||||
[[in]] const VertIn &v_in,
|
||||
[[out]] ResourceIDOut &res_id_out,
|
||||
[[out, condition(use_slice)]] VertOut &v_out,
|
||||
[[position]] float4 &out_position)
|
||||
{
|
||||
SHADER_LIBRARY_CREATE_INFO(draw_resource_id_varying);
|
||||
res_id_out.id = ids.get(inst_index).resource_id<1>();
|
||||
|
||||
drw_ResourceID_iface.resource_id = drw_resource_id_raw();
|
||||
ObjectMatrices model = models.get(res_id_out.id);
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
float3 final_pos;
|
||||
|
||||
|
|
@ -350,24 +349,29 @@ struct VertOut {
|
|||
}
|
||||
|
||||
if (srt.is_legacy_smoke) [[static_branch]] {
|
||||
ObjectInfos info = drw_object_infos();
|
||||
ObjectInfos info = infos.get(res_id_out.id);
|
||||
final_pos = ((final_pos * 0.5f + 0.5f) - info.orco_add) / info.orco_mul;
|
||||
}
|
||||
else {
|
||||
[[resource_table]] Volume &volume = srt.volume;
|
||||
final_pos = (volume.volume_texture_to_object * float4(final_pos * 0.5f + 0.5f, 1.0f)).xyz;
|
||||
}
|
||||
out_position = drw_point_world_to_homogenous(drw_point_object_to_world(final_pos));
|
||||
out_position = view.point_world_to_homogenous(model.point_object_to_world(final_pos));
|
||||
}
|
||||
|
||||
struct FragOut {
|
||||
[[frag_color(0)]] float4 color;
|
||||
};
|
||||
|
||||
[[fragment]] void fragment_function([[resource_table]] Resources &srt,
|
||||
[[frag_coord]] const float4 &frag_coord,
|
||||
[[in, condition(use_slice)]] const VertOut &v_out,
|
||||
[[out]] FragOut &frag_out)
|
||||
[[fragment]] void fragment_function(
|
||||
[[resource_table]] Resources &srt,
|
||||
[[resource_table]] draw::View &views,
|
||||
[[resource_table]] draw::Model &models,
|
||||
[[resource_table]] [[condition(is_legacy_smoke)]] draw::Infos &infos,
|
||||
[[frag_coord]] const float4 &frag_coord,
|
||||
[[in]] const ResourceIDOut &res_id,
|
||||
[[in, condition(use_slice)]] const VertOut &v_out,
|
||||
[[out]] FragOut &frag_out)
|
||||
{
|
||||
uint stencil = texelFetch(srt.stencil_tx, int2(frag_coord.xy), 0).r;
|
||||
|
||||
|
|
@ -378,6 +382,9 @@ struct FragOut {
|
|||
return;
|
||||
}
|
||||
|
||||
ObjectMatrices model = models.get(res_id.id);
|
||||
ViewMatrices view = views.get(0);
|
||||
|
||||
if (srt.use_slice) [[static_branch]] {
|
||||
/* Manual depth test. TODO: remove. */
|
||||
float depth = texelFetch(srt.depth_buffer, int2(frag_coord.xy), 0).r;
|
||||
|
|
@ -402,24 +409,25 @@ struct FragOut {
|
|||
}
|
||||
else {
|
||||
float2 screen_uv = frag_coord.xy / float2(textureSize(srt.depth_buffer, 0).xy);
|
||||
bool is_persp = drw_view().winmat[3][3] == 0.0f;
|
||||
bool is_persp = view.winmat[3][3] == 0.0f;
|
||||
|
||||
float depth = srt.do_depth_test ? texelFetch(srt.depth_buffer, int2(frag_coord.xy), 0).r :
|
||||
1.0f;
|
||||
float depth_end = min(depth, frag_coord.z);
|
||||
float3 vs_ray_end = drw_point_screen_to_view(float3(screen_uv, depth_end));
|
||||
float3 vs_ray_ori = drw_point_screen_to_view(float3(screen_uv, 0.0f));
|
||||
float3 vs_ray_end = view.point_screen_to_view(float3(screen_uv, depth_end));
|
||||
float3 vs_ray_ori = view.point_screen_to_view(float3(screen_uv, 0.0f));
|
||||
float3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : float3(0.0f, 0.0f, -1.0f);
|
||||
vs_ray_dir /= abs(vs_ray_dir.z);
|
||||
|
||||
float3 ls_ray_dir = drw_point_view_to_object(vs_ray_ori + vs_ray_dir);
|
||||
float3 ls_ray_ori = drw_point_view_to_object(vs_ray_ori);
|
||||
float3 ls_ray_end = drw_point_view_to_object(vs_ray_end);
|
||||
float3 ls_ray_dir = model.point_view_to_object(view, vs_ray_ori + vs_ray_dir);
|
||||
float3 ls_ray_ori = model.point_view_to_object(view, vs_ray_ori);
|
||||
float3 ls_ray_end = model.point_view_to_object(view, vs_ray_end);
|
||||
|
||||
if (srt.is_legacy_smoke) [[static_branch]] {
|
||||
ls_ray_dir = (drw_object_orco(ls_ray_dir)) * 2.0f - 1.0f;
|
||||
ls_ray_ori = (drw_object_orco(ls_ray_ori)) * 2.0f - 1.0f;
|
||||
ls_ray_end = (drw_object_orco(ls_ray_end)) * 2.0f - 1.0f;
|
||||
ObjectInfos ob_infos = infos.get(res_id.id);
|
||||
ls_ray_dir = (ob_infos.orco_mul * ls_ray_dir + ob_infos.orco_add) * 2.0f - 1.0f;
|
||||
ls_ray_ori = (ob_infos.orco_mul * ls_ray_ori + ob_infos.orco_add) * 2.0f - 1.0f;
|
||||
ls_ray_end = (ob_infos.orco_mul * ls_ray_end + ob_infos.orco_add) * 2.0f - 1.0f;
|
||||
}
|
||||
else {
|
||||
[[resource_table]] Volume &volume = srt.volume;
|
||||
|
|
|
|||
|
|
@ -1,151 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2018-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "infos/workbench_prepass_infos.hh"
|
||||
|
||||
#ifdef GPU_LIBRARY_SHADER
|
||||
SHADER_LIBRARY_CREATE_INFO(workbench_prepass)
|
||||
#endif
|
||||
|
||||
/* [Drobot2014a] Low Level Optimizations for GCN */
|
||||
float4 fast_rcp(float4 v)
|
||||
{
|
||||
return intBitsToFloat(0x7eef370b - floatBitsToInt(v));
|
||||
}
|
||||
|
||||
float3 brdf_approx(float3 spec_color, float roughness, float NV)
|
||||
{
|
||||
/* Very rough approximation. We don't need it to be correct, just fast.
|
||||
* Just simulate fresnel effect with roughness attenuation. */
|
||||
float fresnel = exp2(-8.35f * NV) * (1.0f - roughness);
|
||||
return mix(spec_color, float3(1.0f), fresnel);
|
||||
}
|
||||
|
||||
void prep_specular(
|
||||
float3 L, float3 I, float3 N, float3 R, float &NL, float &wrapped_NL, float &spec_angle)
|
||||
{
|
||||
wrapped_NL = dot(L, R);
|
||||
float3 half_dir = normalize(L + I);
|
||||
spec_angle = clamp(dot(half_dir, N), 0.0f, 1.0f);
|
||||
NL = clamp(dot(L, N), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/* Normalized Blinn shading */
|
||||
float4 blinn_specular(float4 shininess, float4 spec_angle, float4 NL)
|
||||
{
|
||||
/* Pi is already divided in the light power.
|
||||
* normalization_factor = (shininess + 8.0f) / (8.0f * M_PI) */
|
||||
float4 normalization_factor = shininess * 0.125f + 1.0f;
|
||||
float4 spec_light = pow(spec_angle, shininess) * NL * normalization_factor;
|
||||
|
||||
return spec_light;
|
||||
}
|
||||
|
||||
/* NL need to be unclamped. w in [0..1] range. */
|
||||
float4 wrapped_lighting(float4 NL, float4 w)
|
||||
{
|
||||
float4 w_1 = w + 1.0f;
|
||||
float4 denom = fast_rcp(w_1 * w_1);
|
||||
return clamp((NL + w) * denom, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
float3 get_world_lighting(float3 base_color, float roughness, float metallic, float3 N, float3 I)
|
||||
{
|
||||
float3 specular_color, diffuse_color;
|
||||
|
||||
if (world_data.use_specular) {
|
||||
diffuse_color = mix(base_color, float3(0.0f), metallic);
|
||||
specular_color = mix(float3(0.05f), base_color, metallic);
|
||||
}
|
||||
else {
|
||||
diffuse_color = base_color;
|
||||
specular_color = float3(0.0f);
|
||||
}
|
||||
|
||||
float3 specular_light = world_data.ambient_color.rgb;
|
||||
float3 diffuse_light = world_data.ambient_color.rgb;
|
||||
float4 wrap = float4(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);
|
||||
|
||||
if (world_data.use_specular) {
|
||||
/* Prepare Specular computation. Eval 4 lights at once. */
|
||||
float3 R = -reflect(I, N);
|
||||
|
||||
#ifdef GPU_METAL
|
||||
/* Split vectors into arrays of floats. Partial vector references are unsupported by MSL. */
|
||||
float spec_angle[4], spec_NL[4], wrap_NL[4];
|
||||
# define AS_VEC4(a) float4(a[0], a[1], a[2], a[3])
|
||||
#else
|
||||
float4 spec_angle, spec_NL, wrap_NL;
|
||||
# define AS_VEC4(a) a
|
||||
#endif
|
||||
prep_specular(
|
||||
world_data.lights[0].direction.xyz, I, N, R, spec_NL[0], wrap_NL[0], spec_angle[0]);
|
||||
prep_specular(
|
||||
world_data.lights[1].direction.xyz, I, N, R, spec_NL[1], wrap_NL[1], spec_angle[1]);
|
||||
prep_specular(
|
||||
world_data.lights[2].direction.xyz, I, N, R, spec_NL[2], wrap_NL[2], spec_angle[2]);
|
||||
prep_specular(
|
||||
world_data.lights[3].direction.xyz, I, N, R, spec_NL[3], wrap_NL[3], spec_angle[3]);
|
||||
|
||||
float4 gloss = float4(1.0f - roughness);
|
||||
/* Reduce gloss for smooth light. (simulate bigger light) */
|
||||
gloss *= 1.0f - wrap;
|
||||
float4 shininess = exp2(10.0f * gloss + 1.0f);
|
||||
|
||||
float4 spec_light = blinn_specular(shininess, AS_VEC4(spec_angle), AS_VEC4(spec_NL));
|
||||
|
||||
/* Simulate Env. light. */
|
||||
float4 w = mix(wrap, float4(1.0f), roughness);
|
||||
float4 spec_env = wrapped_lighting(AS_VEC4(wrap_NL), w);
|
||||
#undef AS_VEC4
|
||||
|
||||
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.0f, 1.0f);
|
||||
specular_color = brdf_approx(specular_color, roughness, NV);
|
||||
}
|
||||
specular_light *= specular_color;
|
||||
|
||||
/* Prepare diffuse computation. Eval 4 lights at once. */
|
||||
float4 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);
|
||||
|
||||
float4 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;
|
||||
|
||||
/* Energy conservation with colored specular look strange.
|
||||
* Limit this strangeness by using mono-chromatic specular intensity. */
|
||||
float spec_energy = dot(specular_color, float3(0.33333f));
|
||||
|
||||
diffuse_light *= diffuse_color * (1.0f - spec_energy);
|
||||
|
||||
return diffuse_light + specular_light;
|
||||
}
|
||||
|
||||
float get_shadow(float3 N, bool force_shadow)
|
||||
{
|
||||
float light_factor = -dot(N, world_data.shadow_direction_vs.xyz);
|
||||
float shadow_mix = smoothstep(world_data.shadow_shift, world_data.shadow_focus, light_factor);
|
||||
shadow_mix *= force_shadow ? 0.0f : world_data.shadow_mul;
|
||||
return shadow_mix + world_data.shadow_add;
|
||||
}
|
||||
|
|
@ -24,3 +24,7 @@
|
|||
/* UBOs (Storage buffers in Workbench Next). */
|
||||
#define WB_MATERIAL_SLOT 0
|
||||
#define WB_WORLD_SLOT 1
|
||||
|
||||
[[maybe_unused]] static constexpr int WORKBENCH_LIGHTING_STUDIO = 0;
|
||||
[[maybe_unused]] static constexpr int WORKBENCH_LIGHTING_MATCAP = 1;
|
||||
[[maybe_unused]] static constexpr int WORKBENCH_LIGHTING_FLAT = 2;
|
||||
|
|
|
|||
|
|
@ -186,7 +186,10 @@ int main(int argc, char **argv)
|
|||
if (/* Add non-ported files here. */
|
||||
filename.ends_with("gpu_shader_material_radial_tiling.bsl.hh") ||
|
||||
filename.ends_with("gpu_shader_material_tex_voronoi.bsl.hh") ||
|
||||
/* Need new compiler to have support for raytracing API. */
|
||||
filename.ends_with("workbench_shadow_raytrace.bsl.hh") ||
|
||||
(filename.find("gpu/shaders/") == std::string::npos &&
|
||||
filename.find("workbench/shaders/") == std::string::npos &&
|
||||
filename.find("eevee/shaders/") == std::string::npos))
|
||||
{
|
||||
language = Language::BLENDER_GLSL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue