paysages : HDR rendering (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@495 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-01-14 19:07:56 +00:00 committed by ThunderK
parent 4c72cb5ded
commit 2a0e7851d9
11 changed files with 189 additions and 79 deletions

2
TODO
View file

@ -1,4 +1,5 @@
Technology Preview 2 :
- Implement High Dynamic Range (with OpenEXR or Radiance file format support ?).
- Fully move layer management from BaseForm to BaseFormLayer.
- Replace terrain canvas editor by full sculpting editor.
=> Add a generation dialog, with fixed resolution.
@ -43,7 +44,6 @@ Technlogy Preview 3 :
Technology Preview 4 :
- Restore render progress.
- Store the terrain canvases in a tree to allow "multi-res" edition.
- Implement High Dynamic Range.
- Implement Sub Surface Scattering for water.
- Use bicubic interpolation for antialiasing.
- Allow for larger renders/antialias (will need several two-pass chunks).

View file

@ -26,6 +26,7 @@ static void _renderStart(int width, int height, Color background)
static void _renderDraw(int x, int y, Color col)
{
col = colorProfileApply(_current_dialog->_hdr_profile, col);
_current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
}
@ -79,6 +80,8 @@ DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
_render_thread = NULL;
_renderer = renderer;
_hdr_profile = colorProfileCreate();
setModal(true);
setWindowTitle(tr("Paysages 3D - Render"));
setLayout(new QVBoxLayout());
@ -116,6 +119,7 @@ DialogRender::~DialogRender()
delete _render_thread;
}
colorProfileDelete(_hdr_profile);
delete pixbuf;
delete pixbuf_lock;
}

View file

@ -9,6 +9,7 @@
#include <QLabel>
#include <QMutex>
#include "../lib_paysages/renderer.h"
#include "../lib_paysages/color.h"
class DialogRender : public QDialog
{
@ -25,6 +26,7 @@ public:
QImage* pixbuf;
QMutex* pixbuf_lock;
QWidget* area;
ColorProfile* _hdr_profile;
private slots:
void applyRenderSize(int width, int height);

View file

@ -302,22 +302,6 @@ static Color _transmittanceWithShadow(double r, double mu)
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? COLOR_BLACK : _transmittance(r, mu);
}
static Color _hdr(Color c1, Color c2, Color c3)
{
Color L = {c1.r + c2.r + c3.r, c1.g + c2.g + c3.g, c1.b + c2.b + c3.b, 1.0};
L.r *= exposure;
L.g *= exposure;
L.b *= exposure;
L.a = 1.0;
L.r = L.r < 1.413 ? pow(L.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.r);
L.g = L.g < 1.413 ? pow(L.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.g);
L.b = L.b < 1.413 ? pow(L.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-L.b);
return L;
}
static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, double* muS, double* nu)
{
double d;
@ -1252,9 +1236,12 @@ Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3
Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
Color groundColor = COLOR_BLACK;
Color sunColor = _sunColor(x, 0.0, v, s, r, mu); /* L0 */
return _hdr(sunColor, groundColor, inscatterColor); /* Eq (16) */
inscatterColor.r += sunColor.r;
inscatterColor.g += sunColor.g;
inscatterColor.b += sunColor.b;
return inscatterColor; /* Eq (16) */
}
Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
@ -1297,6 +1284,9 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
Vector3 attenuation;
Color inscatterColor = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
Color groundColor = _groundColor(base, x, t, v, s, r, mu, attenuation); //R[L0]+R[L*]*/
Color sunColor = COLOR_BLACK;
return _hdr(sunColor, groundColor, inscatterColor); /* Eq (16) */
groundColor.r += inscatterColor.r;
groundColor.g += inscatterColor.g;
groundColor.b += inscatterColor.b;
return groundColor; /* Eq (16) */
}

View file

@ -24,34 +24,34 @@ void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset pre
definition->model = ATMOSPHERE_MODEL_BRUNETON;
definition->hour = 15;
definition->minute = 0;
definition->dome_lighting = 0.6;
definition->dome_lighting = 0.2;
break;
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
definition->model = ATMOSPHERE_MODEL_BRUNETON;
definition->hour = 17;
definition->minute = 45;
definition->dome_lighting = 0.8;
definition->dome_lighting = 0.3;
definition->sun_radius = 0.03;
break;
case ATMOSPHERE_PRESET_HAZY_MORNING:
definition->model = ATMOSPHERE_MODEL_PREETHAM;
definition->hour = 8;
definition->minute = 30;
definition->dome_lighting = 0.5;
definition->dome_lighting = 0.25;
definition->humidity = 0.3;
break;
case ATMOSPHERE_PRESET_FOGGY:
definition->model = ATMOSPHERE_MODEL_PREETHAM;
definition->hour = 15;
definition->minute = 0;
definition->dome_lighting = 0.7;
definition->dome_lighting = 0.1;
definition->humidity = 0.6;
break;
case ATMOSPHERE_PRESET_STORMY:
definition->model = ATMOSPHERE_MODEL_PREETHAM;
definition->hour = 15;
definition->minute = 0;
definition->dome_lighting = 0.3;
definition->dome_lighting = 0.05;
definition->humidity = 0.9;
break;
default:

View file

