Cycles / Blackbody Node:
* Some optimizations to avoid divisions on runtime, avoid possible division by zero and code cleanup. Thanks to Brecht for code review!
This commit is contained in:
@@ -44,11 +44,11 @@ CCL_NAMESPACE_BEGIN
|
||||
#define BSSRDF_MIN_RADIUS 1e-8f
|
||||
#define BSSRDF_MAX_ATTEMPTS 8
|
||||
|
||||
#define BB_DRAPPER 800.0
|
||||
#define BB_MAX_TABLE_RANGE 12000.0
|
||||
#define BB_TABLE_XPOWER 1.5
|
||||
#define BB_TABLE_YPOWER 5.0
|
||||
#define BB_TABLE_SPACING 2.0
|
||||
#define BB_DRAPPER 800.0
|
||||
#define BB_MAX_TABLE_RANGE 12000.0
|
||||
#define BB_TABLE_XPOWER 1.5
|
||||
#define BB_TABLE_YPOWER 5.0
|
||||
#define BB_TABLE_SPACING 2.0
|
||||
|
||||
#define TEX_NUM_FLOAT_IMAGES 5
|
||||
|
||||
@@ -828,7 +828,7 @@ typedef struct KernelBSSRDF {
|
||||
int pad1, pad2;
|
||||
} KernelBSSRDF;
|
||||
|
||||
typedef struct KernelBLACKBODY {
|
||||
typedef struct KernelBlackbody {
|
||||
int table_offset;
|
||||
int pad1, pad2, pad3;
|
||||
} KernelBLACKBODY;
|
||||
@@ -843,7 +843,7 @@ typedef struct KernelData {
|
||||
KernelBVH bvh;
|
||||
KernelCurves curve_kernel_data;
|
||||
KernelBSSRDF bssrdf;
|
||||
KernelBLACKBODY blackbody;
|
||||
KernelBlackbody blackbody;
|
||||
} KernelData;
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -26,6 +26,8 @@ shader node_blackbody(
|
||||
|
||||
/* Scale by luminance */
|
||||
float l = luminance(rgb);
|
||||
Color = rgb /= l;
|
||||
if (l != 0.0)
|
||||
rgb /= l;
|
||||
Color = rgb;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,20 +49,20 @@ __device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack
|
||||
else if (temperature <= BB_MAX_TABLE_RANGE) {
|
||||
/* This is the overall size of the table */
|
||||
const int lookuptablesize = 956;
|
||||
const float lookuptablesizef = 956.0f;
|
||||
const float lookuptablenormalize = 1.0f/956.0f;
|
||||
|
||||
/* reconstruct a proper index for the table lookup, compared to OSL we don't look up two colors
|
||||
just one (the OSL-lerp is also automatically done for us by "lookup_table_read") */
|
||||
float t = powf ((temperature - BB_DRAPPER) / BB_TABLE_SPACING, 1.0f/BB_TABLE_XPOWER);
|
||||
float t = powf((temperature - BB_DRAPPER) * (1.0f / BB_TABLE_SPACING), 1.0f/BB_TABLE_XPOWER);
|
||||
|
||||
int blackbody_table_offset = kernel_data.blackbody.table_offset;
|
||||
|
||||
/* Retrieve colors from the lookup table */
|
||||
float lutval = t/lookuptablesizef;
|
||||
float lutval = t*lookuptablenormalize;
|
||||
float R = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize);
|
||||
lutval = (t + 319.0f*1.0f)/lookuptablesizef;
|
||||
lutval = (t + 319.0f*1.0f)*lookuptablenormalize;
|
||||
float G = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize);
|
||||
lutval = (t + 319.0f*2.0f)/lookuptablesizef;
|
||||
lutval = (t + 319.0f*2.0f)*lookuptablenormalize;
|
||||
float B = lookup_table_read(kg, lutval, blackbody_table_offset, lookuptablesize);
|
||||
|
||||
R = powf(R, BB_TABLE_YPOWER);
|
||||
@@ -71,10 +71,11 @@ __device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack
|
||||
|
||||
color_rgb = make_float3(R, G, B);
|
||||
}
|
||||
|
||||
|
||||
/* Luminance */
|
||||
float l = linear_rgb_to_gray(color_rgb);
|
||||
color_rgb /= l;
|
||||
if (l != 0.0f)
|
||||
color_rgb /= l;
|
||||
|
||||
if (stack_valid(col_offset))
|
||||
stack_store_float3(stack, col_offset, color_rgb);
|
||||
|
||||
@@ -265,7 +265,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
|
||||
}
|
||||
|
||||
/* blackbody lookup table */
|
||||
KernelBLACKBODY *kblackbody = &dscene->data.blackbody;
|
||||
KernelBlackbody *kblackbody = &dscene->data.blackbody;
|
||||
|
||||
if(has_converter_blackbody && blackbody_table_offset == TABLE_OFFSET_INVALID) {
|
||||
vector<float> table = blackbody_table();
|
||||
|
||||
@@ -389,11 +389,6 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo
|
||||
nodes_done = true;
|
||||
|
||||
foreach(ShaderNode *node, nodes) {
|
||||
|
||||
/* Detect if we have a blackbody converter, to prepare lookup table */
|
||||
if(node->has_converter_blackbody())
|
||||
current_shader->has_converter_blackbody = true;
|
||||
|
||||
if(done.find(node) == done.end()) {
|
||||
bool inputs_done = true;
|
||||
|
||||
@@ -403,6 +398,10 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo
|
||||
inputs_done = false;
|
||||
|
||||
if(inputs_done) {
|
||||
/* Detect if we have a blackbody converter, to prepare lookup table */
|
||||
if(node->has_converter_blackbody())
|
||||
current_shader->has_converter_blackbody = true;
|
||||
|
||||
node->compile(*this);
|
||||
stack_clear_users(node, done);
|
||||
stack_clear_temporary(node);
|
||||
|
||||
Reference in New Issue
Block a user