Refactored ColorProfile

This commit is contained in:
Michaël Lemaire 2013-11-19 12:51:26 +01:00 committed by Michael Lemaire
parent 82defc96f6
commit a108682b4d
14 changed files with 180 additions and 174 deletions

106
src/basics/ColorProfile.cpp Normal file
View file

@ -0,0 +1,106 @@
#include "ColorProfile.h"
#include "PackStream.h"
ColorProfile::ColorProfile()
{
setToneMapping(TONE_MAPPING_UNCHARTED, 2.0);
}
ColorProfile::ColorProfile(ToneMappingOperator tonemapper, double exposure)
{
setToneMapping(tonemapper, exposure);
}
static inline double _uncharted2Tonemap(double x)
{
double A = 0.15;
double B = 0.50;
double C = 0.10;
double D = 0.20;
double E = 0.02;
double F = 0.30;
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
}
static inline Color _toneMappingUncharted(const Color &pixel, double exposure)
{
static const double W = 11.2;
static const double white_scale = 1.0 / _uncharted2Tonemap(W);
static const double factor = 1.0 / 2.2;
Color result(
pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, factor),
pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, factor),
pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, factor),
pixel.a
);
return result;
}
static inline Color _toneMappingReinhard(const Color &pixel, double exposure)
{
Color result(
(pixel.r * exposure) / (1.0 + pixel.r * exposure),
(pixel.g * exposure) / (1.0 + pixel.g * exposure),
(pixel.b * exposure) / (1.0 + pixel.b * exposure),
pixel.a
);
return result;
}
static inline Color _toneMappingClamp(const Color &pixel)
{
Color result(
pixel.r > 1.0 ? 1.0 : pixel.r,
pixel.g > 1.0 ? 1.0 : pixel.g,
pixel.b > 1.0 ? 1.0 : pixel.b,
pixel.a
);
return result;
}
void ColorProfile::setToneMapping(ToneMappingOperator tonemapper, double exposure)
{
this->mapper = tonemapper;
this->exposure = exposure;
}
void ColorProfile::save(PackStream* stream) const
{
int imapper = (int)mapper;
stream->write(&imapper);
stream->write(&exposure);
}
void ColorProfile::load(PackStream* stream)
{
int imapper = (int)mapper;
stream->read(&imapper);
stream->read(&exposure);
mapper = (ToneMappingOperator)imapper;
}
void ColorProfile::copy(ColorProfile* destination) const
{
destination->mapper = mapper;
destination->exposure = exposure;
}
Color ColorProfile::apply(const Color &pixel) const
{
switch (mapper)
{
case TONE_MAPPING_REIHNARD:
return _toneMappingReinhard(pixel, exposure);
case TONE_MAPPING_UNCHARTED:
return _toneMappingUncharted(pixel, exposure);
default:
return _toneMappingClamp(pixel);
}
}

41
src/basics/ColorProfile.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef COLORPROFILE_H
#define COLORPROFILE_H
#include "basics_global.h"
#include "Color.h"
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT ColorProfile
{
public:
typedef enum
{
TONE_MAPPING_UNCHARTED,
TONE_MAPPING_REIHNARD,
TONE_MAPPING_CLAMP
} ToneMappingOperator;
public:
ColorProfile();
ColorProfile(ToneMappingOperator tonemapper, double exposure);
void setToneMapping(ToneMappingOperator tonemapper, double exposure);
void save(PackStream* stream) const;
void load(PackStream* stream);
void copy(ColorProfile* destination) const;
Color apply(const Color &pixel) const;
private:
ToneMappingOperator mapper;
double exposure;
};
}
}
#endif // COLORPROFILE_H

View file

