Skip to content
Snippets Groups Projects
Commit 14d5ea07 authored by jean-claude iehl's avatar jean-claude iehl
Browse files

framebuffer: accumulation des samples sur des doubles, pour faire de belles...

framebuffer: accumulation des samples sur des doubles, pour faire de belles courbes de convergence...
parent 146d91e5
No related branches found
No related tags found
No related merge requests found
#ifndef _FRAMEBUFFER_H
#define _FRAMEBUFFER_H
#include <vector>
#include "image.h"
// les floats 32 bits ne sont pas assez precis pour accumuler des milliers d'echantillons par pixel...
struct Framebuffer
{
struct pixel
{
double r, g, b;
unsigned n;
};
std::vector<pixel> pixels;
std::vector<pixel> m2;
int m_width;
int m_height;
Framebuffer( const int w, const int h ) : pixels(w*h), m2(w*h), m_width(w), m_height(h) {}
int width() { return m_width; }
int height() { return m_height; }
void splat( const float x, const float y, const Color& color )
{
int px= int(x);
int py= int(y);
assert(px >= 0 && px < m_width);
assert(py >= 0 && py < m_height);
int offset= py * m_width + px;
// evaluation numerique stable de la moyenne et de la variance
// cf https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm
pixels[offset].n++;
double r= color.r - pixels[offset].r;
double g= color.g - pixels[offset].g;
double b= color.b - pixels[offset].b;
// moyenne
pixels[offset].r+= r / pixels[offset].n;
pixels[offset].g+= g / pixels[offset].n;
pixels[offset].b+= b / pixels[offset].n;
// variance
m2[offset].r+= r * ( color.r - pixels[offset].r );
m2[offset].g+= g * ( color.g - pixels[offset].g );
m2[offset].b+= b * ( color.b - pixels[offset].b );
}
// renvoie la moyenne / image classique.
Image flatten( )
{
Image tmp(m_width, m_height);
for(unsigned i= 0; i < tmp.size(); i++)
tmp(i)= Color( float(pixels[i].r), float(pixels[i].g), float(pixels[i].b) );
return tmp;
}
// renvoie la variance / image classique.
Image flatten_var( )
{
Image tmp(m_width, m_height);
for(unsigned i= 0; i < tmp.size(); i++)
tmp(i)= Color( m2[i].r / pixels[i].n, m2[i].g / pixels[i].n, m2[i].b / pixels[i].n );
return tmp;
}
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment