From 6d672eee9a551649d9aa134fca0b1c7a9fbe48ea Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 1 Nov 2004 15:21:50 +0000 Subject: Last new feature before release; patch provided by Goran Kocov. In DisplayButtons, Panel "Output", a new slider "Dither" allows to add random noise dither to rendered output. It works on sky as well as solid and transparent. Note however that in OSA render, the Unified Render gives much better results, since that render nicely delivers full scanlines of high definition color. The old render mode isn't well suited for this postprocess. A dither value of '1.0' will exactly add maximum of 1.0/256.0 to the pixels. Potential improvements for next releases; - regular patterns - dither per color channel - not only add, but also subtract dither Also note that this gives best results for print work or stills. Animating it gives slight visible noise. Also runlength compression wont really work, and Jpeg needs to be given higher quality too. --- source/blender/makesdna/DNA_scene_types.h | 4 ++++ source/blender/render/intern/source/rendercore.c | 22 +++++++++++++++++---- .../render/intern/source/vanillaRenderPipe.c | 23 +++++++++++++--------- source/blender/src/buttons_scene.c | 5 ++++- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 18c596f67e4..36dbd75d741 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -211,6 +211,10 @@ typedef struct RenderData { /** post-production settings. Don't really belong here */ float postmul, postgamma, postadd, postigamma; + /* Dither noise intensity */ + float dither_intensity; + float pad_dither; + /* yafray: global panel params. TODO: move elsewhere */ short GIquality, GIcache, GImethod, GIphotons, GIdirect; short YF_AA, YFexportxml, yfpad1[3]; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 0b545ed73a0..4c64af0afba 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -50,6 +50,8 @@ #include "BKE_global.h" #include "BKE_texture.h" +#include "BLI_rand.h" + /* local include */ #include "RE_callbacks.h" #include "old_zbuffer_types.h" @@ -217,15 +219,18 @@ void RE_sky(float *view, float *col) void RE_sky_char(float *view, char *col) { float f, colf[3]; + float dither_value; + + dither_value = (BLI_frand()*R.r.dither_intensity)/256.0; RE_sky(view, colf); - f= 255.0*colf[0]; + f= 255.0*(colf[0]+dither_value); if(f<=0.0) col[0]= 0; else if(f>255.0) col[0]= 255; else col[0]= (char)f; - f= 255.0*colf[1]; + f= 255.0*(colf[1]+dither_value); if(f<=0.0) col[1]= 0; else if(f>255.0) col[1]= 255; else col[1]= (char)f; - f= 255.0*colf[2]; + f= 255.0*(colf[2]+dither_value); if(f<=0.0) col[2]= 0; else if(f>255.0) col[2]= 255; else col[2]= (char)f; col[3]= 1; /* to prevent wrong optimalisation alphaover of flares */ @@ -2846,12 +2851,21 @@ void shadepixel_short(float x, float y, int vlaknr, int mask, unsigned short *sh else shortcol[2]= 65535.0*colf[2]; if(colf[3]<=0.0) shortcol[3]= 0; else if(colf[3]>=1.0) shortcol[3]= 65535; else shortcol[3]= 65535.0*colf[3]; - + if(usegamtab) { shortcol[0]= igamtab2[ shortcol[0] ]; shortcol[1]= igamtab2[ shortcol[1] ]; shortcol[2]= igamtab2[ shortcol[2] ]; } + + if(R.r.dither_intensity!=0.0) { + short dither_value = (short)(BLI_frand()*R.r.dither_intensity*256.0); + /* no dither for color 254/255, is OK. intensity is <= 2.0 */ + if( shortcol[0] < 65000) shortcol[0]+= dither_value; + if( shortcol[1] < 65000) shortcol[1]+= dither_value; + if( shortcol[2] < 65000) shortcol[2]+= dither_value; + } + } PixStr *addpsmain() diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c index 68476465da3..4e9057904de 100644 --- a/source/blender/render/intern/source/vanillaRenderPipe.c +++ b/source/blender/render/intern/source/vanillaRenderPipe.c @@ -57,6 +57,8 @@ #include "DNA_object_types.h" #include "BKE_global.h" +#include "BLI_rand.h" + /* local includes (from the render module) */ #include "RE_callbacks.h" #include "render.h" /* all kinds of stuff */ @@ -1342,27 +1344,30 @@ void zBufferFillEdge(float *vec1, float *vec2) void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target) { float fval; + float dither_value; + + dither_value = (BLI_frand()*R.r.dither_intensity)/256.0; /* alpha */ - if(buf[3]<=0.0) target[3]= 0; - else if(buf[3]>1.0) target[3]= 255; - else target[3]= 255.0*buf[3]; + if((buf[3]+dither_value)<=0.0) target[3]= 0; + else if((buf[3]+dither_value)>1.0) target[3]= 255; + else target[3]= 255.0*(buf[3]+dither_value); if(R.r.postgamma==1.0) { /* r */ - fval= R.r.postmul*buf[0] + R.r.postadd; + fval= R.r.postmul*buf[0] + R.r.postadd + dither_value; if(fval<=0.0) target[0]= 0; else if(fval>1.0) target[0]= 255; else target[0]= 255.0*fval; /* g */ - fval= R.r.postmul*buf[1] + R.r.postadd; + fval= R.r.postmul*buf[1] + R.r.postadd + dither_value; if(fval<=0.0) target[1]= 0; else if(fval>1.0) target[1]= 255; else target[1]= 255.0*fval; /* b */ - fval= R.r.postmul*buf[2] + R.r.postadd; + fval= R.r.postmul*buf[2] + R.r.postadd + dither_value; if(fval<=0.0) target[2]= 0; else if(fval>1.0) target[2]= 255; else target[2]= 255.0*fval; @@ -1376,19 +1381,19 @@ void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target) /* r */ - fval= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd; + fval= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value; if(fval<=0.0) target[0]= 0; else if(fval>1.0) target[0]= 255; else target[0]= 255.0*fval; /* g */ - fval=pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd; + fval=pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value; if(fval<=0.0) target[1]= 0; else if(fval>1.0) target[1]= 255; else target[1]= 255.0*fval; /* b */ - fval= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd; + fval= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value; if(fval<=0.0) target[2]= 0; else if(fval>1.0) target[2]= 255; else target[2]= 255.0*fval; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index bb5821682d5..b727064f767 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1031,14 +1031,17 @@ static void render_panel_output(void) uiDefButS(block, TOG|BIT|(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &R.winpos, 0, 0, 0, 0, "Render window placement on screen"); uiBlockEndAlign(block); - uiDefButS(block, TOG|BIT|2, REDRAWVIEW3D, "Passepartout", 72, 30, 122, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Draws darkened passepartout in camera view"); uiBlockBeginAlign(block); + uiDefButS(block, TOG|BIT|2, REDRAWVIEW3D, "Passepartout", 72, 30, 122, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Draws darkened passepartout in camera view"); uiDefButS(block, ROW, B_REDR, "DispWin", 72, 10, 60, 20, &R.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output to display in a seperate window"); uiDefButS(block, ROW, B_REDR, "DispView", 134, 10, 60, 20, &R.displaymode, 0.0, (float)R_DISPLAYVIEW, 0, 0, "Sets render output to display in 3D view"); uiBlockEndAlign(block); uiDefButS(block, TOG|BIT|4, 0, "Extensions", 250, 10, 60, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); + /* Dither control */ + uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 1.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); + /* Toon shading buttons */ uiBlockBeginAlign(block); uiDefButI(block, TOG|BIT|5, 0,"Edge", 155, 94, 44, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon shading"); -- cgit v1.2.3