Shader: Only clamp undefined or unsupported inputs of Principled BSDF #112895

Merged
Lukas Stockner merged 39 commits from Alaska/blender:clamp-tint into blender-v4.0-release 2023-10-31 03:14:14 +01:00
74 changed files with 356 additions and 152 deletions
Showing only changes of commit bc703beb79 - Show all commits

View File

@ -223,4 +223,13 @@ ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const f
pheomelanin * rgb_to_spectrum(pheomelanin_color);
}
/* Computes the weight for base closure(s) which are layered under another closure.
* layer_albedo is an estimate of the top layer's reflectivity, while weight is the closure weight
* of the entire base+top combination. */
ccl_device_inline Spectrum closure_layering_weight(const Spectrum layer_albedo,
const Spectrum weight)
{
return weight * saturatef(1.0f - reduce_max(safe_divide_color(layer_albedo, weight)));
}
CCL_NAMESPACE_END

View File

@ -151,7 +151,7 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
if (stack_size == layer_stack_level) {
/* We just finished processing the top layers of a Layer closure, so adjust the weight to
* account for the layering. */
weight *= saturatef(1.0f - reduce_max(safe_divide_color(layer_albedo, weight)));
weight = closure_layering_weight(layer_albedo, weight);
layer_stack_level = -1;
/* If it's fully occluded, skip the base layer we just popped from the stack and grab
* the next entry instead. */

View File

@ -141,7 +141,7 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
float coat_neta = 1.0 / coat_ior;
Alaska marked this conversation as resolved Outdated

As above - having all the clamping together at the start makes it more maintainable (except for cases where the same parameter gets clamped differently depending on context).

As above - having all the clamping together at the start makes it more maintainable (except for cases where the same parameter gets clamped differently depending on context).
float cosNI = dot(I, CoatNormal);
float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI));
BSDF *= pow(coat_tint, coat_weight / cosNT);
BSDF *= mix(color(1.0), pow(CoatTint, 1.0 / cosNT), coat_weight);
}
float coat_r2 = clamp(CoatRoughness, 0.0, 1.0);
coat_r2 = coat_r2 * coat_r2;

View File

@ -212,7 +212,7 @@ ccl_device
/* Attenuate lower layers */
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
weight *= 1.0f - reduce_max(safe_divide_color(albedo, weight));
weight = closure_layering_weight(albedo, weight);
}
}
}
@ -237,7 +237,7 @@ ccl_device
/* Attenuate lower layers */
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
weight *= 1.0f - reduce_max(safe_divide_color(albedo, weight));
weight = closure_layering_weight(albedo, weight);
}
}
@ -265,7 +265,7 @@ ccl_device
* TIR is no concern here since we're always coming from the outside. */
float cosNT = sqrtf(1.0f - sqr(1.0f / coat_ior) * (1 - sqr(cosNI)));
float optical_depth = 1.0f / cosNT;
weight *= power(rgb_to_spectrum(coat_tint), coat_weight * optical_depth);
weight *= mix(one_spectrum(), power(rgb_to_spectrum(coat_tint), optical_depth), coat_weight);
}
}
@ -381,7 +381,7 @@ ccl_device
/* Attenuate lower layers */
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
weight *= 1.0f - reduce_max(safe_divide_color(albedo, weight));
weight = closure_layering_weight(albedo, weight);
}
}

View File

@ -446,7 +446,7 @@ class NODE_PT_geometry_node_tool_object_types(Panel):
types = [
("is_type_mesh", "Mesh", 'MESH_DATA'),
("is_type_curve", "Curves", 'CURVES_DATA'),
("is_type_curve", "Hair Curves", 'CURVES_DATA'),
]
if context.preferences.experimental.use_new_point_cloud_type:
types.append(("is_type_point_cloud", "Point Cloud", 'POINTCLOUD_DATA'))

View File

@ -3527,19 +3527,19 @@ class VIEW3D_MT_sculpt(Menu):
layout.separator()
sculpt_filters_types = [
('SMOOTH', "Smooth"),
('SURFACE_SMOOTH', "Surface Smooth"),
('INFLATE', "Inflate"),
('RELAX', "Relax Topology"),
('RELAX_FACE_SETS', "Relax Face Sets"),
('SHARPEN', "Sharpen"),
('ENHANCE_DETAILS', "Enhance Details"),
('ERASE_DISCPLACEMENT', "Erase Multires Displacement"),
('RANDOM', "Randomize")
('SMOOTH', iface_("Smooth")),
('SURFACE_SMOOTH', iface_("Surface Smooth")),
('INFLATE', iface_("Inflate")),
('RELAX', iface_("Relax Topology")),
('RELAX_FACE_SETS', iface_("Relax Face Sets")),
('SHARPEN', iface_("Sharpen")),
('ENHANCE_DETAILS', iface_("Enhance Details")),
('ERASE_DISCPLACEMENT', iface_("Erase Multires Displacement")),
('RANDOM', iface_("Randomize"))
]
for filter_type, ui_name in sculpt_filters_types:
props = layout.operator("sculpt.mesh_filter", text=ui_name)
props = layout.operator("sculpt.mesh_filter", text=ui_name, translate=False)
props.type = filter_type
layout.separator()

View File

