Cycles: Improve parameter packing for BSDFs and emission
This replaces `stack_assign` with `stack_assign_if_linked`, which should save a few SVM nodes for constant parameters. Running benchmarks (all scenes in the benchmark repo, 3 runs, median value for each) shows 1.0% improvement on CPU and 1.5% on OptiX. Not huge, but fairly (all between -0.2% and 3.0%). Pull Request: https://projects.blender.org/blender/blender/pulls/143404
This commit is contained in:
@@ -531,31 +531,31 @@ ccl_device
|
||||
uint rotation_offset;
|
||||
uint tangent_offset;
|
||||
svm_unpack_node_uchar4(
|
||||
node.z, &base_ior_offset, &edge_tint_k_offset, &rotation_offset, &tangent_offset);
|
||||
data_node.y, &base_ior_offset, &edge_tint_k_offset, &rotation_offset, &tangent_offset);
|
||||
|
||||
const float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
float3 T = stack_load_float3(stack, tangent_offset);
|
||||
const float anisotropy = saturatef(param2);
|
||||
const float roughness = saturatef(param1);
|
||||
float alpha_x = sqr(roughness);
|
||||
float alpha_y = sqr(roughness);
|
||||
if (anisotropy > 0.0f) {
|
||||
bsdf->alpha_x = sqr(roughness);
|
||||
bsdf->alpha_y = sqr(roughness);
|
||||
if (anisotropy > 0.0f && tangent_offset != SVM_STACK_INVALID) {
|
||||
bsdf->T = stack_load_float3(stack, tangent_offset);
|
||||
const float aspect = sqrtf(1.0f - anisotropy * 0.9f);
|
||||
alpha_x /= aspect;
|
||||
alpha_y *= aspect;
|
||||
bsdf->alpha_x /= aspect;
|
||||
bsdf->alpha_y *= aspect;
|
||||
const float anisotropic_rotation = stack_load_float(stack, rotation_offset);
|
||||
if (anisotropic_rotation != 0.0f) {
|
||||
T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
|
||||
bsdf->T = rotate_around_axis(bsdf->T, N, anisotropic_rotation * M_2PI_F);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bsdf->T = zero_float3();
|
||||
}
|
||||
|
||||
bsdf->N = valid_reflection_N;
|
||||
bsdf->ior = 1.0f;
|
||||
bsdf->T = T;
|
||||
bsdf->alpha_x = alpha_x;
|
||||
bsdf->alpha_y = alpha_y;
|
||||
|
||||
const ClosureType distribution = (ClosureType)node.w;
|
||||
const ClosureType distribution = (ClosureType)data_node.z;
|
||||
/* Setup BSDF */
|
||||
if (distribution == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) {
|
||||
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
|
||||
@@ -1458,7 +1458,9 @@ ccl_device_noinline void svm_node_emission_weight(ccl_private float *stack,
|
||||
const uint color_offset = node.y;
|
||||
const uint strength_offset = node.z;
|
||||
|
||||
const float strength = stack_load_float(stack, strength_offset);
|
||||
const float strength = (stack_valid(strength_offset)) ?
|
||||
stack_load_float(stack, strength_offset) :
|
||||
__uint_as_float(node.w);
|
||||
*closure_weight = rgb_to_spectrum(stack_load_float3(stack, color_offset)) * strength;
|
||||
}
|
||||
|
||||
|
||||
@@ -2089,14 +2089,14 @@ void BsdfNode::compile(SVMCompiler &compiler,
|
||||
const int data_z_offset = (data_z) ? compiler.stack_assign(data_z) : SVM_STACK_INVALID;
|
||||
const int data_w_offset = (data_w) ? compiler.stack_assign(data_w) : SVM_STACK_INVALID;
|
||||
|
||||
compiler.add_node(
|
||||
NODE_CLOSURE_BSDF,
|
||||
compiler.encode_uchar4(closure,
|
||||
(bsdf_y) ? compiler.stack_assign(bsdf_y) : SVM_STACK_INVALID,
|
||||
(bsdf_z) ? compiler.stack_assign(bsdf_z) : SVM_STACK_INVALID,
|
||||
compiler.closure_mix_weight_offset()),
|
||||
__float_as_int((bsdf_y) ? get_float(bsdf_y->socket_type) : 0.0f),
|
||||
__float_as_int((bsdf_z) ? get_float(bsdf_z->socket_type) : 0.0f));
|
||||
compiler.add_node(NODE_CLOSURE_BSDF,
|
||||
compiler.encode_uchar4(
|
||||
closure,
|
||||
(bsdf_y) ? compiler.stack_assign_if_linked(bsdf_y) : SVM_STACK_INVALID,
|
||||
(bsdf_z) ? compiler.stack_assign_if_linked(bsdf_z) : SVM_STACK_INVALID,
|
||||
compiler.closure_mix_weight_offset()),
|
||||
__float_as_int((bsdf_y) ? get_float(bsdf_y->socket_type) : 0.0f),
|
||||
__float_as_int((bsdf_z) ? get_float(bsdf_z->socket_type) : 0.0f));
|
||||
|
||||
compiler.add_node(normal_offset, data_y_offset, data_z_offset, data_w_offset);
|
||||
}
|
||||
@@ -2187,36 +2187,32 @@ void MetallicBsdfNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, one_float3());
|
||||
|
||||
ShaderInput *base_color_in = input("Base Color");
|
||||
ShaderInput *edge_tint_in = input("Edge Tint");
|
||||
ShaderInput *ior_in = input("IOR");
|
||||
ShaderInput *k_in = input("Extinction");
|
||||
|
||||
const int base_color_ior_offset = fresnel_type == CLOSURE_BSDF_PHYSICAL_CONDUCTOR ?
|
||||
compiler.stack_assign(ior_in) :
|
||||
compiler.stack_assign(base_color_in);
|
||||
compiler.stack_assign(input("IOR")) :
|
||||
compiler.stack_assign(input("Base Color"));
|
||||
const int edge_tint_k_offset = fresnel_type == CLOSURE_BSDF_PHYSICAL_CONDUCTOR ?
|
||||
compiler.stack_assign(k_in) :
|
||||
compiler.stack_assign(edge_tint_in);
|
||||
compiler.stack_assign(input("Extinction")) :
|
||||
compiler.stack_assign(input("Edge Tint"));
|
||||
|
||||
ShaderInput *anisotropy_in = input("Anisotropy");
|
||||
ShaderInput *rotation_in = input("Rotation");
|
||||
ShaderInput *roughness_in = input("Roughness");
|
||||
ShaderInput *tangent_in = input("Tangent");
|
||||
ShaderInput *anisotropy_in = input("Anisotropy");
|
||||
|
||||
const int normal_offset = compiler.stack_assign_if_linked(input("Normal"));
|
||||
const int tangent_offset = compiler.stack_assign_if_linked(input("Tangent"));
|
||||
const int rotation_offset = compiler.stack_assign(input("Rotation"));
|
||||
|
||||
compiler.add_node(NODE_CLOSURE_BSDF,
|
||||
compiler.encode_uchar4(fresnel_type,
|
||||
compiler.stack_assign(roughness_in),
|
||||
compiler.stack_assign(anisotropy_in),
|
||||
compiler.stack_assign_if_linked(roughness_in),
|
||||
compiler.stack_assign_if_linked(anisotropy_in),
|
||||
compiler.closure_mix_weight_offset()),
|
||||
compiler.encode_uchar4(base_color_ior_offset,
|
||||
edge_tint_k_offset,
|
||||
compiler.stack_assign(rotation_in),
|
||||
compiler.stack_assign(tangent_in)),
|
||||
distribution);
|
||||
compiler.add_node(normal_offset);
|
||||
__float_as_int(get_float(roughness_in->socket_type)),
|
||||
__float_as_int(get_float(anisotropy_in->socket_type)));
|
||||
compiler.add_node(
|
||||
normal_offset,
|
||||
compiler.encode_uchar4(
|
||||
base_color_ior_offset, edge_tint_k_offset, rotation_offset, tangent_offset),
|
||||
distribution);
|
||||
}
|
||||
|
||||
void MetallicBsdfNode::compile(OSLCompiler &compiler)
|
||||
@@ -2914,9 +2910,13 @@ void EmissionNode::compile(SVMCompiler &compiler)
|
||||
ShaderInput *color_in = input("Color");
|
||||
ShaderInput *strength_in = input("Strength");
|
||||
|
||||
const int strength_offset = compiler.stack_assign_if_linked(strength_in);
|
||||
|
||||
if (color_in->link || strength_in->link) {
|
||||
compiler.add_node(
|
||||
NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
|
||||
compiler.add_node(NODE_EMISSION_WEIGHT,
|
||||
compiler.stack_assign(color_in),
|
||||
strength_offset,
|
||||
__float_as_int(get_float(strength_in->socket_type)));
|
||||
}
|
||||
else {
|
||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
|
||||
@@ -2962,9 +2962,13 @@ void BackgroundNode::compile(SVMCompiler &compiler)
|
||||
ShaderInput *color_in = input("Color");
|
||||
ShaderInput *strength_in = input("Strength");
|
||||
|
||||
const int strength_offset = compiler.stack_assign_if_linked(strength_in);
|
||||
|
||||
if (color_in->link || strength_in->link) {
|
||||
compiler.add_node(
|
||||
NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
|
||||
compiler.add_node(NODE_EMISSION_WEIGHT,
|
||||
compiler.stack_assign(color_in),
|
||||
strength_offset,
|
||||
__float_as_int(get_float(strength_in->socket_type)));
|
||||
}
|
||||
else {
|
||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
|
||||
|
||||
Reference in New Issue
Block a user