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:
authorDalai Felinto <dfelinto@gmail.com>2014-01-03 01:05:07 +0400
committerDalai Felinto <dfelinto@gmail.com>2014-05-03 04:19:09 +0400
commiteec3eaba084725a978f4aefb773a16ae9c0420db (patch)
tree68e34c3e8ff42af5263c010895b6649961f82eb6 /intern/cycles/kernel
parent97641a0ec946005d9a042f075697109c6590a28d (diff)
Cycles Bake
Expand Cycles to use the new baking API in Blender. It works on the selected object, and the panel can be accessed in the Render panel (similar to where it is for the Blender Internal). It bakes for the active texture of each material of the object. The active texture is currently defined as the active Image Texture node present in the material nodetree. If you don't want the baking to override an existent material, make sure the active Image Texture node is not connected to the nodetree. The active texture is also the texture shown in the viewport in the rendered mode. Remember to save your images after the baking is complete. Note: Bake currently only works in the CPU Note: This is not supported by Cycles standalone because a lot of the work is done in Blender as part of the operator only, not the engine (Cycles). Documentation: http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Bake Supported Passes: ----------------- Data Passes * Normal * UV * Diffuse/Glossy/Transmission/Subsurface/Emit Color Light Passes * AO * Combined * Shadow * Diffuse/Glossy/Transmission/Subsurface/Emit Direct/Indirect * Environment Review: D421 Reviewed by: Campbell Barton, Brecht van Lommel, Sergey Sharybin, Thomas Dinge Original design by Brecht van Lommel. The entire commit history can be found on the branch: bake-cycles
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h21
-rw-r--r--intern/cycles/kernel/kernel_displace.h267
-rw-r--r--intern/cycles/kernel/kernel_path.h80
-rw-r--r--intern/cycles/kernel/kernel_types.h33
4 files changed, 360 insertions, 41 deletions
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 582a220ab3c..82450b73097 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -407,5 +407,26 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi
return L_sum;
}
+ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples)
+{
+ float fac = 1.0f/num_samples;
+
+ L->direct_diffuse += L_sample->direct_diffuse*fac;
+ L->direct_glossy += L_sample->direct_glossy*fac;
+ L->direct_transmission += L_sample->direct_transmission*fac;
+ L->direct_subsurface += L_sample->direct_subsurface*fac;
+
+ L->indirect_diffuse += L_sample->indirect_diffuse*fac;
+ L->indirect_glossy += L_sample->indirect_glossy*fac;
+ L->indirect_transmission += L_sample->indirect_transmission*fac;
+ L->indirect_subsurface += L_sample->indirect_subsurface*fac;
+
+ L->emission += L_sample->emission*fac;
+ L->background += L_sample->background*fac;
+ L->ao += L_sample->ao*fac;
+ L->shadow += L_sample->shadow*fac;
+ L->mist += L_sample->mist*fac;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index 1935f72ce95..a2709e711d2 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -16,8 +16,275 @@
CCL_NAMESPACE_BEGIN
+ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng, bool is_ao)
+{
+ int samples = kernel_data.integrator.aa_samples;
+
+ /* initialize master radiance accumulator */
+ kernel_assert(kernel_data.film.use_light_pass);
+ path_radiance_init(L, kernel_data.film.use_light_pass);
+
+ /* take multiple samples */
+ for(int sample = 0; sample < samples; sample++) {
+ PathRadiance L_sample;
+ PathState state;
+ Ray ray;
+ float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
+
+ /* init radiance */
+ path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
+
+ /* init path state */
+ path_state_init(kg, &state, &rng, sample);
+ state.num_samples = samples;
+
+ /* evaluate surface shader */
+ float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF);
+ shader_eval_surface(kg, sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
+
+ /* sample ambient occlusion */
+ if(is_ao) {
+ kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput);
+ }
+
+ /* sample light and BSDF */
+ else if(kernel_path_integrate_lighting(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
+#ifdef __LAMP_MIS__
+ state.ray_t = 0.0f;
+#endif
+
+ /* compute indirect light */
+ kernel_path_indirect(kg, &rng, ray, throughput, state.num_samples, 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);
+ }
+
+ /* accumulate into master L */
+ path_radiance_accum_sample(L, &L_sample, samples);
+ }
+}
+
+ccl_device bool is_light_pass(ShaderEvalType type)
+{
+ switch (type) {
+ case SHADER_EVAL_AO:
+ case SHADER_EVAL_COMBINED:
+ case SHADER_EVAL_SHADOW:
+ case SHADER_EVAL_DIFFUSE_DIRECT:
+ case SHADER_EVAL_GLOSSY_DIRECT:
+ case SHADER_EVAL_TRANSMISSION_DIRECT:
+ case SHADER_EVAL_SUBSURFACE_DIRECT:
+ case SHADER_EVAL_DIFFUSE_INDIRECT:
+ case SHADER_EVAL_GLOSSY_INDIRECT:
+ case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i)
+{
+ ShaderData sd;
+ uint4 in = input[i];
+ float3 out;
+
+ 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);
+
+ int shader;
+ float3 P, Ng;
+
+ triangle_point_normal(kg, prim, u, v, &P, &Ng, &shader);
+
+ /* dummy initilizations copied from SHADER_EVAL_DISPLACE */
+ float3 I = Ng;
+ float t = 0.0f;
+ float time = TIME_INVALID;
+ int bounce = 0;
+ int transparent_bounce = 0;
+
+ /* light passes */
+ PathRadiance L;
+
+ /* TODO, disable the closures we won't need */
+ shader_setup_from_sample(kg, &sd, P, Ng, I, shader, object, prim, u, v, t, time, bounce, transparent_bounce);
+
+ if(is_light_pass(type)){
+ RNG rng = cmj_hash(i, 0);
+ compute_light_pass(kg, &sd, &L, rng, (type == SHADER_EVAL_AO));
+ }
+
+ switch (type) {
+ /* data passes */
+ case SHADER_EVAL_NORMAL:
+ {
+ /* compression: normal = (2 * color) - 1 */
+ out = sd.N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
+ break;
+ }
+ case SHADER_EVAL_UV:
+ {
+ out = primitive_uv(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE_COLOR:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_diffuse(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_GLOSSY_COLOR:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_glossy(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION_COLOR:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_transmission(kg, &sd);
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE_COLOR:
+ {
+#ifdef __SUBSURFACE__
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = shader_bsdf_subsurface(kg, &sd);
+#endif
+ break;
+ }
+ case SHADER_EVAL_EMISSION:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_EMISSION);
+ out = shader_emissive_eval(kg, &sd);
+ break;
+ }
+
+ /* light passes */
+ case SHADER_EVAL_AO:
+ {
+ out = L.ao;
+ break;
+ }
+ case SHADER_EVAL_COMBINED:
+ {
+ out = path_radiance_clamp_and_sum(kg, &L);
+ break;
+ }
+ case SHADER_EVAL_SHADOW:
+ {
+ out = make_float3(L.shadow.x, L.shadow.y, L.shadow.z);
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE_DIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_diffuse, shader_bsdf_diffuse(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_GLOSSY_DIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_glossy, shader_bsdf_glossy(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION_DIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_transmission, shader_bsdf_transmission(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE_DIRECT:
+ {
+#ifdef __SUBSURFACE__
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.direct_subsurface, shader_bsdf_subsurface(kg, &sd));
+#endif
+ break;
+ }
+ case SHADER_EVAL_DIFFUSE_INDIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_diffuse, shader_bsdf_diffuse(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_GLOSSY_INDIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_glossy, shader_bsdf_glossy(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_TRANSMISSION_INDIRECT:
+ {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_transmission, shader_bsdf_transmission(kg, &sd));
+ break;
+ }
+ case SHADER_EVAL_SUBSURFACE_INDIRECT:
+ {
+#ifdef __SUBSURFACE__
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ out = safe_divide_color(L.indirect_subsurface, shader_bsdf_subsurface(kg, &sd));
+#endif
+ break;
+ }
+
+ /* 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, 0, 0);
+
+ /* evaluate */
+ int flag = 0; /* we can't know which type of BSDF this is for */
+ out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
+ break;
+ }
+ default:
+ {
+ /* no real shader, returning the position of the verts for debugging */
+ out = normalize(P);
+ break;
+ }
+ }
+
+ /* write output */
+ output[i] = make_float4(out.x, out.y, out.z, 1.0f);
+ return;
+}
+
ccl_device void kernel_shader_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output, ShaderEvalType type, int i)
{
+ if(type >= SHADER_EVAL_BAKE) {
+ kernel_bake_evaluate(kg, input, output, type, i);
+ return;
+ }
+
ShaderData sd;
uint4 in = input[i];
float3 out;
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 1ca6bd38ba9..e71b58aa709 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -212,7 +212,9 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
}
}
-ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_global float *buffer,
+#endif
+
+ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
float3 throughput, int num_samples, PathState state, PathRadiance *L)
{
/* path iteration */
@@ -378,7 +380,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
}
#endif
-#ifdef __EMISSION__
+#if defined(__EMISSION__) && defined(__BRANCHED_PATH__)
if(kernel_data.integrator.use_direct_light) {
bool all = kernel_data.integrator.sample_all_lights_indirect;
kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L, all);
@@ -456,10 +458,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
}
}
-#endif
-
-#ifdef __SUBSURFACE__
-
ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rng,
ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
{
@@ -569,7 +567,39 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
}
}
+ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, float3 throughput)
+{
+ /* todo: solve correlation */
+ float bsdf_u, bsdf_v;
+
+ path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &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;
+ float3 ao_alpha = shader_bsdf_alpha(kg, sd);
+
+ 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) {
+ Ray light_ray;
+ float3 ao_shadow;
+
+ light_ray.P = ray_offset(sd->P, sd->Ng);
+ light_ray.D = ao_D;
+ light_ray.t = kernel_data.background.ao_distance;
+#ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
#endif
+ light_ray.dP = sd->dP;
+ light_ray.dD = differential3_zero();
+
+ if(!shadow_blocked(kg, state, &light_ray, &ao_shadow))
+ path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state->bounce);
+ }
+}
ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer)
{
@@ -738,35 +768,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __AO__
/* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
- /* todo: solve correlation */
- float bsdf_u, bsdf_v;
- path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bsdf_u, &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;
- float3 ao_alpha = shader_bsdf_alpha(kg, &sd);
-
- 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) {
- Ray light_ray;
- float3 ao_shadow;
-
- light_ray.P = ray_offset(sd.P, sd.Ng);
- light_ray.D = ao_D;
- light_ray.t = kernel_data.background.ao_distance;
-#ifdef __OBJECT_MOTION__
- light_ray.time = sd.time;
-#endif
- light_ray.dP = sd.dP;
- light_ray.dD = differential3_zero();
-
- if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
- path_radiance_accum_ao(&L, throughput, ao_alpha, ao_bsdf, ao_shadow, state.bounce);
- }
+ kernel_path_ao(kg, &sd, &L, &state, rng, throughput);
}
#endif
@@ -803,7 +805,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
hit_state.ray_t = 0.0f;
#endif
- kernel_path_indirect(kg, rng, hit_ray, buffer, tp, state.num_samples, hit_state, &L);
+ kernel_path_indirect(kg, rng, hit_ray, tp, state.num_samples, hit_state, &L);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@@ -1022,7 +1024,7 @@ ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *
ps.ray_t = 0.0f;
#endif
- kernel_path_indirect(kg, rng, bsdf_ray, buffer, tp*num_samples_inv, num_samples, ps, L);
+ kernel_path_indirect(kg, rng, bsdf_ray, tp*num_samples_inv, num_samples, ps, L);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@@ -1110,7 +1112,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
if(result == VOLUME_PATH_SCATTERED) {
/* todo: use all-light sampling */
if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &tp, &ps, &L, &pray, num_samples_inv)) {
- kernel_path_indirect(kg, rng, pray, buffer, tp*num_samples_inv, num_samples, ps, &L);
+ kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
@@ -1150,7 +1152,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
if(result == VOLUME_PATH_SCATTERED) {
/* todo: use all-light sampling */
if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &tp, &ps, &L, &pray, num_samples_inv)) {
- kernel_path_indirect(kg, rng, pray, buffer, tp*num_samples_inv, num_samples, ps, &L);
+ kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L);
/* for render passes, sum and reset indirect light pass variables
* for the next samples */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index f83345925ea..b3656c38cae 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -160,7 +160,35 @@ typedef uint RNG;
typedef enum ShaderEvalType {
SHADER_EVAL_DISPLACE,
- SHADER_EVAL_BACKGROUND
+ SHADER_EVAL_BACKGROUND,
+ /* bake types */
+ SHADER_EVAL_BAKE, /* no real shade, it's used in the code to
+ * differentiate the type of shader eval from the above
+ */
+ /* data passes */
+ SHADER_EVAL_NORMAL,
+ SHADER_EVAL_UV,
+ SHADER_EVAL_DIFFUSE_COLOR,
+ SHADER_EVAL_GLOSSY_COLOR,
+ SHADER_EVAL_TRANSMISSION_COLOR,
+ SHADER_EVAL_SUBSURFACE_COLOR,
+ SHADER_EVAL_EMISSION,
+
+ /* light passes */
+ SHADER_EVAL_AO,
+ SHADER_EVAL_COMBINED,
+ SHADER_EVAL_SHADOW,
+ SHADER_EVAL_DIFFUSE_DIRECT,
+ SHADER_EVAL_GLOSSY_DIRECT,
+ SHADER_EVAL_TRANSMISSION_DIRECT,
+ SHADER_EVAL_SUBSURFACE_DIRECT,
+ SHADER_EVAL_DIFFUSE_INDIRECT,
+ SHADER_EVAL_GLOSSY_INDIRECT,
+ SHADER_EVAL_TRANSMISSION_INDIRECT,
+ SHADER_EVAL_SUBSURFACE_INDIRECT,
+
+ /* extra */
+ SHADER_EVAL_ENVIRONMENT,
} ShaderEvalType;
/* Path Tracing
@@ -281,7 +309,8 @@ typedef enum PassType {
PASS_MIST = 2097152,
PASS_SUBSURFACE_DIRECT = 4194304,
PASS_SUBSURFACE_INDIRECT = 8388608,
- PASS_SUBSURFACE_COLOR = 16777216
+ PASS_SUBSURFACE_COLOR = 16777216,
+ PASS_LIGHT = 33554432, /* no real pass, used to force use_light_pass */
} PassType;
#define PASS_ALL (~0)