@ -27,7 +27,8 @@ SOURCES += \
ColorHSL.cpp \ ColorHSL.cpp \
BoundingBox.cpp \ BoundingBox.cpp \
Matrix4.cpp \ Matrix4.cpp \
Curve.cpp Curve.cpp \
ColorProfile.cpp
HEADERS +=\ HEADERS +=\
basics_global.h \ basics_global.h \
@ -42,7 +43,8 @@ HEADERS +=\
ColorHSL.h \ ColorHSL.h \
BoundingBox.h \ BoundingBox.h \
Matrix4.h \ Matrix4.h \
Curve.h Curve.h \
ColorProfile.h
unix:!symbian { unix:!symbian {
maemo5 { maemo5 {

View file

@ -19,6 +19,7 @@ namespace basics {
class Color; class Color;
class NoiseGenerator; class NoiseGenerator;
class Curve; class Curve;
class ColorProfile;
} }
} }
using namespace paysages::basics; using namespace paysages::basics;

View file

@ -19,6 +19,7 @@
#include "tools.h" #include "tools.h"
#include "Scenery.h" #include "Scenery.h"
#include "ColorProfile.h"
static DialogRender* _current_dialog; static DialogRender* _current_dialog;
@ -219,7 +220,7 @@ void DialogRender::saveRender()
void DialogRender::toneMappingChanged() void DialogRender::toneMappingChanged()
{ {
renderSetToneMapping(_renderer->render_area, (ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01); renderSetToneMapping(_renderer->render_area, ColorProfile((ColorProfile::ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01));
} }
void DialogRender::loadLastRender() void DialogRender::loadLastRender()

View file

@ -5,10 +5,9 @@
#include "tools.h" #include "tools.h"
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "BasePreview.h" #include "BasePreview.h"
#include "tools/lighting.h"
#include "tools/color.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "ColorProfile.h"
#include "tools/lighting.h"
/***** Shared renderer *****/ /***** Shared renderer *****/
MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material) MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
@ -27,13 +26,13 @@ MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
render_camera->setLocation(Vector3(0.0, 0.0, 10.0)); render_camera->setLocation(Vector3(0.0, 0.0, 10.0));
_color_profile = colorProfileCreate(); _color_profile = new ColorProfile;
colorProfileSetToneMapping(_color_profile, TONE_MAPPING_UNCHARTED, 1.0); _color_profile->setToneMapping(ColorProfile::TONE_MAPPING_UNCHARTED, 1.0);
} }
MaterialPreviewRenderer::~MaterialPreviewRenderer() MaterialPreviewRenderer::~MaterialPreviewRenderer()
{ {
colorProfileDelete(_color_profile); delete _color_profile;
} }
void MaterialPreviewRenderer::bindEvent(BasePreview* preview) void MaterialPreviewRenderer::bindEvent(BasePreview* preview)
@ -70,7 +69,7 @@ Color MaterialPreviewRenderer::getColor2D(double x, double y, double)
{ {
color.a = (1.0 - dist) / 0.05; color.a = (1.0 - dist) / 0.05;
} }
return colorProfileApply(_color_profile, color); return _color_profile->apply(color);
} }
} }

View file