@ -3,9 +3,12 @@
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include "tools.h"
#include "curve.h"
/******************************** Color ********************************/
Color COLOR_TRANSPARENT = {0.0, 0.0, 0.0, 0.0};
Color COLOR_BLACK = {0.0, 0.0, 0.0, 1.0};
Color COLOR_RED = {1.0, 0.0, 0.0, 1.0};
@ -14,13 +17,6 @@ Color COLOR_BLUE = {0.0, 0.0, 1.0, 1.0};
Color COLOR_WHITE = {1.0, 1.0, 1.0, 1.0};
Color COLOR_GREY = {0.5, 0.5, 0.5, 1.0};
struct ColorGradation
{
Curve* red;
Curve* green;
Curve* blue;
};
void colorSave(PackStream* stream, Color* col)
{
packWriteDouble(stream, &col->r);
@ -125,7 +121,20 @@ void colorMask(Color* base, Color* mask)
double colorNormalize(Color* col)
{
double max = colorGetValue(col);
if (col->r > 1.0)
{
col->r = 1.0;
}
if (col->g > 1.0)
{
col->g = 1.0;
}
if (col->b > 1.0)
{
col->b = 1.0;
}
return 1.0;
/*double max = colorGetValue(col);
assert(max >= 0.0);
assert(col->r >= 0.0);
@ -139,7 +148,7 @@ double colorNormalize(Color* col)
col->g /= max;
col->b /= max;
}
return max;
return max;*/
}
double colorGetValue(Color* col)
@ -158,6 +167,96 @@ double colorGetValue(Color* col)
return max;
}
/******************************** ColorProfile ********************************/
struct ColorProfile
{
double minvalue;
double maxvalue;
};
ColorProfile* colorProfileCreate()
{
ColorProfile* profile;
profile = malloc(sizeof(ColorProfile));
colorProfileClear(profile);
return profile;
}
void colorProfileDelete(ColorProfile* profile)
{
free(profile);
}
void colorProfileSave(PackStream* stream, ColorProfile* profile)
{
/* TODO */
}
void colorProfileLoad(PackStream* stream, ColorProfile* profile)
{
/* 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;
}
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;
static double _uncharted2Tonemap(double x)
{
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}
Color colorProfileApply(ColorProfile* profile, Color pixel)
{
double exposure_bias = 2.0;
double white_scale = 1.0 / _uncharted2Tonemap(W);
pixel.r = pow(_uncharted2Tonemap(pixel.r * exposure_bias) * white_scale, 1.0 / 2.2);
pixel.g = pow(_uncharted2Tonemap(pixel.g * exposure_bias) * white_scale, 1.0 / 2.2);
pixel.b = pow(_uncharted2Tonemap(pixel.b * exposure_bias) * white_scale, 1.0 / 2.2);
return pixel;
}
/******************************** ColorGradation ********************************/
struct ColorGradation
{
Curve* red;
Curve* green;
Curve* blue;
};
ColorGradation* colorGradationCreate()
{
ColorGradation* result;

View file

@ -2,6 +2,7 @@
#define _PAYSAGES_COLOR_H_
#include "curve.h"
#include "pack.h"
#ifdef __cplusplus
extern "C" {
@ -41,6 +42,19 @@ void colorMask(Color* base, Color* mask);
double colorNormalize(Color* col);
double colorGetValue(Color* col);
/* HDR profile for tone-mapping */
typedef struct ColorProfile ColorProfile;
ColorProfile* colorProfileCreate();
void colorProfileDelete(ColorProfile* profile);
void colorProfileSave(PackStream* stream, ColorProfile* profile);
void colorProfileLoad(PackStream* stream, ColorProfile* profile);
void colorProfileClear(ColorProfile* profile);
int colorProfileCollect(ColorProfile* profile, Color pixel);
Color colorProfileApply(ColorProfile* profile, Color pixel);
/* ColorGradation */
typedef struct ColorGradation ColorGradation;

View file

@ -6,6 +6,7 @@
#include "shared/types.h"
#include "color.h"
#include "renderer.h"
#include "system.h"
typedef struct
@ -589,7 +590,7 @@ void* _renderPostProcessChunk(void* data)
if (callback.function)
{
col = callback.function(chunk->renderer, fragment->data.location, callback.data);
colorNormalize(&col);
/*colorNormalize(&col);*/
}
else
{

View file

@ -3,12 +3,25 @@
#include <stdio.h>
#include "shared/types.h"
#include "renderer.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*RenderCallbackStart)(int width, int height, Color background);
typedef void (*RenderCallbackDraw)(int x, int y, Color col);
typedef void (*RenderCallbackUpdate)(double progress);
typedef struct RenderArea RenderArea;
typedef struct
{
int width;
int height;
int antialias;
int quality;
} RenderParams;
void renderInit();
void renderQuit();

View file

@ -4,6 +4,7 @@
#include "shared/types.h"
#include "atmosphere/public.h"
#include "terrain/public.h"
#include "render.h"
#ifdef __cplusplus
extern "C" {

View file

@ -15,14 +15,6 @@ typedef struct LightStatus LightStatus;
typedef Color (*f_RenderFragmentCallback)(struct Renderer* renderer, Vector3 location, void* data);
typedef struct
{
int width;
int height;
int antialias;
int quality;
} RenderParams;
typedef struct
{
int length;
@ -39,12 +31,6 @@ typedef struct
double shininess;
} SurfaceMaterial;
typedef void (*RenderCallbackStart)(int width, int height, Color background);
typedef void (*RenderCallbackDraw)(int x, int y, Color col);
typedef void (*RenderCallbackUpdate)(double progress);
typedef struct RenderArea RenderArea;
typedef struct
{
int hit;