Fix T82336: Cycles standard attributes missing in displacement shaders

Standard attributes are not added to the attributes requests when
shaders only have displacement. This is because nodes are only
considering the case when the surface socket is connected.

To support this, added `Shader.has_surface_link()` which checks for both
cases (`has_surface` and `has_displacement`) and replaces all checks on
`Shader.has_surface`.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D12240
This commit is contained in:
Kévin Dietrich 2021-08-13 13:19:05 +02:00
parent 88dc274d05
commit 60d6333b80
Notes: blender-bot 2023-02-14 11:42:40 +01:00
Referenced by issue #82336, Generated and UV texture coordinates not generated when no surface output is connected
3 changed files with 20 additions and 12 deletions

View File

@ -158,13 +158,13 @@ void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
foreach (ShaderInput *input, inputs) {
if (!input->link) {
if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
if (shader->has_surface)
if (shader->has_surface_link())
attributes->add(ATTR_STD_GENERATED);
if (shader->has_volume)
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
}
else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
if (shader->has_surface)
if (shader->has_surface_link())
attributes->add(ATTR_STD_UV);
}
}

View File

@ -350,7 +350,7 @@ void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attribute
#ifdef WITH_PTEX
/* todo: avoid loading other texture coordinates when using ptex,
* and hide texture coordinate socket in the UI */
if (shader->has_surface && string_endswith(filename, ".ptx")) {
if (shader->has_surface_link() && string_endswith(filename, ".ptx")) {
/* ptex */
attributes->add(ATTR_STD_PTEX_FACE_ID);
attributes->add(ATTR_STD_PTEX_UV);
@ -552,7 +552,7 @@ ImageParams EnvironmentTextureNode::image_params() const
void EnvironmentTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
#ifdef WITH_PTEX
if (shader->has_surface && string_endswith(filename, ".ptx")) {
if (shader->has_surface_link() && string_endswith(filename, ".ptx")) {
/* ptex */
attributes->add(ATTR_STD_PTEX_FACE_ID);
attributes->add(ATTR_STD_PTEX_UV);
@ -2319,7 +2319,7 @@ AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(get_node_type())
void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface) {
if (shader->has_surface_link()) {
ShaderInput *tangent_in = input("Tangent");
if (!tangent_in->link)
@ -2843,7 +2843,7 @@ bool PrincipledBsdfNode::has_surface_bssrdf()
void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface) {
if (shader->has_surface_link()) {
ShaderInput *tangent_in = input("Tangent");
if (!tangent_in->link)
@ -3684,7 +3684,7 @@ GeometryNode::GeometryNode() : ShaderNode(get_node_type())
void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface) {
if (shader->has_surface_link()) {
if (!output("Tangent")->links.empty()) {
attributes->add(ATTR_STD_GENERATED);
}
@ -3830,7 +3830,7 @@ TextureCoordinateNode::TextureCoordinateNode() : ShaderNode(get_node_type())
void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface) {
if (shader->has_surface_link()) {
if (!from_dupli) {
if (!output("Generated")->links.empty())
attributes->add(ATTR_STD_GENERATED);
@ -4388,7 +4388,7 @@ HairInfoNode::HairInfoNode() : ShaderNode(get_node_type())
void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface) {
if (shader->has_surface_link()) {
ShaderOutput *intercept_out = output("Intercept");
if (!intercept_out->links.empty())
@ -6744,7 +6744,7 @@ NormalMapNode::NormalMapNode() : ShaderNode(get_node_type())
void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
if (shader->has_surface_link() && space == NODE_NORMAL_MAP_TANGENT) {
if (attribute.empty()) {
attributes->add(ATTR_STD_UV_TANGENT);
attributes->add(ATTR_STD_UV_TANGENT_SIGN);
@ -6838,7 +6838,7 @@ TangentNode::TangentNode() : ShaderNode(get_node_type())
void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface) {
if (shader->has_surface_link()) {
if (direction_type == NODE_TANGENT_UVMAP) {
if (attribute.empty())
attributes->add(ATTR_STD_UV_TANGENT);
@ -7021,7 +7021,7 @@ void VectorDisplacementNode::constant_fold(const ConstantFolder &folder)
void VectorDisplacementNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
if (shader->has_surface_link() && space == NODE_NORMAL_MAP_TANGENT) {
if (attribute.empty()) {
attributes->add(ATTR_STD_UV_TANGENT);
attributes->add(ATTR_STD_UV_TANGENT_SIGN);

View File

@ -154,6 +154,14 @@ class Shader : public Node {
void tag_update(Scene *scene);
void tag_used(Scene *scene);
/* Return true when either of the surface or displacement socket of the output node is linked.
* This should be used to ensure that surface attributes are also requested even when only the
* displacement socket is linked. */
bool has_surface_link() const
{
return has_surface || has_displacement;
}
bool need_update_geometry() const;
};