Files
test/source/blender/editors/space_node/node_shader_preview.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

851 lines
30 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2023 Blender Authors
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edrend
*
* This file implements shader node previews which rely on a structure owned by each SpaceNode.
* We take advantage of the RenderResult available as ImBuf images to store a Render for every
* viewed nested node tree present in a SpaceNode. The computation is initiated at the moment of
* drawing nodes overlays. One render is started for the current nodetree, having a ViewLayer
* associated with each previewed node.
*
* We separate the previewed nodes in two categories: the shader ones and the non-shader ones.
* - for non-shader nodes, we use AOVs(Arbitrary Output Variable) which highly speed up the
* rendering process by rendering every non-shader node at the same time. They are rendered in the
* first ViewLayer.
* - for shader nodes, we render them each in a different ViewLayer, by routing the node to the
* output of the material in the preview scene.
*
* At the moment of drawing, we take the Render of the viewed node tree and extract the ImBuf of
* the wanted viewlayer/pass for each previewed node.
*/
#include "BLI_string.h"
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
#include "DNA_camera_types.h"
#include "DNA_material_types.h"
#include "DNA_world_types.h"
#include "RNA_access.hh"
#include "RNA_prototypes.h"
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
#include "BKE_colortools.h"
#include "BKE_compute_contexts.hh"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_scene.h"
#include "DEG_depsgraph.hh"
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
#include "IMB_imbuf.h"
#include "WM_api.hh"
#include "ED_datafiles.h"
#include "ED_node_preview.hh"
#include "ED_render.hh"
#include "ED_screen.hh"
#include "node_intern.hh"
namespace blender::ed::space_node {
/* -------------------------------------------------------------------- */
/** \name Local Structs
* \{ */
using NodeSocketPair = std::pair<bNode *, bNodeSocket *>;
struct ShaderNodesPreviewJob {
NestedTreePreviews *tree_previews;
Scene *scene;
/* Pointer to the job's stop variable which is used to know when the job is asked for finishing.
* The idea is that the renderer will read this value frequently and abort the render if it is
* true. */
bool *stop;
/* Pointer to the job's update variable which is set to true to refresh the UI when the renderer
* is delivering a fresh result. It allows the job to give some UI refresh tags to the WM. */
bool *do_update;
Material *mat_copy;
ePreviewType preview_type;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
bNode *mat_output_copy;
NodeSocketPair mat_displacement_copy;
/* TreePath used to locate the nodetree.
* bNodeTreePath elements have some listbase pointers which should not be used. */
Vector<bNodeTreePath *> treepath_copy;
Vector<NodeSocketPair> AOV_nodes;
Vector<NodeSocketPair> shader_nodes;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
bNode *rendering_node;
bool rendering_AOVs;
Main *bmain;
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Compute Context functions
* \{ */
static void ensure_nodetree_previews(const bContext &C,
NestedTreePreviews &tree_previews,
Material &material,
ListBase &treepath);
static std::optional<ComputeContextHash> get_compute_context_hash_for_node_editor(
const SpaceNode &snode)
{
Vector<const bNodeTreePath *> treepath;
LISTBASE_FOREACH (const bNodeTreePath *, item, &snode.treepath) {
treepath.append(item);
}
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
if (treepath.is_empty()) {
return std::nullopt;
}
if (treepath.size() == 1) {
/* Top group. */
ComputeContextHash hash;
hash.v1 = hash.v2 = 0;
return hash;
}
ComputeContextBuilder compute_context_builder;
for (const int i : treepath.index_range().drop_back(1)) {
/* The tree path contains the name of the node but not its ID. */
const bNode *node = nodeFindNodebyName(treepath[i]->nodetree, treepath[i + 1]->node_name);
if (node == nullptr) {
/* The current tree path is invalid, probably because some parent group node has been
* deleted. */
return std::nullopt;
}
compute_context_builder.push<bke::NodeGroupComputeContext>(*node);
}
return compute_context_builder.hash();
}
/*
* This function returns the `NestedTreePreviews *` for the nodetree shown in the SpaceNode.
* This is the first function in charge of the previews by calling `ensure_nodetree_previews`.
*/
NestedTreePreviews *get_nested_previews(const bContext &C, SpaceNode &snode)
{
if (snode.id == nullptr || GS(snode.id->name) != ID_MA) {
return nullptr;
}
NestedTreePreviews *tree_previews = nullptr;
if (auto hash = get_compute_context_hash_for_node_editor(snode)) {
tree_previews = snode.runtime->tree_previews_per_context
.lookup_or_add_cb(*hash,
[&]() {
return std::make_unique<NestedTreePreviews>(
U.node_preview_res);
})
.get();
Material *ma = reinterpret_cast<Material *>(snode.id);
ensure_nodetree_previews(C, *tree_previews, *ma, snode.treepath);
}
return tree_previews;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Preview scene
* \{ */
static Material *duplicate_material(const Material &mat)
{
Material *ma_copy = reinterpret_cast<Material *>(
BKE_id_copy_ex(nullptr,
&mat.id,
nullptr,
LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA));
return ma_copy;
}
static Scene *preview_prepare_scene(const Main *bmain,
const Scene *scene_orig,
Main *pr_main,
Material *mat_copy,
ePreviewType preview_type)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
Scene *scene_preview;
memcpy(pr_main->filepath, BKE_main_blendfile_path(bmain), sizeof(pr_main->filepath));
if (pr_main == nullptr) {
return nullptr;
}
scene_preview = static_cast<Scene *>(pr_main->scenes.first);
if (scene_preview == nullptr) {
return nullptr;
}
ViewLayer *view_layer = static_cast<ViewLayer *>(scene_preview->view_layers.first);
/* Only enable the combined render-pass. */
view_layer->passflag = SCE_PASS_COMBINED;
view_layer->eevee.render_passes = 0;
/* This flag tells render to not execute depsgraph or F-Curves etc. */
scene_preview->r.scemode |= R_BUTS_PREVIEW;
scene_preview->r.mode |= R_PERSISTENT_DATA;
STRNCPY(scene_preview->r.engine, scene_orig->r.engine);
scene_preview->r.color_mgt_flag = scene_orig->r.color_mgt_flag;
BKE_color_managed_display_settings_copy(&scene_preview->display_settings,
&scene_orig->display_settings);
BKE_color_managed_view_settings_free(&scene_preview->view_settings);
BKE_color_managed_view_settings_copy(&scene_preview->view_settings, &scene_orig->view_settings);
scene_preview->r.alphamode = R_ADDSKY;
scene_preview->r.cfra = scene_orig->r.cfra;
/* Setup the world. */
scene_preview->world = ED_preview_prepare_world(
pr_main, scene_preview, scene_orig->world, ID_MA, PR_BUTS_RENDER);
BLI_addtail(&pr_main->materials, mat_copy);
scene_preview->world->use_nodes = false;
scene_preview->world->horr = 0.05f;
scene_preview->world->horg = 0.05f;
scene_preview->world->horb = 0.05f;
ED_preview_set_visibility(pr_main, scene_preview, view_layer, preview_type, PR_BUTS_RENDER);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
BKE_view_layer_synced_ensure(scene_preview, view_layer);
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
if (base->object->id.name[2] == 'p') {
if (OB_TYPE_SUPPORT_MATERIAL(base->object->type)) {
/* Don't use BKE_object_material_assign, it changed mat->id.us, which shows in the UI. */
Material ***matar = BKE_object_material_array_p(base->object);
int actcol = max_ii(base->object->actcol - 1, 0);
if (matar && actcol < base->object->totcol) {
(*matar)[actcol] = mat_copy;
}
}
else if (base->object->type == OB_LAMP) {
base->flag |= BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT;
}
}
}
return scene_preview;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Preview rendering
* \{ */
/**
* Follows some rules to determine the previewed socket and node associated.
* We first seek for an output socket of the node, if none if found, the node is an output node,
* and thus seek for an input socket.
*/
static bNodeSocket *node_find_preview_socket(bNodeTree &ntree, bNode &node)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
bNodeSocket *socket = get_main_socket(ntree, node, SOCK_OUT);
if (socket == nullptr) {
socket = get_main_socket(ntree, node, SOCK_IN);
if (socket != nullptr && socket->link == nullptr) {
if (!(ELEM(socket->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA))) {
/* We can not preview a socket with no link and no manual value. */
return nullptr;
}
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
}
return socket;
}
static bool socket_use_aov(const bNodeSocket *socket)
{
return socket == nullptr || socket->type != SOCK_SHADER;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
static bool node_use_aov(bNodeTree &ntree, const bNode *node)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
bNode *node_preview = const_cast<bNode *>(node);
bNodeSocket *socket_preview = node_find_preview_socket(ntree, *node_preview);
return socket_use_aov(socket_preview);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
static ImBuf *get_image_from_viewlayer_and_pass(RenderResult &rr,
const char *layer_name,
const char *pass_name)
{
RenderLayer *rl;
if (layer_name) {
rl = RE_GetRenderLayer(&rr, layer_name);
}
else {
rl = static_cast<RenderLayer *>(rr.layers.first);
}
if (rl == nullptr) {
return nullptr;
}
RenderPass *rp;
if (pass_name) {
rp = RE_pass_find_by_name(rl, pass_name, nullptr);
}
else {
rp = static_cast<RenderPass *>(rl->passes.first);
}
ImBuf *ibuf = rp ? rp->ibuf : nullptr;
return ibuf;
}
/* `node_release_preview_ibuf` should be called after this. */
ImBuf *node_preview_acquire_ibuf(bNodeTree &ntree,
NestedTreePreviews &tree_previews,
const bNode &node)
{
if (tree_previews.previews_render == nullptr) {
return nullptr;
}
RenderResult *rr = RE_AcquireResultRead(tree_previews.previews_render);
ImBuf *&image_cached = tree_previews.previews_map.lookup_or_add(node.identifier, nullptr);
if (rr == nullptr) {
return image_cached;
}
if (image_cached == nullptr) {
if (tree_previews.rendering == false) {
ntree.runtime->previews_refresh_state++;
}
else {
/* When the render process is started, the user must see that the preview area is open. */
ImBuf *image_latest = nullptr;
if (node_use_aov(ntree, &node)) {
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
image_latest = get_image_from_viewlayer_and_pass(*rr, nullptr, node.name);
}
else {
image_latest = get_image_from_viewlayer_and_pass(*rr, node.name, nullptr);
}
if (image_latest) {
IMB_refImBuf(image_latest);
image_cached = image_latest;
}
}
}
return image_cached;
}
void node_release_preview_ibuf(NestedTreePreviews &tree_previews)
{
if (tree_previews.previews_render == nullptr) {
return;
}
RE_ReleaseResult(tree_previews.previews_render);
}
2023-08-09 11:20:04 +10:00
/**
* Get a link to the node outside the nested node-groups by creating a new output socket for each
* nested node-group. To do so we cover all nested node-trees starting from the farthest, and
* update the `nested_node_iter` pointer to the current node-group instance used for linking.
* We stop before getting to the main node-tree because the output type is different.
*/
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
static void connect_nested_node_to_node(const Span<bNodeTreePath *> treepath,
bNode &nested_node,
bNodeSocket &nested_socket,
bNode &final_node,
bNodeSocket &final_socket,
const char *route_name)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
bNode *nested_node_iter = &nested_node;
bNodeSocket *nested_socket_iter = &nested_socket;
for (int i = treepath.size() - 1; i > 0; --i) {
bNodeTreePath *path = treepath[i];
bNodeTreePath *path_prev = treepath[i - 1];
bNodeTree *nested_nt = path->nodetree;
bNode *output_node = nullptr;
for (bNode *iter_node : nested_nt->all_nodes()) {
if (iter_node->is_group_output() && iter_node->flag & NODE_DO_OUTPUT) {
output_node = iter_node;
break;
}
}
if (output_node == nullptr) {
output_node = nodeAddStaticNode(nullptr, nested_nt, NODE_GROUP_OUTPUT);
output_node->flag |= NODE_DO_OUTPUT;
}
Nodes: Panels integration with blend files and UI Part 3/3 of #109135, #110272 Switch to new node group interfaces and deprecate old DNA and API. This completes support for panels in node drawing and in node group interface declarations in particular. The new node group interface DNA and RNA code has been added in parts 1 and 2 (#110885, #110952) but has not be enabled yet. This commit completes the integration by * enabling the new RNA API * using the new API in UI * read/write new interfaces from blend files * add versioning for backward compatibility * add forward-compatible writing code to reconstruct old interfaces All places accessing node group interface declarations should now be using the new API. A runtime cache has been added that allows simple linear access to socket inputs and outputs even when a panel hierarchy is used. Old DNA has been deprecated and should only be accessed for versioning (inputs/outputs renamed to inputs_legacy/outputs_legacy to catch errors). Versioning code ensures both backward and forward compatibility of existing files. The API for old interfaces is removed. The new API is very similar but is defined on the `ntree.interface` instead of the `ntree` directly. Breaking change notifications and detailed instructions for migrating will be added. A python test has been added for the node group API functions. This includes new functionality such as creating panels and moving items between different levels. This patch does not yet contain panel representations in the modifier UI. This has been tested in a separate branch and will be added with a later PR (#108565). Pull Request: https://projects.blender.org/blender/blender/pulls/111348
2023-08-30 12:37:21 +02:00
nested_nt->tree_interface.add_socket(
route_name, "", nested_socket_iter->idname, NODE_INTERFACE_SOCKET_OUTPUT, nullptr);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
BKE_ntree_update_main_tree(G.pr_main, nested_nt, nullptr);
bNodeSocket *out_socket = blender::bke::node_find_enabled_input_socket(*output_node,
route_name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
nodeAddLink(nested_nt, nested_node_iter, nested_socket_iter, output_node, out_socket);
BKE_ntree_update_main_tree(G.pr_main, nested_nt, nullptr);
2023-08-09 11:20:04 +10:00
/* Change the `nested_node` pointer to the nested node-group instance node. The tree path
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
* contains the name of the instance node but not its ID. */
nested_node_iter = nodeFindNodebyName(path_prev->nodetree, path->node_name);
/* Update the sockets of the node because we added a new interface. */
BKE_ntree_update_tag_node_property(path_prev->nodetree, nested_node_iter);
BKE_ntree_update_main_tree(G.pr_main, path_prev->nodetree, nullptr);
2023-08-09 11:20:04 +10:00
/* Now use the newly created socket of the node-group as previewing socket of the node-group
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
* instance node. */
nested_socket_iter = blender::bke::node_find_enabled_output_socket(*nested_node_iter,
route_name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
nodeAddLink(treepath.first()->nodetree,
nested_node_iter,
nested_socket_iter,
&final_node,
&final_socket);
}
/* Connect the node to the output of the first nodetree from `treepath`. Last element of `treepath`
* should be the path to the node's nodetree */
static void connect_node_to_surface_output(const Span<bNodeTreePath *> treepath,
NodeSocketPair nodesocket,
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
bNode &output_node)
{
bNodeSocket *out_surface_socket = nullptr;
bNodeTree *main_nt = treepath.first()->nodetree;
bNode *node_preview = nodesocket.first;
bNodeSocket *socket_preview = nodesocket.second;
if (socket_preview == nullptr) {
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
return;
}
if (socket_preview->in_out == SOCK_IN) {
BLI_assert(socket_preview->link != nullptr);
node_preview = socket_preview->link->fromnode;
socket_preview = socket_preview->link->fromsock;
}
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
/* Ensure output is usable. */
out_surface_socket = nodeFindSocket(&output_node, SOCK_IN, "Surface");
if (out_surface_socket->link) {
/* Make sure no node is already wired to the output before wiring. */
nodeRemLink(main_nt, out_surface_socket->link);
}
connect_nested_node_to_node(treepath,
*node_preview,
*socket_preview,
output_node,
*out_surface_socket,
nodesocket.first->name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
BKE_ntree_update_main_tree(G.pr_main, main_nt, nullptr);
}
/* Connect the nodes to some aov nodes located in the first nodetree from `treepath`. Last element
* of `treepath` should be the path to the nodes nodetree. */
static void connect_nodes_to_aovs(const Span<bNodeTreePath *> treepath,
const Span<NodeSocketPair> &nodesocket_span)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
if (nodesocket_span.size() == 0) {
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
return;
}
bNodeTree *main_nt = treepath.first()->nodetree;
bNodeTree *active_nt = treepath.last()->nodetree;
for (NodeSocketPair nodesocket : nodesocket_span) {
bNode *node_preview = nodesocket.first;
bNodeSocket *socket_preview = nodesocket.second;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
bNode *aov_node = nodeAddStaticNode(nullptr, main_nt, SH_NODE_OUTPUT_AOV);
STRNCPY(reinterpret_cast<NodeShaderOutputAOV *>(aov_node->storage)->name,
nodesocket.first->name);
if (socket_preview == nullptr) {
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
continue;
}
bNodeSocket *aov_socket = nodeFindSocket(aov_node, SOCK_IN, "Color");
if (socket_preview->in_out == SOCK_IN) {
if (socket_preview->link == nullptr) {
2023-08-12 16:29:51 +10:00
/* Copy the custom value of the socket directly to the AOV node.
* If the socket does not support custom values, it will just render black. */
float vec[4] = {0., 0., 0., 1.};
PointerRNA ptr;
switch (socket_preview->type) {
case SOCK_FLOAT:
ptr = RNA_pointer_create((ID *)active_nt, &RNA_NodeSocket, socket_preview);
vec[0] = RNA_float_get(&ptr, "default_value");
vec[1] = vec[0];
vec[2] = vec[0];
break;
case SOCK_VECTOR:
case SOCK_RGBA:
ptr = RNA_pointer_create((ID *)active_nt, &RNA_NodeSocket, socket_preview);
RNA_float_get_array(&ptr, "default_value", vec);
break;
}
ptr = RNA_pointer_create((ID *)active_nt, &RNA_NodeSocket, aov_socket);
RNA_float_set_array(&ptr, "default_value", vec);
continue;
}
else {
node_preview = socket_preview->link->fromnode;
socket_preview = socket_preview->link->fromsock;
}
}
connect_nested_node_to_node(
treepath, *node_preview, *socket_preview, *aov_node, *aov_socket, nodesocket.first->name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
BKE_ntree_update_main_tree(G.pr_main, main_nt, nullptr);
}
/* Called by renderer, checks job stops. */
static bool nodetree_previews_break(void *spv)
{
ShaderNodesPreviewJob *job_data = static_cast<ShaderNodesPreviewJob *>(spv);
return *(job_data->stop);
}
static bool prepare_viewlayer_update(void *pvl_data, ViewLayer *vl, Depsgraph *depsgraph)
{
NodeSocketPair nodesocket = {nullptr, nullptr};
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
ShaderNodesPreviewJob *job_data = static_cast<ShaderNodesPreviewJob *>(pvl_data);
for (NodeSocketPair nodesocket_iter : job_data->shader_nodes) {
if (STREQ(vl->name, nodesocket_iter.first->name)) {
nodesocket = nodesocket_iter;
job_data->rendering_node = nodesocket_iter.first;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
job_data->rendering_AOVs = false;
break;
}
}
if (nodesocket.first == nullptr) {
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
job_data->rendering_node = nullptr;
job_data->rendering_AOVs = true;
/* The AOV layer is the default `ViewLayer` of the scene(which should be the first one). */
return job_data->AOV_nodes.size() > 0 && !vl->prev;
}
bNodeSocket *displacement_socket = nodeFindSocket(
job_data->mat_output_copy, SOCK_IN, "Displacement");
if (job_data->mat_displacement_copy.first != nullptr && displacement_socket->link == nullptr) {
nodeAddLink(job_data->treepath_copy.first()->nodetree,
job_data->mat_displacement_copy.first,
job_data->mat_displacement_copy.second,
job_data->mat_output_copy,
displacement_socket);
}
connect_node_to_surface_output(job_data->treepath_copy, nodesocket, *job_data->mat_output_copy);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
if (depsgraph != nullptr) {
/* Used to refresh the dependency graph so that the material can be updated. */
for (bNodeTreePath *path_iter : job_data->treepath_copy) {
DEG_graph_id_tag_update(
G.pr_main, depsgraph, &path_iter->nodetree->id, ID_RECALC_NTREE_OUTPUT);
}
}
return true;
}
/* Called by renderer, refresh the UI. */
static void all_nodes_preview_update(void *npv, RenderResult *rr, rcti * /*rect*/)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
ShaderNodesPreviewJob *job_data = static_cast<ShaderNodesPreviewJob *>(npv);
*job_data->do_update = true;
if (bNode *node = job_data->rendering_node) {
ImBuf *&image_cached = job_data->tree_previews->previews_map.lookup_or_add(node->identifier,
nullptr);
ImBuf *image_latest = get_image_from_viewlayer_and_pass(*rr, node->name, nullptr);
if (image_latest == nullptr) {
return;
}
if (image_cached != image_latest) {
if (image_cached != nullptr) {
IMB_freeImBuf(image_cached);
}
IMB_refImBuf(image_latest);
image_cached = image_latest;
}
}
if (job_data->rendering_AOVs) {
for (NodeSocketPair nodesocket_iter : job_data->AOV_nodes) {
ImBuf *&image_cached = job_data->tree_previews->previews_map.lookup_or_add(
nodesocket_iter.first->identifier, nullptr);
ImBuf *image_latest = get_image_from_viewlayer_and_pass(
*rr, nullptr, nodesocket_iter.first->name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
if (image_latest == nullptr) {
continue;
}
if (image_cached != image_latest) {
if (image_cached != nullptr) {
IMB_freeImBuf(image_cached);
}
IMB_refImBuf(image_latest);
image_cached = image_latest;
}
}
}
}
static void preview_render(ShaderNodesPreviewJob &job_data)
{
/* Get the stuff from the builtin preview dbase. */
Scene *scene = preview_prepare_scene(
job_data.bmain, job_data.scene, G.pr_main, job_data.mat_copy, job_data.preview_type);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
if (scene == nullptr) {
return;
}
Span<bNodeTreePath *> treepath = job_data.treepath_copy;
/* AOV nodes are rendered in the first RenderLayer so we route them now. */
connect_nodes_to_aovs(treepath, job_data.AOV_nodes);
/* Create the AOV passes for the viewlayer. */
ViewLayer *AOV_layer = static_cast<ViewLayer *>(scene->view_layers.first);
for (NodeSocketPair nodesocket_iter : job_data.shader_nodes) {
ViewLayer *vl = BKE_view_layer_add(
scene, nodesocket_iter.first->name, AOV_layer, VIEWLAYER_ADD_COPY);
STRNCPY(vl->name, nodesocket_iter.first->name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
for (NodeSocketPair nodesocket_iter : job_data.AOV_nodes) {
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
ViewLayerAOV *aov = BKE_view_layer_add_aov(AOV_layer);
STRNCPY(aov->name, nodesocket_iter.first->name);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
scene->r.xsch = job_data.tree_previews->preview_size;
scene->r.ysch = job_data.tree_previews->preview_size;
scene->r.size = 100;
if (job_data.tree_previews->previews_render == nullptr) {
char name[32];
SNPRINTF(name, "Preview %p", &job_data.tree_previews);
job_data.tree_previews->previews_render = RE_NewRender(name);
}
Render *re = job_data.tree_previews->previews_render;
/* `sce->r` gets copied in RE_InitState. */
scene->r.scemode &= ~(R_MATNODE_PREVIEW | R_TEXNODE_PREVIEW);
scene->r.scemode &= ~R_NO_IMAGE_LOAD;
scene->display.render_aa = SCE_DISPLAY_AA_SAMPLES_8;
RE_display_update_cb(re, &job_data, all_nodes_preview_update);
RE_test_break_cb(re, &job_data, nodetree_previews_break);
RE_prepare_viewlayer_cb(re, &job_data, prepare_viewlayer_update);
/* Lens adjust. */
float oldlens = reinterpret_cast<Camera *>(scene->camera->data)->lens;
RE_ClearResult(re);
RE_PreviewRender(re, G.pr_main, scene);
reinterpret_cast<Camera *>(scene->camera->data)->lens = oldlens;
/* Free the aov layers and the layers generated for each node. */
BLI_freelistN(&AOV_layer->aovs);
ViewLayer *vl = AOV_layer->next;
while (vl) {
ViewLayer *vl_rem = vl;
vl = vl->next;
BLI_remlink(&scene->view_layers, vl_rem);
BKE_view_layer_free(vl_rem);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Preview job management
* \{ */
static void update_needed_flag(NestedTreePreviews &tree_previews,
const bNodeTree &nt,
ePreviewType preview_type)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
if (tree_previews.rendering) {
if (nt.runtime->previews_refresh_state != tree_previews.rendering_previews_refresh_state) {
tree_previews.restart_needed = true;
return;
}
if (preview_type != tree_previews.rendering_preview_type) {
tree_previews.restart_needed = true;
return;
}
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
else {
if (nt.runtime->previews_refresh_state != tree_previews.cached_previews_refresh_state) {
tree_previews.restart_needed = true;
return;
}
if (preview_type != tree_previews.cached_preview_type) {
tree_previews.restart_needed = true;
return;
}
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
if (tree_previews.preview_size != U.node_preview_res) {
tree_previews.restart_needed = true;
return;
}
}
static void shader_preview_startjob(void *customdata, wmJobWorkerStatus *worker_status)
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
{
ShaderNodesPreviewJob *job_data = static_cast<ShaderNodesPreviewJob *>(customdata);
job_data->stop = &worker_status->stop;
job_data->do_update = &worker_status->do_update;
worker_status->do_update = true;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
bool size_changed = job_data->tree_previews->preview_size != U.node_preview_res;
if (size_changed) {
job_data->tree_previews->preview_size = U.node_preview_res;
}
for (bNode *node_iter : job_data->mat_copy->nodetree->all_nodes()) {
if (node_iter->flag & NODE_DO_OUTPUT) {
node_iter->flag &= ~NODE_DO_OUTPUT;
bNodeSocket *disp_socket = nodeFindSocket(node_iter, SOCK_IN, "Displacement");
if (disp_socket != nullptr && disp_socket->link != nullptr) {
job_data->mat_displacement_copy = std::make_pair(disp_socket->link->fromnode,
disp_socket->link->fromsock);
}
break;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
}
/* Add a new output node used only for the previews. This is useful to keep the previously
* connected links (for previewing the output nodes for example). */
job_data->mat_output_copy = nodeAddStaticNode(
nullptr, job_data->mat_copy->nodetree, SH_NODE_OUTPUT_MATERIAL);
job_data->mat_output_copy->flag |= NODE_DO_OUTPUT;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
bNodeTree *active_nodetree = job_data->treepath_copy.last()->nodetree;
for (bNode *node : active_nodetree->all_nodes()) {
if (!(node->flag & NODE_PREVIEW)) {
2023-08-09 11:20:04 +10:00
/* Clear the cached preview for this node to be sure that the preview is re-rendered if
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
* needed. */
if (ImBuf **ibuf = job_data->tree_previews->previews_map.lookup_ptr(node->identifier)) {
IMB_freeImBuf(*ibuf);
*ibuf = nullptr;
}
continue;
}
bNodeSocket *preview_socket = node_find_preview_socket(*active_nodetree, *node);
if (socket_use_aov(preview_socket)) {
job_data->AOV_nodes.append({node, preview_socket});
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
else {
job_data->shader_nodes.append({node, preview_socket});
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
}
if (job_data->tree_previews->preview_size > 0) {
preview_render(*job_data);
}
}
static void shader_preview_free(void *customdata)
{
ShaderNodesPreviewJob *job_data = static_cast<ShaderNodesPreviewJob *>(customdata);
for (bNodeTreePath *path : job_data->treepath_copy) {
MEM_freeN(path);
}
job_data->treepath_copy.clear();
job_data->tree_previews->rendering = false;
job_data->tree_previews->cached_previews_refresh_state =
job_data->tree_previews->rendering_previews_refresh_state;
job_data->tree_previews->cached_preview_type = job_data->preview_type;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
if (job_data->mat_copy != nullptr) {
BLI_remlink(&G.pr_main->materials, job_data->mat_copy);
BKE_id_free(G.pr_main, &job_data->mat_copy->id);
job_data->mat_copy = nullptr;
}
MEM_delete(job_data);
}
static void ensure_nodetree_previews(const bContext &C,
NestedTreePreviews &tree_previews,
Material &material,
ListBase &treepath)
{
Scene *scene = CTX_data_scene(&C);
if (!ED_check_engine_supports_preview(scene)) {
return;
}
bNodeTree *displayed_nodetree = static_cast<bNodeTreePath *>(treepath.last)->nodetree;
ePreviewType preview_type = MA_FLAT;
if (CTX_wm_space_node(&C)->overlay.preview_shape == SN_OVERLAY_PREVIEW_3D) {
preview_type = (ePreviewType)material.pr_type;
}
update_needed_flag(tree_previews, *displayed_nodetree, preview_type);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
if (!(tree_previews.restart_needed)) {
return;
}
if (tree_previews.rendering) {
WM_jobs_stop(CTX_wm_manager(&C), CTX_wm_space_node(&C), shader_preview_startjob);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
return;
}
tree_previews.rendering = true;
tree_previews.restart_needed = false;
tree_previews.rendering_previews_refresh_state =
displayed_nodetree->runtime->previews_refresh_state;
tree_previews.rendering_preview_type = preview_type;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
ED_preview_ensure_dbase(false);
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(&C),
CTX_wm_window(&C),
CTX_wm_space_node(&C),
"Shader Previews",
WM_JOB_EXCL_RENDER,
WM_JOB_TYPE_RENDER_PREVIEW);
ShaderNodesPreviewJob *job_data = MEM_new<ShaderNodesPreviewJob>(__func__);
job_data->scene = scene;
job_data->tree_previews = &tree_previews;
job_data->bmain = CTX_data_main(&C);
job_data->mat_copy = duplicate_material(material);
job_data->rendering_node = nullptr;
job_data->rendering_AOVs = false;
job_data->preview_type = preview_type;
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
/* Update the treepath copied to fit the structure of the nodetree copied. */
bNodeTreePath *root_path = MEM_cnew<bNodeTreePath>(__func__);
root_path->nodetree = job_data->mat_copy->nodetree;
job_data->treepath_copy.append(root_path);
for (bNodeTreePath *original_path = static_cast<bNodeTreePath *>(treepath.first)->next;
original_path;
original_path = original_path->next)
{
bNodeTreePath *new_path = MEM_cnew<bNodeTreePath>(__func__);
memcpy(new_path, original_path, sizeof(bNodeTreePath));
bNode *parent = nodeFindNodebyName(job_data->treepath_copy.last()->nodetree,
original_path->node_name);
new_path->nodetree = reinterpret_cast<bNodeTree *>(parent->id);
job_data->treepath_copy.append(new_path);
}
WM_jobs_customdata_set(wm_job, job_data, shader_preview_free);
WM_jobs_timer(wm_job, 0.2, NC_NODE, NC_NODE);
WM_jobs_callbacks(wm_job, shader_preview_startjob, nullptr, nullptr, nullptr);
WM_jobs_start(CTX_wm_manager(&C), wm_job);
}
void stop_preview_job(wmWindowManager &wm)
{
WM_jobs_stop(&wm, nullptr, shader_preview_startjob);
Nodes: experimental node previews in the shader editor First implementation of node previews in the shader node editor. Using the same user interface as compositor node previews, most shader nodes can now be previewed (except group in/output and material output). This is currently still an experimental feature, as polishing of the user experience and performance improvements are planned. These will be easier to do as incremental changes on this implementation. See #110353 for details on the work that remains to be done and known limitations. Implementation notes: We take advantage of the `RenderResult` available as `ImBuf` images to store a `Render` for every viewed nested node tree present in a `SpaceNode`. The computation is initiated at the moment of drawing nodes overlays. One render is started for the current nodetree, having a `ViewLayer` associated with each previewed node. We separate the previewed nodes in two categories: the shader ones and the non-shader ones. - For non-shader nodes, we use AOVs which highly speed up the rendering process by rendering every non-shader nodes at the same time. They are rendered in the first `ViewLayer`. - For shader nodes, we render them each in a different `ViewLayer`, by rerouting the node to the output of the material in the preview scene. The preview scene takes the same aspect as the Material preview scene, and the same preview object is used. At the moment of drawing the node overlay, we take the `Render` of the viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass for each previewed node. Pull Request: https://projects.blender.org/blender/blender/pulls/110065
2023-08-08 17:36:06 +02:00
}
void free_previews(wmWindowManager &wm, SpaceNode &snode)
{
/* This should not be called from the drawing pass, because it will result in a deadlock. */
WM_jobs_kill(&wm, &snode, shader_preview_startjob);
snode.runtime->tree_previews_per_context.clear_and_shrink();
}
/** \} */
} // namespace blender::ed::space_node