Skip to content

Commit

Permalink
add option to change probability of sampling lights
Browse files Browse the repository at this point in the history
  • Loading branch information
gau-nernst committed Nov 27, 2023
1 parent 7b98209 commit 459ed6b
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 10 deletions.
2 changes: 1 addition & 1 deletion include/raytracing.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef struct Camera {
Vec3 w;
Vec3 dof_disc_u;
Vec3 dof_disc_v;
bool importance_sampling;
float lights_sampling_prob;
} Camera;

void Camera_init(Camera *camera);
Expand Down
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ int main(int argc, char *argv[]) {
camera.vup = vec3(0, 1, 0);
camera.dof_angle = 0.0f;
camera.focal_length = 10.0f;
camera.importance_sampling = true;
camera.lights_sampling_prob = 0.5f;

if (argc > 3)
camera.img_width = strtol(argv[2], NULL, 10);
Expand Down
10 changes: 5 additions & 5 deletions src/material.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ static Vec3 rand_cosine_theta(PCG32 *rng) {
float phi = 2.0f * (float)M_PI * r1;
return vec3(cosf(phi) * sqrtf(r2), sinf(phi) * sqrtf(r2), sqrtf(1.0f - r2));
}
static float Lambertian_scattering_pdf(const HitRecord *rec, Vec3 r_in, Vec3 r_out) {
float cos_theta = vec3_dot(rec->normal, vec3_normalize(r_out));
return cos_theta < 0.0f ? 0.0f : cos_theta / (float)M_PI;
}
static bool Lambertian_scatter(const HitRecord *rec, Vec3 r_in, Vec3 *r_out, Vec3 *color, float *pdf, PCG32 *rng) {
ONB onb;
ONB_from_w(&onb, rec->normal);

*r_out = ONB_local(&onb, rand_cosine_theta(rng));
*color = _Texture_value(rec);
*pdf = vec3_dot(onb.w, vec3_normalize(*r_out)) / (float)M_PI; // cos(theta) / pi
*pdf = Lambertian_scattering_pdf(rec, r_in, *r_out);
return true;
}
static float Lambertian_scattering_pdf(const HitRecord *rec, Vec3 r_in, Vec3 r_out) {
float cos_theta = vec3_dot(rec->normal, vec3_normalize(r_out));
return cos_theta < 0.0f ? 0.0f : cos_theta / (float)M_PI;
}
static MaterialVTable LAMBERTIAN_VTABLE = {Lambertian_scatter, Lambertian_scattering_pdf, Empty_emit};
void Lambertian_init(Material *self, Texture *albedo) {
self->vtable = &LAMBERTIAN_VTABLE;
Expand Down
7 changes: 4 additions & 3 deletions src/raytracing.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ static Vec3 Camera_ray_color(const Camera *camera, const Ray *ray, const World *
return emission_color;

// mixture pdf
if (camera->importance_sampling) {
float prob = camera->lights_sampling_prob;
if (prob > 0.0f) {
const Hittable *lights = &world->lights.hittable;
if (pcg32_f32(rng) < 0.5f) // change scatter ray towards the light half of the time
if (pcg32_f32(rng) < prob) // change scatter ray towards the light
new_ray.direction = lights->vtable->rand(lights, rec.p, rng);
pdf = 0.5f * pdf + 0.5f * lights->vtable->pdf(lights, &new_ray, rng); // update pdf
pdf = (1.0f - prob) * pdf + prob * lights->vtable->pdf(lights, &new_ray, rng); // update pdf
}

// spawn new ray
Expand Down

0 comments on commit 459ed6b

Please sign in to comment.