@ -374,7 +374,7 @@ IDTypeInfo IDType_ID_AR = {
/*main_listbase_index*/ INDEX_ID_AR,
/*struct_size*/ sizeof(bArmature),
/*name*/ "Armature",
/*name_plural*/ "armatures",
/*name_plural*/ N_("armatures"),
/*translation_context*/ BLT_I18NCONTEXT_ID_ARMATURE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -415,7 +415,7 @@ IDTypeInfo IDType_ID_BR = {
/*main_listbase_index*/ INDEX_ID_BR,
/*struct_size*/ sizeof(Brush),
/*name*/ "Brush",
/*name_plural*/ "brushes",
/*name_plural*/ N_("brushes"),
/*translation_context*/ BLT_I18NCONTEXT_ID_BRUSH,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
/*asset_type_info*/ nullptr,

View File

@ -128,7 +128,7 @@ IDTypeInfo IDType_ID_CF = {
/*main_listbase_index*/ INDEX_ID_CF,
/*struct_size*/ sizeof(CacheFile),
/*name*/ "CacheFile",
/*name_plural*/ "cache_files",
/*name_plural*/ N_("cache files"),
/*translation_context*/ BLT_I18NCONTEXT_ID_CACHEFILE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -235,7 +235,7 @@ IDTypeInfo IDType_ID_CA = {
/*main_listbase_index*/ INDEX_ID_CA,
/*struct_size*/ sizeof(Camera),
/*name*/ "Camera",
/*name_plural*/ "cameras",
/*name_plural*/ N_("cameras"),
/*translation_context*/ BLT_I18NCONTEXT_ID_CAMERA,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -334,7 +334,7 @@ IDTypeInfo IDType_ID_GR = {
/*main_listbase_index*/ INDEX_ID_GR,
/*struct_size*/ sizeof(Collection),
/*name*/ "Collection",
/*name_plural*/ "collections",
/*name_plural*/ N_("collections"),
/*translation_context*/ BLT_I18NCONTEXT_ID_COLLECTION,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -278,7 +278,7 @@ IDTypeInfo IDType_ID_CU_LEGACY = {
/*main_listbase_index*/ INDEX_ID_CU_LEGACY,
/*struct_size*/ sizeof(Curve),
/*name*/ "Curve",
/*name_plural*/ "curves",
/*name_plural*/ N_("curves"),
/*translation_context*/ BLT_I18NCONTEXT_ID_CURVE_LEGACY,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -140,7 +140,7 @@ IDTypeInfo IDType_ID_CV = {
/*main_listbase_index*/ INDEX_ID_CV,
/*struct_size*/ sizeof(Curves),
/*name*/ "Curves",
/*name_plural*/ "hair_curves",
/*name_plural*/ N_("hair curves"),
/*translation_context*/ BLT_I18NCONTEXT_ID_CURVES,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -268,7 +268,7 @@ IDTypeInfo IDType_ID_GD_LEGACY = {
/*main_listbase_index*/ INDEX_ID_GD_LEGACY,
/*struct_size*/ sizeof(bGPdata),
/*name*/ "GPencil",
/*name_plural*/ "grease_pencils",
/*name_plural*/ N_("grease pencils"),
/*translation_context*/ BLT_I18NCONTEXT_ID_GPENCIL,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -198,7 +198,7 @@ IDTypeInfo IDType_ID_GP = {
/*main_listbase_index*/ INDEX_ID_GP,
/*struct_size*/ sizeof(GreasePencil),
/*name*/ "GreasePencil",
/*name_plural*/ "grease_pencils_v3",
/*name_plural*/ N_("grease pencils"),
/*translation_context*/ BLT_I18NCONTEXT_ID_GPENCIL,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -160,7 +160,7 @@ IDTypeInfo IDType_ID_IP = {
/*main_listbase_index*/ INDEX_ID_IP,
/*struct_size*/ sizeof(Ipo),
/*name*/ "Ipo",
/*name_plural*/ "ipos",
/*name_plural*/ N_("ipos"),
/*translation_context*/ "",
/*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING | IDTYPE_FLAGS_NO_ANIMDATA,
/*asset_type_info*/ nullptr,

View File

@ -193,7 +193,7 @@ IDTypeInfo IDType_ID_KE = {
/*main_listbase_index*/ INDEX_ID_KE,
/*struct_size*/ sizeof(Key),
/*name*/ "Key",
/*name_plural*/ "shape_keys",
/*name_plural*/ N_("shape keys"),
/*translation_context*/ BLT_I18NCONTEXT_ID_SHAPEKEY,
/*flags*/ IDTYPE_FLAGS_NO_LIBLINKING,
/*asset_type_info*/ nullptr,

View File

@ -165,7 +165,7 @@ IDTypeInfo IDType_ID_LT = {
/*main_listbase_index*/ INDEX_ID_LT,
/*struct_size*/ sizeof(Lattice),
/*name*/ "Lattice",
/*name_plural*/ "lattices",
/*name_plural*/ N_("lattices"),
/*translation_context*/ BLT_I18NCONTEXT_ID_LATTICE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -84,7 +84,7 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
/*main_listbase_index*/ INDEX_ID_NULL,
/*struct_size*/ sizeof(ID),
/*name*/ "LinkPlaceholder",
/*name_plural*/ "link_placeholders",
/*name_plural*/ N_("link placeholders"),
/*translation_context*/ BLT_I18NCONTEXT_ID_ID,
/*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING,
/*asset_type_info*/ nullptr,

View File

@ -89,7 +89,7 @@ IDTypeInfo IDType_ID_LI = {
/*main_listbase_index*/ INDEX_ID_LI,
/*struct_size*/ sizeof(Library),
/*name*/ "Library",
/*name_plural*/ "libraries",
/*name_plural*/ N_("libraries"),
/*translation_context*/ BLT_I18NCONTEXT_ID_LIBRARY,
/*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING | IDTYPE_FLAGS_NO_ANIMDATA,
/*asset_type_info*/ nullptr,

View File

@ -161,7 +161,7 @@ IDTypeInfo IDType_ID_LA = {
/*main_listbase_index*/ INDEX_ID_LA,
/*struct_size*/ sizeof(Light),
/*name*/ "Light",
/*name_plural*/ "lights",
/*name_plural*/ N_("lights"),
/*translation_context*/ BLT_I18NCONTEXT_ID_LIGHT,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -58,7 +58,7 @@ IDTypeInfo IDType_ID_LP = {
/*main_listbase_index*/ INDEX_ID_LP,
/*struct_size*/ sizeof(LightProbe),
/*name*/ "LightProbe",
/*name_plural*/ "lightprobes",
/*name_plural*/ N_("light probes"),
/*translation_context*/ BLT_I18NCONTEXT_ID_LIGHTPROBE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -647,7 +647,7 @@ IDTypeInfo IDType_ID_LS = {
/*main_listbase_index*/ INDEX_ID_LS,
/*struct_size*/ sizeof(FreestyleLineStyle),
/*name*/ "FreestyleLineStyle",
/*name_plural*/ "linestyles",
/*name_plural*/ N_("line styles"),
/*translation_context*/ BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -187,7 +187,7 @@ IDTypeInfo IDType_ID_MSK = {
/*main_listbase_index*/ INDEX_ID_MSK,
/*struct_size*/ sizeof(Mask),
/*name*/ "Mask",
/*name_plural*/ "masks",
/*name_plural*/ N_("masks"),
/*translation_context*/ BLT_I18NCONTEXT_ID_MASK,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -234,7 +234,7 @@ IDTypeInfo IDType_ID_MA = {
/*main_listbase_index*/ INDEX_ID_MA,
/*struct_size*/ sizeof(Material),
/*name*/ "Material",
/*name_plural*/ "materials",
/*name_plural*/ N_("materials"),
/*translation_context*/ BLT_I18NCONTEXT_ID_MATERIAL,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -147,7 +147,7 @@ IDTypeInfo IDType_ID_MB = {
/*main_listbase_index*/ INDEX_ID_MB,
/*struct_size*/ sizeof(MetaBall),
/*name*/ "Metaball",
/*name_plural*/ "metaballs",
/*name_plural*/ N_("metaballs"),
/*translation_context*/ BLT_I18NCONTEXT_ID_METABALL,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -372,7 +372,7 @@ IDTypeInfo IDType_ID_ME = {
/*main_listbase_index*/ INDEX_ID_ME,
/*struct_size*/ sizeof(Mesh),
/*name*/ "Mesh",
/*name_plural*/ "meshes",
/*name_plural*/ N_("meshes"),
/*translation_context*/ BLT_I18NCONTEXT_ID_MESH,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -283,7 +283,7 @@ IDTypeInfo IDType_ID_MC = {
/*main_listbase_index*/ INDEX_ID_MC,
/*struct_size*/ sizeof(MovieClip),
/*name*/ "MovieClip",
/*name_plural*/ "movieclips",
/*name_plural*/ N_("movie clips"),
/*translation_context*/ BLT_I18NCONTEXT_ID_MOVIECLIP,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -513,7 +513,7 @@ static void construct_interface_as_legacy_sockets(bNodeTree *ntree)
auto make_legacy_socket = [&](const bNodeTreeInterfaceSocket &socket,
eNodeSocketInOut in_out) -> bNodeSocket * {
bNodeSocket *iosock = make_socket(
ntree, in_out, socket.socket_type, socket.name, socket.identifier);
ntree, in_out, socket.socket_type, socket.name ? socket.name : "", socket.identifier);
if (!iosock) {
return nullptr;
}
@ -1106,11 +1106,11 @@ void node_update_asset_metadata(bNodeTree &node_tree)
auto outputs = idprop::create_group("outputs");
node_tree.ensure_interface_cache();
for (const bNodeTreeInterfaceSocket *socket : node_tree.interface_inputs()) {
auto property = idprop::create(socket->name, socket->socket_type);
auto property = idprop::create(socket->name ? socket->name : "", socket->socket_type);
IDP_AddToGroup(inputs.get(), property.release());
}
for (const bNodeTreeInterfaceSocket *socket : node_tree.interface_outputs()) {
auto property = idprop::create(socket->name, socket->socket_type);
auto property = idprop::create(socket->name ? socket->name : "", socket->socket_type);
IDP_AddToGroup(outputs.get(), property.release());
}
BKE_asset_metadata_idprop_ensure(asset_data, inputs.release());
@ -1145,7 +1145,7 @@ IDTypeInfo IDType_ID_NT = {
/*main_listbase_index*/ INDEX_ID_NT,
/*struct_size*/ sizeof(bNodeTree),
/*name*/ "NodeTree",
/*name_plural*/ "node_groups",
/*name_plural*/ N_("node groups"),
/*translation_context*/ BLT_I18NCONTEXT_ID_NODETREE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ &AssetType_NT,

View File

@ -423,10 +423,9 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
bNodeTreeInterfaceSocket &dst_socket = reinterpret_cast<bNodeTreeInterfaceSocket &>(dst);
const bNodeTreeInterfaceSocket &src_socket =
reinterpret_cast<const bNodeTreeInterfaceSocket &>(src);
BLI_assert(src_socket.name != nullptr);
BLI_assert(src_socket.socket_type != nullptr);
dst_socket.name = BLI_strdup(src_socket.name);
dst_socket.name = BLI_strdup_null(src_socket.name);
dst_socket.description = BLI_strdup_null(src_socket.description);
dst_socket.socket_type = BLI_strdup(src_socket.socket_type);
dst_socket.default_attribute_name = BLI_strdup_null(src_socket.default_attribute_name);
@ -444,9 +443,8 @@ static void item_copy(bNodeTreeInterfaceItem &dst,
bNodeTreeInterfacePanel &dst_panel = reinterpret_cast<bNodeTreeInterfacePanel &>(dst);
const bNodeTreeInterfacePanel &src_panel = reinterpret_cast<const bNodeTreeInterfacePanel &>(
src);
BLI_assert(src_panel.name != nullptr);
dst_panel.name = BLI_strdup(src_panel.name);
dst_panel.name = BLI_strdup_null(src_panel.name);
dst_panel.description = BLI_strdup_null(src_panel.description);
dst_panel.identifier = generate_uid ? generate_uid() : src_panel.identifier;

View File

@ -1056,7 +1056,7 @@ IDTypeInfo IDType_ID_OB = {
/*main_listbase_index*/ INDEX_ID_OB,
/*struct_size*/ sizeof(Object),
/*name*/ "Object",
/*name_plural*/ "objects",
/*name_plural*/ N_("objects"),
/*translation_context*/ BLT_I18NCONTEXT_ID_OBJECT,
/*flags*/ 0,
/*asset_type_info*/ &AssetType_OB,

View File

@ -144,7 +144,7 @@ IDTypeInfo IDType_ID_PAL = {
/*main_listbase_index*/ INDEX_ID_PAL,
/*struct_size*/ sizeof(Palette),
/*name*/ "Palette",
/*name_plural*/ "palettes",
/*name_plural*/ N_("palettes"),
/*translation_context*/ BLT_I18NCONTEXT_ID_PALETTE,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
/*asset_type_info*/ nullptr,
@ -211,7 +211,7 @@ IDTypeInfo IDType_ID_PC = {
/*main_listbase_index*/ INDEX_ID_PC,
/*struct_size*/ sizeof(PaintCurve),
/*name*/ "PaintCurve",
/*name_plural*/ "paint_curves",
/*name_plural*/ N_("paint curves"),
/*translation_context*/ BLT_I18NCONTEXT_ID_PAINTCURVE,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
/*asset_type_info*/ nullptr,

View File

@ -382,7 +382,7 @@ IDTypeInfo IDType_ID_PA = {
/*main_listbase_index*/ INDEX_ID_PA,
/*struct_size*/ sizeof(ParticleSettings),
/*name*/ "ParticleSettings",
/*name_plural*/ "particles",
/*name_plural*/ N_("particles"),
/*translation_context*/ BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
/*flags*/ 0,
/*asset_type_info*/ nullptr,

View File

@ -147,7 +147,7 @@ IDTypeInfo IDType_ID_PT = {
/*main_listbase_index*/ INDEX_ID_PT,
/*struct_size*/ sizeof(PointCloud),
/*name*/ "PointCloud",
/*name_plural*/ "pointclouds",
/*name_plural*/ N_("point clouds"),
/*translation_context*/ BLT_I18NCONTEXT_ID_POINTCLOUD,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -168,7 +168,7 @@ IDTypeInfo IDType_ID_SCR = {
/*main_listbase_index*/ INDEX_ID_SCR,
/*struct_size*/ sizeof(bScreen),
/*name*/ "Screen",
/*name_plural*/ "screens",
/*name_plural*/ N_("screens"),
/*translation_context*/ BLT_I18NCONTEXT_ID_SCREEN,
/*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA |
IDTYPE_FLAGS_NO_MEMFILE_UNDO,

View File

@ -195,7 +195,7 @@ IDTypeInfo IDType_ID_SO = {
/*main_listbase_index*/ INDEX_ID_SO,
/*struct_size*/ sizeof(bSound),
/*name*/ "Sound",
/*name_plural*/ "sounds",
/*name_plural*/ N_("sounds"),
/*translation_context*/ BLT_I18NCONTEXT_ID_SOUND,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -57,7 +57,7 @@ IDTypeInfo IDType_ID_SPK = {
/*main_listbase_index*/ INDEX_ID_SPK,
/*struct_size*/ sizeof(Speaker),
/*name*/ "Speaker",
/*name_plural*/ "speakers",
/*name_plural*/ N_("speakers"),
/*translation_context*/ BLT_I18NCONTEXT_ID_SPEAKER,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -231,7 +231,7 @@ IDTypeInfo IDType_ID_TXT = {
/*main_listbase_index*/ INDEX_ID_TXT,
/*struct_size*/ sizeof(Text),
/*name*/ "Text",
/*name_plural*/ "texts",
/*name_plural*/ N_("texts"),
/*translation_context*/ BLT_I18NCONTEXT_ID_TEXT,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -201,7 +201,7 @@ IDTypeInfo IDType_ID_TE = {
/*main_listbase_index*/ INDEX_ID_TE,
/*struct_size*/ sizeof(Tex),
/*name*/ "Texture",
/*name_plural*/ "textures",
/*name_plural*/ N_("textures"),
/*translation_context*/ BLT_I18NCONTEXT_ID_TEXTURE,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -160,7 +160,7 @@ IDTypeInfo IDType_ID_VF = {
/*main_listbase_index*/ INDEX_ID_VF,
/*struct_size*/ sizeof(VFont),
/*name*/ "Font",
/*name_plural*/ "fonts",
/*name_plural*/ N_("fonts"),
/*translation_context*/ BLT_I18NCONTEXT_ID_VFONT,
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA | IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -639,7 +639,7 @@ IDTypeInfo IDType_ID_VO = {
/*main_listbase_index*/ INDEX_ID_VO,
/*struct_size*/ sizeof(Volume),
/*name*/ "Volume",
/*name_plural*/ "volumes",
/*name_plural*/ N_("volumes"),
/*translation_context*/ BLT_I18NCONTEXT_ID_VOLUME,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -177,7 +177,7 @@ IDTypeInfo IDType_ID_WS = {
/*main_listbase_index*/ INDEX_ID_WS,
/*struct_size*/ sizeof(WorkSpace),
/*name*/ "WorkSpace",
/*name_plural*/ "workspaces",
/*name_plural*/ N_("workspaces"),
/*translation_context*/ BLT_I18NCONTEXT_ID_WORKSPACE,
/*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA |
IDTYPE_FLAGS_NO_MEMFILE_UNDO,

View File

@ -182,7 +182,7 @@ IDTypeInfo IDType_ID_WO = {
/*main_listbase_index*/ INDEX_ID_WO,
/*struct_size*/ sizeof(World),
/*name*/ "World",
/*name_plural*/ "worlds",
/*name_plural*/ N_("worlds"),
/*translation_context*/ BLT_I18NCONTEXT_ID_WORLD,
/*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
/*asset_type_info*/ nullptr,

View File

@ -849,8 +849,8 @@ static void version_principled_bsdf_specular_tint(bNodeTree *ntree)
static float one[] = {1.0f, 1.0f, 1.0f, 1.0f};
/* If any of the two inputs is dynamic, we add a Mix node. */
if (base_color_sock->link || specular_tint_sock->link) {
/* Add a mix node when working with dynamic inputs. */
if (specular_tint_sock->link || (base_color_sock->link && specular_tint_old != 0)) {
bNode *mix = nodeAddStaticNode(nullptr, ntree, SH_NODE_MIX);
static_cast<NodeShaderMix *>(mix->storage)->data_type = SOCK_RGBA;
mix->locx = node->locx - 170;
@ -891,7 +891,7 @@ static void version_copy_socket(bNodeTreeInterfaceSocket &dst,
char *identifier)
{
/* Node socket copy function based on bNodeTreeInterface::item_copy to avoid using blenkernel. */
dst.name = BLI_strdup(src.name);
dst.name = BLI_strdup_null(src.name);
dst.description = BLI_strdup_null(src.description);
dst.socket_type = BLI_strdup(src.socket_type);
dst.default_attribute_name = BLI_strdup_null(src.default_attribute_name);

View File

@ -545,7 +545,8 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
blo_update_defaults_scene(bmain, scene);
if (app_template && STREQ(app_template, "Video_Editing")) {
if (app_template &&
(STREQ(app_template, "Video_Editing") || STREQ(app_template, "2D_Animation"))) {
/* Filmic is too slow, use standard until it is optimized. */
STRNCPY(scene->view_settings.view_transform, "Standard");
STRNCPY(scene->view_settings.look, "None");
@ -553,7 +554,13 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
else {
/* Default to AgX view transform. */
STRNCPY(scene->view_settings.view_transform, "AgX");
}
if (app_template && STREQ(app_template, "Video_Editing")) {
/* Pass: no extra tweaks needed. Keep the view settings configured above, and rely on the
* default state of enabled AV sync. */
}
else {
/* AV Sync break physics sim caching, disable until that is fixed. */
scene->audio.flag &= ~AUDIO_SYNC;
scene->flag &= ~SCE_FRAME_DROP;

View File

@ -40,8 +40,7 @@ vec3 extrude_offset(vec3 ls_P)
float signed_distance = dot(pass_data.far_plane.xyz, ws_P) - pass_data.far_plane.w;
extrude_distance = -signed_distance / L_dot_FP;
}
vec3 ls_light_direction = normal_world_to_object(vec3(pass_data.light_direction_ws));
return ls_light_direction * extrude_distance;
return pass_data.light_direction_ws * extrude_distance;
}
void emit_cap(const bool front, bool reversed, int triangle_vertex_id)
@ -87,13 +86,16 @@ void main()
/* Calculate front/back Positions. */
vData[0].frontPosition = point_object_to_ndc(vData[0].pos);
vData[0].backPosition = point_object_to_ndc(vData[0].pos + extrude_offset(vData[0].pos));
vData[0].backPosition = point_world_to_ndc(point_object_to_world(vData[0].pos) +
extrude_offset(vData[0].pos));
vData[1].frontPosition = point_object_to_ndc(vData[1].pos);
vData[1].backPosition = point_object_to_ndc(vData[1].pos + extrude_offset(vData[1].pos));
vData[1].backPosition = point_world_to_ndc(point_object_to_world(vData[1].pos) +
extrude_offset(vData[1].pos));
vData[2].frontPosition = point_object_to_ndc(vData[2].pos);
vData[2].backPosition = point_object_to_ndc(vData[2].pos + extrude_offset(vData[2].pos));
vData[2].backPosition = point_world_to_ndc(point_object_to_world(vData[2].pos) +
extrude_offset(vData[2].pos));
/* Geometry shader equivalent calc. */
vec3 v10 = vData[0].pos - vData[1].pos;

View File

@ -71,8 +71,7 @@ vec3 extrude_offset(vec3 ls_P)
float signed_distance = dot(pass_data.far_plane.xyz, ws_P) - pass_data.far_plane.w;
extrude_distance = -signed_distance / L_dot_FP;
}
vec3 ls_light_direction = normal_world_to_object(vec3(pass_data.light_direction_ws));
return ls_light_direction * extrude_distance;
return pass_data.light_direction_ws * extrude_distance;
}
void main()
@ -100,16 +99,20 @@ void main()
/* Calculate front/back Positions. */
vData[0].frontPosition = point_object_to_ndc(vData[0].pos);
vData[0].backPosition = point_object_to_ndc(vData[0].pos + extrude_offset(vData[0].pos));
vData[0].backPosition = point_world_to_ndc(point_object_to_world(vData[0].pos) +
extrude_offset(vData[0].pos));
vData[1].frontPosition = point_object_to_ndc(vData[1].pos);
vData[1].backPosition = point_object_to_ndc(vData[1].pos + extrude_offset(vData[1].pos));
vData[1].backPosition = point_world_to_ndc(point_object_to_world(vData[1].pos) +
extrude_offset(vData[1].pos));
vData[2].frontPosition = point_object_to_ndc(vData[2].pos);
vData[2].backPosition = point_object_to_ndc(vData[2].pos + extrude_offset(vData[2].pos));
vData[2].backPosition = point_world_to_ndc(point_object_to_world(vData[2].pos) +
extrude_offset(vData[2].pos));
vData[3].frontPosition = point_object_to_ndc(vData[3].pos);
vData[3].backPosition = point_object_to_ndc(vData[3].pos + extrude_offset(vData[3].pos));
vData[3].backPosition = point_world_to_ndc(point_object_to_world(vData[3].pos) +
extrude_offset(vData[3].pos));
/* Geometry shader equivalent path. */
vec3 v10 = vData[0].pos - vData[1].pos;

View File

@ -564,6 +564,16 @@ void DrawCommandBuf::finalize_commands(Vector<Header, 0> &headers,
cmd.vertex_len = batch_vert_len;
}
#ifdef WITH_METAL_BACKEND
/* For SSBO vertex fetch, mutate output vertex count by ssbo vertex fetch expansion factor. */
if (cmd.shader) {
int num_input_primitives = gpu_get_prim_count_from_type(cmd.vertex_len,
cmd.batch->prim_type);
cmd.vertex_len = num_input_primitives *
GPU_shader_get_ssbo_vertex_fetch_num_verts_per_prim(cmd.shader);
}
#endif
if (cmd.handle.raw > 0) {
/* Save correct offset to start of resource_id buffer region for this draw. */
uint instance_first = resource_id_count;
@ -624,6 +634,20 @@ void DrawMultiBuf::bind(RecordingState &state,
group.vertex_first = group.vertex_first == -1 ? batch_vert_first : group.vertex_first;
group.base_index = batch_base_index;
#ifdef WITH_METAL_BACKEND
/* For SSBO vertex fetch, mutate output vertex count by ssbo vertex fetch expansion factor. */
if (group.gpu_shader) {
int num_input_primitives = gpu_get_prim_count_from_type(group.vertex_len,
group.gpu_batch->prim_type);
group.vertex_len = num_input_primitives *
GPU_shader_get_ssbo_vertex_fetch_num_verts_per_prim(group.gpu_shader);
/* Override base index to -1, as all SSBO calls are submitted as non-indexed, with the
* index buffer indirection handled within the implemnetation. This is to ensure
* command generation can correctly assigns baseInstance in the non-indexed formatting. */
group.base_index = -1;
}
#endif
/* Instancing attributes are not supported using the new pipeline since we use the base
* instance to set the correct resource_id. Workaround is a storage_buf + gl_InstanceID. */
BLI_assert(batch_inst_len == 1);

View File

@ -291,6 +291,11 @@ struct Draw {
uint vertex_len;
uint vertex_first;
ResourceHandle handle;
#ifdef WITH_METAL_BACKEND
/* Shader is required for extracting SSBO vertex fetch expansion parameters during draw command
* generation. */
GPUShader *shader;
#endif
void execute(RecordingState &state) const;
std::string serialize() const;
@ -399,7 +404,7 @@ union Undetermined {
};
/** Try to keep the command size as low as possible for performance. */
BLI_STATIC_ASSERT(sizeof(Undetermined) <= 24, "One of the command type is too large.")
BLI_STATIC_ASSERT(sizeof(Undetermined) <= /*24*/ 32, "One of the command type is too large.")
/** \} */
@ -435,14 +440,28 @@ class DrawCommandBuf {
uint vertex_len,
uint vertex_first,
ResourceHandle handle,
uint /*custom_id*/)
uint /*custom_id*/
#ifdef WITH_METAL_BACKEND
,
GPUShader *shader = nullptr
#endif
)
{
vertex_first = vertex_first != -1 ? vertex_first : 0;
instance_len = instance_len != -1 ? instance_len : 1;
int64_t index = commands.append_and_get_index({});
headers.append({Type::Draw, uint(index)});
commands[index].draw = {batch, instance_len, vertex_len, vertex_first, handle};
commands[index].draw = {batch,
instance_len,
vertex_len,
vertex_first,
handle
#ifdef WITH_METAL_BACKEND
,
shader
#endif
};
}
void bind(RecordingState &state,
@ -536,7 +555,12 @@ class DrawMultiBuf {
uint vertex_len,
uint vertex_first,
ResourceHandle handle,
uint custom_id)
uint custom_id
#ifdef WITH_METAL_BACKEND
,
GPUShader *shader
#endif
)
{
/* Custom draw-calls cannot be batched and will produce one group per draw. */
const bool custom_group = ((vertex_first != 0 && vertex_first != -1) || vertex_len != -1);
@ -575,6 +599,11 @@ class DrawMultiBuf {
group.back_proto_len = 0;
group.vertex_len = vertex_len;
group.vertex_first = vertex_first;
#ifdef WITH_METAL_BACKEND
/* If SSBO vertex fetch is used, shader must be known to extract vertex expansion parameters.
*/
group.gpu_shader = shader;
#endif
/* Custom group are not to be registered in the group_ids_. */
if (!custom_group) {
group_id = new_group_id;
@ -588,6 +617,11 @@ class DrawMultiBuf {
DrawGroup &group = group_buf_[group_id];
group.len += instance_len;
group.front_facing_len += inverted ? 0 : instance_len;
#ifdef WITH_METAL_BACKEND
/* If SSBO vertex fetch is used, shader must be known to extract vertex expansion parameters.
*/
group.gpu_shader = shader;
#endif
/* For serialization only. */
(inverted ? group.back_proto_len : group.front_proto_len)++;
}

View File

@ -42,6 +42,7 @@ struct DrawGroup {
uint total_counter;
#ifndef GPU_SHADER
/* NOTE: Union just to make sure the struct has always the same size on all platform. */
union {
struct {
@ -50,12 +51,18 @@ struct DrawGroup {
uint back_proto_len;
/** Needed to create the correct draw call. */
GPUBatch *gpu_batch;
# ifdef WITH_METAL_BACKEND
GPUShader *gpu_shader;
# endif
};
struct {
#endif
uint front_facing_counter;
uint back_facing_counter;
uint _pad0, _pad1;
#if defined(WITH_METAL_BACKEND) || defined(GPU_METAL)
uint _pad2, _pad3, _pad4, _pad5;
#endif
#ifndef GPU_SHADER
};
};

View File

@ -673,8 +673,24 @@ inline void PassBase<T>::draw(GPUBatch *batch,
return;
}
BLI_assert(shader_);
draw_commands_buf_.append_draw(
headers_, commands_, batch, instance_len, vertex_len, vertex_first, handle, custom_id);
#ifdef WITH_METAL_BACKEND
/* TEMP: Note, shader_ is passed as part of the draw as vertex-expansion properties for SSBO
* vertex fetch need extracting at command generation time. */
GPUShader *draw_shader = GPU_shader_uses_ssbo_vertex_fetch(shader_) ? shader_ : nullptr;
#endif
draw_commands_buf_.append_draw(headers_,
commands_,
batch,
instance_len,
vertex_len,
vertex_first,
handle,
custom_id
#ifdef WITH_METAL_BACKEND
,
draw_shader
#endif
);
}
template<class T>

View File

@ -252,6 +252,11 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
if (!node_tree->group_output_node()) {
BKE_report(op->reports, RPT_ERROR, "Node group must have a group output node");
return OPERATOR_CANCELLED;
}
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
scene, view_layer, CTX_wm_view3d(C), &objects_len, mode);
@ -345,7 +350,7 @@ static void add_attribute_search_or_value_buttons(uiLayout *layout,
uiItemL(name_row, "", ICON_NONE);
}
else {
uiItemL(name_row, socket.name, ICON_NONE);
uiItemL(name_row, socket.name ? socket.name : "", ICON_NONE);
}
uiLayout *prop_row = uiLayoutRow(split, true);
@ -359,7 +364,7 @@ static void add_attribute_search_or_value_buttons(uiLayout *layout,
uiItemR(prop_row, md_ptr, rna_path_attribute_name.c_str(), UI_ITEM_NONE, "", ICON_NONE);
}
else {
const char *name = socket_type == SOCK_BOOLEAN ? socket.name : "";
const char *name = socket_type == SOCK_BOOLEAN ? (socket.name ? socket.name : "") : "";
uiItemR(prop_row, md_ptr, rna_path.c_str(), UI_ITEM_NONE, name, ICON_NONE);
}
@ -399,29 +404,30 @@ static void draw_property_for_socket(const bNodeTree &node_tree,
/* Use #uiItemPointerR to draw pointer properties because #uiItemR would not have enough
* information about what type of ID to select for editing the values. This is because
* pointer IDProperties contain no information about their type. */
const char *name = socket.name ? socket.name : "";
switch (socket_type) {
case SOCK_OBJECT:
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "objects", socket.name, ICON_OBJECT_DATA);
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "objects", name, ICON_OBJECT_DATA);
break;
case SOCK_COLLECTION:
uiItemPointerR(
row, op_ptr, rna_path, bmain_ptr, "collections", socket.name, ICON_OUTLINER_COLLECTION);
row, op_ptr, rna_path, bmain_ptr, "collections", name, ICON_OUTLINER_COLLECTION);
break;
case SOCK_MATERIAL:
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "materials", socket.name, ICON_MATERIAL);
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "materials", name, ICON_MATERIAL);
break;
case SOCK_TEXTURE:
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "textures", name, ICON_TEXTURE);
break;
case SOCK_IMAGE:
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "images", socket.name, ICON_IMAGE);
uiItemPointerR(row, op_ptr, rna_path, bmain_ptr, "images", name, ICON_IMAGE);
break;
default:
if (nodes::input_has_attribute_toggle(node_tree, socket_index)) {
add_attribute_search_or_value_buttons(row, op_ptr, socket);
}
else {
uiItemR(row, op_ptr, rna_path, UI_ITEM_NONE, socket.name, ICON_NONE);
uiItemR(row, op_ptr, rna_path, UI_ITEM_NONE, name, ICON_NONE);
}
}
if (!nodes::input_has_attribute_toggle(node_tree, socket_index)) {

View File

@ -58,6 +58,7 @@
#include "ED_object.hh"
#include "ED_paint.hh"
#include "ED_undo.hh"
/* for Copy As Driver */
#include "ED_keyframing.hh"
@ -2316,6 +2317,10 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
}
if (UI_but_flag_is_set(but, UI_BUT_UNDO)) {
ED_undo_push(C, RNA_property_ui_name(but->rnaprop));
}
}
else {
if (gamma) {

View File

@ -48,6 +48,8 @@ static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle)
blender::asset_system::AssetRepresentation *asset = ED_asset_handle_get_representation(
asset_handle);
UI_but_dragflag_enable(but, UI_BUT_DRAG_FULL_BUT);
ID *id = asset->local_id();
if (id != nullptr) {
UI_but_drag_set_id(but, id);

View File

@ -2862,8 +2862,10 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* execute the events */
switch (event->type) {
case MOUSEMOVE: {
const float aspect = BLI_rctf_size_x(&rmd->region->v2d.cur) /
(BLI_rcti_size_x(&rmd->region->v2d.mask) + 1);
const float aspect = (rmd->region->v2d.flag & V2D_IS_INIT) ?
(BLI_rctf_size_x(&rmd->region->v2d.cur) /
(BLI_rcti_size_x(&rmd->region->v2d.mask) + 1)) :
1.0f;
const int snap_size_threshold = (U.widget_unit * 2) / aspect;
bool size_changed = false;

View File

@ -486,6 +486,7 @@ bool AssetCatalogDropTarget::drop_assets_into_catalog(bContext *C,
filelist_tag_needs_filtering(tree_view.space_file_.files);
file_select_deselect_all(&tree_view.space_file_, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED);
WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, nullptr);
WM_main_add_notifier(NC_ASSET | ND_ASSET_CATALOGS, nullptr);
}
if (did_update) {

View File

@ -819,7 +819,7 @@ static const char *filelist_get_details_column_string(
nullptr, file->time, false, time, date, &is_today, &is_yesterday);
if (is_today || is_yesterday) {
STRNCPY(date, is_today ? N_("Today") : N_("Yesterday"));
STRNCPY(date, is_today ? IFACE_("Today") : IFACE_("Yesterday"));
}
SNPRINTF(file->draw_data.datetime_str, "%s %s", date, time);
}

View File

@ -336,12 +336,12 @@ static void gather_socket_link_operations(const bContext &C,
return true;
}
}
search_link_ops.append(
{std::string(IFACE_("Group Input")) + " " + UI_MENU_ARROW_SEP + interface_socket.name,
[interface_socket](nodes::LinkSearchOpParams &params) {
add_existing_group_input_fn(params, interface_socket);
},
weight});
search_link_ops.append({std::string(IFACE_("Group Input")) + " " + UI_MENU_ARROW_SEP +
(interface_socket.name ? interface_socket.name : ""),
[interface_socket](nodes::LinkSearchOpParams &params) {
add_existing_group_input_fn(params, interface_socket);
},
weight});
weight--;
return true;
});

View File

@ -1621,6 +1621,7 @@ static void view3d_header_region_listener(const wmRegionListenerParams *params)
break;
case NC_ASSET:
switch (wmn->data) {
case ND_ASSET_CATALOGS:
case ND_ASSET_LIST_READING:
blender::ed::geometry::clear_operator_asset_trees();
ED_region_tag_redraw(region);

View File

@ -35,6 +35,8 @@
#include "BLI_polyfill_2d_beautify.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
@ -5278,6 +5280,7 @@ void UV_OT_select_similar(wmOperatorType *ot)
/* properties */
PropertyRNA *prop = ot->prop = RNA_def_enum(
ot->srna, "type", uv_select_similar_type_items, SIMVERT_NORMAL, "Type", "");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MESH);
RNA_def_enum_funcs(prop, uv_select_similar_type_itemf);
RNA_def_enum(ot->srna, "compare", prop_similar_compare_types, SIM_CMP_EQ, "Compare", "");
RNA_def_float(ot->srna, "threshold", 0.0f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f);

View File

@ -218,6 +218,14 @@ GPUShader *GPU_shader_create_ex(const char *vertcode,
bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf);
void GPU_shader_transform_feedback_disable(GPUShader *shader);
/**
* SSBO Vertex-fetch is used as an alternative path to geometry shaders wherein the vertex count is
* expanded up-front. This function fetches the number of specified output vertices per input
* primitive.
*/
int GPU_shader_get_ssbo_vertex_fetch_num_verts_per_prim(GPUShader *shader);
bool GPU_shader_uses_ssbo_vertex_fetch(GPUShader *shader);
/**
* Shader cache warming.
* For each shader, rendering APIs perform a two-step compilation:

View File

@ -636,6 +636,16 @@ int GPU_shader_get_program(GPUShader *shader)
return unwrap(shader)->program_handle_get();
}
int GPU_shader_get_ssbo_vertex_fetch_num_verts_per_prim(GPUShader *shader)
{
return unwrap(shader)->get_ssbo_vertex_fetch_output_num_verts();
}
bool GPU_shader_uses_ssbo_vertex_fetch(GPUShader *shader)
{
return unwrap(shader)->get_uses_ssbo_vertex_fetch();
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -79,6 +79,10 @@ class Shader {
/* DEPRECATED: Kept only because of BGL API. */
virtual int program_handle_get() const = 0;
/* Only used by SSBO Vertex fetch. */
virtual bool get_uses_ssbo_vertex_fetch() const = 0;
virtual int get_ssbo_vertex_fetch_output_num_verts() const = 0;
inline const char *const name_get() const
{
return name;

View File

@ -903,10 +903,30 @@ void MTLBatch::draw_advanced_indirect(GPUStorageBuf *indirect_buf, intptr_t offs
return;
}
/* Render using SSBO Vertex Fetch not supported by Draw Indirect.
* NOTE: Add support? */
if (active_shader_->get_uses_ssbo_vertex_fetch()) {
printf("Draw indirect for SSBO vertex fetch disabled\n");
/* Fetch indirect buffer Metal handle. */
MTLStorageBuf *mtlssbo = static_cast<MTLStorageBuf *>(unwrap(indirect_buf));
id<MTLBuffer> mtl_indirect_buf = mtlssbo->get_metal_buffer();
BLI_assert(mtl_indirect_buf != nil);
if (mtl_indirect_buf == nil) {
MTL_LOG_WARNING("Metal Indirect Draw Storage Buffer is nil.");
/* End of draw. */
this->unbind(rec);
return;
}
/* Indirect SSBO vertex fetch calls require the draw command in the buffer to be mutated at
* command encoding time. This takes place within the draw manager when a shader supporting
* SSBO Vertex-Fetch is used. */
if (active_shader_->get_uses_ssbo_vertex_fetch())
{ /* Set depth stencil state (requires knowledge of primitive type). */
ctx->ensure_depth_stencil_state(active_shader_->get_ssbo_vertex_fetch_output_prim_type());
/* Issue draw call. */
[rec drawPrimitives:active_shader_->get_ssbo_vertex_fetch_output_prim_type()
indirectBuffer:mtl_indirect_buf
indirectBufferOffset:offset];
ctx->main_command_buffer.register_draw_counters(1);
/* End of draw. */
this->unbind(rec);
@ -929,18 +949,6 @@ void MTLBatch::draw_advanced_indirect(GPUStorageBuf *indirect_buf, intptr_t offs
return;
}
/* Fetch indirect buffer Metal handle. */
MTLStorageBuf *mtlssbo = static_cast<MTLStorageBuf *>(unwrap(indirect_buf));
id<MTLBuffer> mtl_indirect_buf = mtlssbo->get_metal_buffer();
BLI_assert(mtl_indirect_buf != nil);
if (mtl_indirect_buf == nil) {
MTL_LOG_WARNING("Metal Indirect Draw Storage Buffer is nil.");
/* End of draw. */
this->unbind(rec);
return;
}
if (mtl_elem == NULL) {
/* Set depth stencil state (requires knowledge of primitive type). */
ctx->ensure_depth_stencil_state(mtl_prim_type);

View File

@ -307,24 +307,26 @@ class MTLShader : public Shader {
bool get_push_constant_is_dirty();
void push_constant_bindstate_mark_dirty(bool is_dirty);
/* SSBO vertex fetch draw parameters. */
bool get_uses_ssbo_vertex_fetch() const override
{
return use_ssbo_vertex_fetch_mode_;
}
int get_ssbo_vertex_fetch_output_num_verts() const override
{
return ssbo_vertex_fetch_output_num_verts_;
}
/* DEPRECATED: Kept only because of BGL API. (Returning -1 in METAL). */
int program_handle_get() const override
{
return -1;
}
bool get_uses_ssbo_vertex_fetch()
{
return use_ssbo_vertex_fetch_mode_;
}
MTLPrimitiveType get_ssbo_vertex_fetch_output_prim_type()
{
return ssbo_vertex_fetch_output_prim_type_;
}
uint32_t get_ssbo_vertex_fetch_output_num_verts()
{
return ssbo_vertex_fetch_output_num_verts_;
}
static int ssbo_vertex_type_to_attr_type(MTLVertexFormat attribute_type);
void prepare_ssbo_vertex_fetch_metadata();

View File

@ -69,6 +69,16 @@ class GLShader : public Shader {
void uniform_float(int location, int comp_len, int array_size, const float *data) override;
void uniform_int(int location, int comp_len, int array_size, const int *data) override;
/* Unusued: SSBO vertex fetch draw parameters. */
bool get_uses_ssbo_vertex_fetch() const override
{
return false;
}
int get_ssbo_vertex_fetch_output_num_verts() const override
{
return 0;
}
/** DEPRECATED: Kept only because of BGL API. */
int program_handle_get() const override;

View File

@ -133,7 +133,7 @@ void node_bsdf_principled(vec4 base_color,
float coat_neta = 1.0 / coat_ior;
float NT = fast_sqrt(1.0 - coat_neta * coat_neta * (1 - NV * NV));
/* Tint lower layers. */
coat_tint.rgb = pow(coat_tint.rgb, vec3(coat_weight / NT));
coat_tint.rgb = mix(vec3(1.0), pow(coat_tint.rgb, vec3(1.0 / NT)), coat_weight);
}
}
else {

View File

@ -60,6 +60,16 @@ class VKShader : public Shader {
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override;
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override;
/* Unusued: SSBO vertex fetch draw parameters. */
bool get_uses_ssbo_vertex_fetch() const override
{
return false;
}
int get_ssbo_vertex_fetch_output_num_verts() const override
{
return 0;
}
/* DEPRECATED: Kept only because of BGL API. */
int program_handle_get() const override;

View File

@ -748,14 +748,17 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md)
geometry_socket_count++;
}
else {
BKE_modifier_set_error(ob, md, "Missing property for input socket \"%s\"", socket->name);
BKE_modifier_set_error(
ob, md, "Missing property for input socket \"%s\"", socket->name ? socket->name : "");
}
continue;
}
if (!nodes::id_property_type_matches_socket(*socket, *property)) {
BKE_modifier_set_error(
ob, md, "Property type does not match input socket \"(%s)\"", socket->name);
BKE_modifier_set_error(ob,
md,
"Property type does not match input socket \"(%s)\"",
socket->name ? socket->name : "");
continue;
}
}
@ -1494,7 +1497,7 @@ static void add_attribute_search_or_value_buttons(const bContext &C,
uiItemL(name_row, "", ICON_NONE);
}
else {
uiItemL(name_row, socket.name, ICON_NONE);
uiItemL(name_row, socket.name ? socket.name : "", ICON_NONE);
}
uiLayout *prop_row = uiLayoutRow(split, true);
@ -1508,7 +1511,7 @@ static void add_attribute_search_or_value_buttons(const bContext &C,
uiItemL(layout, "", ICON_BLANK1);
}
else {
const char *name = type == SOCK_BOOLEAN ? socket.name : "";
const char *name = type == SOCK_BOOLEAN ? (socket.name ? socket.name : "") : "";
uiItemR(prop_row, md_ptr, rna_path.c_str(), UI_ITEM_NONE, name, ICON_NONE);
uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1);
}
@ -1561,26 +1564,27 @@ static void draw_property_for_socket(const bContext &C,
* pointer IDProperties contain no information about their type. */
const bNodeSocketType *typeinfo = socket.socket_typeinfo();
const eNodeSocketDatatype type = typeinfo ? eNodeSocketDatatype(typeinfo->type) : SOCK_CUSTOM;
const char *name = socket.name ? socket.name : "";
switch (type) {
case SOCK_OBJECT: {
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "objects", socket.name, ICON_OBJECT_DATA);
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "objects", name, ICON_OBJECT_DATA);
break;
}
case SOCK_COLLECTION: {
uiItemPointerR(
row, md_ptr, rna_path, bmain_ptr, "collections", socket.name, ICON_OUTLINER_COLLECTION);
row, md_ptr, rna_path, bmain_ptr, "collections", name, ICON_OUTLINER_COLLECTION);
break;
}
case SOCK_MATERIAL: {
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "materials", socket.name, ICON_MATERIAL);
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "materials", name, ICON_MATERIAL);
break;
}
case SOCK_TEXTURE: {
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "textures", name, ICON_TEXTURE);
break;
}
case SOCK_IMAGE: {
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "images", socket.name, ICON_IMAGE);
uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "images", name, ICON_IMAGE);
break;
}
default: {
@ -1588,7 +1592,7 @@ static void draw_property_for_socket(const bContext &C,
add_attribute_search_or_value_buttons(C, row, *nmd, md_ptr, socket);
}
else {
uiItemR(row, md_ptr, rna_path, UI_ITEM_NONE, socket.name, ICON_NONE);
uiItemR(row, md_ptr, rna_path, UI_ITEM_NONE, name, ICON_NONE);
}
}
}
@ -1612,7 +1616,7 @@ static void draw_property_for_output_socket(const bContext &C,
uiLayout *split = uiLayoutSplit(layout, 0.4f, false);
uiLayout *name_row = uiLayoutRow(split, false);
uiLayoutSetAlignment(name_row, UI_LAYOUT_ALIGN_RIGHT);
uiItemL(name_row, socket.name, ICON_NONE);
uiItemL(name_row, socket.name ? socket.name : "", ICON_NONE);
uiLayout *row = uiLayoutRow(split, true);
add_attribute_search_button(C, row, nmd, md_ptr, rna_path_attribute_name, socket, true);

View File

@ -361,7 +361,7 @@ static void interpolate_curve_shapes(bke::CurvesGeometry &child_curves,
const float neighbor_weight = neighbor_weights[neighbor_i];
const IndexRange guide_points = guide_points_by_curve[neighbor_index];
const Span<float3> neighbor_positions = guide_positions.slice(guide_points);
const float3 &neighbor_root = neighbor_positions[0];
const float3 &neighbor_root = neighbor_positions.first();
const float3 neighbor_up = guides_up[neighbor_index];
BLI_assert(math::is_unit_scale(neighbor_up));
@ -390,8 +390,22 @@ static void interpolate_curve_shapes(bke::CurvesGeometry &child_curves,
/* This method is used when guide curves have different amounts of control points. In
* this case, some additional interpolation is necessary compared to the method above. */
const Span<float> lengths = parameterized_guide_lengths.slice(
parameterized_guide_offsets[neighbor_index]);
const IndexRange guide_offsets = parameterized_guide_offsets[neighbor_index];
if (guide_offsets.is_empty()) {
/* Single point curve. */
float3 rotated_relative = neighbor_root;
if (!is_same_up_vector) {
rotated_relative = normal_rotation * rotated_relative;
}
const float3 global_pos = rotated_relative * neighbor_weight;
for (float3 &position : child_positions) {
position += global_pos;
}
continue;
}
const Span<float> lengths = parameterized_guide_lengths.slice(guide_offsets);
const float neighbor_length = lengths.last();
sample_lengths.reinitialize(points.size());
@ -535,8 +549,17 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
}
}
else {
const Span<float> lengths = parameterized_guide_lengths.slice(
parameterized_guide_offsets[neighbor_index]);
const IndexRange guide_offsets = parameterized_guide_offsets[neighbor_index];
if (guide_offsets.is_empty()) {
/* Single point curve. */
const T &curve_value = src[guide_points.first()];
for (const int i : points) {
mixer.mix_in(i, curve_value, neighbor_weight);
}
continue;
}
const Span<float> lengths = parameterized_guide_lengths.slice(guide_offsets);
const float neighbor_length = lengths.last();
sample_lengths.reinitialize(points.size());

View File

@ -2559,14 +2559,16 @@ struct GeometryNodesLazyFunctionBuilder {
for (const bNodeTreeInterfaceSocket *interface_input : btree_.interface_inputs()) {
lf::GraphOutputSocket &lf_socket = lf_graph.add_output(
CPPType::get<bool>(), StringRef("Usage: ") + interface_input->name);
CPPType::get<bool>(),
StringRef("Usage: ") + (interface_input->name ? interface_input->name : ""));
group_input_usage_sockets_.append(&lf_socket);
}
Vector<lf::GraphInputSocket *> lf_output_usages;
for (const bNodeTreeInterfaceSocket *interface_output : btree_.interface_outputs()) {
lf::GraphInputSocket &lf_socket = lf_graph.add_input(
CPPType::get<bool>(), StringRef("Usage: ") + interface_output->name);
CPPType::get<bool>(),
StringRef("Usage: ") + (interface_output->name ? interface_output->name : ""));
group_output_used_sockets_.append(&lf_socket);
lf_output_usages.append(&lf_socket);
}
@ -3014,8 +3016,9 @@ struct GeometryNodesLazyFunctionBuilder {
const Span<const bNodeTreeInterfaceSocket *> interface_inputs = btree_.interface_inputs();
for (const bNodeTreeInterfaceSocket *interface_input : interface_inputs) {
const bNodeSocketType *typeinfo = interface_input->socket_typeinfo();
lf::GraphInputSocket &lf_socket = lf_graph.add_input(*typeinfo->geometry_nodes_cpp_type,
interface_input->name);
lf::GraphInputSocket &lf_socket = lf_graph.add_input(
*typeinfo->geometry_nodes_cpp_type,
interface_input->name ? interface_input->name : nullptr);
group_input_sockets_.append(&lf_socket);
}
}
@ -3029,7 +3032,8 @@ struct GeometryNodesLazyFunctionBuilder {
for (const bNodeTreeInterfaceSocket *interface_output : btree_.interface_outputs()) {
const bNodeSocketType *typeinfo = interface_output->socket_typeinfo();
const CPPType &type = *typeinfo->geometry_nodes_cpp_type;
lf::GraphOutputSocket &lf_socket = lf_graph.add_output(type, interface_output->name);
lf::GraphOutputSocket &lf_socket = lf_graph.add_output(
type, interface_output->name ? interface_output->name : "");
lf_socket.set_default_value(type.default_value());
standard_group_output_sockets_.append(&lf_socket);
}
@ -3196,8 +3200,8 @@ struct GeometryNodesLazyFunctionBuilder {
const bNodeSocket &bsocket = bnode.input_socket(i);
const bNodeSocketType *typeinfo = interface_output.socket_typeinfo();
const CPPType &type = *typeinfo->geometry_nodes_cpp_type;
lf::GraphOutputSocket &lf_socket = graph_params.lf_graph.add_output(type,
interface_output.name);
lf::GraphOutputSocket &lf_socket = graph_params.lf_graph.add_output(
type, interface_output.name ? interface_output.name : "");
lf_graph_outputs.append(&lf_socket);
graph_params.lf_inputs_by_bsocket.add(&bsocket, &lf_socket);
mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
@ -3851,9 +3855,10 @@ struct GeometryNodesLazyFunctionBuilder {
for (const int i : output_indices.index_range()) {
const int output_index = output_indices[i];
const char *name = btree_.interface_outputs()[output_index]->name;
lf::GraphInputSocket &lf_socket = lf_graph.add_input(
CPPType::get<bke::AnonymousAttributeSet>(),
StringRef("Propagate: ") + btree_.interface_outputs()[output_index]->name);
StringRef("Propagate: ") + (name ? name : ""));
attribute_set_by_geometry_output_.add(output_index, &lf_socket);
}
}

View File

@ -306,7 +306,7 @@ static SocketDeclarationPtr declaration_for_interface_socket(
dst = std::move(value);
break;
}
dst->name = io_socket.name;
dst->name = io_socket.name ? io_socket.name : "";
dst->identifier = io_socket.identifier;
dst->in_out = in_out;
dst->description = io_socket.description ? io_socket.description : "";

View File

@ -113,7 +113,7 @@ NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
/* TODO: implement */
return get_input_value("Value", NodeItem::Type::Vector3);
return get_input_value("Vector", NodeItem::Type::Vector3);
}
#endif
NODE_SHADER_MATERIALX_END

View File

@ -245,7 +245,7 @@ IDTypeInfo IDType_ID_WM = {
/*main_listbase_index*/ INDEX_ID_WM,
/*struct_size*/ sizeof(wmWindowManager),
/*name*/ "WindowManager",
/*name_plural*/ "window_managers",
/*name_plural*/ N_("window managers"),
/*translation_context*/ BLT_I18NCONTEXT_ID_WINDOWMANAGER,
/*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING | IDTYPE_FLAGS_NO_ANIMDATA |
IDTYPE_FLAGS_NO_MEMFILE_UNDO,