本文整理汇总了C++中SamplingContext类的典型用法代码示例。如果您正苦于以下问题:C++ SamplingContext类的具体用法?C++ SamplingContext怎么用?C++ SamplingContext使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SamplingContext类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: take_single_bsdf_or_light_sample
void DirectLightingIntegrator::take_single_bsdf_or_light_sample(
SamplingContext& sampling_context,
Spectrum& radiance,
SpectrumStack& aovs)
{
radiance.set(0.0f);
aovs.set(0.0f);
sampling_context.split_in_place(1, 1);
if (sampling_context.next_double2() < 0.5)
{
sampling_context.split_in_place(3, m_light_sample_count);
take_single_light_sample(
sampling_context,
DirectLightingIntegrator::mis_balance,
radiance,
aovs);
}
else
{
take_single_bsdf_sample(
sampling_context,
DirectLightingIntegrator::mis_balance,
radiance,
aovs);
}
}
示例2: sample_lens
Vector3d sample_lens(SamplingContext& sampling_context) const
{
if (m_diaphragm_map_bound)
{
sampling_context.split_in_place(2, 1);
const Vector2f s = sampling_context.next2<Vector2f>();
size_t x, y;
Vector2d payload;
float prob_xy;
m_importance_sampler->sample(s, x, y, payload, prob_xy);
const Vector2d lens_point = m_lens_radius * payload;
return Vector3d(lens_point.x, lens_point.y, 0.0);
}
else if (m_diaphragm_blade_count == 0)
{
sampling_context.split_in_place(2, 1);
const Vector2d s = sampling_context.next2<Vector2d>();
const Vector2d lens_point = m_lens_radius * sample_disk_uniform(s);
return Vector3d(lens_point.x, lens_point.y, 0.0);
}
else
{
sampling_context.split_in_place(3, 1);
const Vector3d s = sampling_context.next2<Vector3d>();
const Vector2d lens_point =
m_lens_radius *
sample_regular_polygon_uniform(
s,
m_diaphragm_vertices.size(),
&m_diaphragm_vertices.front());
return Vector3d(lens_point.x, lens_point.y, 0.0);
}
}
示例3: compute_outgoing_radiance_light_sampling
void DirectLightingIntegrator::compute_outgoing_radiance_light_sampling(
SamplingContext& sampling_context,
const MISHeuristic mis_heuristic,
const Dual3d& outgoing,
Spectrum& radiance,
SpectrumStack& aovs) const
{
radiance.set(0.0f);
aovs.set(0.0f);
sampling_context.split_in_place(3, m_light_sample_count);
for (size_t i = 0; i < m_light_sample_count; ++i)
{
take_single_light_sample(
sampling_context,
mis_heuristic,
outgoing,
radiance,
aovs);
}
if (m_light_sample_count > 1)
{
const float rcp_light_sample_count = 1.0f / m_light_sample_count;
radiance *= rcp_light_sample_count;
aovs *= rcp_light_sample_count;
}
}
示例4: compute_outgoing_radiance_single_sample
void DirectLightingIntegrator::compute_outgoing_radiance_single_sample(
SamplingContext& sampling_context,
const Dual3d& outgoing,
Spectrum& radiance,
SpectrumStack& aovs) const
{
radiance.set(0.0f);
aovs.set(0.0f);
if (m_light_sampler.get_emitting_triangle_count() > 0)
{
sampling_context.split_in_place(1, 1);
if (sampling_context.next_double2() < 0.5)
{
sampling_context.split_in_place(3, 1);
take_single_light_sample(
sampling_context,
MISBalance,
outgoing,
radiance,
aovs);
}
else
{
take_single_bsdf_sample(
sampling_context,
MISBalance,
outgoing,
radiance,
aovs);
}
radiance *= 2.0f;
aovs *= 2.0f;
}
else
{
take_single_light_sample(
sampling_context,
MISNone,
outgoing,
radiance,
aovs);
}
}
示例5: compute_fast_ambient_occlusion
double compute_fast_ambient_occlusion(
const SamplingContext& sampling_context,
const AOVoxelTreeIntersector& intersector,
const Vector3d& point,
const Vector3d& geometric_normal,
const Basis3d& shading_basis,
const double max_distance,
const size_t sample_count,
double& min_distance)
{
// Create a sampling context.
SamplingContext child_sampling_context = sampling_context.split(2, sample_count);
// Construct the ambient occlusion ray.
ShadingRay::RayType ray;
ray.m_org = point;
ray.m_tmin = 0.0;
ray.m_tmax = max_distance;
size_t computed_samples = 0;
size_t occluded_samples = 0;
min_distance = max_distance;
for (size_t i = 0; i < sample_count; ++i)
{
// Generate a cosine-weighted direction over the unit hemisphere.
ray.m_dir = sample_hemisphere_cosine(child_sampling_context.next_vector2<2>());
// Transform the direction to world space.
ray.m_dir = shading_basis.transform_to_parent(ray.m_dir);
// Don't cast rays on or below the geometric surface.
if (dot(ray.m_dir, geometric_normal) <= 0.0)
continue;
// Count the number of computed samples.
++computed_samples;
// Trace the ambient occlusion ray and count the number of occluded samples.
double distance;
if (intersector.trace(ray, true, distance))
{
++occluded_samples;
min_distance = min(min_distance, distance);
}
}
// Compute occlusion as a scalar between 0.0 and 1.0.
double occlusion = static_cast<double>(occluded_samples);
if (computed_samples > 1)
occlusion /= computed_samples;
assert(occlusion >= 0.0);
assert(occlusion <= 1.0);
return occlusion;
}
示例6: trace_non_physical_light_photon
void trace_non_physical_light_photon(
SamplingContext& sampling_context,
const LightSample& light_sample)
{
// Sample the light.
InputEvaluator input_evaluator(m_texture_cache);
SamplingContext child_sampling_context = sampling_context.split(2, 1);
Vector3d emission_position, emission_direction;
Spectrum light_value;
double light_prob;
light_sample.m_light->sample(
input_evaluator,
child_sampling_context.next_vector2<2>(),
emission_position,
emission_direction,
light_value,
light_prob);
// Transform the emission position and direction from assembly space to world space.
emission_position = light_sample.m_light_transform.point_to_parent(emission_position);
emission_direction = normalize(light_sample.m_light_transform.vector_to_parent(emission_direction));
// Compute the initial particle weight.
Spectrum initial_flux = light_value;
initial_flux /= static_cast<float>(light_sample.m_probability * light_prob);
// Build the photon ray.
child_sampling_context.split_in_place(1, 1);
const ShadingRay ray(
emission_position,
emission_direction,
child_sampling_context.next_double2(),
~0);
// Build the path tracer.
const bool cast_indirect_light = (light_sample.m_light->get_flags() & EDF::CastIndirectLight) != 0;
PathVisitor path_visitor(
initial_flux,
m_params.m_dl_mode == SPPMParameters::SPPM, // store direct lighting photons?
cast_indirect_light,
m_params.m_enable_caustics,
m_local_photons);
PathTracer<PathVisitor, true> path_tracer( // true = adjoint
path_visitor,
m_params.m_photon_tracing_rr_min_path_length,
m_params.m_photon_tracing_max_path_length,
m_params.m_max_iterations);
// Trace the photon path.
path_tracer.trace(
child_sampling_context,
m_intersector,
m_texture_cache,
ray);
}
示例7: generate_non_physical_light_sample
size_t generate_non_physical_light_sample(
SamplingContext& sampling_context,
const LightSample& light_sample,
SampleVector& samples)
{
// Sample the light.
InputEvaluator input_evaluator(m_texture_cache);
sampling_context.split_in_place(2, 1);
Vector3d emission_position, emission_direction;
Spectrum light_value;
double light_prob;
light_sample.m_light->sample(
input_evaluator,
sampling_context.next_vector2<2>(),
emission_position,
emission_direction,
light_value,
light_prob);
// Transform the emission position and direction from assembly space to world space.
emission_position = light_sample.m_light_transform.point_to_parent(emission_position);
emission_direction = normalize(light_sample.m_light_transform.vector_to_parent(emission_direction));
// Compute the initial particle weight.
Spectrum initial_flux = light_value;
initial_flux /= static_cast<float>(light_sample.m_probability * light_prob);
// Build the light ray.
sampling_context.split_in_place(1, 1);
const ShadingRay light_ray(
emission_position,
emission_direction,
sampling_context.next_double2(),
m_ray_dtime,
ShadingRay::LightRay);
// Build the path tracer.
PathVisitor path_visitor(
m_params,
m_scene,
m_frame,
m_shading_context,
samples,
initial_flux);
PathTracerType path_tracer(
path_visitor,
m_params.m_rr_min_path_length,
m_params.m_max_path_length,
m_params.m_max_iterations);
// Handle the light vertex separately.
Spectrum light_particle_flux = light_value;
light_particle_flux /= static_cast<float>(light_sample.m_probability);
path_visitor.visit_non_physical_light_vertex(
emission_position,
light_particle_flux,
light_ray.m_time);
// Trace the light path.
const size_t path_length =
path_tracer.trace(
sampling_context,
m_shading_context,
light_ray);
// Update path statistics.
++m_path_count;
m_path_length.insert(path_length);
// Return the number of samples generated when tracing this light path.
return path_visitor.get_sample_count();
}
示例8: generate_emitting_triangle_sample
size_t generate_emitting_triangle_sample(
SamplingContext& sampling_context,
LightSample& light_sample,
SampleVector& samples)
{
// Make sure the geometric normal of the light sample is in the same hemisphere as the shading normal.
light_sample.m_geometric_normal =
flip_to_same_hemisphere(
light_sample.m_geometric_normal,
light_sample.m_shading_normal);
const Material* material = light_sample.m_triangle->m_material;
const EDF* edf = material->get_edf();
// Evaluate the EDF inputs.
InputEvaluator input_evaluator(m_texture_cache);
// TODO: refactor this code (est.).
ShadingPoint shading_point;
light_sample.make_shading_point(
shading_point,
light_sample.m_shading_normal,
m_shading_context.get_intersector());
#ifdef WITH_OSL
if (const ShaderGroup* sg = material->get_osl_surface())
{
// TODO: get object area somehow.
const float surface_area = 0.0f;
m_shading_context.execute_osl_emission(*sg, shading_point, surface_area);
}
#endif
edf->evaluate_inputs(input_evaluator, shading_point);
// Sample the EDF.
sampling_context.split_in_place(2, 1);
Vector3d emission_direction;
Spectrum edf_value;
double edf_prob;
edf->sample(
sampling_context,
input_evaluator.data(),
light_sample.m_geometric_normal,
Basis3d(light_sample.m_shading_normal),
sampling_context.next_vector2<2>(),
emission_direction,
edf_value,
edf_prob);
// Compute the initial particle weight.
Spectrum initial_flux = edf_value;
initial_flux *=
static_cast<float>(
dot(emission_direction, light_sample.m_shading_normal)
/ (light_sample.m_probability * edf_prob));
// Make a shading point that will be used to avoid self-intersections with the light sample.
ShadingPoint parent_shading_point;
light_sample.make_shading_point(
parent_shading_point,
emission_direction,
m_intersector);
// Build the light ray.
sampling_context.split_in_place(1, 1);
const ShadingRay light_ray(
light_sample.m_point,
emission_direction,
sampling_context.next_double2(),
m_ray_dtime,
ShadingRay::LightRay);
// Build the path tracer.
PathVisitor path_visitor(
m_params,
m_scene,
m_frame,
m_shading_context,
samples,
initial_flux);
PathTracerType path_tracer(
path_visitor,
m_params.m_rr_min_path_length,
m_params.m_max_path_length,
m_params.m_max_iterations,
edf->get_light_near_start()); // don't illuminate points closer than the light near start value
// Handle the light vertex separately.
Spectrum light_particle_flux = edf_value; // todo: only works for diffuse EDF? What we need is the light exitance
light_particle_flux /= static_cast<float>(light_sample.m_probability);
path_visitor.visit_area_light_vertex(
light_sample,
light_particle_flux,
light_ray.m_time);
// Trace the light path.
const size_t path_length =
path_tracer.trace(
sampling_context,
m_shading_context,
light_ray,
//.........这里部分代码省略.........
示例9: compute_ibl_environment_sampling
void compute_ibl_environment_sampling(
SamplingContext& sampling_context,
const ShadingContext& shading_context,
const EnvironmentEDF& environment_edf,
const ShadingPoint& shading_point,
const Vector3d& outgoing,
const BSDF& bsdf,
const void* bsdf_data,
const int env_sampling_modes,
const size_t bsdf_sample_count,
const size_t env_sample_count,
Spectrum& radiance)
{
assert(is_normalized(outgoing));
const Vector3d& geometric_normal = shading_point.get_geometric_normal();
const Basis3d& shading_basis = shading_point.get_shading_basis();
radiance.set(0.0f);
// todo: if we had a way to know that a BSDF is purely specular, we could
// immediately return black here since there will be no contribution from
// such a BSDF.
sampling_context.split_in_place(2, env_sample_count);
for (size_t i = 0; i < env_sample_count; ++i)
{
// Generate a uniform sample in [0,1)^2.
const Vector2d s = sampling_context.next_vector2<2>();
// Sample the environment.
InputEvaluator input_evaluator(shading_context.get_texture_cache());
Vector3d incoming;
Spectrum env_value;
double env_prob;
environment_edf.sample(
input_evaluator,
s,
incoming,
env_value,
env_prob);
// Cull samples behind the shading surface.
assert(is_normalized(incoming));
const double cos_in = dot(incoming, shading_basis.get_normal());
if (cos_in < 0.0)
continue;
// Discard occluded samples.
const double transmission =
shading_context.get_tracer().trace(
shading_point,
incoming,
ShadingRay::ShadowRay);
if (transmission == 0.0)
continue;
// Evaluate the BSDF.
Spectrum bsdf_value;
const double bsdf_prob =
bsdf.evaluate(
bsdf_data,
false, // not adjoint
true, // multiply by |cos(incoming, normal)|
geometric_normal,
shading_basis,
outgoing,
incoming,
env_sampling_modes,
bsdf_value);
if (bsdf_prob == 0.0)
continue;
// Compute MIS weight.
const double mis_weight =
mis_power2(
env_sample_count * env_prob,
bsdf_sample_count * bsdf_prob);
// Add the contribution of this sample to the illumination.
env_value *= static_cast<float>(transmission / env_prob * mis_weight);
env_value *= bsdf_value;
radiance += env_value;
}
if (env_sample_count > 1)
radiance /= static_cast<float>(env_sample_count);
}
示例10: compute_incoming_radiance
bool DirectLightingIntegrator::compute_incoming_radiance(
SamplingContext& sampling_context,
Vector3d& incoming,
double& incoming_prob,
Spectrum& radiance) const
{
if (!m_light_sampler.has_lights_or_emitting_triangles())
return false;
sampling_context.split_in_place(3, 1);
const Vector3d s = sampling_context.next_vector2<3>();
LightSample sample;
m_light_sampler.sample(m_time, s, sample);
if (sample.m_triangle)
{
const Material* material = sample.m_triangle->m_material;
const Material::RenderData& material_data = material->get_render_data();
const EDF* edf = material_data.m_edf;
// No contribution if we are computing indirect lighting but this light does not cast indirect light.
if (m_indirect && !(edf->get_flags() & EDF::CastIndirectLight))
return false;
// Compute the incoming direction in world space.
incoming = sample.m_point - m_point;
// No contribution if the shading point is behind the light.
double cos_on_light = dot(-incoming, sample.m_shading_normal);
if (cos_on_light <= 0.0)
return false;
// Compute the transmission factor between the light sample and the shading point.
const double transmission =
m_shading_context.get_tracer().trace_between(
m_shading_point,
sample.m_point,
VisibilityFlags::ShadowRay);
// Discard occluded samples.
if (transmission == 0.0)
return false;
// Don't use this sample if we're closer than the light near start value.
const double square_distance = square_norm(incoming);
if (square_distance < square(edf->get_light_near_start()))
return false;
// Normalize the incoming direction.
const double rcp_square_distance = 1.0 / square_distance;
const double rcp_distance = sqrt(rcp_square_distance);
incoming *= rcp_distance;
cos_on_light *= rcp_distance;
// Build a shading point on the light source.
ShadingPoint light_shading_point;
sample.make_shading_point(
light_shading_point,
sample.m_shading_normal,
m_shading_context.get_intersector());
#ifdef APPLESEED_WITH_OSL
if (material_data.m_shader_group)
{
m_shading_context.execute_osl_emission(
*material_data.m_shader_group,
light_shading_point);
}
#endif
// Evaluate the EDF inputs.
InputEvaluator edf_input_evaluator(m_shading_context.get_texture_cache());
edf->evaluate_inputs(edf_input_evaluator, light_shading_point);
// Evaluate the EDF.
edf->evaluate(
edf_input_evaluator.data(),
sample.m_geometric_normal,
Basis3d(sample.m_shading_normal),
-incoming,
radiance);
// Compute probability with respect to solid angle of incoming direction.
const double g = cos_on_light * rcp_square_distance;
incoming_prob = sample.m_probability / g;
// Compute and return the incoming radiance.
radiance *= static_cast<float>(transmission * g / sample.m_probability);
}
else
{
const Light* light = sample.m_light;
// No contribution if we are computing indirect lighting but this light does not cast indirect light.
if (m_indirect && !(light->get_flags() & Light::CastIndirectLight))
return false;
// Evaluate the light.
InputEvaluator input_evaluator(m_shading_context.get_texture_cache());
//.........这里部分代码省略.........
示例11: evaluate
void DiagnosticSurfaceShader::evaluate(
SamplingContext& sampling_context,
const PixelContext& pixel_context,
const ShadingContext& shading_context,
const ShadingPoint& shading_point,
ShadingResult& shading_result) const
{
switch (m_shading_mode)
{
case Color:
{
shading_result.set_main_to_opaque_pink_linear_rgba();
const Material* material = shading_point.get_material();
if (material)
{
const Material::RenderData& material_data = material->get_render_data();
#ifdef APPLESEED_WITH_OSL
// Execute the OSL shader if there is one.
if (material_data.m_shader_group)
{
shading_context.execute_osl_shading(
*material_data.m_shader_group,
shading_point);
}
#endif
if (material_data.m_bsdf)
{
InputEvaluator input_evaluator(shading_context.get_texture_cache());
material_data.m_bsdf->evaluate_inputs(
shading_context,
input_evaluator,
shading_point);
const Vector3d direction = -normalize(shading_point.get_ray().m_dir);
material_data.m_bsdf->evaluate(
input_evaluator.data(),
false,
false,
shading_point.get_geometric_normal(),
shading_point.get_shading_basis(),
direction,
direction,
ScatteringMode::All,
shading_result.m_main.m_color);
shading_result.m_color_space = ColorSpaceSpectral;
}
}
}
break;
case Coverage:
shading_result.set_main_to_linear_rgb(Color3f(1.0f));
break;
case Barycentric:
shading_result.set_main_to_linear_rgb(
vector2_to_color(shading_point.get_bary()));
break;
case UV:
shading_result.set_main_to_linear_rgb(
uvs_to_color(shading_point.get_uv(0)));
break;
case Tangent:
case Bitangent:
case ShadingNormal:
{
#ifdef APPLESEED_WITH_OSL
const Material* material = shading_point.get_material();
if (material)
{
const Material::RenderData& material_data = material->get_render_data();
// Execute the OSL shader if there is one.
if (material_data.m_shader_group)
{
sampling_context.split_in_place(2, 1);
shading_context.execute_osl_bump(
*material_data.m_shader_group,
shading_point,
sampling_context.next_vector2<2>());
}
}
#endif
const Vector3d v =
m_shading_mode == ShadingNormal ? shading_point.get_shading_basis().get_normal() :
m_shading_mode == Tangent ? shading_point.get_shading_basis().get_tangent_u() :
shading_point.get_shading_basis().get_tangent_v();
shading_result.set_main_to_linear_rgb(vector3_to_color(v));
}
break;
case GeometricNormal:
//.........这里部分代码省略.........
示例12: add_non_physical_light_sample_contribution
void DirectLightingIntegrator::add_non_physical_light_sample_contribution(
SamplingContext& sampling_context,
const LightSample& sample,
const Dual3d& outgoing,
DirectShadingComponents& radiance,
LightPathStream* light_path_stream) const
{
const Light* light = sample.m_light;
// No contribution if we are computing indirect lighting but this light does not cast indirect light.
if (m_indirect && !(light->get_flags() & Light::CastIndirectLight))
return;
// Generate a uniform sample in [0,1)^2.
SamplingContext child_sampling_context = sampling_context.split(2, 1);
const Vector2d s = child_sampling_context.next2<Vector2d>();
// Evaluate the light.
Vector3d emission_position, emission_direction;
Spectrum light_value(Spectrum::Illuminance);
float probability;
light->sample(
m_shading_context,
sample.m_light_transform,
m_material_sampler.get_point(),
s,
emission_position,
emission_direction,
light_value,
probability);
// Compute the incoming direction in world space.
const Vector3d incoming = -emission_direction;
// Compute the transmission factor between the light sample and the shading point.
Spectrum transmission;
m_material_sampler.trace_between(
m_shading_context,
emission_position,
transmission);
// Discard occluded samples.
if (is_zero(transmission))
return;
// Evaluate the BSDF (or volume).
DirectShadingComponents material_value;
const float material_probability =
m_material_sampler.evaluate(
Vector3f(outgoing.get_value()),
Vector3f(incoming),
m_light_sampling_modes,
material_value);
assert(material_probability >= 0.0f);
if (material_probability == 0.0f)
return;
// Add the contribution of this sample to the illumination.
const float attenuation = light->compute_distance_attenuation(
m_material_sampler.get_point(), emission_position);
light_value *= transmission;
light_value *= attenuation / (sample.m_probability * probability);
madd(radiance, material_value, light_value);
// Record light path event.
if (light_path_stream)
{
light_path_stream->sampled_non_physical_light(
*light,
emission_position,
material_value.m_beauty,
light_value);
}
}
示例13: dot
void DirectLightingIntegrator::add_emitting_shape_sample_contribution(
SamplingContext& sampling_context,
const LightSample& sample,
const MISHeuristic mis_heuristic,
const Dual3d& outgoing,
DirectShadingComponents& radiance,
LightPathStream* light_path_stream) const
{
const Material* material = sample.m_shape->get_material();
const Material::RenderData& material_data = material->get_render_data();
const EDF* edf = material_data.m_edf;
// No contribution if we are computing indirect lighting but this light does not cast indirect light.
if (m_indirect && !(edf->get_flags() & EDF::CastIndirectLight))
return;
// Compute the incoming direction in world space.
Vector3d incoming = sample.m_point - m_material_sampler.get_point();
// No contribution if the shading point is behind the light.
double cos_on = dot(-incoming, sample.m_shading_normal);
if (cos_on <= 0.0)
return;
// Compute the square distance between the light sample and the shading point.
const double square_distance = square_norm(incoming);
// Don't use this sample if we're closer than the light near start value.
if (square_distance < square(edf->get_light_near_start()))
return;
const double rcp_sample_square_distance = 1.0 / square_distance;
const double rcp_sample_distance = sqrt(rcp_sample_square_distance);
// Normalize the incoming direction.
cos_on *= rcp_sample_distance;
incoming *= rcp_sample_distance;
// Probabilistically skip light samples with low maximum contribution.
float contribution_prob = 1.0f;
if (m_low_light_threshold > 0.0f)
{
// Compute the approximate maximum contribution of this light sample.
const float max_contribution =
static_cast<float>(
cos_on *
rcp_sample_square_distance *
sample.m_shape->get_max_flux());
// Use Russian Roulette to skip this sample if its maximum contribution is low.
if (max_contribution < m_low_light_threshold)
{
// Generate a uniform sample in [0,1).
SamplingContext child_sampling_context = sampling_context.split(1, 1);
const float s = child_sampling_context.next2<float>();
// Compute the probability of taking the sample's contribution into account.
contribution_prob = max_contribution / m_low_light_threshold;
// Russian Roulette.
if (!pass_rr(contribution_prob, s))
return;
}
}
// Compute the transmission factor between the light sample and the shading point.
Spectrum transmission;
m_material_sampler.trace_between(
m_shading_context,
sample.m_point,
transmission);
// Discard occluded samples.
if (is_zero(transmission))
return;
// Evaluate the BSDF (or volume).
DirectShadingComponents material_value;
const float material_probability =
m_material_sampler.evaluate(
Vector3f(outgoing.get_value()),
Vector3f(incoming),
m_light_sampling_modes,
material_value);
assert(material_probability >= 0.0f);
if (material_probability == 0.0f)
return;
// Build a shading point on the light source.
ShadingPoint light_shading_point;
sample.make_shading_point(
light_shading_point,
sample.m_shading_normal,
m_shading_context.get_intersector());
if (material_data.m_shader_group)
{
m_shading_context.execute_osl_emission(
*material_data.m_shader_group,
light_shading_point);
//.........这里部分代码省略.........
示例14: compute_ibl_environment_sampling
void compute_ibl_environment_sampling(
SamplingContext& sampling_context,
const ShadingContext& shading_context,
const EnvironmentEDF& environment_edf,
const BSSRDF& bssrdf,
const void* bssrdf_data,
const ShadingPoint& incoming_point,
const ShadingPoint& outgoing_point,
const Dual3d& outgoing,
const size_t bssrdf_sample_count,
const size_t env_sample_count,
Spectrum& radiance)
{
assert(is_normalized(outgoing.get_value()));
const Basis3d& shading_basis = incoming_point.get_shading_basis();
radiance.set(0.0f);
sampling_context.split_in_place(2, env_sample_count);
for (size_t i = 0; i < env_sample_count; ++i)
{
// Generate a uniform sample in [0,1)^2.
const Vector2d s = sampling_context.next_vector2<2>();
// Sample the environment.
InputEvaluator input_evaluator(shading_context.get_texture_cache());
Vector3d incoming;
Spectrum env_value;
double env_prob;
environment_edf.sample(
shading_context,
input_evaluator,
s,
incoming,
env_value,
env_prob);
// Cull samples behind the shading surface.
assert(is_normalized(incoming));
const double cos_in = dot(incoming, shading_basis.get_normal());
if (cos_in <= 0.0)
continue;
// Discard occluded samples.
const double transmission =
shading_context.get_tracer().trace(
incoming_point,
incoming,
VisibilityFlags::ShadowRay);
if (transmission == 0.0)
continue;
// Evaluate the BSSRDF.
Spectrum bssrdf_value;
bssrdf.evaluate(
bssrdf_data,
outgoing_point,
outgoing.get_value(),
incoming_point,
incoming,
bssrdf_value);
// Compute MIS weight.
const double bssrdf_prob = cos_in * RcpPi;
const double mis_weight =
mis_power2(
env_sample_count * env_prob,
bssrdf_sample_count * bssrdf_prob);
// Add the contribution of this sample to the illumination.
env_value *= static_cast<float>(transmission * cos_in / env_prob * mis_weight);
env_value *= bssrdf_value;
radiance += env_value;
}
if (env_sample_count > 1)
radiance /= static_cast<float>(env_sample_count);
}
示例15: compute_ibl_bssrdf_sampling
void compute_ibl_bssrdf_sampling(
SamplingContext& sampling_context,
const ShadingContext& shading_context,
const EnvironmentEDF& environment_edf,
const BSSRDF& bssrdf,
const void* bssrdf_data,
const ShadingPoint& incoming_point,
const ShadingPoint& outgoing_point,
const Dual3d& outgoing,
const size_t bssrdf_sample_count,
const size_t env_sample_count,
Spectrum& radiance)
{
assert(is_normalized(outgoing.get_value()));
radiance.set(0.0f);
sampling_context.split_in_place(2, bssrdf_sample_count);
for (size_t i = 0; i < bssrdf_sample_count; ++i)
{
// Generate a uniform sample in [0,1)^2.
const Vector2d s = sampling_context.next_vector2<2>();
// Sample the BSSRDF (hemisphere cosine).
Vector3d incoming = sample_hemisphere_cosine(s);
const double cos_in = incoming.y;
const double bssrdf_prob = cos_in * RcpPi;
incoming = incoming_point.get_shading_basis().transform_to_parent(incoming);
if (incoming_point.get_side() == ObjectInstance::BackSide)
incoming = -incoming;
assert(is_normalized(incoming));
// Discard occluded samples.
const double transmission =
shading_context.get_tracer().trace(
incoming_point,
incoming,
VisibilityFlags::ShadowRay);
if (transmission == 0.0)
continue;
// Evaluate the BSSRDF.
Spectrum bssrdf_value;
bssrdf.evaluate(
bssrdf_data,
outgoing_point,
outgoing.get_value(),
incoming_point,
incoming,
bssrdf_value);
// Evaluate the environment's EDF.
InputEvaluator input_evaluator(shading_context.get_texture_cache());
Spectrum env_value;
double env_prob;
environment_edf.evaluate(
shading_context,
input_evaluator,
incoming,
env_value,
env_prob);
// Compute MIS weight.
const double mis_weight =
mis_power2(
bssrdf_sample_count * bssrdf_prob,
env_sample_count * env_prob);
// Add the contribution of this sample to the illumination.
env_value *= static_cast<float>(transmission * cos_in / bssrdf_prob * mis_weight);
env_value *= bssrdf_value;
radiance += env_value;
}
if (bssrdf_sample_count > 1)
radiance /= static_cast<float>(bssrdf_sample_count);
}