Gizmo: press shift key to scale area lights uniformly #104418

Closed
Weizhen Huang wants to merge 13 commits from weizhen:shift_uniform_scale into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
15 changed files with 226 additions and 299 deletions
Showing only changes of commit c5253309da - Show all commits

View File

@ -105,7 +105,7 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height)
/* Bind shader now to enable uniform assignment. */
GPU_shader_bind(shader_program_);
float slot = 0;
int slot = 0;
GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot);
float size[2];
size[0] = width;

View File

@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
{
/* Special trick for fast navigation: schedule multiple samples during fast navigation
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
* usable visual feedback for artists. There are a couple of tricks though. */
* usable visual feedback for artists. */
if (is_denoise_active_during_update()) {
/* When denoising is used during navigation prefer using a higher resolution with less samples
@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
return 1;
}
if (resolution_divider <= pixel_size_) {
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
* the sample count at this resolution division, but instead assists in the calculation of
* the resolution divider. */
return 1;
}
if (resolution_divider == pixel_size_ * 2) {
/* When resolution divider is the previous step to the final resolution, schedule two samples.
* This is so that rendering on lower resolution does not exceed time that it takes to render
* first sample at the full resolution. */
return 2;
}
/* Always render 4 samples, even if scene is configured for less.
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
* at one sample. */
return 4;
/* Schedule samples equal to the resolution divider up to a maximum of 4.
* The idea is to have enough information on the screen by increasing the sample count as the
* resolution is decreased. */
/* NOTE: Changeing this formula will change the formula in
* "RenderScheduler::calculate_resolution_divider_for_time()"*/
return min(max(1, resolution_divider / pixel_size_), 4);
}
bool RenderScheduler::work_need_adaptive_filter() const
@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
* render time is somewhere on a boundary between two resolutions. */
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
* simple and compute device is fast). */
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
* unreadable viewport render. */
start_resolution_divider_ = min(resolution_divider_for_update,
default_start_resolution_divider_);
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
}
@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
{
/* TODO(sergey): There should a non-iterative analytical formula here. */
const double ratio_between_times = actual_time / desired_time;
int resolution_divider = 1;
/* We can pass "ratio_between_times" to "get_num_samples_during_navigation()" to get our
* navigation samples because the equation for calculating the resolution divider is as follows:
* "actual_time / desired_time = sqr(resolution_divider) / sample_count".
* While "resolution_divider" is less than or equal to 4, "resolution_divider = sample_count"
* (This relationship is determined in "get_num_samples_during_navigation()"). With some
* substitution we end up with "actual_time / desired_time = resolution_divider" while the
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
* the relationsip of "actual_time / desired_time = resolution_divider" is no longer true,
* however the sample count retrieved from "get_num_samples_during_navigation()" is still
* accurate if we continue using this assumption. It should be noted that the interaction between
* pixel_size, sample count, and resolution divider are automatically accounted for and that's
* why pixel_size isn't included in any of the equations. */
const int navigation_samples = get_num_samples_during_navigation(
ceil_to_int(ratio_between_times));
/* This algorithm iterates through resolution dividers until a divider is found that achieves
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
* pre_resolution_division_samples and post_resolution_division_samples are used in this
* calculation to better predict the performance impact of changing resolution divisions as
* the sample count can also change between resolution divisions. */
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
resolution_divider = resolution_divider * 2;
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
}
return resolution_divider;
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
}
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)

View File

