Shading: Add invert option to Vector Rotate Node

Checkbox to invert rotation angle, suggested by @simonthommes

Differential Revision: https://developer.blender.org/D6932
This commit is contained in:
Charlie Jolly 2020-02-25 14:52:01 +00:00
parent 493c99078a
commit 847c091ae8
9 changed files with 92 additions and 68 deletions

View File

@ -327,6 +327,7 @@ static ShaderNode *add_node(Scene *scene,
BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node);
VectorRotateNode *vector_rotate_node = new VectorRotateNode();
vector_rotate_node->type = (NodeVectorRotateType)b_vector_rotate_node.rotation_type();
vector_rotate_node->invert = b_vector_rotate_node.invert();
node = vector_rotate_node;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {

View File

@ -17,7 +17,8 @@
#include "stdcycles.h"
#include "node_math.h"
shader node_vector_rotate(string type = "axis",
shader node_vector_rotate(int invert = 0,
string type = "axis",
vector VectorIn = vector(0.0, 0.0, 0.0),
point Center = point(0.0, 0.0, 0.0),
point Rotation = point(0.0, 0.0, 0.0),
@ -26,20 +27,23 @@ shader node_vector_rotate(string type = "axis",
output vector VectorOut = vector(0.0, 0.0, 0.0))
{
if (type == "euler_xyz") {
VectorOut = transform(euler_to_mat(Rotation), VectorIn - Center) + Center;
matrix rmat = (invert) ? transpose(euler_to_mat(Rotation)) : euler_to_mat(Rotation);
VectorOut = transform(rmat, VectorIn - Center) + Center;
}
else if (type == "x_axis") {
VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(1.0, 0.0, 0.0)) + Center;
}
else if (type == "y_axis") {
VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(0.0, 1.0, 0.0)) + Center;
}
else if (type == "z_axis") {
VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(0.0, 0.0, 1.0)) + Center;
}
else { // axis
VectorOut = (length(Axis) != 0.0) ?
rotate(VectorIn - Center, Angle, point(0.0), Axis) + Center :
VectorIn;
else {
float a = (invert) ? -Angle : Angle;
if (type == "x_axis") {
VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(1.0, 0.0, 0.0)) + Center;
}
else if (type == "y_axis") {
VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(0.0, 1.0, 0.0)) + Center;
}
else if (type == "z_axis") {
VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(0.0, 0.0, 1.0)) + Center;
}
else { // axis
VectorOut = (length(Axis) != 0.0) ? rotate(VectorIn - Center, a, point(0.0), Axis) + Center :
VectorIn;
}
}
}

View File

@ -25,45 +25,52 @@ ccl_device void svm_node_vector_rotate(ShaderData *sd,
uint result_stack_offset)
{
uint type, vector_stack_offset, rotation_stack_offset, center_stack_offset, axis_stack_offset,
angle_stack_offset;
angle_stack_offset, invert;
svm_unpack_node_uchar3(input_stack_offsets, &type, &vector_stack_offset, &rotation_stack_offset);
svm_unpack_node_uchar4(
input_stack_offsets, &type, &vector_stack_offset, &rotation_stack_offset, &invert);
svm_unpack_node_uchar3(
axis_stack_offsets, &center_stack_offset, &axis_stack_offset, &angle_stack_offset);
float3 vector = stack_load_float3(stack, vector_stack_offset);
float3 center = stack_load_float3(stack, center_stack_offset);
float3 result = make_float3(0.0f, 0.0f, 0.0f);
if (type == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ.
Transform rotationTransform = euler_to_transform(rotation);
result = transform_direction(&rotationTransform, vector - center) + center;
}
else {
float3 axis;
switch (type) {
case NODE_VECTOR_ROTATE_TYPE_AXIS_X:
axis = make_float3(1.0f, 0.0f, 0.0f);
break;
case NODE_VECTOR_ROTATE_TYPE_AXIS_Y:
axis = make_float3(0.0f, 1.0f, 0.0f);
break;
case NODE_VECTOR_ROTATE_TYPE_AXIS_Z:
axis = make_float3(0.0f, 0.0f, 1.0f);
break;
default:
axis = normalize(stack_load_float3(stack, axis_stack_offset));
break;
}
float angle = stack_load_float(stack, angle_stack_offset);
result = (len_squared(axis) != 0.0f) ?
rotate_around_axis(vector - center, axis, angle) + center :
vector;
}
/* Output */
if (stack_valid(result_stack_offset)) {
float3 vector = stack_load_float3(stack, vector_stack_offset);
float3 center = stack_load_float3(stack, center_stack_offset);
float3 result = make_float3(0.0f, 0.0f, 0.0f);
if (type == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ.
Transform rotationTransform = euler_to_transform(rotation);
if (invert) {
result = transform_direction_transposed(&rotationTransform, vector - center) + center;
}
else {
result = transform_direction(&rotationTransform, vector - center) + center;
}
}
else {
float3 axis;
switch (type) {
case NODE_VECTOR_ROTATE_TYPE_AXIS_X:
axis = make_float3(1.0f, 0.0f, 0.0f);
break;
case NODE_VECTOR_ROTATE_TYPE_AXIS_Y:
axis = make_float3(0.0f, 1.0f, 0.0f);
break;
case NODE_VECTOR_ROTATE_TYPE_AXIS_Z:
axis = make_float3(0.0f, 0.0f, 1.0f);
break;
default:
axis = normalize(stack_load_float3(stack, axis_stack_offset));
break;
}
float angle = stack_load_float(stack, angle_stack_offset);
angle = invert ? -angle : angle;
result = (len_squared(axis) != 0.0f) ?
rotate_around_axis(vector - center, axis, angle) + center :
vector;
}
stack_store_float3(stack, result_stack_offset, result);
}
}

