USD: improve I/O of emission color in preview surface
Don't export color if strength is 0, and on import set strength to 1 when there is a color. This is more important now that the default is color white and strength 0 in the Principled BSDF. Ref #99447 Ref #112848
This commit is contained in:
parent
3d38b51435
commit
a469640861
@ -464,10 +464,16 @@ void USDMaterialReader::set_principled_node_inputs(bNode *principled,
|
||||
set_node_input(diffuse_input, principled, "Base Color", ntree, column, &context);
|
||||
}
|
||||
|
||||
float emission_strength = 0.0f;
|
||||
if (pxr::UsdShadeInput emissive_input = usd_shader.GetInput(usdtokens::emissiveColor)) {
|
||||
set_node_input(emissive_input, principled, "Emission Color", ntree, column, &context);
|
||||
if (set_node_input(emissive_input, principled, "Emission Color", ntree, column, &context)) {
|
||||
emission_strength = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bNodeSocket *emission_strength_sock = nodeFindSocket(principled, SOCK_IN, "Emission Strength");
|
||||
((bNodeSocketValueFloat *)emission_strength_sock->default_value)->value = emission_strength;
|
||||
|
||||
if (pxr::UsdShadeInput specular_input = usd_shader.GetInput(usdtokens::specularColor)) {
|
||||
set_node_input(specular_input, principled, "Specular Tint", ntree, column, &context);
|
||||
}
|
||||
@ -503,7 +509,7 @@ void USDMaterialReader::set_principled_node_inputs(bNode *principled,
|
||||
}
|
||||
}
|
||||
|
||||
void USDMaterialReader::set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
bool USDMaterialReader::set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
bNode *dest_node,
|
||||
const char *dest_socket_name,
|
||||
bNodeTree *ntree,
|
||||
@ -511,13 +517,13 @@ void USDMaterialReader::set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
NodePlacementContext *r_ctx) const
|
||||
{
|
||||
if (!(usd_input && dest_node && r_ctx)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usd_input.HasConnectedSource()) {
|
||||
/* The USD shader input has a connected source shader. Follow the connection
|
||||
* and attempt to convert the connected USD shader to a Blender node. */
|
||||
follow_connection(usd_input, dest_node, dest_socket_name, ntree, column, r_ctx);
|
||||
return follow_connection(usd_input, dest_node, dest_socket_name, ntree, column, r_ctx);
|
||||
}
|
||||
else {
|
||||
/* Set the destination node socket value from the USD shader input value. */
|
||||
@ -525,41 +531,46 @@ void USDMaterialReader::set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
bNodeSocket *sock = nodeFindSocket(dest_node, SOCK_IN, dest_socket_name);
|
||||
if (!sock) {
|
||||
std::cerr << "ERROR: couldn't get destination node socket " << dest_socket_name << std::endl;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::VtValue val;
|
||||
if (!usd_input.Get(&val)) {
|
||||
std::cerr << "ERROR: couldn't get value for usd shader input "
|
||||
<< usd_input.GetPrim().GetPath() << std::endl;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (sock->type) {
|
||||
case SOCK_FLOAT:
|
||||
if (val.IsHolding<float>()) {
|
||||
((bNodeSocketValueFloat *)sock->default_value)->value = val.UncheckedGet<float>();
|
||||
return true;
|
||||
}
|
||||
else if (val.IsHolding<pxr::GfVec3f>()) {
|
||||
pxr::GfVec3f v3f = val.UncheckedGet<pxr::GfVec3f>();
|
||||
float average = (v3f[0] + v3f[1] + v3f[2]) / 3.0f;
|
||||
((bNodeSocketValueFloat *)sock->default_value)->value = average;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SOCK_RGBA:
|
||||
if (val.IsHolding<pxr::GfVec3f>()) {
|
||||
pxr::GfVec3f v3f = val.UncheckedGet<pxr::GfVec3f>();
|
||||
copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, v3f.data());
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SOCK_VECTOR:
|
||||
if (val.IsHolding<pxr::GfVec3f>()) {
|
||||
pxr::GfVec3f v3f = val.UncheckedGet<pxr::GfVec3f>();
|
||||
copy_v3_v3(((bNodeSocketValueVector *)sock->default_value)->value, v3f.data());
|
||||
return true;
|
||||
}
|
||||
else if (val.IsHolding<pxr::GfVec2f>()) {
|
||||
pxr::GfVec2f v2f = val.UncheckedGet<pxr::GfVec2f>();
|
||||
copy_v2_v2(((bNodeSocketValueVector *)sock->default_value)->value, v2f.data());
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -568,9 +579,11 @@ void USDMaterialReader::set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
bNode *dest_node,
|
||||
const char *dest_socket_name,
|
||||
bNodeTree *ntree,
|
||||
@ -578,7 +591,7 @@ void USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
NodePlacementContext *r_ctx) const
|
||||
{
|
||||
if (!(usd_input && dest_node && dest_socket_name && ntree && r_ctx)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::UsdShadeConnectableAPI source;
|
||||
@ -588,20 +601,20 @@ void USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
usd_input.GetConnectedSource(&source, &source_name, &source_type);
|
||||
|
||||
if (!(source && source.GetPrim().IsA<pxr::UsdShadeShader>())) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::UsdShadeShader source_shader(source.GetPrim());
|
||||
|
||||
if (!source_shader) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::TfToken shader_id;
|
||||
if (!source_shader.GetShaderId(&shader_id)) {
|
||||
std::cerr << "ERROR: couldn't get shader id for source shader "
|
||||
<< source_shader.GetPrim().GetPath() << std::endl;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* For now, only convert UsdUVTexture and UsdPrimvarReader_float2 inputs. */
|
||||
@ -635,6 +648,8 @@ void USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
convert_usd_primvar_reader_float2(
|
||||
source_shader, source_name, dest_node, dest_socket_name, ntree, column + 1, r_ctx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void USDMaterialReader::convert_usd_uv_texture(const pxr::UsdShadeShader &usd_shader,
|
||||
|
@ -95,7 +95,7 @@ class USDMaterialReader {
|
||||
const pxr::UsdShadeShader &usd_shader) const;
|
||||
|
||||
/** Convert the given USD shader input to an input on the given Blender node. */
|
||||
void set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
bool set_node_input(const pxr::UsdShadeInput &usd_input,
|
||||
bNode *dest_node,
|
||||
const char *dest_socket_name,
|
||||
bNodeTree *ntree,
|
||||
@ -106,7 +106,7 @@ class USDMaterialReader {
|
||||
* Follow the connected source of the USD input to create corresponding inputs
|
||||
* for the given Blender node.
|
||||
*/
|
||||
void follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
bool follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
bNode *dest_node,
|
||||
const char *dest_socket_name,
|
||||
bNodeTree *ntree,
|
||||
|
@ -157,8 +157,18 @@ static void create_usd_preview_surface_material(const USDExporterContext &usd_ex
|
||||
}
|
||||
|
||||
const InputSpec &input_spec = it->second;
|
||||
bNodeLink *input_link = traverse_channel(sock, SH_NODE_TEX_IMAGE);
|
||||
|
||||
if (bNodeLink *input_link = traverse_channel(sock, SH_NODE_TEX_IMAGE)) {
|
||||
if (input_spec.input_name == usdtokens::emissive_color) {
|
||||
/* Don't export emission color if strength is zero. */
|
||||
bNodeSocket *emission_strength_sock = nodeFindSocket(node, SOCK_IN, "Emission Strength");
|
||||
if (!input_link &&
|
||||
((bNodeSocketValueFloat *)emission_strength_sock->default_value)->value == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (input_link) {
|
||||
/* Convert the texture image node connected to this input. */
|
||||
bNode *input_node = input_link->fromnode;
|
||||
pxr::UsdShadeShader usd_shader = create_usd_preview_shader(
|
||||
|
Loading…
Reference in New Issue
Block a user