@ -23,11 +23,15 @@ struct ID;
namespace blender::asset_system {
class AssetLibrary;
class AssetRepresentation {
AssetIdentifier identifier_;
/** Indicate if this is a local or external asset, and as such, which of the union members below
* should be used. */
const bool is_local_id_ = false;
/** Asset library that owns this asset representation. */
const AssetLibrary *owner_asset_library_;
struct ExternalAsset {
std::string name;
@ -44,10 +48,13 @@ class AssetRepresentation {
/** Constructs an asset representation for an external ID. The asset will not be editable. */
AssetRepresentation(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata);
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
* local and fully editable. */
AssetRepresentation(AssetIdentifier &&identifier, ID &id);
AssetRepresentation(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library);
AssetRepresentation(AssetRepresentation &&other);
/* Non-copyable type. */
AssetRepresentation(const AssetRepresentation &other) = delete;
@ -65,6 +72,7 @@ class AssetRepresentation {
AssetMetaData &get_metadata() const;
/** Returns if this asset is stored inside this current file, and as such fully editable. */
bool is_local_id() const;
const AssetLibrary &owner_asset_library() const;
};
} // namespace blender::asset_system

View File

@ -169,13 +169,14 @@ AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_p
std::unique_ptr<AssetMetaData> metadata)
{
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
return asset_storage_->add_external_asset(std::move(identifier), name, std::move(metadata));
return asset_storage_->add_external_asset(
std::move(identifier), name, std::move(metadata), *this);
}
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
{
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
return asset_storage_->add_local_id_asset(std::move(identifier), id);
return asset_storage_->add_local_id_asset(std::move(identifier), id, *this);
}
bool AssetLibrary::remove_asset(AssetRepresentation &asset)

View File

@ -17,15 +17,24 @@ namespace blender::asset_system {
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata)
: identifier_(identifier), is_local_id_(false), external_asset_()
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
is_local_id_(false),
owner_asset_library_(&owner_asset_library),
external_asset_()
{
external_asset_.name = name;
external_asset_.metadata_ = std::move(metadata);
}
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, ID &id)
: identifier_(identifier), is_local_id_(true), local_asset_id_(&id)
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
is_local_id_(true),
owner_asset_library_(&owner_asset_library),
local_asset_id_(&id)
{
if (!id.asset_data) {
throw std::invalid_argument("Passed ID is not an asset");
@ -75,6 +84,11 @@ bool AssetRepresentation::is_local_id() const
return is_local_id_;
}
const AssetLibrary &AssetRepresentation::owner_asset_library() const
{
return *owner_asset_library_;
}
} // namespace blender::asset_system
using namespace blender;

View File

@ -15,18 +15,21 @@
namespace blender::asset_system {
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, ID &id)
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library)
{
return *local_id_assets_.lookup_key_or_add(
std::make_unique<AssetRepresentation>(std::move(identifier), id));
std::make_unique<AssetRepresentation>(std::move(identifier), id, owner_asset_library));
}
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata)
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
{
return *external_assets_.lookup_key_or_add(
std::make_unique<AssetRepresentation>(std::move(identifier), name, std::move(metadata)));
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
std::move(identifier), name, std::move(metadata), owner_asset_library));
}
bool AssetStorage::remove_asset(AssetRepresentation &asset)

View File

@ -35,9 +35,12 @@ class AssetStorage {
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata);
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, ID &id);
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library);
/** See #AssetLibrary::remove_asset(). */
bool remove_asset(AssetRepresentation &asset);

View File

@ -97,8 +97,9 @@ MINLINE float saacos(float fac);
MINLINE float saasin(float fac);
MINLINE float sasqrt(float fac);
MINLINE float interpf(float a, float b, float t);
MINLINE double interpd(double a, double b, double t);
/* Compute linear interpolation (lerp) between origin and target. */
MINLINE float interpf(float target, float origin, float t);
MINLINE double interpd(double target, double origin, double t);
MINLINE float ratiof(float min, float max, float pos);
MINLINE double ratiod(double min, double max, double pos);

View File