View File

@ -6157,6 +6157,8 @@ NODE_DEFINE(VectorRotateNode)
type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ);
SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
SOCKET_BOOLEAN(invert, "Invert", false);
SOCKET_IN_VECTOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_IN_POINT(rotation, "Rotation", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_IN_POINT(center, "Center", make_float3(0.0f, 0.0f, 0.0f));
@ -6180,19 +6182,20 @@ void VectorRotateNode::compile(SVMCompiler &compiler)
ShaderInput *angle_in = input("Angle");
ShaderOutput *vector_out = output("Vector");
compiler.add_node(NODE_VECTOR_ROTATE,
compiler.encode_uchar4(type,
compiler.stack_assign(vector_in),
compiler.stack_assign(rotation_in)),
compiler.encode_uchar4(compiler.stack_assign(center_in),
compiler.stack_assign(axis_in),
compiler.stack_assign(angle_in)),
compiler.stack_assign(vector_out));
compiler.add_node(
NODE_VECTOR_ROTATE,
compiler.encode_uchar4(
type, compiler.stack_assign(vector_in), compiler.stack_assign(rotation_in), invert),
compiler.encode_uchar4(compiler.stack_assign(center_in),
compiler.stack_assign(axis_in),
compiler.stack_assign(angle_in)),
compiler.stack_assign(vector_out));
}
void VectorRotateNode::compile(OSLCompiler &compiler)
{
compiler.parameter(this, "type");
compiler.parameter(this, "invert");
compiler.add(this, "node_vector_rotate");
}

View File

@ -1400,6 +1400,7 @@ class VectorRotateNode : public ShaderNode {
return NODE_GROUP_LEVEL_3;
}
NodeVectorRotateType type;
bool invert;
float3 vector;
float3 center;
float3 axis;

View File

@ -748,6 +748,7 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
static void node_shader_buts_vector_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "rotation_type", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "invert", 0, NULL, 0);
}
static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)

View File

@ -20,33 +20,34 @@ vec3 rotate_around_axis(vec3 p, vec3 axis, float angle)
}
void node_vector_rotate_axis_angle(
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, float invert, out vec3 vec)
{
vec = (length(axis) != 0.0) ?
rotate_around_axis(vector_in - center, normalize(axis), angle) + center :
rotate_around_axis(vector_in - center, normalize(axis), angle * invert) + center :
vector_in;
}
void node_vector_rotate_axis_x(
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, float invert, out vec3 vec)
{
vec = rotate_around_axis(vector_in - center, vec3(1.0, 0.0, 0.0), angle) + center;
vec = rotate_around_axis(vector_in - center, vec3(1.0, 0.0, 0.0), angle * invert) + center;
}
void node_vector_rotate_axis_y(
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, float invert, out vec3 vec)
{
vec = rotate_around_axis(vector_in - center, vec3(0.0, 1.0, 0.0), angle) + center;
vec = rotate_around_axis(vector_in - center, vec3(0.0, 1.0, 0.0), angle * invert) + center;
}
void node_vector_rotate_axis_z(
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, float invert, out vec3 vec)
{
vec = rotate_around_axis(vector_in - center, vec3(0.0, 0.0, 1.0), angle) + center;
vec = rotate_around_axis(vector_in - center, vec3(0.0, 0.0, 1.0), angle * invert) + center;
}
void node_vector_rotate_euler_xyz(
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, float invert, out vec3 vec)
{
vec = euler_to_mat3(rotation) * (vector_in - center) + center;
mat3 rmat = (invert < 0.0) ? transpose(euler_to_mat3(rotation)) : euler_to_mat3(rotation);
vec = rmat * (vector_in - center) + center;
}

View File

@ -4166,6 +4166,11 @@ static void def_sh_vector_rotate(StructRNA *srna)
RNA_def_property_enum_items(prop, rna_enum_vector_rotate_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of rotation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom2", 0);
RNA_def_property_ui_text(prop, "Invert", "Invert angle");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_sh_attribute(StructRNA *srna)

View File

@ -51,7 +51,8 @@ static int gpu_shader_vector_rotate(GPUMaterial *mat,
};
if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
return GPU_stack_link(mat, node, names[node->custom1], in, out);
float invert = (node->custom2) ? -1.0 : 1.0;
return GPU_stack_link(mat, node, names[node->custom1], in, out, GPU_constant(&invert));
}
else {
return 0;