* Fix missing update when editing objects with emission materials.
* Fix preview pass rendering set to 1 not showing full resolution.
* Fix CUDA runtime compiling failing due to missing cache directory.
* Use settings from first render layer for visibility and material override.

And a bunch of incomplete and still disabled code mostly related to closure
sampling.
This commit is contained in:
Brecht Van Lommel
2011-09-12 13:13:56 +00:00
parent c40492205b
commit ebc653463d
43 changed files with 1239 additions and 712 deletions

View File

@@ -119,13 +119,13 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data();
if(prim) {
FlatClosure flat;
flat.prim = prim;
flat.weight = weight;
ShaderClosure sc;
sc.prim = prim;
sc.weight = weight;
switch(prim->category()) {
case ClosurePrimitive::BSDF: {
if(sd->osl_closure.num_bsdf == MAX_OSL_CLOSURE)
if(sd->num_closure == MAX_CLOSURE)
return;
OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)prim;
@@ -140,7 +140,8 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
float sample_weight = fabsf(average(weight))*albedo;
float sample_sum = sd->osl_closure.bsdf_sample_sum + sample_weight;
flat.sample_weight = sample_weight;
sc.sample_weight = sample_weight;
sc.type = CLOSURE_BSDF_ID;
sd->osl_closure.bsdf_sample_sum = sample_sum;
/* scattering flags */
@@ -152,29 +153,35 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
sd->flag |= SD_BSDF;
/* add */
sd->osl_closure.bsdf[sd->osl_closure.num_bsdf++] = flat;
sd->closure[sd->num_closure++] = sc;
break;
}
case ClosurePrimitive::Emissive: {
if(sd->osl_closure.num_bsdf == MAX_OSL_CLOSURE)
if(sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */
float sample_weight = fabsf(average(weight));
float sample_sum = sd->osl_closure.emissive_sample_sum + sample_weight;
flat.sample_weight = sample_weight;
sc.sample_weight = sample_weight;
sc.type = CLOSURE_EMISSION_ID;
sd->osl_closure.emissive_sample_sum = sample_sum;
/* flag */
sd->flag |= SD_EMISSION;
sd->osl_closure.emissive[sd->osl_closure.num_emissive++] = flat;
sd->closure[sd->num_closure++] = sc;
break;
}
case ClosurePrimitive::Holdout:
sd->osl_closure.holdout_weight += weight;
if(sd->num_closure == MAX_CLOSURE)
return;
sc.sample_weight = 0.0f;
sc.type = CLOSURE_HOLDOUT_ID;
sd->flag |= SD_HOLDOUT;
sd->closure[sd->num_closure++] = sc;
break;
case ClosurePrimitive::BSSRDF:
case ClosurePrimitive::Debug:
@@ -213,12 +220,8 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int
ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[sd->shader]), *globals);
/* flatten closure tree */
sd->osl_closure.bsdf_sample_sum = 0.0f;
sd->osl_closure.emissive_sample_sum = 0.0f;
sd->osl_closure.num_bsdf = 0;
sd->osl_closure.num_emissive = 0;
sd->osl_closure.holdout_weight = make_float3(0.0f, 0.0f, 0.0f);
sd->osl_closure.randb = randb;
sd->num_closure = 0;
sd->randb_closure = randb;
if(globals->Ci) {
bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics;
@@ -292,24 +295,25 @@ static void flatten_volume_closure_tree(ShaderData *sd,
OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data();
if(prim) {
FlatClosure flat;
flat.prim = prim;
flat.weight = weight;
ShaderClosure sc;
sc.prim = prim;
sc.weight = weight;
switch(prim->category()) {
case ClosurePrimitive::Volume: {
if(sd->osl_closure.num_bsdf == MAX_OSL_CLOSURE)
if(sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */
float sample_weight = fabsf(average(weight));
float sample_sum = sd->osl_closure.volume_sample_sum + sample_weight;
flat.sample_weight = sample_weight;
sc.sample_weight = sample_weight;
sc.type = CLOSURE_VOLUME_ID;
sd->osl_closure.volume_sample_sum = sample_sum;
/* add */
sd->osl_closure.volume[sd->osl_closure.num_volume++] = flat;
sd->closure[sd->num_closure++] = sc;
break;
}
case ClosurePrimitive::Holdout:
@@ -389,183 +393,76 @@ void OSLShader::release(KernelGlobals *kg, const ShaderData *sd)
/* BSDF Closure */
int OSLShader::bsdf_sample(const ShaderData *sd, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
{
OSL::BSDFClosure *sample_bsdf = NULL;
OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure*)sc->prim;
int label = LABEL_NONE;
float r = sd->osl_closure.randb*sd->osl_closure.bsdf_sample_sum;
float sample_sum = 0.0f;
pdf = 0.0f;
if(sd->osl_closure.bsdf_sample_sum == 0.0f)
return LABEL_NONE;
/* sample BSDF closure */
ustring ulabel;
/* find a closure to sample */
for(int i = 0; i < sd->osl_closure.num_bsdf; i++) {
const FlatClosure *flat = &sd->osl_closure.bsdf[i];
sample_sum += flat->sample_weight;
ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng),
TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy),
randu, randv,
TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy),
pdf, TO_COLOR3(eval));
if(r > sample_sum)
continue;
/* convert OSL label */
if(ulabel == OSL::Labels::REFLECT)
label = LABEL_REFLECT;
else if(ulabel == OSL::Labels::TRANSMIT)
label = LABEL_TRANSMIT;
else
return LABEL_NONE; /* sampling failed */
/* sample BSDF closure */
sample_bsdf = (OSL::BSDFClosure*)flat->prim;
ustring ulabel;
/* convert scattering to our bitflag label */
ustring uscattering = sample_bsdf->scattering();
ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng),
TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy),
randu, randv,
TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy),
pdf, TO_COLOR3(eval));
/* convert OSL label */
if(ulabel == OSL::Labels::REFLECT)
label = LABEL_REFLECT;
else if(ulabel == OSL::Labels::TRANSMIT)
label = LABEL_TRANSMIT;
else
return LABEL_NONE; /* sampling failed */
/* convert scattering to our bitflag label */
ustring uscattering = sample_bsdf->scattering();
if(uscattering == OSL::Labels::DIFFUSE)
label |= LABEL_DIFFUSE;
else if(uscattering == OSL::Labels::GLOSSY)
label |= LABEL_GLOSSY;
else if(uscattering == OSL::Labels::SINGULAR)
label |= LABEL_SINGULAR;
else
label |= LABEL_TRANSPARENT;
/* eval + pdf */
eval *= flat->weight;
pdf *= flat->sample_weight;
break;
}
if(!sample_bsdf || pdf == 0.0f)
return LABEL_NONE;
/* add eval/pdf from other BSDF closures */
for(int i = 0; i < sd->osl_closure.num_bsdf; i++) {
const FlatClosure *flat = &sd->osl_closure.bsdf[i];
OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)flat->prim;
if(bsdf != sample_bsdf) {
OSL::Color3 bsdf_eval;
float bsdf_pdf = 0.0f;
if(dot(sd->Ng, omega_in) >= 0.0f)
bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), bsdf_pdf);
else
bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), bsdf_pdf);
if(bsdf_pdf != 0.0f) {
eval += TO_FLOAT3(bsdf_eval)*flat->weight;
pdf += bsdf_pdf*flat->sample_weight;
}
}
}
pdf *= 1.0f/(sd->osl_closure.bsdf_sample_sum);
if(uscattering == OSL::Labels::DIFFUSE)
label |= LABEL_DIFFUSE;
else if(uscattering == OSL::Labels::GLOSSY)
label |= LABEL_GLOSSY;
else if(uscattering == OSL::Labels::SINGULAR)
label |= LABEL_SINGULAR;
else
label |= LABEL_TRANSPARENT;
return label;
}
float3 OSLShader::bsdf_eval(const ShaderData *sd, const float3& omega_in, float& pdf)
float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf)
{
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)sc->prim;
OSL::Color3 bsdf_eval;
pdf = 0.0f;
for(int i = 0; i < sd->osl_closure.num_bsdf; i++) {
const FlatClosure *flat = &sd->osl_closure.bsdf[i];
OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)flat->prim;
OSL::Color3 bsdf_eval;
float bsdf_pdf = 0.0f;
if(dot(sd->Ng, omega_in) >= 0.0f)
bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), bsdf_pdf);
else
bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), bsdf_pdf);
if(bsdf_pdf != 0.0f) {
eval += TO_FLOAT3(bsdf_eval)*flat->weight;
pdf += bsdf_pdf*flat->sample_weight;
}
}
pdf *= 1.0f/sd->osl_closure.bsdf_sample_sum;
return eval;
if(dot(sd->Ng, omega_in) >= 0.0f)
bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
else
bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
return TO_FLOAT3(bsdf_eval);
}
/* Emissive Closure */
float3 OSLShader::emissive_eval(const ShaderData *sd)
float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc)
{
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->osl_closure.num_emissive; i++) {
const FlatClosure *flat = &sd->osl_closure.emissive[i];
OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure*)flat->prim;
OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I));
eval += TO_FLOAT3(emissive_eval)*flat->weight;
}
OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure*)sc->prim;
OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I));
eval += TO_FLOAT3(emissive_eval);
return eval;
}
void OSLShader::emissive_sample(const ShaderData *sd, float randu, float randv, float3 *eval, float3 *I, float *pdf)
{
float r = sd->osl_closure.randb*sd->osl_closure.emissive_sample_sum;
float sample_sum = 0.0f;
*pdf = 0.0f;
if(sd->osl_closure.emissive_sample_sum == 0.0f)
return;
/* find a closure to sample */
for(int i = 0; i < sd->osl_closure.num_emissive; i++) {
const FlatClosure *flat = &sd->osl_closure.emissive[i];
sample_sum += flat->sample_weight;
if(r <= sample_sum) {
/* sample emissive closure */
OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure*)flat->prim;
emissive->sample(TO_VEC3(sd->Ng), randu, randv, TO_VEC3(*I), *pdf);
*eval = flat->weight;
*pdf *= flat->sample_weight/sd->osl_closure.emissive_sample_sum;
return;
}
}
}
/* Volume Closure */
float3 OSLShader::volume_eval_phase(const ShaderData *sd, const float3 omega_in, const float3 omega_out)
float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->osl_closure.num_volume; i++) {
const FlatClosure *flat = &sd->osl_closure.volume[i];
OSL::VolumeClosure *volume = (OSL::VolumeClosure*)flat->prim;
OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out));
eval += TO_FLOAT3(volume_eval)*flat->weight;
}
return eval;
}
/* Holdout Closure */
float3 OSLShader::holdout_eval(const ShaderData *sd)
{
return sd->osl_closure.holdout_weight;
OSL::VolumeClosure *volume = (OSL::VolumeClosure*)sc->prim;
OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out));
return TO_FLOAT3(volume_eval)*sc->weight;
}
CCL_NAMESPACE_END