@ -612,6 +612,25 @@ TEST(string, StrFormatIntegerUnits)
EXPECT_STREQ("-2B", size_str);
}
TEST(string, StringNLen)
{
EXPECT_EQ(0, BLI_strnlen("", 0));
EXPECT_EQ(0, BLI_strnlen("", 1));
EXPECT_EQ(0, BLI_strnlen("", 100));
EXPECT_EQ(0, BLI_strnlen("x", 0));
EXPECT_EQ(1, BLI_strnlen("x", 1));
EXPECT_EQ(1, BLI_strnlen("x", 100));
// ü is \xc3\xbc
EXPECT_EQ(2, BLI_strnlen("ü", 100));
EXPECT_EQ(0, BLI_strnlen("this is a longer string", 0));
EXPECT_EQ(1, BLI_strnlen("this is a longer string", 1));
EXPECT_EQ(5, BLI_strnlen("this is a longer string", 5));
EXPECT_EQ(47, BLI_strnlen("This string writes about an agent without name.", 100));
}
struct WordInfo {
WordInfo() = default;
WordInfo(int start, int end) : start(start), end(end)

View File

@ -409,7 +409,7 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
/* Offset in tiles from the origin to the center of the first tile-maps. */
int2 origin_offset = int2(round(float2(near_point) / tile_size));
/* Offset in tiles between the first andlod the last tile-maps. */
/* Offset in tiles between the first and the last tile-maps. */
int2 offset_vector = int2(round(farthest_tilemap_center / tile_size));
light.clipmap_base_offset = (offset_vector * (1 << 16)) / max_ii(levels_range.size() - 1, 1);

View File

@ -793,21 +793,19 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
if (curves.points_num() == 0) {
continue;
}
const GVArray src = attributes.lookup(".selection", domain);
if (src.is_empty()) {
continue;
}
const CPPType &type = src.type();
void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__);
src.materialize(dst);
if (const GVArray src = attributes.lookup(".selection", domain)) {
const CPPType &type = src.type();
void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__);
src.materialize(dst);
attributes.remove(".selection");
if (!attributes.add(".selection",
domain,
bke::cpp_type_to_custom_data_type(type),
bke::AttributeInitMoveArray(dst))) {
MEM_freeN(dst);
attributes.remove(".selection");
if (!attributes.add(".selection",
domain,
bke::cpp_type_to_custom_data_type(type),
bke::AttributeInitMoveArray(dst))) {
MEM_freeN(dst);
}
}
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic

View File

@ -1171,12 +1171,9 @@ static int gizmo_cage2d_modal(bContext *C,
}
}
if (delta_orig < 0) {
scale[i] = -delta_curr / (pivot[i] + 0.5f);
}
else {
scale[i] = delta_curr / (0.5f - pivot[i]);
}
/* Original cursor position does not exactly lie on the cage boundary due to margin. */
const float delta_boundary = signf(delta_orig) * 0.5f - pivot[i];
scale[i] = delta_curr / delta_boundary;
}
}

View File

@ -539,12 +539,9 @@ static int gizmo_cage3d_modal(bContext *C,
}
}
if (delta_orig < 0) {
scale[i] = -delta_curr / (pivot[i] + 0.5f);
}
else {
scale[i] = delta_curr / (0.5f - pivot[i]);
}
/* Original cursor position does not exactly lie on the cage boundary due to margin. */
const float delta_boundary = signf(delta_orig) * 0.5f - pivot[i];
scale[i] = delta_curr / delta_boundary;
}
}

View File

