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:
Thomas Dinges
2013-07-31 19:03:42 +00:00
parent 380ee3d30a
commit b6024a0e75
5 changed files with 23 additions and 21 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);