Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Ebb <matt@mke3.net>2009-07-17 06:43:15 +0400
committerMatt Ebb <matt@mke3.net>2009-07-17 06:43:15 +0400
commit1ef729358517248888073be71ba5d3b6e3d723ee (patch)
treedfa33f083ac1afd500e76dcf4bc581394637d0dd /source/blender/render
parent70f6255433fcb1f5551199ef7a285a9ab80a3318 (diff)
Colour Management
- 1st stage: Linear Workflow This implements automatic linear workflow in Blender's renderer. With the new Colour Management option on in the Render buttons, all inputs to the renderer and compositor are converted to linear colour space before rendering, and gamma corrected afterwards. In essence, this makes all manual gamma correction with nodes, etc unnecessary, since it's done automatically through the pipeline. It's all explained much better in the notes/doc here, so please have a look: http://wiki.blender.org/index.php/Dev:Source/Blender/Architecture/Colour_Management And an example of the sort of difference it makes: http://mke3.net/blender/devel/rendering/b25_colormanagement_test01.jpg This also enables Colour Management in the default B.blend, and changes the default lamp falloff to inverse square, which is more correct, and much easier to use now it's all gamma corrected properly. Next step is to look into profiles/soft proofing for the compositor. Thanks to brecht for reviewing and fixing some oversights!
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/include/shading.h1
-rw-r--r--source/blender/render/intern/source/convertblender.c14
-rw-r--r--source/blender/render/intern/source/pipeline.c5
-rw-r--r--source/blender/render/intern/source/pixelshading.c22
-rw-r--r--source/blender/render/intern/source/rayshade.c3
-rw-r--r--source/blender/render/intern/source/rendercore.c13
-rw-r--r--source/blender/render/intern/source/shadeinput.c55
-rw-r--r--source/blender/render/intern/source/sss.c6
-rw-r--r--source/blender/render/intern/source/strand.c4
-rw-r--r--source/blender/render/intern/source/texture.c21
10 files changed, 113 insertions, 31 deletions
diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h
index 54311d2515a..d195f32d5ef 100644
--- a/source/blender/render/intern/include/shading.h
+++ b/source/blender/render/intern/include/shading.h
@@ -66,6 +66,7 @@ void shade_input_set_strand(struct ShadeInput *shi, struct StrandRen *strand, st
void shade_input_set_strand_texco(struct ShadeInput *shi, struct StrandRen *strand, struct StrandVert *svert, struct StrandPoint *spoint);
void shade_input_do_shade(struct ShadeInput *shi, struct ShadeResult *shr);
+void shade_input_init_material(struct ShadeInput *shi);
void shade_input_initialize(struct ShadeInput *shi, struct RenderPart *pa, struct RenderLayer *rl, int sample);
void shade_sample_initialize(struct ShadeSample *ssamp, struct RenderPart *pa, struct RenderLayer *rl);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 65942a14be9..da77d578efc 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -4701,6 +4701,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
extern int slurph_opt; /* key.c */
Scene *sce;
float mat[4][4];
+ float amb[3];
unsigned int lay;
re->scene= scene;
@@ -4747,7 +4748,9 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
/* still bad... doing all */
init_render_textures(re);
- init_render_materials(re->r.mode, &re->wrld.ambr);
+ if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(amb, &re->wrld.ambr);
+ else VECCOPY(amb, &re->wrld.ambr);
+ init_render_materials(re->r.mode, amb);
set_node_shader_lamp_loop(shade_material_loop);
/* MAKE RENDER DATA */
@@ -5358,6 +5361,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
{
float mat[4][4];
+ float amb[3];
unsigned int lay;
int onlyselected, nolamps;
@@ -5419,9 +5423,13 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
/* still bad... doing all */
init_render_textures(re);
- init_render_materials(re->r.mode, &re->wrld.ambr);
+
+ if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(amb, &re->wrld.ambr);
+ else VECCOPY(amb, &re->wrld.ambr);
+ init_render_materials(re->r.mode, amb);
+
set_node_shader_lamp_loop(shade_material_loop);
-
+
/* MAKE RENDER DATA */
nolamps= !ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW);
onlyselected= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 3ef50af53c2..bdf327d6638 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2543,13 +2543,16 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
int ok;
- /* if not exists, BKE_write_ibuf makes one */
+ /* if not exists, BKE_write_ibuf makes one */
ibuf->rect= (unsigned int *)rres.rect32;
ibuf->rect_float= rres.rectf;
ibuf->zbuf_float= rres.rectz;
/* float factor for random dither, imbuf takes care of it */
ibuf->dither= scene->r.dither_intensity;
+ /* gamma correct to sRGB color space */
+ if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
+ ibuf->profile = IB_PROFILE_SRGB;
ok= BKE_write_ibuf(scene, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index af6093ab36c..75a2ab257f4 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -43,6 +43,7 @@
#include "DNA_texture_types.h"
#include "DNA_lamp_types.h"
+#include "BKE_colortools.h"
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_material.h"
@@ -58,6 +59,7 @@
#include "rendercore.h"
#include "shadbuf.h"
#include "pixelshading.h"
+#include "shading.h"
#include "sunsky.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -536,9 +538,15 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th
blend= fabs(0.5+ view[1]);
}
- hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb;
- zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb;
-
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ color_manage_linearize(hor, &R.wrld.horr);
+ color_manage_linearize(zen, &R.wrld.zenr);
+ }
+ else {
+ VECCOPY(hor, &R.wrld.horr);
+ VECCOPY(zen, &R.wrld.zenr);
+ }
+
/* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */
/* SKYBLEND is active, the texture and color blend are added. */
if(R.wrld.skytype & WO_SKYTEX) {
@@ -625,9 +633,11 @@ void shadeSkyPixel(float *collector, float fx, float fy, short thread)
}
else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/* 2. solid color */
- collector[0] = R.wrld.horr;
- collector[1] = R.wrld.horg;
- collector[2] = R.wrld.horb;
+ if(R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
+ color_manage_linearize(collector, &R.wrld.horr);
+ else
+ VECCOPY(collector, &R.wrld.horr);
+
collector[3] = 0.0f;
}
else {
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 33b58cf9751..df74e88e87e 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -225,8 +225,7 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
shi->obr= obi->obr;
shi->vlr= vlr;
shi->mat= vlr->mat;
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
- shi->har= shi->mat->har;
+ shade_input_init_material(shi);
// Osa structs we leave unchanged now
SWAP(int, osatex, shi->osatex);
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 165cb88de71..3a3d6f57830 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1515,9 +1515,7 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe
shi->mat= mat;
/* init material vars */
- // note, keep this synced with render_types.h
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
- shi->har= shi->mat->har;
+ shade_input_init_material(shi);
/* render */
shade_input_set_shade_texco(shi);
@@ -1950,10 +1948,7 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
if(shi->mat->nodetree && shi->mat->use_nodes)
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
else {
- /* copy all relevant material vars, note, keep this synced with render_types.h */
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
- shi->har= shi->mat->har;
-
+ shade_input_init_material(shi);
shade_material_loop(shi, shr);
}
}
@@ -2104,9 +2099,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int
ShadeResult shr;
VlakRen *vlr= shi->vlr;
- /* init material vars */
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
- shi->har= shi->mat->har;
+ shade_input_init_material(shi);
if(bs->type==RE_BAKE_AO) {
ambient_occlusion(shi);
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 1cd8ec110f9..931595eae60 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -39,6 +39,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
+#include "BKE_colortools.h"
#include "BKE_utildefines.h"
#include "BKE_node.h"
@@ -84,11 +85,45 @@ extern struct Render R;
*/
+/* initialise material variables in shadeinput,
+ * doing inverse gamma correction where applicable */
+void shade_input_init_material(ShadeInput *shi)
+{
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ color_manage_linearize(&shi->r, &shi->mat->r);
+ color_manage_linearize(&shi->specr, &shi->mat->specr);
+ color_manage_linearize(&shi->mirr, &shi->mat->mirr);
+
+ /* material ambr / ambg / ambb is overwritten from world
+ color_manage_linearize(shi->ambr, shi->mat->ambr);
+ */
+
+ /* note, keep this synced with render_types.h */
+ memcpy(&shi->amb, &shi->mat->amb, 11*sizeof(float));
+ shi->har= shi->mat->har;
+ } else {
+ /* note, keep this synced with render_types.h */
+ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
+ shi->har= shi->mat->har;
+ }
+
+}
+
+static void shadeinput_colors_linearize(ShadeInput *shi)
+{
+ color_manage_linearize(&shi->r, &shi->r);
+ color_manage_linearize(&shi->specr, &shi->specr);
+ color_manage_linearize(&shi->mirr, &shi->mirr);
+}
/* also used as callback for nodes */
/* delivers a fully filled in ShadeResult, for all passes */
void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
{
+ /* because node materials don't have access to rendering context,
+ * inverse gamma correction must happen here. evil. */
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT && shi->nodes == 1)
+ shadeinput_colors_linearize(shi);
shade_lamp_loop(shi, shr); /* clears shr */
@@ -96,9 +131,7 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
ShadeResult shr_t;
float fac= shi->translucency;
- /* gotta copy it again */
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
- shi->har= shi->mat->har;
+ shade_input_init_material(shi);
VECCOPY(shi->vn, shi->vno);
VECMUL(shi->vn, -1.0f);
@@ -148,8 +181,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
}
else {
/* copy all relevant material vars, note, keep this synced with render_types.h */
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
- shi->har= shi->mat->har;
+ shade_input_init_material(shi);
shade_material_loop(shi, shr);
}
@@ -571,6 +603,13 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
/* not supported */
}
}
+
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
+ color_manage_linearize(shi->vcol, shi->vcol);
+ }
+ }
+
}
/* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
@@ -1240,6 +1279,12 @@ void shade_input_set_shade_texco(ShadeInput *shi)
} /* else {
Note! For raytracing winco is not set, important because thus means all shader input's need to have their variables set to zero else in-initialized values are used
*/
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
+ color_manage_linearize(shi->vcol, shi->vcol);
+ }
+ }
+
}
/* ****************** ShadeSample ************************************** */
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 7bb2aef2e6e..bd022e768f8 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -55,6 +55,7 @@
#include "DNA_material_types.h"
+#include "BKE_colortools.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -916,7 +917,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
if(!re->test_break(re->tbh)) {
SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData");
float ior= mat->sss_ior, cfac= mat->sss_colfac;
- float *col= mat->sss_col, *radius= mat->sss_radius;
+ float col[3], *radius= mat->sss_radius;
float fw= mat->sss_front, bw= mat->sss_back;
float error = mat->sss_error;
@@ -924,6 +925,9 @@ static void sss_create_tree_mat(Render *re, Material *mat)
if((re->r.scemode & R_PREVIEWBUTS) && error < 0.5f)
error= 0.5f;
+ if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(col, mat->sss_col);
+ else VECCOPY(col, mat->sss_col);
+
sss->ss[0]= scatter_settings_new(col[0], radius[0], ior, cfac, fw, bw);
sss->ss[1]= scatter_settings_new(col[1], radius[1], ior, cfac, fw, bw);
sss->ss[2]= scatter_settings_new(col[2], radius[2], ior, cfac, fw, bw);
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 3c8c1640b75..a47fef840ca 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -281,9 +281,7 @@ void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, Str
shade_input_set_strand_texco(shi, sseg->strand, sseg->v[1], spoint);
/* init material vars */
- // note, keep this synced with render_types.h
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
- shi->har= shi->mat->har;
+ shade_input_init_material(shi);
/* shade */
shade_samples_do_AO(ssamp);
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index d9fc075c1c4..e11bb0004b2 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -48,6 +48,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "BKE_colortools.h"
#include "BKE_image.h"
#include "BKE_node.h"
#include "BKE_plugin_types.h"
@@ -1808,6 +1809,11 @@ void do_material_tex(ShadeInput *shi)
}
else texres.tin= texres.ta;
+ /* inverse gamma correction */
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ color_manage_linearize(tcol, tcol);
+ }
+
if(mtex->mapto & MAP_COL) {
texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype);
}
@@ -2127,6 +2133,11 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
}
else texres.tin= texres.ta;
+ /* inverse gamma correction */
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ color_manage_linearize(&texres.tr, &texres.tr);
+ }
+
fact= texres.tin*mtex->colfac;
facm= 1.0-fact;
@@ -2314,6 +2325,11 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb;
+ /* inverse gamma correction */
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ color_manage_linearize(tcol, tcol);
+ }
+
if(mtex->mapto & WOMAP_HORIZ) {
texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype);
}
@@ -2496,6 +2512,11 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef
}
else texres.tin= texres.ta;
+ /* inverse gamma correction */
+ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ color_manage_linearize(&texres.tr, &texres.tr);
+ }
+
/* lamp colors were premultiplied with this */
col[0]= texres.tr*la->energy;
col[1]= texres.tg*la->energy;