@ -49,12 +49,17 @@
#include "eyedropper_intern.hh"
#include "interface_intern.hh"
typedef enum eGP_EyeMode {
GP_EYE_MATERIAL = 0,
GP_EYE_PALETTE = 1,
} eGP_EyeMode;
struct EyedropperGPencil {
struct ColorManagedDisplay *display;
/** color under cursor RGB */
float color[3];
/** Mode */
int mode;
eGP_EyeMode mode;
};
/* Helper: Draw status message while the user is running the operator */
@ -79,7 +84,7 @@ static bool eyedropper_gpencil_init(bContext *C, wmOperator *op)
display_device = scene->display_settings.display_device;
eye->display = IMB_colormanagement_display_get_named(display_device);
eye->mode = RNA_enum_get(op->ptr, "mode");
eye->mode = (eGP_EyeMode)RNA_enum_get(op->ptr, "mode");
return true;
}
@ -228,10 +233,10 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed
float col_conv[4];
/* Convert from linear rgb space to display space because grease pencil colors are in display
/* Convert from linear rgb space to display space because palette colors are in display
* space, and this conversion is needed to undo the conversion to linear performed by
* eyedropper_color_sample_fl. */
if (eye->display) {
if ((eye->display) && (eye->mode == GP_EYE_PALETTE)) {
copy_v3_v3(col_conv, eye->color);
IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
}
@ -240,7 +245,7 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed
}
/* Add material or Palette color. */
if (eye->mode == 0) {
if (eye->mode == GP_EYE_MATERIAL) {
eyedropper_add_material(C, col_conv, only_stroke, only_fill, both);
}
else {
@ -348,8 +353,8 @@ static bool eyedropper_gpencil_poll(bContext *C)
void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot)
{
static const EnumPropertyItem items_mode[] = {
{0, "MATERIAL", 0, "Material", ""},
{1, "PALETTE", 0, "Palette", ""},
{GP_EYE_MATERIAL, "MATERIAL", 0, "Material", ""},
{GP_EYE_PALETTE, "PALETTE", 0, "Palette", ""},
{0, nullptr, 0, nullptr, nullptr},
};
@ -369,5 +374,5 @@ void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
/* properties */
ot->prop = RNA_def_enum(ot->srna, "mode", items_mode, 0, "Mode", "");
ot->prop = RNA_def_enum(ot->srna, "mode", items_mode, GP_EYE_MATERIAL, "Mode", "");
}

View File

@ -12,205 +12,105 @@
/* Cache of built-in shaders (each is created on first use). */
static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {{nullptr}};
typedef struct {
const char *name;
const char *create_info;
/** Optional. */
const char *clipped_create_info;
} GPUShaderStages;
static const char *builtin_shader_create_info_name(eGPUBuiltinShader shader)
{
switch (shader) {
case GPU_SHADER_TEXT:
return "gpu_shader_text";
case GPU_SHADER_KEYFRAME_SHAPE:
return "gpu_shader_keyframe_shape";
case GPU_SHADER_SIMPLE_LIGHTING:
return "gpu_shader_simple_lighting";
case GPU_SHADER_3D_IMAGE:
return "gpu_shader_3D_image";
case GPU_SHADER_3D_IMAGE_COLOR:
return "gpu_shader_3D_image_color";
case GPU_SHADER_2D_CHECKER:
return "gpu_shader_2D_checker";
case GPU_SHADER_2D_DIAG_STRIPES:
return "gpu_shader_2D_diag_stripes";
case GPU_SHADER_ICON:
return "gpu_shader_icon";
case GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE:
return "gpu_shader_2D_image_overlays_merge";
case GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE:
return "gpu_shader_2D_image_overlays_stereo_merge";
case GPU_SHADER_2D_IMAGE_DESATURATE_COLOR:
return "gpu_shader_2D_image_desaturate_color";
case GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR:
return "gpu_shader_2D_image_shuffle_color";
case GPU_SHADER_2D_IMAGE_RECT_COLOR:
return "gpu_shader_2D_image_rect_color";
case GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR:
return "gpu_shader_2D_image_multi_rect_color";
case GPU_SHADER_3D_UNIFORM_COLOR:
return "gpu_shader_3D_uniform_color";
case GPU_SHADER_3D_FLAT_COLOR:
return "gpu_shader_3D_flat_color";
case GPU_SHADER_3D_SMOOTH_COLOR:
return "gpu_shader_3D_smooth_color";
case GPU_SHADER_3D_DEPTH_ONLY:
return "gpu_shader_3D_depth_only";
case GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR:
return "gpu_shader_3D_clipped_uniform_color";
case GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR:
return "gpu_shader_3D_polyline_uniform_color";
case GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR:
return "gpu_shader_3D_polyline_uniform_color_clipped";
case GPU_SHADER_3D_POLYLINE_FLAT_COLOR:
return "gpu_shader_3D_polyline_flat_color";
case GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR:
return "gpu_shader_3D_polyline_smooth_color";
case GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR:
return "gpu_shader_3D_line_dashed_uniform_color";
case GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA:
return "gpu_shader_2D_point_uniform_size_uniform_color_aa";
case GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA:
return "gpu_shader_2D_point_uniform_size_uniform_color_outline_aa";
case GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR:
return "gpu_shader_3D_point_varying_size_varying_color";
case GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA:
return "gpu_shader_3D_point_uniform_size_uniform_color_aa";
case GPU_SHADER_2D_AREA_BORDERS:
return "gpu_shader_2D_area_borders";
case GPU_SHADER_2D_WIDGET_BASE:
return "gpu_shader_2D_widget_base";
case GPU_SHADER_2D_WIDGET_BASE_INST:
return "gpu_shader_2D_widget_base_inst";
case GPU_SHADER_2D_WIDGET_SHADOW:
return "gpu_shader_2D_widget_shadow";
case GPU_SHADER_2D_NODELINK:
return "gpu_shader_2D_nodelink";
case GPU_SHADER_2D_NODELINK_INST:
return "gpu_shader_2D_nodelink_inst";
case GPU_SHADER_GPENCIL_STROKE:
return "gpu_shader_gpencil_stroke";
default:
BLI_assert_unreachable();
return "";
}
}
static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
[GPU_SHADER_TEXT] =
{
.name = "GPU_SHADER_TEXT",
.create_info = "gpu_shader_text",
},
[GPU_SHADER_KEYFRAME_SHAPE] =
{
.name = "GPU_SHADER_KEYFRAME_SHAPE",
.create_info = "gpu_shader_keyframe_shape",
},
[GPU_SHADER_SIMPLE_LIGHTING] =
{
.name = "GPU_SHADER_SIMPLE_LIGHTING",
.create_info = "gpu_shader_simple_lighting",
},
[GPU_SHADER_3D_IMAGE] =
{
.name = "GPU_SHADER_3D_IMAGE",
.create_info = "gpu_shader_3D_image",
},
[GPU_SHADER_3D_IMAGE_COLOR] =
{
.name = "GPU_SHADER_3D_IMAGE_COLOR",
.create_info = "gpu_shader_3D_image_color",
},
[GPU_SHADER_2D_CHECKER] =
{
.name = "GPU_SHADER_2D_CHECKER",
.create_info = "gpu_shader_2D_checker",
},
[GPU_SHADER_2D_DIAG_STRIPES] =
{
.name = "GPU_SHADER_2D_DIAG_STRIPES",
.create_info = "gpu_shader_2D_diag_stripes",
},
[GPU_SHADER_ICON] =
{
.name = "GPU_SHADER_ICON",
.create_info = "gpu_shader_icon",
},
[GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] =
{
.name = "GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE",
.create_info = "gpu_shader_2D_image_overlays_merge",
},
[GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE] =
{
.name = "GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE",
.create_info = "gpu_shader_2D_image_overlays_stereo_merge",
},
[GPU_SHADER_2D_IMAGE_DESATURATE_COLOR] =
{
.name = "GPU_SHADER_2D_IMAGE_DESATURATE_COLOR",
.create_info = "gpu_shader_2D_image_desaturate_color",
},
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] =
{
.name = "GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR",
.create_info = "gpu_shader_2D_image_shuffle_color",
},
[GPU_SHADER_2D_IMAGE_RECT_COLOR] =
{
.name = "GPU_SHADER_2D_IMAGE_RECT_COLOR",
.create_info = "gpu_shader_2D_image_rect_color",
},
[GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR] =
{
.name = "GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR",
.create_info = "gpu_shader_2D_image_multi_rect_color",
},
[GPU_SHADER_3D_UNIFORM_COLOR] =
{
.name = "GPU_SHADER_3D_UNIFORM_COLOR",
.create_info = "gpu_shader_3D_uniform_color",
.clipped_create_info = "gpu_shader_3D_uniform_color_clipped",
},
[GPU_SHADER_3D_FLAT_COLOR] =
{
.name = "GPU_SHADER_3D_FLAT_COLOR",
.create_info = "gpu_shader_3D_flat_color",
.clipped_create_info = "gpu_shader_3D_flat_color_clipped",
},
[GPU_SHADER_3D_SMOOTH_COLOR] =
{
.name = "GPU_SHADER_3D_SMOOTH_COLOR",
.create_info = "gpu_shader_3D_smooth_color",
.clipped_create_info = "gpu_shader_3D_smooth_color_clipped",
},
[GPU_SHADER_3D_DEPTH_ONLY] =
{
.name = "GPU_SHADER_3D_DEPTH_ONLY",
.create_info = "gpu_shader_3D_depth_only",
.clipped_create_info = "gpu_shader_3D_depth_only_clipped",
},
[GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] =
{
.name = "GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR",
.create_info = "gpu_shader_3D_clipped_uniform_color",
},
[GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR] =
{
.name = "GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR",
.create_info = "gpu_shader_3D_polyline_uniform_color",
},
[GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR] =
{
.name = "GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR",
.create_info = "gpu_shader_3D_polyline_uniform_color_clipped",
},
[GPU_SHADER_3D_POLYLINE_FLAT_COLOR] =
{
.name = "GPU_SHADER_3D_POLYLINE_FLAT_COLOR",
.create_info = "gpu_shader_3D_polyline_flat_color",
},
[GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR] =
{
.name = "GPU_SHADER_3D_POLYLINE_SMOOTH_COLOR",
.create_info = "gpu_shader_3D_polyline_smooth_color",
},
[GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR] =
{
.name = "GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR",
.create_info = "gpu_shader_3D_line_dashed_uniform_color",
.clipped_create_info = "gpu_shader_3D_line_dashed_uniform_color_clipped",
},
[GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
{
.name = "GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA",
.create_info = "gpu_shader_2D_point_uniform_size_uniform_color_aa",
},
[GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA] =
{
.name = "GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA",
.create_info = "gpu_shader_2D_point_uniform_size_uniform_color_outline_aa",
},
[GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR] =
{
.name = "GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR",
.create_info = "gpu_shader_3D_point_varying_size_varying_color",
},
[GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA] =
{
.name = "GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA",
.create_info = "gpu_shader_3D_point_uniform_size_uniform_color_aa",
.clipped_create_info = "gpu_shader_3D_point_uniform_size_uniform_color_aa_clipped",
},
[GPU_SHADER_2D_AREA_BORDERS] =
{
.name = "GPU_SHADER_2D_AREA_BORDERS",
.create_info = "gpu_shader_2D_area_borders",
},
[GPU_SHADER_2D_WIDGET_BASE] =
{
.name = "GPU_SHADER_2D_WIDGET_BASE",
.create_info = "gpu_shader_2D_widget_base",
},
[GPU_SHADER_2D_WIDGET_BASE_INST] =
{
.name = "GPU_SHADER_2D_WIDGET_BASE_INST",
.create_info = "gpu_shader_2D_widget_base_inst",
},
[GPU_SHADER_2D_WIDGET_SHADOW] =
{
.name = "GPU_SHADER_2D_WIDGET_SHADOW",
.create_info = "gpu_shader_2D_widget_shadow",
},
[GPU_SHADER_2D_NODELINK] =
{
.name = "GPU_SHADER_2D_NODELINK",
.create_info = "gpu_shader_2D_nodelink",
},
[GPU_SHADER_2D_NODELINK_INST] =
{
.name = "GPU_SHADER_2D_NODELINK_INST",
.create_info = "gpu_shader_2D_nodelink_inst",
},
[GPU_SHADER_GPENCIL_STROKE] =
{
.name = "GPU_SHADER_GPENCIL_STROKE",
.create_info = "gpu_shader_gpencil_stroke",
},
};
static const char *builtin_shader_create_info_name_clipped(eGPUBuiltinShader shader)
{
switch (shader) {
case GPU_SHADER_3D_UNIFORM_COLOR:
return "gpu_shader_3D_uniform_color_clipped";
case GPU_SHADER_3D_FLAT_COLOR:
return "gpu_shader_3D_flat_color_clipped";
case GPU_SHADER_3D_SMOOTH_COLOR:
return "gpu_shader_3D_smooth_color_clipped";
case GPU_SHADER_3D_DEPTH_ONLY:
return "gpu_shader_3D_depth_only_clipped";
case GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR:
return "gpu_shader_3D_line_dashed_uniform_color_clipped";
case GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA:
return "gpu_shader_3D_point_uniform_size_uniform_color_aa_clipped";
default:
BLI_assert_unreachable();
return "";
}
}
GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
eGPUShaderConfig sh_cfg)
@ -220,11 +120,9 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
GPUShader **sh_p = &builtin_shaders[sh_cfg][shader];
if (*sh_p == nullptr) {
const GPUShaderStages *stages = &builtin_shader_stages[shader];
/* common case */
if (sh_cfg == GPU_SHADER_CFG_DEFAULT) {
*sh_p = GPU_shader_create_from_info_name(stages->create_info);
/* Common case. */
*sh_p = GPU_shader_create_from_info_name(builtin_shader_create_info_name(shader));
if (ELEM(shader,
GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR,
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR,
@ -238,12 +136,7 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
}
else if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
/* In rare cases geometry shaders calculate clipping themselves. */
if (stages->clipped_create_info != nullptr) {
*sh_p = GPU_shader_create_from_info_name(stages->clipped_create_info);
}
else {
BLI_assert_msg(0, "Shader doesn't support clip mode.");
}
*sh_p = GPU_shader_create_from_info_name(builtin_shader_create_info_name_clipped(shader));
}
else {
BLI_assert(0);