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:
authorThomas Dinges <blender@dingto.org>2014-01-27 22:58:54 +0400
committerThomas Dinges <blender@dingto.org>2014-01-27 22:59:06 +0400
commite983ed6aaa4d32326163ffc281d7ad4ade617674 (patch)
tree69e65eb5a7b1797bbece55c40648ccef4c824286 /source/blender/render
parent15e08394a0650ff1837124eea303340cc87d7879 (diff)
Revert the removal of Blender Internal Edge rendering, after artist feedback.
This reverts commit fb91a602c756f3ee5a122efa1862b8be7604186b.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/source/initrender.c2
-rw-r--r--source/blender/render/intern/source/pipeline.c7
-rw-r--r--source/blender/render/intern/source/rendercore.c130
3 files changed, 133 insertions, 6 deletions
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 28932d0e93b..2fb723faa12 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -608,7 +608,7 @@ void RE_parts_init(Render *re, int do_crop)
RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part");
/* Non-box filters need 2 pixels extra to work */
- if (do_crop && re->r.filtertype) {
+ if (do_crop && (re->r.filtertype || (re->r.mode & R_EDGE))) {
pa->crop = 2;
disprect.xmin -= pa->crop;
disprect.ymin -= pa->crop;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 0577ee60842..ec2644e4d9b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2414,6 +2414,13 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r
BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path");
return 0;
}
+
+ /* no fullsample and edge */
+ if ((scemode & R_FULL_SAMPLE) && (scene->r.mode & R_EDGE)) {
+ BKE_report(reports, RPT_ERROR, "Full sample does not support edge enhance");
+ return 0;
+ }
+
}
if (scemode & R_DOCOMP) {
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 2fb956ee3a6..1fb65a4782e 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -967,6 +967,25 @@ static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int ma
ps->shadfac= 0;
}
+static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
+{
+ float addcol[4];
+ int pix;
+
+ if (arect==NULL)
+ return;
+
+ for (pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
+ if (*arect != 0.0f) {
+ addcol[0]= *arect * R.r.edgeR;
+ addcol[1]= *arect * R.r.edgeG;
+ addcol[2]= *arect * R.r.edgeB;
+ addcol[3]= *arect;
+ addAlphaOverFloat(rectf, addcol);
+ }
+ }
+}
+
/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
{
@@ -991,6 +1010,67 @@ static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
}
}
+/* adds only alpha values */
+static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
+{
+ /* use zbuffer to define edges, add it to the image */
+ int y, x, col, *rz, *rz1, *rz2, *rz3;
+ int zval1, zval2, zval3;
+ float *rf;
+
+ /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
+ rz= rectz;
+ if (rz==NULL) return;
+
+ for (y=0; y<pa->recty; y++)
+ for (x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
+
+ rz1= rectz;
+ rz2= rz1+pa->rectx;
+ rz3= rz2+pa->rectx;
+
+ rf= rectf+pa->rectx+1;
+
+ for (y=0; y<pa->recty-2; y++) {
+ for (x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
+
+ /* prevent overflow with sky z values */
+ zval1= rz1[0] + 2*rz1[1] + rz1[2];
+ zval2= 2*rz2[0] + 2*rz2[2];
+ zval3= rz3[0] + 2*rz3[1] + rz3[2];
+
+ col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
+ if (col<0) col= -col;
+
+ col >>= 5;
+ if (col > (1<<16)) col= (1<<16);
+ else col= (R.r.edgeint*col)>>8;
+
+ if (col>0) {
+ float fcol;
+
+ if (col>255) fcol= 1.0f;
+ else fcol= (float)col/255.0f;
+
+ if (R.osa)
+ *rf+= fcol/(float)R.osa;
+ else
+ *rf= fcol;
+ }
+ }
+ rz1+= 2;
+ rz2+= 2;
+ rz3+= 2;
+ rf+= 2;
+ }
+
+ /* shift back zbuf values, we might need it still */
+ rz= rectz;
+ for (y=0; y<pa->recty; y++)
+ for (x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
+
+}
+
static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
{
/* for all pixels with max speed, set to zero */
@@ -1069,6 +1149,7 @@ static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dma
typedef struct ZbufSolidData {
RenderLayer *rl;
ListBase *psmlist;
+ float *edgerect;
} ZbufSolidData;
static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
@@ -1090,6 +1171,10 @@ static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *da
}
}
}
+
+ if (sdata->rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edge_enhance_tile(pa, sdata->edgerect, zspan->rectz);
}
/* main call for shading Delta Accum, for OSA */
@@ -1099,6 +1184,7 @@ void zbufshadeDA_tile(RenderPart *pa)
RenderResult *rr= pa->result;
RenderLayer *rl;
ListBase psmlist= {NULL, NULL};
+ float *edgerect= NULL;
/* allocate the necessary buffers */
/* zbuffer inits these rects */
@@ -1109,16 +1195,21 @@ void zbufshadeDA_tile(RenderPart *pa)
if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
- /* initialize pixelstructs */
+ /* initialize pixelstructs and edge buffer */
addpsmain(&psmlist);
pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd");
+ if (rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
+
/* always fill visibility */
for (pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
ZbufSolidData sdata;
sdata.rl= rl;
sdata.psmlist= &psmlist;
+ sdata.edgerect= edgerect;
zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
if (R.test_break(R.tbh)) break;
}
@@ -1185,12 +1276,18 @@ void zbufshadeDA_tile(RenderPart *pa)
}
/* sun/sky */
- if (rl->layflag & SCE_LAY_SKY) {
+ if (rl->layflag & SCE_LAY_SKY)
atm_tile(pa, rl);
+
+ /* sky before edge */
+ if (rl->layflag & SCE_LAY_SKY)
sky_tile(pa, rl);
- }
- /* extra layers */
+ /* extra layers */
+ if (rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edge_enhance_add(pa, rl->rectf, edgerect);
+
if (rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
@@ -1200,6 +1297,9 @@ void zbufshadeDA_tile(RenderPart *pa)
/* free stuff within loop! */
MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
freeps(&psmlist);
+
+ if (edgerect) MEM_freeN(edgerect);
+ edgerect= NULL;
if (pa->rectmask) {
MEM_freeN(pa->rectmask);
@@ -1228,6 +1328,7 @@ void zbufshade_tile(RenderPart *pa)
RenderResult *rr= pa->result;
RenderLayer *rl;
PixStr ps;
+ float *edgerect= NULL;
/* fake pixel struct, to comply to osa render */
ps.next= NULL;
@@ -1249,6 +1350,14 @@ void zbufshade_tile(RenderPart *pa)
if (!R.test_break(R.tbh)) { /* NOTE: this if () is not consistent */
+ /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
+ if (rl->layflag & SCE_LAY_EDGE) {
+ if (R.r.mode & R_EDGE) {
+ edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
+ edge_enhance_tile(pa, edgerect, pa->rectz);
+ }
+ }
+
/* initialize scanline updates for main thread */
rr->renrect.ymin = 0;
rr->renlay= rl;
@@ -1329,13 +1438,24 @@ void zbufshade_tile(RenderPart *pa)
}
/* sun/sky */
- if (rl->layflag & SCE_LAY_SKY) {
+ if (rl->layflag & SCE_LAY_SKY)
atm_tile(pa, rl);
+
+ /* sky before edge */
+ if (rl->layflag & SCE_LAY_SKY)
sky_tile(pa, rl);
+
+ if (!R.test_break(R.tbh)) {
+ if (rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edge_enhance_add(pa, rl->rectf, edgerect);
}
if (rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
+
+ if (edgerect) MEM_freeN(edgerect);
+ edgerect= NULL;
if (pa->rectmask) {
MEM_freeN(pa->rectmask);