Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/kernel_bake.h')
-rw-r--r--intern/cycles/kernel/kernel_bake.h944
1 files changed, 455 insertions, 489 deletions
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index 37c163f2538..10b71bc6bdf 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -18,191 +18,172 @@ CCL_NAMESPACE_BEGIN
#ifdef __BAKING__
-ccl_device_inline void compute_light_pass(KernelGlobals *kg,
- ShaderData *sd,
- PathRadiance *L,
- uint rng_hash,
- int pass_filter,
- int sample)
+ccl_device_inline void compute_light_pass(
+ KernelGlobals *kg, ShaderData *sd, PathRadiance *L, uint rng_hash, int pass_filter, int sample)
{
- kernel_assert(kernel_data.film.use_light_pass);
-
- PathRadiance L_sample;
- PathState state;
- Ray ray;
- float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
-
- /* emission and indirect shader data memory used by various functions */
- ShaderData emission_sd, indirect_sd;
-
- ray.P = sd->P + sd->Ng;
- ray.D = -sd->Ng;
- ray.t = FLT_MAX;
-#ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
-#endif
-
- /* init radiance */
- path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
-
- /* init path state */
- path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
-
- /* evaluate surface shader */
- shader_eval_surface(kg, sd, &state, state.flag);
-
- /* TODO, disable more closures we don't need besides transparent */
- shader_bsdf_disable_transparency(kg, sd);
-
-#ifdef __BRANCHED_PATH__
- if(!kernel_data.integrator.branched) {
- /* regular path tracer */
-#endif
-
- /* sample ambient occlusion */
- if(pass_filter & BAKE_FILTER_AO) {
- kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
- }
-
- /* sample emission */
- if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
- float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(&L_sample, &state, throughput, emission);
- }
-
- bool is_sss_sample = false;
-
-#ifdef __SUBSURFACE__
- /* sample subsurface scattering */
- if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
- /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
- SubsurfaceIndirectRays ss_indirect;
- kernel_path_subsurface_init_indirect(&ss_indirect);
- if(kernel_path_subsurface_scatter(kg,
- sd,
- &emission_sd,
- &L_sample,
- &state,
- &ray,
- &throughput,
- &ss_indirect))
- {
- while(ss_indirect.num_rays) {
- kernel_path_subsurface_setup_indirect(kg,
- &ss_indirect,
- &state,
- &ray,
- &L_sample,
- &throughput);
- kernel_path_indirect(kg,
- &indirect_sd,
- &emission_sd,
- &ray,
- throughput,
- &state,
- &L_sample);
- }
- is_sss_sample = true;
- }
- }
-#endif
-
- /* sample light and BSDF */
- if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
- kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
-
- if(kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
-#ifdef __LAMP_MIS__
- state.ray_t = 0.0f;
-#endif
- /* compute indirect light */
- kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
-
- /* sum and reset indirect light pass variables for the next samples */
- path_radiance_sum_indirect(&L_sample);
- path_radiance_reset_indirect(&L_sample);
- }
- }
-#ifdef __BRANCHED_PATH__
- }
- else {
- /* branched path tracer */
-
- /* sample ambient occlusion */
- if(pass_filter & BAKE_FILTER_AO) {
- kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
- }
-
- /* sample emission */
- if((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
- float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(&L_sample, &state, throughput, emission);
- }
-
-#ifdef __SUBSURFACE__
- /* sample subsurface scattering */
- if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
- /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
- kernel_branched_path_subsurface_scatter(kg, sd, &indirect_sd,
- &emission_sd, &L_sample, &state, &ray, throughput);
- }
-#endif
-
- /* sample light and BSDF */
- if(pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT)) {
-#if defined(__EMISSION__)
- /* direct light */
- if(kernel_data.integrator.use_direct_light) {
- int all = kernel_data.integrator.sample_all_lights_direct;
- kernel_branched_path_surface_connect_light(kg,
- sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
- }
-#endif
-
- /* indirect light */
- kernel_branched_path_surface_indirect_light(kg,
- sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
- }
- }
-#endif
-
- /* accumulate into master L */
- path_radiance_accum_sample(L, &L_sample);
+ kernel_assert(kernel_data.film.use_light_pass);
+
+ PathRadiance L_sample;
+ PathState state;
+ Ray ray;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+
+ /* emission and indirect shader data memory used by various functions */
+ ShaderData emission_sd, indirect_sd;
+
+ ray.P = sd->P + sd->Ng;
+ ray.D = -sd->Ng;
+ ray.t = FLT_MAX;
+# ifdef __CAMERA_MOTION__
+ ray.time = 0.5f;
+# endif
+
+ /* init radiance */
+ path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
+
+ /* init path state */
+ path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
+
+ /* evaluate surface shader */
+ shader_eval_surface(kg, sd, &state, state.flag);
+
+ /* TODO, disable more closures we don't need besides transparent */
+ shader_bsdf_disable_transparency(kg, sd);
+
+# ifdef __BRANCHED_PATH__
+ if (!kernel_data.integrator.branched) {
+ /* regular path tracer */
+# endif
+
+ /* sample ambient occlusion */
+ if (pass_filter & BAKE_FILTER_AO) {
+ kernel_path_ao(
+ kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
+ }
+
+ /* sample emission */
+ if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+ float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+ path_radiance_accum_emission(&L_sample, &state, throughput, emission);
+ }
+
+ bool is_sss_sample = false;
+
+# ifdef __SUBSURFACE__
+ /* sample subsurface scattering */
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
+ /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
+ SubsurfaceIndirectRays ss_indirect;
+ kernel_path_subsurface_init_indirect(&ss_indirect);
+ if (kernel_path_subsurface_scatter(
+ kg, sd, &emission_sd, &L_sample, &state, &ray, &throughput, &ss_indirect)) {
+ while (ss_indirect.num_rays) {
+ kernel_path_subsurface_setup_indirect(
+ kg, &ss_indirect, &state, &ray, &L_sample, &throughput);
+ kernel_path_indirect(
+ kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
+ }
+ is_sss_sample = true;
+ }
+ }
+# endif
+
+ /* sample light and BSDF */
+ if (!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
+ kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
+
+ if (kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
+# ifdef __LAMP_MIS__
+ state.ray_t = 0.0f;
+# endif
+ /* compute indirect light */
+ kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
+
+ /* sum and reset indirect light pass variables for the next samples */
+ path_radiance_sum_indirect(&L_sample);
+ path_radiance_reset_indirect(&L_sample);
+ }
+ }
+# ifdef __BRANCHED_PATH__
+ }
+ else {
+ /* branched path tracer */
+
+ /* sample ambient occlusion */
+ if (pass_filter & BAKE_FILTER_AO) {
+ kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
+ }
+
+ /* sample emission */
+ if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
+ float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
+ path_radiance_accum_emission(&L_sample, &state, throughput, emission);
+ }
+
+# ifdef __SUBSURFACE__
+ /* sample subsurface scattering */
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
+ /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
+ kernel_branched_path_subsurface_scatter(
+ kg, sd, &indirect_sd, &emission_sd, &L_sample, &state, &ray, throughput);
+ }
+# endif
+
+ /* sample light and BSDF */
+ if (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT)) {
+# if defined(__EMISSION__)
+ /* direct light */
+ if (kernel_data.integrator.use_direct_light) {
+ int all = kernel_data.integrator.sample_all_lights_direct;
+ kernel_branched_path_surface_connect_light(
+ kg, sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
+ }
+# endif
+
+ /* indirect light */
+ kernel_branched_path_surface_indirect_light(
+ kg, sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
+ }
+ }
+# endif
+
+ /* accumulate into master L */
+ path_radiance_accum_sample(L, &L_sample);
}
/* this helps with AA but it's not the real solution as it does not AA the geometry
* but it's better than nothing, thus committed */
ccl_device_inline float bake_clamp_mirror_repeat(float u, float max)
{
- /* use mirror repeat (like opengl texture) so that if the barycentric
- * coordinate goes past the end of the triangle it is not always clamped
- * to the same value, gives ugly patterns */
- u /= max;
- float fu = floorf(u);
- u = u - fu;
-
- return ((((int)fu) & 1)? 1.0f - u: u) * max;
+ /* use mirror repeat (like opengl texture) so that if the barycentric
+ * coordinate goes past the end of the triangle it is not always clamped
+ * to the same value, gives ugly patterns */
+ u /= max;
+ float fu = floorf(u);
+ u = u - fu;
+
+ return ((((int)fu) & 1) ? 1.0f - u : u) * max;
}
ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg,
ShaderData *sd,
const ShaderEvalType type)
{
- switch(type) {
- case SHADER_EVAL_DIFFUSE:
- return shader_bsdf_diffuse(kg, sd);
- case SHADER_EVAL_GLOSSY:
- return shader_bsdf_glossy(kg, sd);
- case SHADER_EVAL_TRANSMISSION:
- return shader_bsdf_transmission(kg, sd);
-#ifdef __SUBSURFACE__
- case SHADER_EVAL_SUBSURFACE:
- return shader_bsdf_subsurface(kg, sd);
-#endif
- default:
- kernel_assert(!"Unknown bake type passed to BSDF evaluate");
- return make_float3(0.0f, 0.0f, 0.0f);
- }
+ switch (type) {
+ case SHADER_EVAL_DIFFUSE:
+ return shader_bsdf_diffuse(kg, sd);
+ case SHADER_EVAL_GLOSSY:
+ return shader_bsdf_glossy(kg, sd);
+ case SHADER_EVAL_TRANSMISSION:
+ return shader_bsdf_transmission(kg, sd);
+# ifdef __SUBSURFACE__
+ case SHADER_EVAL_SUBSURFACE:
+ return shader_bsdf_subsurface(kg, sd);
+# endif
+ default:
+ kernel_assert(!"Unknown bake type passed to BSDF evaluate");
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
@@ -213,316 +194,301 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
const ShaderEvalType type,
const int pass_filter)
{
- float3 color;
- const bool is_color = (pass_filter & BAKE_FILTER_COLOR) != 0;
- const bool is_direct = (pass_filter & BAKE_FILTER_DIRECT) != 0;
- const bool is_indirect = (pass_filter & BAKE_FILTER_INDIRECT) != 0;
- float3 out = make_float3(0.0f, 0.0f, 0.0f);
-
- if(is_color) {
- if(is_direct || is_indirect) {
- /* Leave direct and diffuse channel colored. */
- color = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- /* surface color of the pass only */
- shader_eval_surface(kg, sd, state, 0);
- return kernel_bake_shader_bsdf(kg, sd, type);
- }
- }
- else {
- shader_eval_surface(kg, sd, state, 0);
- color = kernel_bake_shader_bsdf(kg, sd, type);
- }
-
- if(is_direct) {
- out += safe_divide_even_color(direct, color);
- }
-
- if(is_indirect) {
- out += safe_divide_even_color(indirect, color);
- }
-
- return out;
+ float3 color;
+ const bool is_color = (pass_filter & BAKE_FILTER_COLOR) != 0;
+ const bool is_direct = (pass_filter & BAKE_FILTER_DIRECT) != 0;
+ const bool is_indirect = (pass_filter & BAKE_FILTER_INDIRECT) != 0;
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
+
+ if (is_color) {
+ if (is_direct || is_indirect) {
+ /* Leave direct and diffuse channel colored. */
+ color = make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ /* surface color of the pass only */
+ shader_eval_surface(kg, sd, state, 0);
+ return kernel_bake_shader_bsdf(kg, sd, type);
+ }
+ }
+ else {
+ shader_eval_surface(kg, sd, state, 0);
+ color = kernel_bake_shader_bsdf(kg, sd, type);
+ }
+
+ if (is_direct) {
+ out += safe_divide_even_color(direct, color);
+ }
+
+ if (is_indirect) {
+ out += safe_divide_even_color(indirect, color);
+ }
+
+ return out;
}
-ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output,
- ShaderEvalType type, int pass_filter, int i, int offset, int sample)
+ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
+ ccl_global uint4 *input,
+ ccl_global float4 *output,
+ ShaderEvalType type,
+ int pass_filter,
+ int i,
+ int offset,
+ int sample)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i * 2];
- uint4 diff = input[i * 2 + 1];
-
- float3 out = make_float3(0.0f, 0.0f, 0.0f);
-
- int object = in.x;
- int prim = in.y;
-
- if(prim == -1)
- return;
-
- float u = __uint_as_float(in.z);
- float v = __uint_as_float(in.w);
-
- float dudx = __uint_as_float(diff.x);
- float dudy = __uint_as_float(diff.y);
- float dvdx = __uint_as_float(diff.z);
- float dvdy = __uint_as_float(diff.w);
-
- int num_samples = kernel_data.integrator.aa_samples;
-
- /* random number generator */
- uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
-
- float filter_x, filter_y;
- if(sample == 0) {
- filter_x = filter_y = 0.5f;
- }
- else {
- path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
- }
-
- /* subpixel u/v offset */
- if(sample > 0) {
- u = bake_clamp_mirror_repeat(u + dudx*(filter_x - 0.5f) + dudy*(filter_y - 0.5f), 1.0f);
- v = bake_clamp_mirror_repeat(v + dvdx*(filter_x - 0.5f) + dvdy*(filter_y - 0.5f), 1.0f - u);
- }
-
- /* triangle */
- int shader;
- float3 P, Ng;
-
- triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
-
- /* light passes */
- PathRadiance L;
- path_radiance_init(&L, kernel_data.film.use_light_pass);
-
- shader_setup_from_sample(kg, &sd,
- P, Ng, Ng,
- shader, object, prim,
- u, v, 1.0f, 0.5f,
- !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
- LAMP_NONE);
- sd.I = sd.N;
-
- /* update differentials */
- sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
- sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
- sd.du.dx = dudx;
- sd.du.dy = dudy;
- sd.dv.dx = dvdx;
- sd.dv.dy = dvdy;
-
- /* set RNG state for shaders that use sampling */
- state.rng_hash = rng_hash;
- state.rng_offset = 0;
- state.sample = sample;
- state.num_samples = num_samples;
- state.min_ray_pdf = FLT_MAX;
-
- /* light passes if we need more than color */
- if(pass_filter & ~BAKE_FILTER_COLOR)
- compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
-
- switch(type) {
- /* data passes */
- case SHADER_EVAL_NORMAL:
- case SHADER_EVAL_ROUGHNESS:
- case SHADER_EVAL_EMISSION:
- {
- if(type != SHADER_EVAL_NORMAL || (sd.flag & SD_HAS_BUMP)) {
- int path_flag = (type == SHADER_EVAL_EMISSION) ? PATH_RAY_EMISSION : 0;
- shader_eval_surface(kg, &sd, &state, path_flag);
- }
-
- if(type == SHADER_EVAL_NORMAL) {
- float3 N = sd.N;
- if(sd.flag & SD_HAS_BUMP) {
- N = shader_bsdf_average_normal(kg, &sd);
- }
-
- /* encoding: normal = (2 * color) - 1 */
- out = N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
- }
- else if(type == SHADER_EVAL_ROUGHNESS) {
- float roughness = shader_bsdf_average_roughness(&sd);
- out = make_float3(roughness, roughness, roughness);
- }
- else {
- out = shader_emissive_eval(&sd);
- }
- break;
- }
- case SHADER_EVAL_UV:
- {
- out = primitive_uv(kg, &sd);
- break;
- }
-#ifdef __PASSES__
- /* light passes */
- case SHADER_EVAL_AO:
- {
- out = L.ao;
- break;
- }
- case SHADER_EVAL_COMBINED:
- {
- if((pass_filter & BAKE_FILTER_COMBINED) == BAKE_FILTER_COMBINED) {
- float alpha;
- out = path_radiance_clamp_and_sum(kg, &L, &alpha);
- break;
- }
-
- if((pass_filter & BAKE_FILTER_DIFFUSE_DIRECT) == BAKE_FILTER_DIFFUSE_DIRECT)
- out += L.direct_diffuse;
- if((pass_filter & BAKE_FILTER_DIFFUSE_INDIRECT) == BAKE_FILTER_DIFFUSE_INDIRECT)
- out += L.indirect_diffuse;
-
- if((pass_filter & BAKE_FILTER_GLOSSY_DIRECT) == BAKE_FILTER_GLOSSY_DIRECT)
- out += L.direct_glossy;
- if((pass_filter & BAKE_FILTER_GLOSSY_INDIRECT) == BAKE_FILTER_GLOSSY_INDIRECT)
- out += L.indirect_glossy;
-
- if((pass_filter & BAKE_FILTER_TRANSMISSION_DIRECT) == BAKE_FILTER_TRANSMISSION_DIRECT)
- out += L.direct_transmission;
- if((pass_filter & BAKE_FILTER_TRANSMISSION_INDIRECT) == BAKE_FILTER_TRANSMISSION_INDIRECT)
- out += L.indirect_transmission;
-
- if((pass_filter & BAKE_FILTER_SUBSURFACE_DIRECT) == BAKE_FILTER_SUBSURFACE_DIRECT)
- out += L.direct_subsurface;
- if((pass_filter & BAKE_FILTER_SUBSURFACE_INDIRECT) == BAKE_FILTER_SUBSURFACE_INDIRECT)
- out += L.indirect_subsurface;
-
- if((pass_filter & BAKE_FILTER_EMISSION) != 0)
- out += L.emission;
-
- break;
- }
- case SHADER_EVAL_SHADOW:
- {
- out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
- break;
- }
- case SHADER_EVAL_DIFFUSE:
- {
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_diffuse,
- L.indirect_diffuse,
- type,
- pass_filter);
- break;
- }
- case SHADER_EVAL_GLOSSY:
- {
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_glossy,
- L.indirect_glossy,
- type,
- pass_filter);
- break;
- }
- case SHADER_EVAL_TRANSMISSION:
- {
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_transmission,
- L.indirect_transmission,
- type,
- pass_filter);
- break;
- }
- case SHADER_EVAL_SUBSURFACE:
- {
-#ifdef __SUBSURFACE__
- out = kernel_bake_evaluate_direct_indirect(kg,
- &sd,
- &state,
- L.direct_subsurface,
- L.indirect_subsurface,
- type,
- pass_filter);
-#endif
- break;
- }
-#endif
-
- /* extra */
- case SHADER_EVAL_ENVIRONMENT:
- {
- /* setup ray */
- Ray ray;
-
- ray.P = make_float3(0.0f, 0.0f, 0.0f);
- ray.D = normalize(P);
- ray.t = 0.0f;
-#ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
-#endif
-
-#ifdef __RAY_DIFFERENTIALS__
- ray.dD = differential3_zero();
- ray.dP = differential3_zero();
-#endif
-
- /* setup shader data */
- shader_setup_from_background(kg, &sd, &ray);
-
- /* evaluate */
- int path_flag = 0; /* we can't know which type of BSDF this is for */
- shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
- out = shader_background_eval(&sd);
- break;
- }
- default:
- {
- /* no real shader, returning the position of the verts for debugging */
- out = normalize(P);
- break;
- }
- }
-
- /* write output */
- const float output_fac = 1.0f/num_samples;
- const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
-
- output[i] = (sample == 0)? scaled_result: output[i] + scaled_result;
+ ShaderData sd;
+ PathState state = {0};
+ uint4 in = input[i * 2];
+ uint4 diff = input[i * 2 + 1];
+
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
+
+ int object = in.x;
+ int prim = in.y;
+
+ if (prim == -1)
+ return;
+
+ float u = __uint_as_float(in.z);
+ float v = __uint_as_float(in.w);
+
+ float dudx = __uint_as_float(diff.x);
+ float dudy = __uint_as_float(diff.y);
+ float dvdx = __uint_as_float(diff.z);
+ float dvdy = __uint_as_float(diff.w);
+
+ int num_samples = kernel_data.integrator.aa_samples;
+
+ /* random number generator */
+ uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
+
+ float filter_x, filter_y;
+ if (sample == 0) {
+ filter_x = filter_y = 0.5f;
+ }
+ else {
+ path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
+ }
+
+ /* subpixel u/v offset */
+ if (sample > 0) {
+ u = bake_clamp_mirror_repeat(u + dudx * (filter_x - 0.5f) + dudy * (filter_y - 0.5f), 1.0f);
+ v = bake_clamp_mirror_repeat(v + dvdx * (filter_x - 0.5f) + dvdy * (filter_y - 0.5f),
+ 1.0f - u);
+ }
+
+ /* triangle */
+ int shader;
+ float3 P, Ng;
+
+ triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
+
+ /* light passes */
+ PathRadiance L;
+ path_radiance_init(&L, kernel_data.film.use_light_pass);
+
+ shader_setup_from_sample(
+ kg,
+ &sd,
+ P,
+ Ng,
+ Ng,
+ shader,
+ object,
+ prim,
+ u,
+ v,
+ 1.0f,
+ 0.5f,
+ !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
+ LAMP_NONE);
+ sd.I = sd.N;
+
+ /* update differentials */
+ sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
+ sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
+ sd.du.dx = dudx;
+ sd.du.dy = dudy;
+ sd.dv.dx = dvdx;
+ sd.dv.dy = dvdy;
+
+ /* set RNG state for shaders that use sampling */
+ state.rng_hash = rng_hash;
+ state.rng_offset = 0;
+ state.sample = sample;
+ state.num_samples = num_samples;
+ state.min_ray_pdf = FLT_MAX;
+
+ /* light passes if we need more than color */
+ if (pass_filter & ~BAKE_FILTER_COLOR)
+ compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
+
+ switch (type) {
+ /* data passes */
+ case SHADER_EVAL_NORMAL:
+ case SHADER_EVAL_ROUGHNESS:
+ case SHADER_EVAL_EMISSION: {
+ if (type != SHADER_EVAL_NORMAL || (sd.flag & SD_HAS_BUMP)) {
+ int path_flag = (type == SHADER_EVAL_EMISSION) ? PATH_RAY_EMISSION : 0;
+ shader_eval_surface(kg, &sd, &state, path_flag);
+ }
+
+ if (type == SHADER_EVAL_NORMAL) {
+ float3 N = sd.N;
+ if (sd.flag & SD_HAS_BUMP) {
+ N = shader_bsdf_average_normal(kg, &sd);
+ }
+
+ /* encoding: normal = (2 * color) - 1 */
+ out = N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
+ }
+ else if (type == SHADER_EVAL_ROUGHNESS) {
+ float roughness = shader_bsdf_average_roughness(&sd);
+ out = make_float3(roughness, roughness, roughness);
+ }
+ else {
+ out = shader_emissive_eval(&sd);
+ }
+ break;
+ }
+ case SHADER_EVAL_UV: {
+ out = primitive_uv(kg, &sd);
+ break;
+ }
+# ifdef __PASSES__
+ /* light passes */
+ case SHADER_EVAL_AO: {
+ out = L.ao;
+ break;
+ }
+ case SHADER_EVAL_COMBINED: {
+ if ((pass_filter & BAKE_FILTER_COMBINED) == BAKE_FILTER_COMBINED) {
+ float alpha;
+ out = path_radiance_clamp_and_sum(kg, &L, &alpha);
+ break;
+ }
+
+ if ((pass_filter & BAKE_FILTER_DIFFUSE_DIRECT) == BAKE_FILTER_DIFFUSE_DIRECT)
+ out += L.direct_diffuse;
+ if ((pass_filter & BAKE_FILTER_DIFFUSE_INDIRECT) == BAKE_FILTER_DIFFUSE_INDIRECT)
+ out += L.indirect_diffuse;
+
+ if ((pass_filter & BAKE_FILTER_GLOSSY_DIRECT) == BAKE_FILTER_GLOSSY_DIRECT)
+ out += L.direct_glossy;
+ if ((pass_filter & BAKE_FILTER_GLOSSY_INDIRECT) == BAKE_FILTER_GLOSSY_INDIRECT)
+ out += L.indirect_glossy;
+
+ if ((pass_filter & BAKE_FILTER_TRANSMISSION_DIRECT) == BAKE_FILTER_TRANSMISSION_DIRECT)
+ out += L.direct_transmission;
+ if ((pass_filter & BAKE_FILTER_TRANSMISSION_INDIRECT) == BAKE_FILTER_TRANSMISSION_INDIRECT)
+ out += L.indirect_transmission;
+
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE_DIRECT) == BAKE_FILTER_SUBSURFACE_DIRECT)
+ out += L.direct_subsurface;
+ if ((pass_filter & BAKE_FILTER_SUBSURFACE_INDIRECT) == BAKE_FILTER_SUBSURFACE_INDIRECT)
+ out += L.indirect_subsurface;
+
+ if ((pass_filter & BAKE_FILTER_EMISSION) != 0)
+ out += L.emission;
+
+ break;
+ }
+ case SHADER_EVAL_SHADOW: {
+ out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE: {
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_diffuse, L.indirect_diffuse, type, pass_filter);
+ break;
+ }
+ case SHADER_EVAL_GLOSSY: {
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_glossy, L.indirect_glossy, type, pass_filter);
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION: {
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_transmission, L.indirect_transmission, type, pass_filter);
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE: {
+# ifdef __SUBSURFACE__
+ out = kernel_bake_evaluate_direct_indirect(
+ kg, &sd, &state, L.direct_subsurface, L.indirect_subsurface, type, pass_filter);
+# endif
+ break;
+ }
+# endif
+
+ /* extra */
+ case SHADER_EVAL_ENVIRONMENT: {
+ /* setup ray */
+ Ray ray;
+
+ ray.P = make_float3(0.0f, 0.0f, 0.0f);
+ ray.D = normalize(P);
+ ray.t = 0.0f;
+# ifdef __CAMERA_MOTION__
+ ray.time = 0.5f;
+# endif
+
+# ifdef __RAY_DIFFERENTIALS__
+ ray.dD = differential3_zero();
+ ray.dP = differential3_zero();
+# endif
+
+ /* setup shader data */
+ shader_setup_from_background(kg, &sd, &ray);
+
+ /* evaluate */
+ int path_flag = 0; /* we can't know which type of BSDF this is for */
+ shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
+ out = shader_background_eval(&sd);
+ break;
+ }
+ default: {
+ /* no real shader, returning the position of the verts for debugging */
+ out = normalize(P);
+ break;
+ }
+ }
+
+ /* write output */
+ const float output_fac = 1.0f / num_samples;
+ const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
+
+ output[i] = (sample == 0) ? scaled_result : output[i] + scaled_result;
}
-#endif /* __BAKING__ */
+#endif /* __BAKING__ */
ccl_device void kernel_displace_evaluate(KernelGlobals *kg,
ccl_global uint4 *input,
ccl_global float4 *output,
int i)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i];
+ ShaderData sd;
+ PathState state = {0};
+ uint4 in = input[i];
- /* setup shader data */
- int object = in.x;
- int prim = in.y;
- float u = __uint_as_float(in.z);
- float v = __uint_as_float(in.w);
+ /* setup shader data */
+ int object = in.x;
+ int prim = in.y;
+ float u = __uint_as_float(in.z);
+ float v = __uint_as_float(in.w);
- shader_setup_from_displace(kg, &sd, object, prim, u, v);
+ shader_setup_from_displace(kg, &sd, object, prim, u, v);
- /* evaluate */
- float3 P = sd.P;
- shader_eval_displacement(kg, &sd, &state);
- float3 D = sd.P - P;
+ /* evaluate */
+ float3 P = sd.P;
+ shader_eval_displacement(kg, &sd, &state);
+ float3 D = sd.P - P;
- object_inverse_dir_transform(kg, &sd, &D);
+ object_inverse_dir_transform(kg, &sd, &D);
- /* write output */
- output[i] += make_float4(D.x, D.y, D.z, 0.0f);
+ /* write output */
+ output[i] += make_float4(D.x, D.y, D.z, 0.0f);
}
ccl_device void kernel_background_evaluate(KernelGlobals *kg,
@@ -530,37 +496,37 @@ ccl_device void kernel_background_evaluate(KernelGlobals *kg,
ccl_global float4 *output,
int i)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i];
-
- /* setup ray */
- Ray ray;
- float u = __uint_as_float(in.x);
- float v = __uint_as_float(in.y);
-
- ray.P = make_float3(0.0f, 0.0f, 0.0f);
- ray.D = equirectangular_to_direction(u, v);
- ray.t = 0.0f;
+ ShaderData sd;
+ PathState state = {0};
+ uint4 in = input[i];
+
+ /* setup ray */
+ Ray ray;
+ float u = __uint_as_float(in.x);
+ float v = __uint_as_float(in.y);
+
+ ray.P = make_float3(0.0f, 0.0f, 0.0f);
+ ray.D = equirectangular_to_direction(u, v);
+ ray.t = 0.0f;
#ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
+ ray.time = 0.5f;
#endif
#ifdef __RAY_DIFFERENTIALS__
- ray.dD = differential3_zero();
- ray.dP = differential3_zero();
+ ray.dD = differential3_zero();
+ ray.dP = differential3_zero();
#endif
- /* setup shader data */
- shader_setup_from_background(kg, &sd, &ray);
+ /* setup shader data */
+ shader_setup_from_background(kg, &sd, &ray);
- /* evaluate */
- int path_flag = 0; /* we can't know which type of BSDF this is for */
- shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
- float3 color = shader_background_eval(&sd);
+ /* evaluate */
+ int path_flag = 0; /* we can't know which type of BSDF this is for */
+ shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
+ float3 color = shader_background_eval(&sd);
- /* write output */
- output[i] += make_float4(color.x, color.y, color.z, 0.0f);
+ /* write output */
+ output[i] += make_float4(color.x, color.y, color.z, 0.0f);
}
CCL_NAMESPACE_END