Skip to content

Commit

Permalink
Try to clamp out fireflies (bright dots in image)
Browse files Browse the repository at this point in the history
These sometimes happen - Somewhere in the renderer, something divides by
zero in some exceedingly unlikely case, and the resulting sample
contains NaNs.
It's fairly common to just clamp these out, but a proper approach would
be to actually trace where the goof happens, and fix that.
  • Loading branch information
vkoskiv committed Nov 3, 2023
1 parent c0ca45d commit b05b814
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/datatypes/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ static inline bool colorEquals(struct color a, struct color b) {
return a.red == b.red && a.green == b.green && a.blue == b.blue && a.alpha == b.alpha;
}

static inline void nan_clamp(struct color *a, struct color *b) {
if (a->red != a->red || a->green != a->green || a->blue != a->blue || a->alpha != a->alpha)
*a = *b;
}

struct color colorForKelvin(float kelvin);

struct color color_from_hsl(float hue, float saturation, float lightness);
Expand Down
5 changes: 5 additions & 0 deletions src/renderer/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ void *renderThreadInteractive(void *arg) {
struct color output = textureGetPixel(r->state.renderBuffer, x, y, false);
struct lightRay incidentRay = cam_get_ray(cam, x, y, sampler);
struct color sample = path_trace(&incidentRay, r->scene, r->prefs.bounces, sampler);

nan_clamp(&sample, &output);

//And process the running average
output = colorCoef((float)(r->state.finishedPasses - 1), output);
Expand Down Expand Up @@ -304,6 +306,9 @@ void *renderThread(void *arg) {
struct lightRay incidentRay = cam_get_ray(cam, x, y, sampler);
struct color sample = path_trace(&incidentRay, r->scene, r->prefs.bounces, sampler);

// Clamp out fireflies - This is probably not a good way to do that.
nan_clamp(&sample, &output);

//And process the running average
output = colorCoef((float)(threadState->completedSamples - 1), output);
output = colorAdd(output, sample);
Expand Down
2 changes: 2 additions & 0 deletions src/utils/protocol/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ static void *workerThread(void *arg) {
struct color output = textureGetPixel(r->state.renderBuffer, x, y, false);
struct lightRay incidentRay = cam_get_ray(cam, x, y, sampler);
struct color sample = path_trace(&incidentRay, r->scene, r->prefs.bounces, sampler);

nan_clamp(&sample, &output);

//And process the running average
output = colorCoef((float)(thread->completedSamples - 1), output);
Expand Down

0 comments on commit b05b814

Please sign in to comment.