Cycles: ambient occlusion now takes per-BSDF normals into account.
This commit is contained in:
@@ -331,12 +331,15 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
|
|||||||
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
|
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
|
||||||
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
|
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
|
||||||
|
|
||||||
|
float ao_factor = kernel_data.background.ao_factor;
|
||||||
|
float3 ao_N;
|
||||||
|
float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
|
||||||
float3 ao_D;
|
float3 ao_D;
|
||||||
float ao_pdf;
|
float ao_pdf;
|
||||||
|
|
||||||
sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
|
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
|
||||||
|
|
||||||
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
|
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f && average(ao_bsdf) != 0.0f) {
|
||||||
Ray light_ray;
|
Ray light_ray;
|
||||||
float3 ao_shadow;
|
float3 ao_shadow;
|
||||||
|
|
||||||
@@ -347,13 +350,10 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
|
|||||||
light_ray.time = sd.time;
|
light_ray.time = sd.time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
|
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
|
||||||
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
|
|
||||||
ao_bsdf += shader_bsdf_ao(kg, &sd);
|
|
||||||
path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
|
path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __EMISSION__
|
#ifdef __EMISSION__
|
||||||
@@ -509,12 +509,15 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
|
|||||||
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
|
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
|
||||||
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
|
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
|
||||||
|
|
||||||
|
float ao_factor = kernel_data.background.ao_factor;
|
||||||
|
float3 ao_N;
|
||||||
|
float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
|
||||||
float3 ao_D;
|
float3 ao_D;
|
||||||
float ao_pdf;
|
float ao_pdf;
|
||||||
|
|
||||||
sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
|
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
|
||||||
|
|
||||||
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
|
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f && average(ao_bsdf) != 0.0f) {
|
||||||
Ray light_ray;
|
Ray light_ray;
|
||||||
float3 ao_shadow;
|
float3 ao_shadow;
|
||||||
|
|
||||||
@@ -525,13 +528,10 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
|
|||||||
light_ray.time = sd.time;
|
light_ray.time = sd.time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
|
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
|
||||||
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
|
|
||||||
ao_bsdf += shader_bsdf_ao(kg, &sd);
|
|
||||||
path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
|
path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __EMISSION__
|
#ifdef __EMISSION__
|
||||||
@@ -712,6 +712,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
|
|||||||
int num_samples = kernel_data.integrator.ao_samples;
|
int num_samples = kernel_data.integrator.ao_samples;
|
||||||
float num_samples_inv = 1.0f/num_samples;
|
float num_samples_inv = 1.0f/num_samples;
|
||||||
float ao_factor = kernel_data.background.ao_factor;
|
float ao_factor = kernel_data.background.ao_factor;
|
||||||
|
float3 ao_N;
|
||||||
|
float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
|
||||||
|
|
||||||
for(int j = 0; j < num_samples; j++) {
|
for(int j = 0; j < num_samples; j++) {
|
||||||
/* todo: solve correlation */
|
/* todo: solve correlation */
|
||||||
@@ -721,9 +723,9 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
|
|||||||
float3 ao_D;
|
float3 ao_D;
|
||||||
float ao_pdf;
|
float ao_pdf;
|
||||||
|
|
||||||
sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
|
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
|
||||||
|
|
||||||
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
|
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f && average(ao_bsdf) != 0.0f) {
|
||||||
Ray light_ray;
|
Ray light_ray;
|
||||||
float3 ao_shadow;
|
float3 ao_shadow;
|
||||||
|
|
||||||
@@ -734,14 +736,11 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
|
|||||||
light_ray.time = sd.time;
|
light_ray.time = sd.time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
|
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
|
||||||
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor;
|
|
||||||
ao_bsdf += shader_bsdf_ao(kg, &sd);
|
|
||||||
path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce);
|
path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __EMISSION__
|
#ifdef __EMISSION__
|
||||||
|
@@ -599,21 +599,35 @@ __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd)
|
__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
|
||||||
{
|
{
|
||||||
#ifdef __MULTI_CLOSURE__
|
#ifdef __MULTI_CLOSURE__
|
||||||
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
*N = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
for(int i = 0; i< sd->num_closure; i++) {
|
for(int i = 0; i< sd->num_closure; i++) {
|
||||||
ShaderClosure *sc = &sd->closure[i];
|
ShaderClosure *sc = &sd->closure[i];
|
||||||
|
|
||||||
if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type))
|
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
|
||||||
eval += sc->weight;
|
eval += sc->weight*ao_factor;
|
||||||
|
*N += sc->N*average(sc->weight);
|
||||||
}
|
}
|
||||||
|
if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
|
||||||
|
eval += sc->weight;
|
||||||
|
*N += sd->N*average(sc->weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*N = normalize(*N);
|
||||||
|
|
||||||
return eval;
|
return eval;
|
||||||
#else
|
#else
|
||||||
if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
|
*N = sd->N;
|
||||||
|
|
||||||
|
if(CLOSURE_IS_DIFFUSE(sd->closure.type))
|
||||||
|
return sd->closure.weight*ao_factor;
|
||||||
|
else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
|
||||||
return sd->closure.weight;
|
return sd->closure.weight;
|
||||||
else
|
else
|
||||||
return make_float3(0.0f, 0.0f, 0.0f);
|
return make_float3(0.0f, 0.0f, 0.0f);
|
||||||
|
Reference in New Issue
Block a user