diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-15 19:37:58 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-15 19:37:58 +0400 |
commit | 613cf7ae376b0994c9bd7c57b13123d72831bd3a (patch) | |
tree | 95b9f78858a8b365b21da1246c4096b87af53062 | |
parent | 1c410ab6e79b140f912b257863b42ec2028d6b23 (diff) |
Cycles: ambient occlusion now takes per-BSDF normals into account.
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 35 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 20 |
2 files changed, 34 insertions, 21 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 585068ce8e2..b893aa4d03d 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -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_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; 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; float3 ao_shadow; @@ -347,11 +350,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, light_ray.time = sd.time; #endif - 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); + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce); - } } } #endif @@ -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_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; 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; float3 ao_shadow; @@ -525,11 +528,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray light_ray.time = sd.time; #endif - 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); + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce); - } } } #endif @@ -712,6 +712,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam int num_samples = kernel_data.integrator.ao_samples; float num_samples_inv = 1.0f/num_samples; 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++) { /* todo: solve correlation */ @@ -721,9 +723,9 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam float3 ao_D; 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; float3 ao_shadow; @@ -734,11 +736,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam light_ray.time = sd.time; #endif - 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); + if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce); - } } } } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 1af5e048ad9..a2a741935a1 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -599,21 +599,35 @@ __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd) #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__ 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++) { ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) + if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) { + 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; #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; else return make_float3(0.0f, 0.0f, 0.0f); |