2011-04-27 11:58:34 +00:00
|
|
|
/*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Copyright 2011-2013 Blender Foundation
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
2014-12-25 01:50:24 +00:00
|
|
|
* limitations under the License.
|
2011-04-27 11:58:34 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
2016-05-06 21:11:41 +00:00
|
|
|
#ifdef __BAKING__
|
2016-02-05 13:11:16 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
ccl_device_inline void compute_light_pass(
|
|
|
|
KernelGlobals *kg, ShaderData *sd, PathRadiance *L, uint rng_hash, int pass_filter, int sample)
|
2014-01-02 21:05:07 +00:00
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
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)) {
|
2019-05-01 11:14:11 +00:00
|
|
|
/* When mixing BSSRDF and BSDF closures we should skip BSDF lighting
|
|
|
|
* if scattering was successful. */
|
2019-04-17 04:17:24 +00:00
|
|
|
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)) {
|
2019-05-01 11:14:11 +00:00
|
|
|
/* When mixing BSSRDF and BSDF closures we should skip BSDF lighting
|
|
|
|
* if scattering was successful. */
|
2019-04-17 04:17:24 +00:00
|
|
|
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);
|
2014-06-06 12:40:09 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 15:02:55 +00:00
|
|
|
/* 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 */
|
2016-02-21 13:14:52 +00:00
|
|
|
ccl_device_inline float bake_clamp_mirror_repeat(float u, float max)
|
2014-06-06 12:40:09 +00:00
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
/* 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;
|
2014-06-06 12:40:09 +00:00
|
|
|
}
|
|
|
|
|
2016-01-19 21:51:43 +00:00
|
|
|
ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg,
|
|
|
|
ShaderData *sd,
|
|
|
|
const ShaderEvalType type)
|
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
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);
|
|
|
|
}
|
2016-01-19 21:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
|
|
|
|
ShaderData *sd,
|
|
|
|
PathState *state,
|
|
|
|
float3 direct,
|
|
|
|
float3 indirect,
|
|
|
|
const ShaderEvalType type,
|
|
|
|
const int pass_filter)
|
2016-01-15 15:00:56 +00:00
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
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;
|
2016-01-15 15:00:56 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
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)
|
2014-01-02 21:05:07 +00:00
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
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;
|
2014-01-02 21:05:07 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
#endif /* __BAKING__ */
|
2016-02-05 13:11:16 +00:00
|
|
|
|
2017-10-05 13:17:09 +00:00
|
|
|
ccl_device void kernel_displace_evaluate(KernelGlobals *kg,
|
|
|
|
ccl_global uint4 *input,
|
|
|
|
ccl_global float4 *output,
|
|
|
|
int i)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
ShaderData sd;
|
|
|
|
PathState state = {0};
|
|
|
|
uint4 in = input[i];
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
/* 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);
|
2011-12-31 15:18:13 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
shader_setup_from_displace(kg, &sd, object, prim, u, v);
|
2011-12-31 15:18:13 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
/* evaluate */
|
|
|
|
float3 P = sd.P;
|
|
|
|
shader_eval_displacement(kg, &sd, &state);
|
|
|
|
float3 D = sd.P - P;
|
2016-09-03 01:37:17 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
object_inverse_dir_transform(kg, &sd, &D);
|
2017-10-05 13:17:09 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
/* write output */
|
|
|
|
output[i] += make_float4(D.x, D.y, D.z, 0.0f);
|
2017-10-05 13:17:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ccl_device void kernel_background_evaluate(KernelGlobals *kg,
|
|
|
|
ccl_global uint4 *input,
|
|
|
|
ccl_global float4 *output,
|
|
|
|
int i)
|
|
|
|
{
|
2019-04-17 04:17:24 +00:00
|
|
|
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;
|
2012-10-17 22:48:29 +00:00
|
|
|
#ifdef __CAMERA_MOTION__
|
2019-04-17 04:17:24 +00:00
|
|
|
ray.time = 0.5f;
|
2012-10-17 22:48:29 +00:00
|
|
|
#endif
|
2011-12-31 15:18:13 +00:00
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
2019-04-17 04:17:24 +00:00
|
|
|
ray.dD = differential3_zero();
|
|
|
|
ray.dP = differential3_zero();
|
2011-12-31 15:18:13 +00:00
|
|
|
#endif
|
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
/* setup shader data */
|
|
|
|
shader_setup_from_background(kg, &sd, &ray);
|
2017-10-05 13:17:09 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
/* 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);
|
2011-12-31 15:18:13 +00:00
|
|
|
|
2019-04-17 04:17:24 +00:00
|
|
|
/* write output */
|
|
|
|
output[i] += make_float4(color.x, color.y, color.z, 0.0f);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|