forked from bartvdbraak/blender
Cycles: internal support for alpha output for attribute node
Not exposed in Blender yet. Ref D2057
This commit is contained in:
parent
b7558e3c9c
commit
70040e7b0b
@ -20,20 +20,26 @@ shader node_attribute(string bump_offset = "center",
|
||||
string name = "",
|
||||
output point Vector = point(0.0, 0.0, 0.0),
|
||||
output color Color = 0.0,
|
||||
output float Fac = 0.0)
|
||||
output float Fac = 0.0,
|
||||
output float Alpha = 0.0)
|
||||
{
|
||||
getattribute(name, Color);
|
||||
float data[4];
|
||||
getattribute(name, data);
|
||||
Color = color(data[0], data[1], data[2]);
|
||||
Vector = point(Color);
|
||||
getattribute(name, Fac);
|
||||
Alpha = data[3];
|
||||
|
||||
if (bump_offset == "dx") {
|
||||
Color += Dx(Color);
|
||||
Vector += Dx(Vector);
|
||||
Fac += Dx(Fac);
|
||||
Alpha += Dx(Alpha);
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
Color += Dy(Color);
|
||||
Vector += Dy(Vector);
|
||||
Fac += Dy(Fac);
|
||||
Alpha += Dy(Alpha);
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ CCL_NAMESPACE_BEGIN
|
||||
/* Attribute Node */
|
||||
|
||||
ccl_device AttributeDescriptor svm_node_attr_init(
|
||||
KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, uint *out_offset)
|
||||
KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeOutputType *type, uint *out_offset)
|
||||
{
|
||||
*out_offset = node.z;
|
||||
*type = (NodeAttributeType)node.w;
|
||||
*type = (NodeAttributeOutputType)node.w;
|
||||
|
||||
AttributeDescriptor desc;
|
||||
|
||||
@ -46,7 +46,7 @@ ccl_device AttributeDescriptor svm_node_attr_init(
|
||||
|
||||
ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
NodeAttributeType type = NODE_ATTR_FLOAT;
|
||||
NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
|
||||
uint out_offset = 0;
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
@ -56,72 +56,91 @@ ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, u
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
const float4 value = volume_attribute_float4(kg, sd, desc);
|
||||
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
const float f = volume_attribute_value_to_float(value);
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
const float3 f = volume_attribute_value_to_float3(value);
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
}
|
||||
else {
|
||||
const float f = volume_attribute_value_to_alpha(value);
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Surface */
|
||||
/* Surface. */
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f, f, f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(float4_to_float3(f)));
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, float4_to_float3(f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
NodeAttributeType type = NODE_ATTR_FLOAT;
|
||||
NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
|
||||
uint out_offset = 0;
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* Volume */
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, 0.0f);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -130,60 +149,75 @@ ccl_device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float dx;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f + dx);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dx;
|
||||
float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dx.x);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 dx;
|
||||
float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(float4_to_float3(f + dx)));
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, float4_to_float3(f + dx));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w + dx.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f + dx));
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f + dx);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
||||
{
|
||||
NodeAttributeType type = NODE_ATTR_FLOAT;
|
||||
NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT;
|
||||
uint out_offset = 0;
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
#ifdef __VOLUME__
|
||||
/* Volume */
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, 0.0f);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -192,42 +226,54 @@ ccl_device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float dy;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f + dy);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dy;
|
||||
float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dy.x);
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 dy;
|
||||
float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(float4_to_float3(f + dy)));
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, float4_to_float3(f + dy));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w + dy.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f + dy));
|
||||
}
|
||||
else {
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f + dy);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,12 @@ typedef enum ShaderNodeType {
|
||||
* match the switch case order in svm.h. */
|
||||
} ShaderNodeType;
|
||||
|
||||
typedef enum NodeAttributeOutputType {
|
||||
NODE_ATTR_OUTPUT_FLOAT3 = 0,
|
||||
NODE_ATTR_OUTPUT_FLOAT,
|
||||
NODE_ATTR_OUTPUT_FLOAT_ALPHA,
|
||||
} NodeAttributeOutputType;
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
NODE_ATTR_FLOAT = 0,
|
||||
NODE_ATTR_FLOAT2,
|
||||
|
@ -3743,7 +3743,7 @@ void GeometryNode::compile(SVMCompiler &compiler)
|
||||
if (!out->links.empty()) {
|
||||
if (compiler.output_type() != SHADER_TYPE_VOLUME) {
|
||||
compiler.add_node(
|
||||
attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_FLOAT);
|
||||
attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
|
||||
}
|
||||
else {
|
||||
compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
|
||||
@ -3753,8 +3753,10 @@ void GeometryNode::compile(SVMCompiler &compiler)
|
||||
out = output("Random Per Island");
|
||||
if (!out->links.empty()) {
|
||||
if (compiler.output_type() != SHADER_TYPE_VOLUME) {
|
||||
compiler.add_node(
|
||||
attr_node, ATTR_STD_RANDOM_PER_ISLAND, compiler.stack_assign(out), NODE_ATTR_FLOAT);
|
||||
compiler.add_node(attr_node,
|
||||
ATTR_STD_RANDOM_PER_ISLAND,
|
||||
compiler.stack_assign(out),
|
||||
NODE_ATTR_OUTPUT_FLOAT);
|
||||
}
|
||||
else {
|
||||
compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
|
||||
@ -3872,7 +3874,7 @@ void TextureCoordinateNode::compile(SVMCompiler &compiler)
|
||||
}
|
||||
else {
|
||||
int attr = compiler.attribute(ATTR_STD_GENERATED);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3889,7 +3891,7 @@ void TextureCoordinateNode::compile(SVMCompiler &compiler)
|
||||
}
|
||||
else {
|
||||
int attr = compiler.attribute(ATTR_STD_UV);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4007,7 +4009,7 @@ void UVMapNode::compile(SVMCompiler &compiler)
|
||||
else
|
||||
attr = compiler.attribute(ATTR_STD_UV);
|
||||
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4403,7 +4405,7 @@ void HairInfoNode::compile(SVMCompiler &compiler)
|
||||
out = output("Intercept");
|
||||
if (!out->links.empty()) {
|
||||
int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
|
||||
compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
|
||||
compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
|
||||
}
|
||||
|
||||
out = output("Thickness");
|
||||
@ -4424,7 +4426,7 @@ void HairInfoNode::compile(SVMCompiler &compiler)
|
||||
out = output("Random");
|
||||
if (!out->links.empty()) {
|
||||
int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
|
||||
compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
|
||||
compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5386,6 +5388,7 @@ NODE_DEFINE(AttributeNode)
|
||||
SOCKET_OUT_COLOR(color, "Color");
|
||||
SOCKET_OUT_VECTOR(vector, "Vector");
|
||||
SOCKET_OUT_FLOAT(fac, "Fac");
|
||||
SOCKET_OUT_FLOAT(alpha, "Alpha");
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -5399,8 +5402,10 @@ void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *vector_out = output("Vector");
|
||||
ShaderOutput *fac_out = output("Fac");
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
|
||||
if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) {
|
||||
if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty() ||
|
||||
!alpha_out->links.empty()) {
|
||||
attributes->add_standard(attribute);
|
||||
}
|
||||
|
||||
@ -5416,6 +5421,7 @@ void AttributeNode::compile(SVMCompiler &compiler)
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *vector_out = output("Vector");
|
||||
ShaderOutput *fac_out = output("Fac");
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
ShaderNodeType attr_node = NODE_ATTR;
|
||||
int attr = compiler.attribute_standard(attribute);
|
||||
|
||||
@ -5426,15 +5432,22 @@ void AttributeNode::compile(SVMCompiler &compiler)
|
||||
|
||||
if (!color_out->links.empty() || !vector_out->links.empty()) {
|
||||
if (!color_out->links.empty()) {
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_FLOAT3);
|
||||
compiler.add_node(
|
||||
attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_OUTPUT_FLOAT3);
|
||||
}
|
||||
if (!vector_out->links.empty()) {
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_FLOAT3);
|
||||
compiler.add_node(
|
||||
attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_OUTPUT_FLOAT3);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fac_out->links.empty()) {
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_FLOAT);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_OUTPUT_FLOAT);
|
||||
}
|
||||
|
||||
if (!alpha_out->links.empty()) {
|
||||
compiler.add_node(
|
||||
attr_node, attr, compiler.stack_assign(alpha_out), NODE_ATTR_OUTPUT_FLOAT_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user