forked from blender/blender
Create parsing system that converts supported nodes and ignores unsupported #2
@ -209,6 +209,10 @@ if(WITH_OPENVDB)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_MATERIALX)
|
||||||
|
list(APPEND LIB MaterialXCore)
|
||||||
|
endif()
|
||||||
|
|
||||||
blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||||
|
|
||||||
# RNA_prototypes.h
|
# RNA_prototypes.h
|
||||||
|
@ -52,7 +52,9 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
const View3D *view3d = nullptr;
|
const View3D *view3d = nullptr;
|
||||||
Main *bmain = nullptr;
|
Main *bmain = nullptr;
|
||||||
Scene *scene = nullptr;
|
Scene *scene = nullptr;
|
||||||
|
|
||||||
ShadingSettings shading_settings;
|
ShadingSettings shading_settings;
|
||||||
|
bool use_materialx = true;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ObjectDataMap objects_;
|
ObjectDataMap objects_;
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
#include <pxr/imaging/hd/tokens.h>
|
#include <pxr/imaging/hd/tokens.h>
|
||||||
#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
|
#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
|
||||||
|
|
||||||
|
#include <pxr/usd/usdMtlx/reader.h>
|
||||||
|
#include <pxr/usd/usdMtlx/utils.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "BKE_lib_id.h"
|
#include "BKE_lib_id.h"
|
||||||
@ -30,6 +33,7 @@
|
|||||||
|
|
||||||
#include "intern/usd_exporter_context.h"
|
#include "intern/usd_exporter_context.h"
|
||||||
#include "intern/usd_writer_material.h"
|
#include "intern/usd_writer_material.h"
|
||||||
|
#include "shader/materialx/material.h"
|
||||||
|
|
||||||
namespace blender::io::hydra {
|
namespace blender::io::hydra {
|
||||||
|
|
||||||
@ -66,10 +70,22 @@ void MaterialData::init()
|
|||||||
time,
|
time,
|
||||||
export_params,
|
export_params,
|
||||||
image_cache_file_path()};
|
image_cache_file_path()};
|
||||||
|
|
||||||
/* Create USD material. */
|
/* Create USD material. */
|
||||||
pxr::UsdShadeMaterial usd_material = usd::create_usd_material(
|
pxr::UsdShadeMaterial usd_material;
|
||||||
export_context, material_path, (Material *)id, "st");
|
if (scene_delegate_->use_materialx) {
|
||||||
|
MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(
|
||||||
|
scene_delegate_->depsgraph, (Material *)id);
|
||||||
|
pxr::UsdMtlxRead(doc, stage);
|
||||||
|
if (pxr::UsdPrim materials = stage->GetPrimAtPath(pxr::SdfPath("/MaterialX/Materials"))) {
|
||||||
|
pxr::UsdPrimSiblingRange children = materials.GetChildren();
|
||||||
|
if (!children.empty()) {
|
||||||
|
usd_material = pxr::UsdShadeMaterial(*children.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
usd_material = usd::create_usd_material(export_context, material_path, (Material *)id, "st");
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert USD material to Hydra material network map, adapted for render delegate. */
|
/* Convert USD material to Hydra material network map, adapted for render delegate. */
|
||||||
const pxr::HdRenderDelegate *render_delegate =
|
const pxr::HdRenderDelegate *render_delegate =
|
||||||
|
@ -145,18 +145,19 @@ set(LIB
|
|||||||
|
|
||||||
if(WITH_MATERIALX)
|
if(WITH_MATERIALX)
|
||||||
list(APPEND LIB MaterialXCore)
|
list(APPEND LIB MaterialXCore)
|
||||||
|
list(APPEND LIB MaterialXFormat)
|
||||||
list(APPEND SRC
|
list(APPEND SRC
|
||||||
materialx/material.cc
|
materialx/material.cc
|
||||||
materialx/nodes/node.cc
|
materialx/nodes/bsdf_principled.cc
|
||||||
materialx/nodes/material_output.cc
|
materialx/nodes/node_parser.cc
|
||||||
materialx/nodes/principled_bsdf.cc
|
materialx/nodes/output_material.cc
|
||||||
materialx/nodes/image.cc
|
materialx/nodes/tex_image.cc
|
||||||
|
|
||||||
materialx/material.h
|
materialx/material.h
|
||||||
materialx/nodes/node.h
|
materialx/nodes/bsdf_principled.h
|
||||||
materialx/nodes/material_output.h
|
materialx/nodes/node_parser.h
|
||||||
materialx/nodes/principled_bsdf.h
|
materialx/nodes/output_material.h
|
||||||
materialx/nodes/image.h
|
materialx/nodes/tex_image.h
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -3,34 +3,37 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "nodes/material_output.h"
|
#include "nodes/output_material.h"
|
||||||
|
|
||||||
#include <MaterialXCore/Node.h>
|
#include <MaterialXCore/Node.h>
|
||||||
|
#include <MaterialXFormat/XmlIo.h>
|
||||||
|
|
||||||
#include "NOD_shader.h"
|
#include "NOD_shader.h"
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
static void export_nodegraph(MaterialX::DocumentPtr doc, Depsgraph *depsgraph, Material *material)
|
static void export_nodegraph(MaterialX::GraphElement *graph,
|
||||||
|
Depsgraph *depsgraph,
|
||||||
|
Material *material)
|
||||||
{
|
{
|
||||||
material->nodetree->ensure_topology_cache();
|
material->nodetree->ensure_topology_cache();
|
||||||
|
|
||||||
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
||||||
MaterialXMaterialOutputNode material_node(doc, depsgraph, material, output_node);
|
OutputMaterialNodeParser parser(graph, depsgraph, material, output_node);
|
||||||
material_node.convert();
|
parser.compute();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_standard_surface(MaterialX::DocumentPtr doc, Material *material)
|
static void create_standard_surface(MaterialX::GraphElement *graph, Material *material)
|
||||||
{
|
{
|
||||||
MaterialX::NodePtr surfacematerial = doc->addNode(
|
MaterialX::NodePtr standard_surface = graph->addNode(
|
||||||
"surfacematerial", MaterialX::EMPTY_STRING, "material");
|
|
||||||
MaterialX::NodePtr standard_surface = doc->addNode(
|
|
||||||
"standard_surface", MaterialX::EMPTY_STRING, "surfaceshader");
|
"standard_surface", MaterialX::EMPTY_STRING, "surfaceshader");
|
||||||
|
|
||||||
standard_surface->addInput("base", "float")->setValue(1.0);
|
standard_surface->addInput("base", "float")->setValue(1.0);
|
||||||
standard_surface->addInput("base_color", "color3")
|
standard_surface->addInput("base_color", "color3")
|
||||||
->setValue(MaterialX::Color3(material->r, material->g, material->b));
|
->setValue(MaterialX::Color3(material->r, material->g, material->b));
|
||||||
|
|
||||||
|
MaterialX::NodePtr surfacematerial = graph->addNode(
|
||||||
|
"surfacematerial", MaterialX::EMPTY_STRING, "material");
|
||||||
surfacematerial->addInput(standard_surface->getType(), standard_surface->getType())
|
surfacematerial->addInput(standard_surface->getType(), standard_surface->getType())
|
||||||
->setNodeName(standard_surface->getName());
|
->setNodeName(standard_surface->getName());
|
||||||
}
|
}
|
||||||
@ -39,11 +42,13 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
|
|||||||
{
|
{
|
||||||
MaterialX::DocumentPtr doc = MaterialX::createDocument();
|
MaterialX::DocumentPtr doc = MaterialX::createDocument();
|
||||||
if (material->use_nodes) {
|
if (material->use_nodes) {
|
||||||
export_nodegraph(doc, depsgraph, material);
|
export_nodegraph(doc.get(), depsgraph, material);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
create_standard_surface(doc, material);
|
create_standard_surface(doc.get(), material);
|
||||||
}
|
}
|
||||||
|
std::string str = MaterialX::writeToXmlString(doc);
|
||||||
|
printf("\nMaterial: %s\n%s\n", material->id.name, str.c_str());
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
145
source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc
Normal file
145
source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "bsdf_principled.h"
|
||||||
|
|
||||||
|
#include <BKE_node_runtime.hh>
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem BSDFPrincipledNodeParser::compute()
|
||||||
|
{
|
||||||
|
auto enabled = [](NodeItem &val) -> bool {
|
||||||
|
if (val.node) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!val.value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (val.value->isA<float>()) {
|
||||||
|
return val.value->asA<float>() != 0.0f;
|
||||||
|
}
|
||||||
|
if (val.value->isA<MaterialX::Color4>()) {
|
||||||
|
auto c = val.value->asA<MaterialX::Color4>();
|
||||||
|
return c[0] != 0.0f || c[1] != 0.0f || c[2] != 0.0f;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Getting required inputs
|
||||||
|
* Note: if some inputs are not needed they won't be taken */
|
||||||
|
NodeItem base_color = get_input_value("Base Color");
|
||||||
|
|
||||||
|
NodeItem subsurface = get_input_value("Subsurface");
|
||||||
|
NodeItem subsurface_radius = empty_value();
|
||||||
|
NodeItem subsurface_color = empty_value();
|
||||||
|
if (enabled(subsurface)) {
|
||||||
|
subsurface_radius = get_input_value("Subsurface Radius");
|
||||||
|
subsurface_color = get_input_value("Subsurface Color");
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem metallic = get_input_value("Metallic");
|
||||||
|
NodeItem specular = get_input_value("Specular");
|
||||||
|
// NodeItem specular_tint = get_input_value("Specular Tint");
|
||||||
|
NodeItem roughness = get_input_value("Roughness");
|
||||||
|
|
||||||
|
NodeItem anisotropic = empty_value();
|
||||||
|
NodeItem anisotropic_rotation = empty_value();
|
||||||
|
if (enabled(metallic)) {
|
||||||
|
/* TODO: use Specular Tint input */
|
||||||
|
anisotropic = get_input_value("Anisotropic");
|
||||||
|
if (enabled(anisotropic)) {
|
||||||
|
anisotropic_rotation = get_input_value("Anisotropic Rotation");
|
||||||
|
// anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem sheen = get_input_value("Sheen");
|
||||||
|
// sheen_tint = empty_value();
|
||||||
|
// if enabled(sheen):
|
||||||
|
// sheen_tint = get_input_value("Sheen Tint");
|
||||||
|
|
||||||
|
NodeItem clearcoat = get_input_value("Clearcoat");
|
||||||
|
NodeItem clearcoat_roughness = empty_value();
|
||||||
|
if (enabled(clearcoat)) {
|
||||||
|
clearcoat_roughness = get_input_value("Clearcoat Roughness");
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem ior = get_input_value("IOR");
|
||||||
|
|
||||||
|
NodeItem transmission = get_input_value("Transmission");
|
||||||
|
NodeItem transmission_roughness = empty_value();
|
||||||
|
if (enabled(transmission)) {
|
||||||
|
transmission_roughness = get_input_value("Transmission Roughness");
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem emission = get_input_value("Emission");
|
||||||
|
NodeItem emission_strength = get_input_value("Emission Strength");
|
||||||
|
|
||||||
|
NodeItem alpha = get_input_value("Alpha");
|
||||||
|
// transparency = 1.0 - alpha
|
||||||
|
|
||||||
|
NodeItem normal = get_input_link("Normal");
|
||||||
|
NodeItem clearcoat_normal = get_input_link("Clearcoat Normal");
|
||||||
|
NodeItem tangent = get_input_link("Tangent");
|
||||||
|
|
||||||
|
/* Creating standard_surface */
|
||||||
|
NodeItem res = create_node("standard_surface", "surfaceshader");
|
||||||
|
res.set_input("base", 1.0, "float");
|
||||||
|
res.set_input("base_color", base_color.to_color3());
|
||||||
|
res.set_input("diffuse_roughness", roughness);
|
||||||
|
res.set_input("normal", normal);
|
||||||
|
res.set_input("tangent", tangent);
|
||||||
|
|
||||||
|
if (enabled(metallic)) {
|
||||||
|
res.set_input("metalness", metallic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled(specular)) {
|
||||||
|
res.set_input("specular", specular);
|
||||||
|
res.set_input("specular_color", base_color.to_color3());
|
||||||
|
res.set_input("specular_roughness", roughness);
|
||||||
|
res.set_input("specular_IOR", ior);
|
||||||
|
res.set_input("specular_anisotropy", anisotropic);
|
||||||
|
res.set_input("specular_rotation", anisotropic_rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled(transmission)) {
|
||||||
|
res.set_input("transmission", transmission);
|
||||||
|
res.set_input("transmission_color", base_color.to_color3());
|
||||||
|
res.set_input("transmission_extra_roughness", transmission_roughness);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled(subsurface)) {
|
||||||
|
res.set_input("subsurface", subsurface);
|
||||||
|
res.set_input("subsurface_color", subsurface_color);
|
||||||
|
res.set_input("subsurface_radius", subsurface_radius);
|
||||||
|
res.set_input("subsurface_anisotropy", anisotropic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled(sheen)) {
|
||||||
|
res.set_input("sheen", sheen);
|
||||||
|
res.set_input("sheen_color", base_color.to_color3());
|
||||||
|
res.set_input("sheen_roughness", roughness);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled(clearcoat)) {
|
||||||
|
res.set_input("coat", clearcoat);
|
||||||
|
res.set_input("coat_color", base_color.to_color3());
|
||||||
|
res.set_input("coat_roughness", clearcoat_roughness);
|
||||||
|
res.set_input("coat_IOR", ior);
|
||||||
|
res.set_input("coat_anisotropy", anisotropic);
|
||||||
|
res.set_input("coat_rotation", anisotropic_rotation);
|
||||||
|
res.set_input("coat_normal", clearcoat_normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled(emission)) {
|
||||||
|
res.set_input("emission", emission_strength);
|
||||||
|
res.set_input("emission_color", emission);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
class BSDFPrincipledNodeParser : public NodeParser {
|
||||||
|
public:
|
||||||
|
using NodeParser::NodeParser;
|
||||||
|
NodeItem compute() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -1,45 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
#include "hydra/image.h"
|
|
||||||
|
|
||||||
#include "DEG_depsgraph_query.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
const MaterialX::Color3 MaterialXTexImageNode::texture_error_color_{1.0, 0.0, 1.0};
|
|
||||||
|
|
||||||
MaterialXTexImageNode::MaterialXTexImageNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node)
|
|
||||||
: MaterialXNode(doc, depsgraph, material, node)
|
|
||||||
{
|
|
||||||
matx_node = doc->addNode("image", MaterialX::createValidName(node->name), "color3");
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialX::NodePtr MaterialXTexImageNode::convert()
|
|
||||||
{
|
|
||||||
Image *image = (Image *)node->id;
|
|
||||||
NodeTexImage *tex = static_cast<NodeTexImage *>(node->storage);
|
|
||||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
|
||||||
Main *bmain = DEG_get_bmain(depsgraph);
|
|
||||||
std::string image_path;
|
|
||||||
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contain
|
|
||||||
* pretty general code, so could be moved from bf_usd project. */
|
|
||||||
#ifdef WITH_HYDRA
|
|
||||||
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
|
||||||
#endif
|
|
||||||
MaterialX::NodePtr uv_node = doc->addNode("texcoord", MaterialX::EMPTY_STRING, "vector2");
|
|
||||||
|
|
||||||
matx_node->addInput("file", "filename")->setValue(image_path);
|
|
||||||
matx_node->addInput("texcoord", "vector2")->setNodeName(uv_node->getName());
|
|
||||||
|
|
||||||
return matx_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
@ -1,24 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
class MaterialXTexImageNode : public MaterialXNode {
|
|
||||||
protected:
|
|
||||||
/* Following Cycles color for wrong Texture nodes. */
|
|
||||||
static const MaterialX::Color3 texture_error_color_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MaterialXTexImageNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node);
|
|
||||||
MaterialX::NodePtr convert() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
@ -1,35 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#include "material_output.h"
|
|
||||||
#include "principled_bsdf.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
MaterialXMaterialOutputNode::MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node)
|
|
||||||
: MaterialXNode(doc, depsgraph, material, node)
|
|
||||||
{
|
|
||||||
matx_node = doc->addNode("surfacematerial", MaterialX::createValidName(node->name), "material");
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialX::NodePtr MaterialXMaterialOutputNode::convert()
|
|
||||||
{
|
|
||||||
LISTBASE_FOREACH (const bNodeSocket *, sock, &node->inputs) {
|
|
||||||
if (!sock->link) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (STREQ(sock->name, "Surface")) {
|
|
||||||
const bNode *inode = sock->link->fromnode;
|
|
||||||
MaterialXPrincipledBSDFNode surface_node(doc, depsgraph, material, inode);
|
|
||||||
surface_node.convert();
|
|
||||||
matx_node->addInput("surfaceshader", "surfaceshader")->setNodeName(inode->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matx_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
@ -1,20 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
class MaterialXMaterialOutputNode : public MaterialXNode {
|
|
||||||
public:
|
|
||||||
MaterialXMaterialOutputNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node);
|
|
||||||
MaterialX::NodePtr convert() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
@ -1,17 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
MaterialXNode::MaterialXNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node)
|
|
||||||
: depsgraph(depsgraph), material(material), node(node), doc(doc)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
@ -1,33 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <MaterialXCore/Document.h>
|
|
||||||
|
|
||||||
#include "DEG_depsgraph.h"
|
|
||||||
#include "DNA_material_types.h"
|
|
||||||
#include "DNA_node_types.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
class MaterialXNode {
|
|
||||||
public:
|
|
||||||
const Depsgraph *depsgraph = nullptr;
|
|
||||||
const Material *material = nullptr;
|
|
||||||
const bNode *node = nullptr;
|
|
||||||
MaterialX::NodePtr matx_node;
|
|
||||||
MaterialX::DocumentPtr doc;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MaterialXNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node);
|
|
||||||
virtual ~MaterialXNode() = default;
|
|
||||||
|
|
||||||
virtual MaterialX::NodePtr convert() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
180
source/blender/nodes/shader/materialx/nodes/node_parser.cc
Normal file
180
source/blender/nodes/shader/materialx/nodes/node_parser.cc
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
#include "bsdf_principled.h"
|
||||||
|
#include "tex_image.h"
|
||||||
|
|
||||||
|
#include <BKE_node_runtime.hh>
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem::NodeItem(MaterialX::GraphElement *graph) : graph_(graph) {}
|
||||||
|
|
||||||
|
void NodeItem::set_input(const std::string &name, const NodeItem &item)
|
||||||
|
{
|
||||||
|
if (item.value) {
|
||||||
|
set_input(name, item.value);
|
||||||
|
}
|
||||||
|
else if (item.node) {
|
||||||
|
set_input(name, item.node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeItem::set_input(const std::string &name, const MaterialX::ValuePtr value)
|
||||||
|
{
|
||||||
|
if (value->isA<float>()) {
|
||||||
|
set_input(name, value->asA<float>(), "float");
|
||||||
|
}
|
||||||
|
else if (value->isA<MaterialX::Vector3>()) {
|
||||||
|
set_input(name, value->asA<MaterialX::Vector3>(), "vector3");
|
||||||
|
}
|
||||||
|
else if (value->isA<MaterialX::Vector4>()) {
|
||||||
|
set_input(name, value->asA<MaterialX::Vector4>(), "vector4");
|
||||||
|
}
|
||||||
|
else if (value->isA<MaterialX::Color3>()) {
|
||||||
|
set_input(name, value->asA<MaterialX::Color3>(), "color3");
|
||||||
|
}
|
||||||
|
else if (value->isA<MaterialX::Color4>()) {
|
||||||
|
set_input(name, value->asA<MaterialX::Color4>(), "color4");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeItem::set_input(const std::string &name, const MaterialX::NodePtr node)
|
||||||
|
{
|
||||||
|
this->node->setConnectedNode(name, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem::operator bool() const
|
||||||
|
{
|
||||||
|
return value || node;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::to_color3()
|
||||||
|
{
|
||||||
|
NodeItem res(graph_);
|
||||||
|
if (value) {
|
||||||
|
if (value->isA<float>()) {
|
||||||
|
float v = value->asA<float>();
|
||||||
|
res.value = MaterialX::Value::createValue<MaterialX::Color3>(MaterialX::Color3(v, v, v));
|
||||||
|
}
|
||||||
|
else if (value->isA<MaterialX::Color3>()) {
|
||||||
|
res.value = value;
|
||||||
|
}
|
||||||
|
else if (value->isA<MaterialX::Color4>()) {
|
||||||
|
auto c = value->asA<MaterialX::Color4>();
|
||||||
|
res.value = MaterialX::Value::createValue<MaterialX::Color3>(
|
||||||
|
MaterialX::Color3(c[0], c[1], c[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node) {
|
||||||
|
res.node = node;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
||||||
|
const Depsgraph *depsgraph,
|
||||||
|
const Material *material,
|
||||||
|
const bNode *node)
|
||||||
|
: graph(graph), depsgraph(depsgraph), material(material), node(node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeParser::create_node(const std::string &mx_category,
|
||||||
|
const std::string &mx_type,
|
||||||
|
bool accessory)
|
||||||
|
{
|
||||||
|
NodeItem res = empty_value();
|
||||||
|
res.node = graph->addNode(mx_category,
|
||||||
|
accessory ? MaterialX::EMPTY_STRING :
|
||||||
|
MaterialX::createValidName(node->name),
|
||||||
|
mx_type);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeParser::get_input_default(const std::string &name)
|
||||||
|
{
|
||||||
|
NodeItem res = empty_value();
|
||||||
|
|
||||||
|
const bNodeSocket &socket = node->input_by_identifier(name);
|
||||||
|
switch (socket.type) {
|
||||||
|
case SOCK_FLOAT: {
|
||||||
|
float v = socket.default_value_typed<bNodeSocketValueFloat>()->value;
|
||||||
|
res.value = MaterialX::Value::createValue<float>(v);
|
||||||
|
} break;
|
||||||
|
case SOCK_VECTOR: {
|
||||||
|
const float *v = socket.default_value_typed<bNodeSocketValueVector>()->value;
|
||||||
|
res.value = MaterialX::Value::createValue<MaterialX::Vector3>(
|
||||||
|
MaterialX::Vector3(v[0], v[1], v[2]));
|
||||||
|
} break;
|
||||||
|
case SOCK_RGBA: {
|
||||||
|
const float *v = socket.default_value_typed<bNodeSocketValueRGBA>()->value;
|
||||||
|
res.value = MaterialX::Value::createValue<MaterialX::Color4>(
|
||||||
|
MaterialX::Color4(v[0], v[1], v[2], v[3]));
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
// TODO log warn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeParser::get_input_link(const std::string &name)
|
||||||
|
{
|
||||||
|
NodeItem res = empty_value();
|
||||||
|
|
||||||
|
const bNodeLink *link = node->input_by_identifier(name).link;
|
||||||
|
if (!(link && link->is_used())) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bNode *in_node = link->fromnode;
|
||||||
|
|
||||||
|
/* Passing NODE_REROUTE nodes */
|
||||||
|
while (in_node->type == NODE_REROUTE) {
|
||||||
|
link = in_node->input_socket(0).link;
|
||||||
|
if (!(link && link->is_used())) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
in_node = link->fromnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Getting required NodeParser object */
|
||||||
|
std::unique_ptr<NodeParser> parser;
|
||||||
|
switch (in_node->type) {
|
||||||
|
case SH_NODE_BSDF_PRINCIPLED:
|
||||||
|
parser = std::make_unique<BSDFPrincipledNodeParser>(graph, depsgraph, material, in_node);
|
||||||
|
break;
|
||||||
|
case SH_NODE_TEX_IMAGE:
|
||||||
|
parser = std::make_unique<TexImageNodeParser>(graph, depsgraph, material, in_node);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO: warning log
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = parser->compute();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeParser::get_input_value(const std::string &name)
|
||||||
|
{
|
||||||
|
NodeItem res = get_input_link(name);
|
||||||
|
if (!res) {
|
||||||
|
res = get_input_default(name);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeParser::empty_value()
|
||||||
|
{
|
||||||
|
return NodeItem(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
70
source/blender/nodes/shader/materialx/nodes/node_parser.h
Normal file
70
source/blender/nodes/shader/materialx/nodes/node_parser.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <MaterialXCore/Document.h>
|
||||||
|
|
||||||
|
#include "DEG_depsgraph.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_node_types.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
class NodeItem {
|
||||||
|
public:
|
||||||
|
MaterialX::ValuePtr value;
|
||||||
|
MaterialX::NodePtr node;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MaterialX::GraphElement *graph_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NodeItem(MaterialX::GraphElement *graph);
|
||||||
|
~NodeItem() = default;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void set_input(const std::string &name, const T &value, const std::string &mx_type);
|
||||||
|
void set_input(const std::string &name, const NodeItem &item);
|
||||||
|
void set_input(const std::string &name, const MaterialX::ValuePtr value);
|
||||||
|
void set_input(const std::string &name, const MaterialX::NodePtr node);
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
|
NodeItem to_color3();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void NodeItem::set_input(const std::string &name, const T &value, const std::string &mx_type)
|
||||||
|
{
|
||||||
|
node->setInputValue(name, value, mx_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NodeParser {
|
||||||
|
public:
|
||||||
|
MaterialX::GraphElement *graph;
|
||||||
|
const Depsgraph *depsgraph;
|
||||||
|
const Material *material;
|
||||||
|
const bNode *node;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NodeParser(MaterialX::GraphElement *graph,
|
||||||
|
const Depsgraph *depsgraph,
|
||||||
|
const Material *material,
|
||||||
|
const bNode *node);
|
||||||
|
virtual ~NodeParser() = default;
|
||||||
|
|
||||||
|
virtual NodeItem compute() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NodeItem create_node(const std::string &mx_category,
|
||||||
|
const std::string &mx_type,
|
||||||
|
bool accessory = false);
|
||||||
|
NodeItem get_input_default(const std::string &name);
|
||||||
|
NodeItem get_input_link(const std::string &name);
|
||||||
|
NodeItem get_input_value(const std::string &name);
|
||||||
|
NodeItem empty_value();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -0,0 +1,20 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "output_material.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem OutputMaterialNodeParser::compute()
|
||||||
|
{
|
||||||
|
NodeItem node = empty_value();
|
||||||
|
NodeItem surface = get_input_link("Surface");
|
||||||
|
if (surface) {
|
||||||
|
node = create_node("surfacematerial", "material");
|
||||||
|
node.set_input("surfaceshader", surface);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
class OutputMaterialNodeParser : public NodeParser {
|
||||||
|
public:
|
||||||
|
using NodeParser::NodeParser;
|
||||||
|
NodeItem compute() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -1,126 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#include "principled_bsdf.h"
|
|
||||||
|
|
||||||
#include <BKE_node_runtime.hh>
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
const MaterialX::Color3 MaterialXPrincipledBSDFNode::default_white_color_{1.0, 1.0, 1.0};
|
|
||||||
|
|
||||||
MaterialXPrincipledBSDFNode::MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node)
|
|
||||||
: MaterialXNode(doc, depsgraph, material, node)
|
|
||||||
{
|
|
||||||
matx_node = doc->addNode(
|
|
||||||
"standard_surface", MaterialX::createValidName(node->name), "surfaceshader");
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialX::NodePtr MaterialXPrincipledBSDFNode::convert()
|
|
||||||
{
|
|
||||||
#pragma region get inputs
|
|
||||||
const float *base_color =
|
|
||||||
node->input_by_identifier("Base Color").default_value_typed<bNodeSocketValueRGBA>()->value;
|
|
||||||
const float subsurface =
|
|
||||||
node->input_by_identifier("Subsurface").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
|
|
||||||
const float *subsurface_radius = node->input_by_identifier("Subsurface Radius")
|
|
||||||
.default_value_typed<bNodeSocketValueVector>()
|
|
||||||
->value;
|
|
||||||
const float *subsurface_color = node->input_by_identifier("Subsurface Color")
|
|
||||||
.default_value_typed<bNodeSocketValueRGBA>()
|
|
||||||
->value;
|
|
||||||
const float metallic =
|
|
||||||
node->input_by_identifier("Metallic").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float specular =
|
|
||||||
node->input_by_identifier("Specular").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float roughness =
|
|
||||||
node->input_by_identifier("Roughness").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float anisotropic =
|
|
||||||
node->input_by_identifier("Anisotropic").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float anisotropic_rot = node->input_by_identifier("Anisotropic Rotation")
|
|
||||||
.default_value_typed<bNodeSocketValueFloat>()
|
|
||||||
->value;
|
|
||||||
const float sheen =
|
|
||||||
node->input_by_identifier("Sheen").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float clearcoat =
|
|
||||||
node->input_by_identifier("Clearcoat").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float clearcoat_roughness = node->input_by_identifier("Clearcoat Roughness")
|
|
||||||
.default_value_typed<bNodeSocketValueFloat>()
|
|
||||||
->value;
|
|
||||||
const float IOR =
|
|
||||||
node->input_by_identifier("IOR").default_value_typed<bNodeSocketValueFloat>()->value;
|
|
||||||
const float transmission = node->input_by_identifier("Transmission")
|
|
||||||
.default_value_typed<bNodeSocketValueFloat>()
|
|
||||||
->value;
|
|
||||||
const float *emission =
|
|
||||||
node->input_by_identifier("Emission").default_value_typed<bNodeSocketValueRGBA>()->value;
|
|
||||||
const float emission_str = node->input_by_identifier("Emission Strength")
|
|
||||||
.default_value_typed<bNodeSocketValueFloat>()
|
|
||||||
->value;
|
|
||||||
const float *normal =
|
|
||||||
node->input_by_identifier("Normal").default_value_typed<bNodeSocketValueVector>()->value;
|
|
||||||
const float *clearcoat_normal = node->input_by_identifier("Clearcoat Normal")
|
|
||||||
.default_value_typed<bNodeSocketValueVector>()
|
|
||||||
->value;
|
|
||||||
const float *tangent =
|
|
||||||
node->input_by_identifier("Tangent").default_value_typed<bNodeSocketValueVector>()->value;
|
|
||||||
#pragma endregion get inputs
|
|
||||||
|
|
||||||
#pragma region set inputs
|
|
||||||
matx_node->addInput("base", "float")->setValue(1.0);
|
|
||||||
matx_node->addInput("base_color", "color3")
|
|
||||||
->setValue(MaterialX::Color3(base_color[0], base_color[1], base_color[2]));
|
|
||||||
matx_node->addInput("diffuse_roughness", "float")->setValue(roughness);
|
|
||||||
matx_node->addInput("normal", "vector3")
|
|
||||||
->setValue(MaterialX::Vector3(normal[0], normal[1], normal[2]));
|
|
||||||
matx_node->addInput("tangent", "vector3")
|
|
||||||
->setValue(MaterialX::Vector3(tangent[0], tangent[1], tangent[2]));
|
|
||||||
|
|
||||||
matx_node->addInput("metalness", "float")->setValue(metallic);
|
|
||||||
|
|
||||||
matx_node->addInput("specular", "float")->setValue(specular);
|
|
||||||
matx_node->addInput("specular_color", "color3")->setValue(default_white_color_);
|
|
||||||
matx_node->addInput("specular_roughness", "float")->setValue(roughness);
|
|
||||||
matx_node->addInput("specular_IOR", "float")->setValue(IOR);
|
|
||||||
matx_node->addInput("specular_anisotropy", "float")->setValue(anisotropic);
|
|
||||||
matx_node->addInput("specular_rotation", "float")->setValue(anisotropic_rot);
|
|
||||||
|
|
||||||
matx_node->addInput("transmission", "float")->setValue(transmission);
|
|
||||||
matx_node->addInput("transmission_color", "color3")->setValue(default_white_color_);
|
|
||||||
matx_node->addInput("transmission_extra_roughness", "float")->setValue(roughness);
|
|
||||||
|
|
||||||
matx_node->addInput("subsurface", "float")->setValue(subsurface);
|
|
||||||
matx_node->addInput("subsurface_color", "color3")
|
|
||||||
->setValue(MaterialX::Color3(subsurface_color[0], subsurface_color[1], subsurface_color[2]));
|
|
||||||
matx_node->addInput("subsurface_radius", "color3")
|
|
||||||
->setValue(
|
|
||||||
MaterialX::Color3(subsurface_radius[0], subsurface_radius[1], subsurface_radius[2]));
|
|
||||||
matx_node->addInput("subsurface_anisotropy", "float")->setValue(anisotropic);
|
|
||||||
|
|
||||||
matx_node->addInput("sheen", "float")->setValue(sheen);
|
|
||||||
matx_node->addInput("sheen_color", "color3")->setValue(default_white_color_);
|
|
||||||
matx_node->addInput("sheen_roughness", "float")->setValue(roughness);
|
|
||||||
|
|
||||||
matx_node->addInput("coat", "float")->setValue(clearcoat);
|
|
||||||
matx_node->addInput("coat_color", "color3")->setValue(default_white_color_);
|
|
||||||
matx_node->addInput("coat_roughness", "float")->setValue(clearcoat_roughness);
|
|
||||||
matx_node->addInput("coat_IOR", "float")->setValue(IOR);
|
|
||||||
matx_node->addInput("coat_anisotropy", "float")->setValue(anisotropic);
|
|
||||||
matx_node->addInput("coat_rotation", "float")->setValue(anisotropic_rot);
|
|
||||||
matx_node->addInput("coat_normal", "vector3")
|
|
||||||
->setValue(
|
|
||||||
MaterialX::Vector3(clearcoat_normal[0], clearcoat_normal[1], clearcoat_normal[2]));
|
|
||||||
|
|
||||||
matx_node->addInput("emission", "float")->setValue(emission_str);
|
|
||||||
matx_node->addInput("emission_color", "color3")
|
|
||||||
->setValue(MaterialX::Color3(emission[0], emission[1], emission[2]));
|
|
||||||
#pragma endregion set inputs
|
|
||||||
return matx_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
@ -1,23 +0,0 @@
|
|||||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
|
|
||||||
namespace blender::nodes::materialx {
|
|
||||||
|
|
||||||
class MaterialXPrincipledBSDFNode : public MaterialXNode {
|
|
||||||
protected:
|
|
||||||
static const MaterialX::Color3 default_white_color_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MaterialXPrincipledBSDFNode(MaterialX::DocumentPtr doc,
|
|
||||||
const Depsgraph *depsgraph,
|
|
||||||
const Material *material,
|
|
||||||
const bNode *node);
|
|
||||||
MaterialX::NodePtr convert() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
|
34
source/blender/nodes/shader/materialx/nodes/tex_image.cc
Normal file
34
source/blender/nodes/shader/materialx/nodes/tex_image.cc
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "tex_image.h"
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
#include "hydra/image.h"
|
||||||
|
|
||||||
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
NodeItem TexImageNodeParser::compute()
|
||||||
|
{
|
||||||
|
Image *image = (Image *)node->id;
|
||||||
|
NodeTexImage *tex = static_cast<NodeTexImage *>(node->storage);
|
||||||
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
|
Main *bmain = DEG_get_bmain(depsgraph);
|
||||||
|
std::string image_path;
|
||||||
|
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contain
|
||||||
|
* pretty general code, so could be moved from bf_usd project. */
|
||||||
|
#ifdef WITH_HYDRA
|
||||||
|
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NodeItem texcoord = create_node("texcoord", "vector2", true);
|
||||||
|
NodeItem res = create_node("image", "color3");
|
||||||
|
res.set_input("file", image_path, "filename");
|
||||||
|
res.set_input("texcoord", texcoord);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
17
source/blender/nodes/shader/materialx/nodes/tex_image.h
Normal file
17
source/blender/nodes/shader/materialx/nodes/tex_image.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "node_parser.h"
|
||||||
|
|
||||||
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
|
class TexImageNodeParser : public NodeParser {
|
||||||
|
public:
|
||||||
|
using NodeParser::NodeParser;
|
||||||
|
NodeItem compute() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::nodes::materialx
|
@ -89,6 +89,7 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context)
|
|||||||
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene");
|
pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene");
|
||||||
hydra_scene_delegate_ = std::make_unique<io::hydra::HydraSceneDelegate>(render_index_.get(),
|
hydra_scene_delegate_ = std::make_unique<io::hydra::HydraSceneDelegate>(render_index_.get(),
|
||||||
scene_path);
|
scene_path);
|
||||||
|
hydra_scene_delegate_->use_materialx = bl_engine_->type->flag & RE_USE_MATERIALX;
|
||||||
}
|
}
|
||||||
hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr);
|
hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user