Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Light cdfs #1066

Merged
merged 1 commit into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 28 additions & 29 deletions libs/yocto/yocto_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2209,7 +2209,7 @@ static vec3f sample_lights(const trace_scene* scene, const trace_lights* lights,
auto light = lights->lights[light_id];
if (light->instance != nullptr) {
auto instance = light->instance;
auto element = sample_discrete_cdf(instance->shape->elements_cdf, rel);
auto element = sample_discrete_cdf(light->elements_cdf, rel);
auto uv = (!instance->shape->triangles.empty()) ? sample_triangle(ruv)
: ruv;
auto lposition = eval_position(light->instance, element, uv);
Expand All @@ -2218,7 +2218,7 @@ static vec3f sample_lights(const trace_scene* scene, const trace_lights* lights,
auto environment = light->environment;
if (environment->emission_tex != nullptr) {
auto emission_tex = environment->emission_tex;
auto idx = sample_discrete_cdf(environment->texels_cdf, rel);
auto idx = sample_discrete_cdf(light->elements_cdf, rel);
auto size = texture_size(emission_tex);
auto uv = vec2f{
((idx % size.x) + 0.5f) / size.x, ((idx / size.x) + 0.5f) / size.y};
Expand Down Expand Up @@ -2252,7 +2252,7 @@ static float sample_lights_pdf(const trace_scene* scene,
auto lnormal = eval_element_normal(
light->instance, intersection.element);
// prob triangle * area triangle = area triangle mesh
auto area = light->instance->shape->elements_cdf.back();
auto area = light->elements_cdf.back();
lpdf += distance_squared(lposition, position) /
(abs(dot(lnormal, direction)) * area);
// continue
Expand All @@ -2271,8 +2271,8 @@ static float sample_lights_pdf(const trace_scene* scene,
auto i = clamp((int)(texcoord.x * size.x), 0, size.x - 1);
auto j = clamp((int)(texcoord.y * size.y), 0, size.y - 1);
auto prob = sample_discrete_cdf_pdf(
light->environment->texels_cdf, j * size.x + i) /
light->environment->texels_cdf.back();
light->elements_cdf, j * size.x + i) /
light->elements_cdf.back();
auto angle = (2 * pif / size.x) * (pif / size.y) *
sin(pif * (j + 0.5f) / size.y);
pdf += prob / angle;
Expand Down Expand Up @@ -2844,50 +2844,49 @@ void init_lights(trace_lights* lights, const trace_scene* scene,
auto shape = instance->shape;
if (shape->triangles.empty() && shape->quads.empty()) continue;
if (progress_cb) progress_cb("build light", progress.x++, ++progress.y);
auto light = add_light(lights);
light->instance = instance;
light->environment = nullptr;
if (!shape->triangles.empty()) {
shape->elements_cdf = vector<float>(shape->triangles.size());
for (auto idx = 0; idx < shape->elements_cdf.size(); idx++) {
light->elements_cdf = vector<float>(shape->triangles.size());
for (auto idx = 0; idx < light->elements_cdf.size(); idx++) {
auto& t = shape->triangles[idx];
shape->elements_cdf[idx] = triangle_area(shape->positions[t.x],
light->elements_cdf[idx] = triangle_area(shape->positions[t.x],
shape->positions[t.y], shape->positions[t.z]);
if (idx != 0) shape->elements_cdf[idx] += shape->elements_cdf[idx - 1];
if (idx != 0) light->elements_cdf[idx] += light->elements_cdf[idx - 1];
}
}
if (!shape->quads.empty()) {
shape->elements_cdf = vector<float>(shape->quads.size());
for (auto idx = 0; idx < shape->elements_cdf.size(); idx++) {
light->elements_cdf = vector<float>(shape->quads.size());
for (auto idx = 0; idx < light->elements_cdf.size(); idx++) {
auto& t = shape->quads[idx];
shape->elements_cdf[idx] = quad_area(shape->positions[t.x],
light->elements_cdf[idx] = quad_area(shape->positions[t.x],
shape->positions[t.y], shape->positions[t.z],
shape->positions[t.w]);
if (idx != 0) shape->elements_cdf[idx] += shape->elements_cdf[idx - 1];
if (idx != 0) light->elements_cdf[idx] += light->elements_cdf[idx - 1];
}
}
auto light = add_light(lights);
light->instance = instance;
light->environment = nullptr;
}
for (auto environment : scene->environments) {
if (environment->emission == zero3f) continue;
if (progress_cb) progress_cb("build light", progress.x++, ++progress.y);
auto light = add_light(lights);
light->instance = nullptr;
light->environment = environment;
if (environment->emission_tex != nullptr) {
auto texture = environment->emission_tex;
auto size = texture_size(texture);
environment->texels_cdf = vector<float>(size.x * size.y);
auto texture = environment->emission_tex;
auto size = texture_size(texture);
light->elements_cdf = vector<float>(size.x * size.y);
if (size != zero2i) {
for (auto i = 0; i < environment->texels_cdf.size(); i++) {
auto ij = vec2i{i % size.x, i / size.x};
auto th = (ij.y + 0.5f) * pif / size.y;
auto value = lookup_texture(texture, ij);
environment->texels_cdf[i] = max(value) * sin(th);
if (i != 0)
environment->texels_cdf[i] += environment->texels_cdf[i - 1];
for (auto i = 0; i < light->elements_cdf.size(); i++) {
auto ij = vec2i{i % size.x, i / size.x};
auto th = (ij.y + 0.5f) * pif / size.y;
auto value = lookup_texture(texture, ij);
light->elements_cdf[i] = max(value) * sin(th);
if (i != 0) light->elements_cdf[i] += light->elements_cdf[i - 1];
}
}
}
auto light = add_light(lights);
light->instance = nullptr;
light->environment = environment;
}

// handle progress
Expand Down
11 changes: 3 additions & 8 deletions libs/yocto/yocto_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,6 @@ struct trace_shape {
RTCScene embree_bvh = nullptr;
#endif

// element cdf for sampling
vector<float> elements_cdf = {};

// cleanup
~trace_shape();
};
Expand All @@ -218,9 +215,6 @@ struct trace_environment {
frame3f frame = identity3x4f;
vec3f emission = {0, 0, 0};
trace_texture* emission_tex = nullptr;

// computed properties
vector<float> texels_cdf = {};
};

// Scene comprised an array of objects whose memory is owened by the scene.
Expand Down Expand Up @@ -537,8 +531,9 @@ namespace yocto {

// Scene lights used during rendering. These are created automatically.
struct trace_light {
trace_instance* instance = nullptr;
trace_environment* environment = nullptr;
trace_instance* instance = nullptr;
trace_environment* environment = nullptr;
vector<float> elements_cdf = {};
};

// Scene lights
Expand Down