forked from bartvdbraak/blender
Cycles: add ConstantFolder class for constant folding boilerplate.
Reviewed By: brecht, sergey Differential Revision: https://developer.blender.org/D2089
This commit is contained in:
parent
10b0e33de1
commit
5234e9ddd3
@ -22,6 +22,7 @@ set(SRC
|
|||||||
bake.cpp
|
bake.cpp
|
||||||
buffers.cpp
|
buffers.cpp
|
||||||
camera.cpp
|
camera.cpp
|
||||||
|
constant_fold.cpp
|
||||||
film.cpp
|
film.cpp
|
||||||
graph.cpp
|
graph.cpp
|
||||||
image.cpp
|
image.cpp
|
||||||
@ -49,6 +50,7 @@ set(SRC_HEADERS
|
|||||||
background.h
|
background.h
|
||||||
buffers.h
|
buffers.h
|
||||||
camera.h
|
camera.h
|
||||||
|
constant_fold.h
|
||||||
film.h
|
film.h
|
||||||
graph.h
|
graph.h
|
||||||
image.h
|
image.h
|
||||||
|
122
intern/cycles/render/constant_fold.cpp
Normal file
122
intern/cycles/render/constant_fold.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2013 Blender Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "constant_fold.h"
|
||||||
|
#include "graph.h"
|
||||||
|
|
||||||
|
#include "util_foreach.h"
|
||||||
|
|
||||||
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output)
|
||||||
|
: graph(graph), node(node), output(output)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConstantFolder::all_inputs_constant() const
|
||||||
|
{
|
||||||
|
foreach(ShaderInput *input, node->inputs) {
|
||||||
|
if(input->link) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::make_constant(float value) const
|
||||||
|
{
|
||||||
|
foreach(ShaderInput *sock, output->links) {
|
||||||
|
sock->set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
graph->disconnect(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::make_constant(float3 value) const
|
||||||
|
{
|
||||||
|
foreach(ShaderInput *sock, output->links) {
|
||||||
|
sock->set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
graph->disconnect(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::make_constant_clamp(float value, bool clamp) const
|
||||||
|
{
|
||||||
|
make_constant(clamp ? saturate(value) : value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::make_constant_clamp(float3 value, bool clamp) const
|
||||||
|
{
|
||||||
|
if (clamp) {
|
||||||
|
value.x = saturate(value.x);
|
||||||
|
value.y = saturate(value.y);
|
||||||
|
value.z = saturate(value.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
make_constant(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::bypass(ShaderOutput *new_output) const
|
||||||
|
{
|
||||||
|
assert(new_output);
|
||||||
|
|
||||||
|
/* Remove all outgoing links from socket and connect them to new_output instead.
|
||||||
|
* The graph->relink method affects node inputs, so it's not safe to use in constant
|
||||||
|
* folding if the node has multiple outputs and will thus be folded multiple times. */
|
||||||
|
vector<ShaderInput*> outputs = output->links;
|
||||||
|
|
||||||
|
graph->disconnect(output);
|
||||||
|
|
||||||
|
foreach(ShaderInput *sock, outputs) {
|
||||||
|
graph->connect(new_output, sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::discard() const
|
||||||
|
{
|
||||||
|
assert(output->type() == SocketType::CLOSURE);
|
||||||
|
graph->disconnect(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantFolder::bypass_or_discard(ShaderInput *input) const
|
||||||
|
{
|
||||||
|
assert(input->type() == SocketType::CLOSURE);
|
||||||
|
|
||||||
|
if (input->link) {
|
||||||
|
bypass(input->link);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConstantFolder::try_bypass_or_make_constant(ShaderInput *input, float3 input_value, bool clamp) const
|
||||||
|
{
|
||||||
|
if(!input->link) {
|
||||||
|
make_constant_clamp(input_value, clamp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(!clamp) {
|
||||||
|
bypass(input->link);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCL_NAMESPACE_END
|
59
intern/cycles/render/constant_fold.h
Normal file
59
intern/cycles/render/constant_fold.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2013 Blender Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONSTANT_FOLD_H__
|
||||||
|
#define __CONSTANT_FOLD_H__
|
||||||
|
|
||||||
|
#include "util_types.h"
|
||||||
|
|
||||||
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class ShaderGraph;
|
||||||
|
class ShaderInput;
|
||||||
|
class ShaderNode;
|
||||||
|
class ShaderOutput;
|
||||||
|
|
||||||
|
class ConstantFolder {
|
||||||
|
public:
|
||||||
|
ShaderGraph *const graph;
|
||||||
|
ShaderNode *const node;
|
||||||
|
ShaderOutput *const output;
|
||||||
|
|
||||||
|
ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output);
|
||||||
|
|
||||||
|
bool all_inputs_constant() const;
|
||||||
|
|
||||||
|
/* Constant folding helpers, always return true for convenience. */
|
||||||
|
void make_constant(float value) const;
|
||||||
|
void make_constant(float3 value) const;
|
||||||
|
void make_constant_clamp(float value, bool clamp) const;
|
||||||
|
void make_constant_clamp(float3 value, bool clamp) const;
|
||||||
|
|
||||||
|
/* Bypass node, relinking to another output socket. */
|
||||||
|
void bypass(ShaderOutput *output) const;
|
||||||
|
|
||||||
|
/* For closure nodes, discard node entirely or bypass to one of its inputs. */
|
||||||
|
void discard() const;
|
||||||
|
void bypass_or_discard(ShaderInput *input) const;
|
||||||
|
|
||||||
|
/* Bypass or make constant, unless we can't due to clamp being true. */
|
||||||
|
bool try_bypass_or_make_constant(ShaderInput *input, float3 input_value, bool clamp) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif /* __CONSTANT_FOLD_H__ */
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011-2013 Blender Foundation
|
* Copyright 2011-2016 Blender Foundation
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
#include "constant_fold.h"
|
||||||
|
|
||||||
#include "util_algorithm.h"
|
#include "util_algorithm.h"
|
||||||
#include "util_debug.h"
|
#include "util_debug.h"
|
||||||
@ -126,17 +127,6 @@ ShaderOutput *ShaderNode::output(ustring name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderNode::all_inputs_constant() const
|
|
||||||
{
|
|
||||||
foreach(ShaderInput *input, inputs) {
|
|
||||||
if(input->link) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||||
{
|
{
|
||||||
foreach(ShaderInput *input, inputs) {
|
foreach(ShaderInput *input, inputs) {
|
||||||
@ -278,6 +268,17 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderGraph::disconnect(ShaderOutput *from)
|
||||||
|
{
|
||||||
|
assert(!finalized);
|
||||||
|
|
||||||
|
foreach(ShaderInput *sock, from->links) {
|
||||||
|
sock->link = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
from->links.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderGraph::disconnect(ShaderInput *to)
|
void ShaderGraph::disconnect(ShaderInput *to)
|
||||||
{
|
{
|
||||||
assert(!finalized);
|
assert(!finalized);
|
||||||
@ -525,15 +526,8 @@ void ShaderGraph::constant_fold()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Optimize current node. */
|
/* Optimize current node. */
|
||||||
if(node->constant_fold(this, output, output->links[0])) {
|
ConstantFolder folder(this, node, output);
|
||||||
/* Apply optimized value to other connected sockets and disconnect. */
|
node->constant_fold(folder);
|
||||||
vector<ShaderInput*> links(output->links);
|
|
||||||
for(size_t i = 0; i < links.size(); i++) {
|
|
||||||
if(i > 0)
|
|
||||||
links[i]->parent->copy_value(links[i]->socket_type, *links[0]->parent, links[0]->socket_type);
|
|
||||||
disconnect(links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011-2013 Blender Foundation
|
* Copyright 2011-2016 Blender Foundation
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -41,6 +41,7 @@ class ShaderGraph;
|
|||||||
class SVMCompiler;
|
class SVMCompiler;
|
||||||
class OSLCompiler;
|
class OSLCompiler;
|
||||||
class OutputNode;
|
class OutputNode;
|
||||||
|
class ConstantFolder;
|
||||||
|
|
||||||
/* Bump
|
/* Bump
|
||||||
*
|
*
|
||||||
@ -140,9 +141,7 @@ public:
|
|||||||
|
|
||||||
/* ** Node optimization ** */
|
/* ** Node optimization ** */
|
||||||
/* Check whether the node can be replaced with single constant. */
|
/* Check whether the node can be replaced with single constant. */
|
||||||
virtual bool constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, ShaderInput * /*optimized*/) { return false; }
|
virtual void constant_fold(const ConstantFolder& /*folder*/) {}
|
||||||
|
|
||||||
bool all_inputs_constant() const;
|
|
||||||
|
|
||||||
/* Simplify settings used by artists to the ones which are simpler to
|
/* Simplify settings used by artists to the ones which are simpler to
|
||||||
* evaluate in the kernel but keep the final result unchanged.
|
* evaluate in the kernel but keep the final result unchanged.
|
||||||
@ -251,6 +250,7 @@ public:
|
|||||||
OutputNode *output();
|
OutputNode *output();
|
||||||
|
|
||||||
void connect(ShaderOutput *from, ShaderInput *to);
|
void connect(ShaderOutput *from, ShaderInput *to);
|
||||||
|
void disconnect(ShaderOutput *from);
|
||||||
void disconnect(ShaderInput *to);
|
void disconnect(ShaderInput *to);
|
||||||
void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
|
void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "svm_color_util.h"
|
#include "svm_color_util.h"
|
||||||
#include "svm_math_util.h"
|
#include "svm_math_util.h"
|
||||||
#include "osl.h"
|
#include "osl.h"
|
||||||
|
#include "constant_fold.h"
|
||||||
|
|
||||||
#include "util_sky_model.h"
|
#include "util_sky_model.h"
|
||||||
#include "util_foreach.h"
|
#include "util_foreach.h"
|
||||||
@ -1576,16 +1577,11 @@ RGBToBWNode::RGBToBWNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RGBToBWNode::constant_fold(ShaderGraph * /*graph*/,
|
void RGBToBWNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(linear_rgb_to_gray(color));
|
folder.make_constant(linear_rgb_to_gray(color));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGBToBWNode::compile(SVMCompiler& compiler)
|
void RGBToBWNode::compile(SVMCompiler& compiler)
|
||||||
@ -1663,40 +1659,35 @@ ConvertNode::ConvertNode(SocketType::Type from_, SocketType::Type to_, bool auto
|
|||||||
special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
|
special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConvertNode::constant_fold(ShaderGraph * /*graph*/,
|
void ConvertNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
/* proxy nodes should have been removed at this point */
|
/* proxy nodes should have been removed at this point */
|
||||||
assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
|
assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
|
||||||
|
|
||||||
/* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
|
/* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
|
||||||
|
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
if(from == SocketType::FLOAT) {
|
if(from == SocketType::FLOAT) {
|
||||||
if(SocketType::is_float3(to)) {
|
if(SocketType::is_float3(to)) {
|
||||||
optimized->set(make_float3(value_float, value_float, value_float));
|
folder.make_constant(make_float3(value_float, value_float, value_float));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(SocketType::is_float3(from)) {
|
else if(SocketType::is_float3(from)) {
|
||||||
if(to == SocketType::FLOAT) {
|
if(to == SocketType::FLOAT) {
|
||||||
if(from == SocketType::COLOR)
|
if(from == SocketType::COLOR) {
|
||||||
/* color to float */
|
/* color to float */
|
||||||
optimized->set(linear_rgb_to_gray(value_color));
|
folder.make_constant(linear_rgb_to_gray(value_color));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
/* vector/point/normal to float */
|
/* vector/point/normal to float */
|
||||||
optimized->set(average(value_vector));
|
folder.make_constant(average(value_vector));
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
else if(SocketType::is_float3(to)) {
|
else if(SocketType::is_float3(to)) {
|
||||||
optimized->set(value_color);
|
folder.make_constant(value_color);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertNode::compile(SVMCompiler& compiler)
|
void ConvertNode::compile(SVMCompiler& compiler)
|
||||||
@ -2366,15 +2357,15 @@ void EmissionNode::compile(OSLCompiler& compiler)
|
|||||||
compiler.add(this, "node_emission");
|
compiler.add(this, "node_emission");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmissionNode::constant_fold(ShaderGraph * /*graph*/,
|
void EmissionNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput * /*optimized*/)
|
|
||||||
{
|
{
|
||||||
ShaderInput *color_in = input("Color");
|
ShaderInput *color_in = input("Color");
|
||||||
ShaderInput *strength_in = input("Strength");
|
ShaderInput *strength_in = input("Strength");
|
||||||
|
|
||||||
return ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
|
if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
|
||||||
(!strength_in->link && strength == 0.0f));
|
(!strength_in->link && strength == 0.0f)) {
|
||||||
|
folder.discard();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Background Closure */
|
/* Background Closure */
|
||||||
@ -2418,15 +2409,15 @@ void BackgroundNode::compile(OSLCompiler& compiler)
|
|||||||
compiler.add(this, "node_background");
|
compiler.add(this, "node_background");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BackgroundNode::constant_fold(ShaderGraph * /*graph*/,
|
void BackgroundNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput * /*optimized*/)
|
|
||||||
{
|
{
|
||||||
ShaderInput *color_in = input("Color");
|
ShaderInput *color_in = input("Color");
|
||||||
ShaderInput *strength_in = input("Strength");
|
ShaderInput *strength_in = input("Strength");
|
||||||
|
|
||||||
return ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
|
if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) ||
|
||||||
(!strength_in->link && strength == 0.0f));
|
(!strength_in->link && strength == 0.0f)) {
|
||||||
|
folder.discard();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Holdout Closure */
|
/* Holdout Closure */
|
||||||
@ -3388,12 +3379,9 @@ ValueNode::ValueNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValueNode::constant_fold(ShaderGraph * /*graph*/,
|
void ValueNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
optimized->set(value);
|
folder.make_constant(value);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValueNode::compile(SVMCompiler& compiler)
|
void ValueNode::compile(SVMCompiler& compiler)
|
||||||
@ -3426,12 +3414,9 @@ ColorNode::ColorNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ColorNode::constant_fold(ShaderGraph * /*graph*/,
|
void ColorNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
optimized->set(value);
|
folder.make_constant(value);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorNode::compile(SVMCompiler& compiler)
|
void ColorNode::compile(SVMCompiler& compiler)
|
||||||
@ -3480,6 +3465,20 @@ void AddClosureNode::compile(OSLCompiler& compiler)
|
|||||||
compiler.add(this, "node_add_closure");
|
compiler.add(this, "node_add_closure");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddClosureNode::constant_fold(const ConstantFolder& folder)
|
||||||
|
{
|
||||||
|
ShaderInput *closure1_in = input("Closure1");
|
||||||
|
ShaderInput *closure2_in = input("Closure2");
|
||||||
|
|
||||||
|
/* remove useless add closures nodes */
|
||||||
|
if(!closure1_in->link) {
|
||||||
|
folder.bypass_or_discard(closure2_in);
|
||||||
|
}
|
||||||
|
else if(!closure2_in->link) {
|
||||||
|
folder.bypass_or_discard(closure1_in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Mix Closure */
|
/* Mix Closure */
|
||||||
|
|
||||||
NODE_DEFINE(MixClosureNode)
|
NODE_DEFINE(MixClosureNode)
|
||||||
@ -3511,37 +3510,28 @@ void MixClosureNode::compile(OSLCompiler& compiler)
|
|||||||
compiler.add(this, "node_mix_closure");
|
compiler.add(this, "node_mix_closure");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MixClosureNode::constant_fold(ShaderGraph *graph,
|
void MixClosureNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput * /*optimized*/)
|
|
||||||
{
|
{
|
||||||
ShaderInput *fac_in = input("Fac");
|
ShaderInput *fac_in = input("Fac");
|
||||||
ShaderInput *closure1_in = input("Closure1");
|
ShaderInput *closure1_in = input("Closure1");
|
||||||
ShaderInput *closure2_in = input("Closure2");
|
ShaderInput *closure2_in = input("Closure2");
|
||||||
ShaderOutput *closure_out = output("Closure");
|
|
||||||
|
|
||||||
/* remove useless mix closures nodes */
|
/* remove useless mix closures nodes */
|
||||||
if(closure1_in->link == closure2_in->link) {
|
if(closure1_in->link == closure2_in->link) {
|
||||||
graph->relink(this, closure_out, closure1_in->link);
|
folder.bypass_or_discard(closure1_in);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
/* remove unused mix closure input when factor is 0.0 or 1.0
|
||||||
/* remove unused mix closure input when factor is 0.0 or 1.0 */
|
* check for closure links and make sure factor link is disconnected */
|
||||||
/* check for closure links and make sure factor link is disconnected */
|
else if(!fac_in->link) {
|
||||||
if(closure1_in->link && closure2_in->link && !fac_in->link) {
|
|
||||||
/* factor 0.0 */
|
/* factor 0.0 */
|
||||||
if(fac == 0.0f) {
|
if(fac <= 0.0f) {
|
||||||
graph->relink(this, closure_out, closure1_in->link);
|
folder.bypass_or_discard(closure1_in);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
/* factor 1.0 */
|
/* factor 1.0 */
|
||||||
else if(fac == 1.0f) {
|
else if(fac >= 1.0f) {
|
||||||
graph->relink(this, closure_out, closure2_in->link);
|
folder.bypass_or_discard(closure2_in);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mix Closure */
|
/* Mix Closure */
|
||||||
@ -3603,28 +3593,21 @@ InvertNode::InvertNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InvertNode::constant_fold(ShaderGraph *graph,
|
void InvertNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
ShaderInput *fac_in = input("Fac");
|
ShaderInput *fac_in = input("Fac");
|
||||||
ShaderInput *color_in = input("Color");
|
ShaderInput *color_in = input("Color");
|
||||||
ShaderOutput *color_out = output("Color");
|
|
||||||
|
|
||||||
if(!fac_in->link) {
|
if(!fac_in->link) {
|
||||||
/* evaluate fully constant node */
|
/* evaluate fully constant node */
|
||||||
if(!color_in->link) {
|
if(!color_in->link) {
|
||||||
optimized->set(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac));
|
folder.make_constant(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
/* remove no-op node */
|
/* remove no-op node */
|
||||||
else if(fac == 0.0f) {
|
else if(fac == 0.0f) {
|
||||||
graph->relink(this, color_out, color_in->link);
|
folder.bypass(color_in->link);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvertNode::compile(SVMCompiler& compiler)
|
void InvertNode::compile(SVMCompiler& compiler)
|
||||||
@ -3713,63 +3696,47 @@ void MixNode::compile(OSLCompiler& compiler)
|
|||||||
compiler.add(this, "node_mix");
|
compiler.add(this, "node_mix");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MixNode::constant_fold(ShaderGraph *graph,
|
void MixNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
ShaderInput *fac_in = input("Fac");
|
ShaderInput *fac_in = input("Fac");
|
||||||
ShaderInput *color1_in = input("Color1");
|
ShaderInput *color1_in = input("Color1");
|
||||||
ShaderInput *color2_in = input("Color2");
|
ShaderInput *color2_in = input("Color2");
|
||||||
ShaderOutput *color_out = output("Color");
|
|
||||||
|
|
||||||
/* evaluate fully constant node */
|
/* evaluate fully constant node */
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
float3 result = svm_mix(type, fac, color1, color2);
|
folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp);
|
||||||
optimized->set(use_clamp ? svm_mix_clamp(result) : result);
|
return;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove no-op node when factor is 0.0 */
|
/* remove no-op node when factor is 0.0 */
|
||||||
if(!fac_in->link && fac <= 0.0f) {
|
if(!fac_in->link && fac <= 0.0f) {
|
||||||
/* note that some of the modes will clamp out of bounds values even without use_clamp */
|
/* note that some of the modes will clamp out of bounds values even without use_clamp */
|
||||||
if(!color1_in->link) {
|
if(type == NODE_MIX_LIGHT || type == NODE_MIX_DODGE || type == NODE_MIX_BURN) {
|
||||||
float3 result = svm_mix(type, 0.0f, color1, color1);
|
if(!color1_in->link) {
|
||||||
optimized->set(use_clamp ? svm_mix_clamp(result) : result);
|
folder.make_constant_clamp(svm_mix(type, 0.0f, color1, color1), use_clamp);
|
||||||
return true;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(!use_clamp && type != NODE_MIX_LIGHT && type != NODE_MIX_DODGE && type != NODE_MIX_BURN) {
|
else if(folder.try_bypass_or_make_constant(color1_in, color1, use_clamp)) {
|
||||||
graph->relink(this, color_out, color1_in->link);
|
return;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type != NODE_MIX_BLEND) {
|
if(type == NODE_MIX_BLEND) {
|
||||||
return false;
|
/* remove useless mix colors nodes */
|
||||||
}
|
if(color1_in->link ? (color1_in->link == color2_in->link) : (!color2_in->link && color1 == color2)) {
|
||||||
|
if(folder.try_bypass_or_make_constant(color1_in, color1, use_clamp)) {
|
||||||
/* remove useless mix colors nodes */
|
return;
|
||||||
if(color1_in->link && color1_in->link == color2_in->link && !use_clamp) {
|
}
|
||||||
graph->relink(this, color_out, color1_in->link);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(!color1_in->link && !color2_in->link && color1 == color2) {
|
|
||||||
optimized->set(use_clamp ? svm_mix_clamp(color1) : color1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove no-op mix color node when factor is 1.0 */
|
|
||||||
if(!fac_in->link && fac >= 1.0f) {
|
|
||||||
if(!color2_in->link) {
|
|
||||||
optimized->set(use_clamp ? svm_mix_clamp(color2) : color2);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else if(!use_clamp) {
|
|
||||||
graph->relink(this, color_out, color2_in->link);
|
/* remove no-op mix color node when factor is 1.0 */
|
||||||
return true;
|
if(!fac_in->link && fac >= 1.0f) {
|
||||||
|
if(folder.try_bypass_or_make_constant(color2_in, color2, use_clamp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Combine RGB */
|
/* Combine RGB */
|
||||||
@ -3792,16 +3759,11 @@ CombineRGBNode::CombineRGBNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CombineRGBNode::constant_fold(ShaderGraph * /*graph*/,
|
void CombineRGBNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(make_float3(r, g, b));
|
folder.make_constant(make_float3(r, g, b));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineRGBNode::compile(SVMCompiler& compiler)
|
void CombineRGBNode::compile(SVMCompiler& compiler)
|
||||||
@ -3849,16 +3811,11 @@ CombineXYZNode::CombineXYZNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CombineXYZNode::constant_fold(ShaderGraph * /*graph*/,
|
void CombineXYZNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(make_float3(x, y, z));
|
folder.make_constant(make_float3(x, y, z));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineXYZNode::compile(SVMCompiler& compiler)
|
void CombineXYZNode::compile(SVMCompiler& compiler)
|
||||||
@ -3906,16 +3863,11 @@ CombineHSVNode::CombineHSVNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CombineHSVNode::constant_fold(ShaderGraph * /*graph*/,
|
void CombineHSVNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(hsv_to_rgb(make_float3(h, s, v)));
|
folder.make_constant(hsv_to_rgb(make_float3(h, s, v)));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineHSVNode::compile(SVMCompiler& compiler)
|
void CombineHSVNode::compile(SVMCompiler& compiler)
|
||||||
@ -3956,16 +3908,11 @@ GammaNode::GammaNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GammaNode::constant_fold(ShaderGraph * /*graph*/,
|
void GammaNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(svm_math_gamma_color(color, gamma));
|
folder.make_constant(svm_math_gamma_color(color, gamma));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GammaNode::compile(SVMCompiler& compiler)
|
void GammaNode::compile(SVMCompiler& compiler)
|
||||||
@ -4005,16 +3952,11 @@ BrightContrastNode::BrightContrastNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrightContrastNode::constant_fold(ShaderGraph * /*graph*/,
|
void BrightContrastNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(svm_brightness_contrast(color, bright, contrast));
|
folder.make_constant(svm_brightness_contrast(color, bright, contrast));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrightContrastNode::compile(SVMCompiler& compiler)
|
void BrightContrastNode::compile(SVMCompiler& compiler)
|
||||||
@ -4057,20 +3999,16 @@ SeparateRGBNode::SeparateRGBNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SeparateRGBNode::constant_fold(ShaderGraph * /*graph*/,
|
void SeparateRGBNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput *socket,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
for(int channel = 0; channel < 3; channel++) {
|
for(int channel = 0; channel < 3; channel++) {
|
||||||
if(outputs[channel] == socket) {
|
if(outputs[channel] == folder.output) {
|
||||||
optimized->set(color[channel]);
|
folder.make_constant(color[channel]);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeparateRGBNode::compile(SVMCompiler& compiler)
|
void SeparateRGBNode::compile(SVMCompiler& compiler)
|
||||||
@ -4118,20 +4056,16 @@ SeparateXYZNode::SeparateXYZNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SeparateXYZNode::constant_fold(ShaderGraph * /*graph*/,
|
void SeparateXYZNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput *socket,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
for(int channel = 0; channel < 3; channel++) {
|
for(int channel = 0; channel < 3; channel++) {
|
||||||
if(outputs[channel] == socket) {
|
if(outputs[channel] == folder.output) {
|
||||||
optimized->set(vector[channel]);
|
folder.make_constant(vector[channel]);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeparateXYZNode::compile(SVMCompiler& compiler)
|
void SeparateXYZNode::compile(SVMCompiler& compiler)
|
||||||
@ -4179,22 +4113,18 @@ SeparateHSVNode::SeparateHSVNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SeparateHSVNode::constant_fold(ShaderGraph * /*graph*/,
|
void SeparateHSVNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput *socket,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
float3 hsv = rgb_to_hsv(color);
|
float3 hsv = rgb_to_hsv(color);
|
||||||
|
|
||||||
for(int channel = 0; channel < 3; channel++) {
|
for(int channel = 0; channel < 3; channel++) {
|
||||||
if(outputs[channel] == socket) {
|
if(outputs[channel] == folder.output) {
|
||||||
optimized->set(hsv[channel]);
|
folder.make_constant(hsv[channel]);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeparateHSVNode::compile(SVMCompiler& compiler)
|
void SeparateHSVNode::compile(SVMCompiler& compiler)
|
||||||
@ -4580,16 +4510,11 @@ BlackbodyNode::BlackbodyNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlackbodyNode::constant_fold(ShaderGraph * /*graph*/,
|
void BlackbodyNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
optimized->set(svm_math_blackbody_color(temperature));
|
folder.make_constant(svm_math_blackbody_color(temperature));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackbodyNode::compile(SVMCompiler& compiler)
|
void BlackbodyNode::compile(SVMCompiler& compiler)
|
||||||
@ -4691,17 +4616,11 @@ MathNode::MathNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MathNode::constant_fold(ShaderGraph * /*graph*/,
|
void MathNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
float value = svm_math(type, value1, value2);
|
folder.make_constant_clamp(svm_math(type, value1, value2), use_clamp);
|
||||||
optimized->set(use_clamp ? saturate(value) : value);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MathNode::compile(SVMCompiler& compiler)
|
void MathNode::compile(SVMCompiler& compiler)
|
||||||
@ -4755,31 +4674,25 @@ VectorMathNode::VectorMathNode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VectorMathNode::constant_fold(ShaderGraph * /*graph*/,
|
void VectorMathNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput *socket,
|
|
||||||
ShaderInput *optimized)
|
|
||||||
{
|
{
|
||||||
float value;
|
float value;
|
||||||
float3 vector;
|
float3 vector;
|
||||||
|
|
||||||
if(all_inputs_constant()) {
|
if(folder.all_inputs_constant()) {
|
||||||
svm_vector_math(&value,
|
svm_vector_math(&value,
|
||||||
&vector,
|
&vector,
|
||||||
type,
|
type,
|
||||||
vector1,
|
vector1,
|
||||||
vector2);
|
vector2);
|
||||||
|
|
||||||
if(socket == output("Value")) {
|
if(folder.output == output("Value")) {
|
||||||
optimized->set(value);
|
folder.make_constant(value);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else if(socket == output("Vector")) {
|
else if(folder.output == output("Vector")) {
|
||||||
optimized->set(vector);
|
folder.make_constant(vector);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorMathNode::compile(SVMCompiler& compiler)
|
void VectorMathNode::compile(SVMCompiler& compiler)
|
||||||
@ -4913,9 +4826,7 @@ void BumpNode::compile(OSLCompiler& compiler)
|
|||||||
compiler.add(this, "node_bump");
|
compiler.add(this, "node_bump");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BumpNode::constant_fold(ShaderGraph *graph,
|
void BumpNode::constant_fold(const ConstantFolder& folder)
|
||||||
ShaderOutput * /*socket*/,
|
|
||||||
ShaderInput * /*optimized*/)
|
|
||||||
{
|
{
|
||||||
ShaderInput *height_in = input("Height");
|
ShaderInput *height_in = input("Height");
|
||||||
ShaderInput *normal_in = input("Normal");
|
ShaderInput *normal_in = input("Normal");
|
||||||
@ -4923,18 +4834,15 @@ bool BumpNode::constant_fold(ShaderGraph *graph,
|
|||||||
if(height_in->link == NULL) {
|
if(height_in->link == NULL) {
|
||||||
if(normal_in->link == NULL) {
|
if(normal_in->link == NULL) {
|
||||||
GeometryNode *geom = new GeometryNode();
|
GeometryNode *geom = new GeometryNode();
|
||||||
graph->add(geom);
|
folder.graph->add(geom);
|
||||||
graph->relink(this, outputs[0], geom->output("Normal"));
|
folder.bypass(geom->output("Normal"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
graph->relink(this, outputs[0], normal_in->link);
|
folder.bypass(normal_in->link);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(sergey): Ignore bump with zero strength. */
|
/* TODO(sergey): Ignore bump with zero strength. */
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ public:
|
|||||||
class RGBToBWNode : public ShaderNode {
|
class RGBToBWNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(RGBToBWNode)
|
SHADER_NODE_CLASS(RGBToBWNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
float3 color;
|
float3 color;
|
||||||
};
|
};
|
||||||
@ -299,7 +299,7 @@ public:
|
|||||||
ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false);
|
ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false);
|
||||||
SHADER_NODE_BASE_CLASS(ConvertNode)
|
SHADER_NODE_BASE_CLASS(ConvertNode)
|
||||||
|
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
SocketType::Type from, to;
|
SocketType::Type from, to;
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ public:
|
|||||||
class EmissionNode : public ShaderNode {
|
class EmissionNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(EmissionNode)
|
SHADER_NODE_CLASS(EmissionNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; }
|
virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; }
|
||||||
|
|
||||||
bool has_surface_emission() { return true; }
|
bool has_surface_emission() { return true; }
|
||||||
@ -449,7 +449,7 @@ public:
|
|||||||
class BackgroundNode : public ShaderNode {
|
class BackgroundNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BackgroundNode)
|
SHADER_NODE_CLASS(BackgroundNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual ClosureType get_closure_type() { return CLOSURE_BACKGROUND_ID; }
|
virtual ClosureType get_closure_type() { return CLOSURE_BACKGROUND_ID; }
|
||||||
|
|
||||||
float3 color;
|
float3 color;
|
||||||
@ -605,7 +605,7 @@ class ValueNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(ValueNode)
|
SHADER_NODE_CLASS(ValueNode)
|
||||||
|
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
float value;
|
float value;
|
||||||
};
|
};
|
||||||
@ -614,7 +614,7 @@ class ColorNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(ColorNode)
|
SHADER_NODE_CLASS(ColorNode)
|
||||||
|
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
float3 value;
|
float3 value;
|
||||||
};
|
};
|
||||||
@ -622,12 +622,13 @@ public:
|
|||||||
class AddClosureNode : public ShaderNode {
|
class AddClosureNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(AddClosureNode)
|
SHADER_NODE_CLASS(AddClosureNode)
|
||||||
|
void constant_fold(const ConstantFolder& folder);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MixClosureNode : public ShaderNode {
|
class MixClosureNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(MixClosureNode)
|
SHADER_NODE_CLASS(MixClosureNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
float fac;
|
float fac;
|
||||||
};
|
};
|
||||||
@ -643,7 +644,7 @@ public:
|
|||||||
class InvertNode : public ShaderNode {
|
class InvertNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(InvertNode)
|
SHADER_NODE_CLASS(InvertNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float fac;
|
float fac;
|
||||||
@ -653,7 +654,7 @@ public:
|
|||||||
class MixNode : public ShaderNode {
|
class MixNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(MixNode)
|
SHADER_NODE_CLASS(MixNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
@ -667,7 +668,7 @@ public:
|
|||||||
class CombineRGBNode : public ShaderNode {
|
class CombineRGBNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(CombineRGBNode)
|
SHADER_NODE_CLASS(CombineRGBNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float r, g, b;
|
float r, g, b;
|
||||||
@ -676,7 +677,7 @@ public:
|
|||||||
class CombineHSVNode : public ShaderNode {
|
class CombineHSVNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(CombineHSVNode)
|
SHADER_NODE_CLASS(CombineHSVNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float h, s, v;
|
float h, s, v;
|
||||||
@ -685,7 +686,7 @@ public:
|
|||||||
class CombineXYZNode : public ShaderNode {
|
class CombineXYZNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(CombineXYZNode)
|
SHADER_NODE_CLASS(CombineXYZNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
@ -694,7 +695,7 @@ public:
|
|||||||
class GammaNode : public ShaderNode {
|
class GammaNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(GammaNode)
|
SHADER_NODE_CLASS(GammaNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
||||||
|
|
||||||
float3 color;
|
float3 color;
|
||||||
@ -704,7 +705,7 @@ public:
|
|||||||
class BrightContrastNode : public ShaderNode {
|
class BrightContrastNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BrightContrastNode)
|
SHADER_NODE_CLASS(BrightContrastNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
||||||
|
|
||||||
float3 color;
|
float3 color;
|
||||||
@ -715,7 +716,7 @@ public:
|
|||||||
class SeparateRGBNode : public ShaderNode {
|
class SeparateRGBNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(SeparateRGBNode)
|
SHADER_NODE_CLASS(SeparateRGBNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float3 color;
|
float3 color;
|
||||||
@ -724,7 +725,7 @@ public:
|
|||||||
class SeparateHSVNode : public ShaderNode {
|
class SeparateHSVNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(SeparateHSVNode)
|
SHADER_NODE_CLASS(SeparateHSVNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float3 color;
|
float3 color;
|
||||||
@ -733,7 +734,7 @@ public:
|
|||||||
class SeparateXYZNode : public ShaderNode {
|
class SeparateXYZNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(SeparateXYZNode)
|
SHADER_NODE_CLASS(SeparateXYZNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float3 vector;
|
float3 vector;
|
||||||
@ -806,7 +807,7 @@ public:
|
|||||||
class BlackbodyNode : public ShaderNode {
|
class BlackbodyNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BlackbodyNode)
|
SHADER_NODE_CLASS(BlackbodyNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_3; }
|
||||||
|
|
||||||
float temperature;
|
float temperature;
|
||||||
@ -816,7 +817,7 @@ class MathNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(MathNode)
|
SHADER_NODE_CLASS(MathNode)
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
float value1;
|
float value1;
|
||||||
float value2;
|
float value2;
|
||||||
@ -837,7 +838,7 @@ class VectorMathNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(VectorMathNode)
|
SHADER_NODE_CLASS(VectorMathNode)
|
||||||
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
virtual int get_group() { return NODE_GROUP_LEVEL_1; }
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
|
|
||||||
float3 vector1;
|
float3 vector1;
|
||||||
float3 vector2;
|
float3 vector2;
|
||||||
@ -859,7 +860,7 @@ public:
|
|||||||
class BumpNode : public ShaderNode {
|
class BumpNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BumpNode)
|
SHADER_NODE_CLASS(BumpNode)
|
||||||
bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized);
|
void constant_fold(const ConstantFolder& folder);
|
||||||
bool has_spatial_varying() { return true; }
|
bool has_spatial_varying() { return true; }
|
||||||
virtual int get_feature() {
|
virtual int get_feature() {
|
||||||
return NODE_FEATURE_BUMP;
|
return NODE_FEATURE_BUMP;
|
||||||
|
Loading…
Reference in New Issue
Block a user