@ -2,6 +2,7 @@
#include <QImage> #include <QImage>
#include <QGLWidget> #include <QGLWidget>
#include "ColorProfile.h"
#ifndef GL_CLAMP_TO_EDGE #ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F #define GL_CLAMP_TO_EDGE 0x812F
@ -10,7 +11,7 @@
BaseExplorerChunk::BaseExplorerChunk(Renderer* renderer) BaseExplorerChunk::BaseExplorerChunk(Renderer* renderer)
{ {
_renderer = renderer; _renderer = renderer;
_color_profile = colorProfileCreate(); _color_profile = new ColorProfile;
priority = 0.0; priority = 0.0;
_reset_needed = false; _reset_needed = false;
@ -25,7 +26,7 @@ BaseExplorerChunk::BaseExplorerChunk(Renderer* renderer)
BaseExplorerChunk::~BaseExplorerChunk() BaseExplorerChunk::~BaseExplorerChunk()
{ {
_lock_data.lock(); _lock_data.lock();
colorProfileDelete(_color_profile); delete _color_profile;
delete _texture; delete _texture;
_lock_data.unlock(); _lock_data.unlock();
} }
@ -57,7 +58,7 @@ bool BaseExplorerChunk::maintain()
if (_texture_current_size <= 1 || i % 2 != 0 || j % 2 != 0) if (_texture_current_size <= 1 || i % 2 != 0 || j % 2 != 0)
{ {
Color color = getTextureColor((double)i / (double)new_texture_size, 1.0 - (double)j / (double)new_texture_size); Color color = getTextureColor((double)i / (double)new_texture_size, 1.0 - (double)j / (double)new_texture_size);
color = colorProfileApply(_color_profile, color); color = _color_profile->apply(color);
colorNormalize(&color); colorNormalize(&color);
new_image->setPixel(i, j, colorTo32BitBGRA(&color)); new_image->setPixel(i, j, colorTo32BitBGRA(&color));
} }

View file

@ -4,12 +4,11 @@
#include "opengl_global.h" #include "opengl_global.h"
#include <QMutex> #include <QMutex>
#include "tools/color.h" #include "Color.h"
class QImage; class QImage;
class QGLWidget; class QGLWidget;
class Renderer; class Renderer;
class ColorProfile;
namespace paysages { namespace paysages {
namespace opengl { namespace opengl {
@ -27,7 +26,7 @@ public:
protected: protected:
BaseExplorerChunk(Renderer* renderer); BaseExplorerChunk(Renderer* renderer);
inline Renderer* renderer() {return _renderer;}; inline Renderer* renderer() {return _renderer;}
void askReset(); void askReset();
void setMaxTextureSize(int size); void setMaxTextureSize(int size);

View file

@ -14,6 +14,7 @@
#include "PackStream.h" #include "PackStream.h"
#include "Base2dPreviewRenderer.h" #include "Base2dPreviewRenderer.h"
#include "PreviewOsd.h" #include "PreviewOsd.h"
#include "ColorProfile.h"
/*************** PreviewChunk ***************/ /*************** PreviewChunk ***************/
class PreviewChunk class PreviewChunk
@ -406,7 +407,7 @@ DrawingWidget(parent)
_info->setStyleSheet("QLabel { background-color: white; color: black; }"); _info->setStyleSheet("QLabel { background-color: white; color: black; }");
_hdr_enabled = false; _hdr_enabled = false;
_hdr_profile = colorProfileCreate(); _hdr_profile = new ColorProfile;
this->alive = true; this->alive = true;
@ -423,7 +424,7 @@ BasePreview::~BasePreview()
{ {
alive = false; alive = false;
colorProfileDelete(_hdr_profile); delete _hdr_profile;
_drawing_manager->removeChunks(this); _drawing_manager->removeChunks(this);
@ -643,7 +644,7 @@ QColor BasePreview::getPixelColor(int x, int y)
Color col = getColor((double) (x - _width / 2) * scaling + xoffset, (double) (y - _height / 2) * scaling + yoffset); Color col = getColor((double) (x - _width / 2) * scaling + xoffset, (double) (y - _height / 2) * scaling + yoffset);
if (_hdr_enabled) if (_hdr_enabled)
{ {
col = colorProfileApply(_hdr_profile, col); col = _hdr_profile->apply(col);
} }
col.normalize(); col.normalize();
return QColor::fromRgbF(col.r, col.g, col.b, col.a); return QColor::fromRgbF(col.r, col.g, col.b, col.a);

View file

@ -1,8 +1,6 @@
#include "render.h" #include "render.h"
#include <stdlib.h> #include <cmath>
#include <stdio.h>
#include <math.h>
#include "renderer.h" #include "renderer.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
@ -11,6 +9,7 @@
#include "Mutex.h" #include "Mutex.h"
#include "System.h" #include "System.h"
#include "Vector3.h" #include "Vector3.h"
#include "ColorProfile.h"
typedef struct typedef struct
{ {
@ -112,7 +111,7 @@ RenderArea* renderCreateArea(Renderer* renderer)
result = new RenderArea; result = new RenderArea;
result->renderer = renderer; result->renderer = renderer;
result->hdr_mapping = colorProfileCreate(); result->hdr_mapping = new ColorProfile;
result->params.width = 1; result->params.width = 1;
result->params.height = 1; result->params.height = 1;
result->params.antialias = 1; result->params.antialias = 1;
@ -136,7 +135,7 @@ RenderArea* renderCreateArea(Renderer* renderer)
void renderDeleteArea(RenderArea* area) void renderDeleteArea(RenderArea* area)
{ {
colorProfileDelete(area->hdr_mapping); delete area->hdr_mapping;
delete area->lock; delete area->lock;
free(area->pixels); free(area->pixels);
free(area); free(area);
@ -171,9 +170,9 @@ void renderSetParams(RenderArea* area, RenderParams params)
renderClear(area); renderClear(area);
} }
void renderSetToneMapping(RenderArea* area, ToneMappingOperator tonemapper, double exposure) void renderSetToneMapping(RenderArea* area, const ColorProfile &profile)
{ {
colorProfileSetToneMapping(area->hdr_mapping, tonemapper, exposure); profile.copy(area->hdr_mapping);
_setAllDirty(area); _setAllDirty(area);
renderUpdate(area); renderUpdate(area);
} }
@ -275,7 +274,7 @@ static inline Color _getFinalPixel(RenderArea* area, int x, int y)
} }
} }
return colorProfileApply(area->hdr_mapping, result); return area->hdr_mapping->apply(result);
} }
static void _processDirtyPixels(RenderArea* area) static void _processDirtyPixels(RenderArea* area)

View file

@ -29,7 +29,7 @@ RENDERINGSHARED_EXPORT RenderArea* renderCreateArea(Renderer* renderer);
RENDERINGSHARED_EXPORT void renderDeleteArea(RenderArea* area); RENDERINGSHARED_EXPORT void renderDeleteArea(RenderArea* area);
RENDERINGSHARED_EXPORT void renderSetParams(RenderArea* area, RenderParams params); RENDERINGSHARED_EXPORT void renderSetParams(RenderArea* area, RenderParams params);
RENDERINGSHARED_EXPORT void renderSetToneMapping(RenderArea* area, ToneMappingOperator tonemapper, double exposure); RENDERINGSHARED_EXPORT void renderSetToneMapping(RenderArea* area, const ColorProfile &profile);
RENDERINGSHARED_EXPORT void renderSetBackgroundColor(RenderArea* area, const Color& col); RENDERINGSHARED_EXPORT void renderSetBackgroundColor(RenderArea* area, const Color& col);
RENDERINGSHARED_EXPORT void renderClear(RenderArea* area); RENDERINGSHARED_EXPORT void renderClear(RenderArea* area);
RENDERINGSHARED_EXPORT void renderUpdate(RenderArea* area); RENDERINGSHARED_EXPORT void renderUpdate(RenderArea* area);

View file

@ -7,130 +7,6 @@
#include "PackStream.h" #include "PackStream.h"
#include "Curve.h" #include "Curve.h"
/******************************** ColorProfile ********************************/
class ColorProfile
{
public:
double minvalue;
double maxvalue;
Color(*mapper)(Color col, double exposure);
double exposure;
};
ColorProfile* colorProfileCreate()
{
ColorProfile* profile;
profile = new ColorProfile;
colorProfileSetToneMapping(profile, TONE_MAPPING_UNCHARTED, 2.0);
colorProfileClear(profile);
return profile;
}
void colorProfileDelete(ColorProfile* profile)
{
delete profile;
}
static inline double _uncharted2Tonemap(double x)
{
double A = 0.15;
double B = 0.50;
double C = 0.10;
double D = 0.20;
double E = 0.02;
double F = 0.30;
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
}
static Color _toneMappingUncharted(Color pixel, double exposure)
{
double W = 11.2;
double white_scale = 1.0 / _uncharted2Tonemap(W);
pixel.r = pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, 1.0 / 2.2);
pixel.g = pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, 1.0 / 2.2);
pixel.b = pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, 1.0 / 2.2);
return pixel;
}
static Color _toneMappingReinhard(Color pixel, double exposure)
{
pixel.r = (pixel.r * exposure) / (1.0 + pixel.r * exposure);
pixel.g = (pixel.g * exposure) / (1.0 + pixel.g * exposure);
pixel.b = (pixel.b * exposure) / (1.0 + pixel.b * exposure);
return pixel;
}
static Color _toneMappingClamp(Color pixel, double)
{
pixel.r = pixel.r > 1.0 ? 1.0 : pixel.r;
pixel.g = pixel.g > 1.0 ? 1.0 : pixel.g;
pixel.b = pixel.b > 1.0 ? 1.0 : pixel.b;
return pixel;
}
void colorProfileSetToneMapping(ColorProfile* profile, ToneMappingOperator tonemapper, double exposure)
{
switch (tonemapper)
{
case TONE_MAPPING_REIHNARD:
profile->mapper = _toneMappingReinhard;
break;
case TONE_MAPPING_UNCHARTED:
profile->mapper = _toneMappingUncharted;
break;
default:
profile->mapper = _toneMappingClamp;
}
profile->exposure = exposure;
}
void colorProfileSave(PackStream*, ColorProfile*)
{
/* TODO */
}
void colorProfileLoad(PackStream*, ColorProfile*)
{
/* TODO */
}
void colorProfileClear(ColorProfile* profile)
{
profile->minvalue = 0.0;
profile->maxvalue = 3.0;
}
int colorProfileCollect(ColorProfile* profile, Color pixel)
{
int changed = 0;
double value = pixel.r + pixel.g + pixel.b;
if (value < profile->minvalue)
{
profile->minvalue = value;
changed = 1;
}
if (value > profile->maxvalue)
{
profile->maxvalue = value;
changed = 1;
}
return changed;
}
Color colorProfileApply(ColorProfile* profile, Color pixel)
{
return profile->mapper(pixel, profile->exposure);
}
/******************************** ColorGradation ********************************/ /******************************** ColorGradation ********************************/
struct ColorGradation struct ColorGradation
{ {

View file

@ -3,27 +3,6 @@
#include "../rendering_global.h" #include "../rendering_global.h"
/* HDR profile for tone-mapping */
class ColorProfile;
typedef enum
{
TONE_MAPPING_UNCHARTED,
TONE_MAPPING_REIHNARD,
TONE_MAPPING_CLAMP
} ToneMappingOperator;
RENDERINGSHARED_EXPORT ColorProfile* colorProfileCreate();
RENDERINGSHARED_EXPORT void colorProfileDelete(ColorProfile* profile);
RENDERINGSHARED_EXPORT void colorProfileSetToneMapping(ColorProfile* profile, ToneMappingOperator tonemapper, double exposure);
RENDERINGSHARED_EXPORT void colorProfileSave(PackStream* stream, ColorProfile* profile);
RENDERINGSHARED_EXPORT void colorProfileLoad(PackStream* stream, ColorProfile* profile);
RENDERINGSHARED_EXPORT void colorProfileClear(ColorProfile* profile);
RENDERINGSHARED_EXPORT int colorProfileCollect(ColorProfile* profile, Color pixel);
RENDERINGSHARED_EXPORT Color colorProfileApply(ColorProfile* profile, Color pixel);
/* ColorGradation */ /* ColorGradation */
typedef struct ColorGradation ColorGradation; typedef struct ColorGradation ColorGradation;

View file

@ -3,6 +3,7 @@
#include <cmath> #include <cmath>
#include "renderer.h" #include "renderer.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "ColorProfile.h"
#include "System.h" #include "System.h"
static Color _postProcessFragment(Renderer*, Vector3 location, void*) static Color _postProcessFragment(Renderer*, Vector3 location, void*)
@ -36,7 +37,7 @@ TEST(Render, quad)
renderer->render_width = 800; renderer->render_width = 800;
renderer->render_height = 600; renderer->render_height = 600;
renderer->render_quality = 1; renderer->render_quality = 1;
renderSetToneMapping(renderer->render_area, TONE_MAPPING_CLAMP, 0.0); renderSetToneMapping(renderer->render_area, ColorProfile(ColorProfile::TONE_MAPPING_CLAMP, 0.0));
renderer->render_camera->setLocationCoords(0.0, 0.5, 2.0); renderer->render_camera->setLocationCoords(0.0, 0.5, 2.0);
renderer->render_camera->setTargetCoords(0.0, 0.5, 0.0); renderer->render_camera->setTargetCoords(0.0, 0.5, 0.0);