[Bf-blender-cvs] [d2134740709] master: Moved vectorblur code from render to compositor

Jeroen Bakker noreply at git.blender.org
Thu Apr 12 13:45:50 CEST 2018


Commit: d213474070965ec142b4bee8a2cc9cb18fc7dad8
Author: Jeroen Bakker
Date:   Thu Apr 12 10:27:38 2018 +0200
Branches: master
https://developer.blender.org/rBd213474070965ec142b4bee8a2cc9cb18fc7dad8

Moved vectorblur code from render to compositor

In preparation of the removal of blender internal render we
moved the vectorblur code that was placed in the render package
(legacy) to the compositor. The compositor is only using this
code even the blender internal renderer did not use the code at
all.

===================================================================

M	source/blender/compositor/operations/COM_RenderLayersProg.h
M	source/blender/compositor/operations/COM_VectorBlurOperation.cpp
M	source/blender/render/extern/include/RE_pipeline.h
M	source/blender/render/extern/include/RE_render_ext.h
M	source/blender/render/intern/source/zbuf.c
M	source/blenderplayer/bad_level_call_stubs/stubs.c

===================================================================

diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h
index 1be15906770..7cfead7e98c 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.h
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.h
@@ -30,8 +30,6 @@
 #include "BKE_image.h"
 extern "C" {
 #  include "RE_pipeline.h"
-#  include "RE_shader_ext.h"
-#  include "RE_render_ext.h"
 #  include "MEM_guardedalloc.h"
 }
 
@@ -46,7 +44,7 @@ protected:
 	 * Reference to the scene object.
 	 */
 	Scene *m_scene;
-	
+
 	/**
 	 * layerId of the layer where this operation needs to get its data from
 	 */
@@ -61,24 +59,24 @@ protected:
 	 * cached instance to the float buffer inside the layer
 	 */
 	float *m_inputBuffer;
-	
+
 	/**
 	 * renderpass where this operation needs to get its data from
 	 */
 	std::string m_passName;
-	
+
 	int m_elementsize;
 
 	/**
 	 * @brief render data used for active rendering
 	 */
 	const RenderData *m_rd;
-	
+
 	/**
 	 * Determine the output resolution. The resolution is retrieved from the Renderer
 	 */
 	void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
-	
+
 	/**
 	 * retrieve the reference to the float buffer of the renderer.
 	 */
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index 36f06e92436..bccfe025089 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -20,16 +20,30 @@
  *		Monique Dewanchand
  */
 
-#include "COM_VectorBlurOperation.h"
-#include "BLI_math.h"
-
+#include <string.h>
 #include "MEM_guardedalloc.h"
-
-// use the implementation of blender internal renderer to calculate the vector blur.
+#include "BLI_math.h"
 extern "C" {
-#  include "RE_pipeline.h"
+	#include "BLI_jitter_2d.h"
 }
+#include "COM_VectorBlurOperation.h"
 
+
+/* Defined */
+#define PASS_VECTOR_MAX	10000.0f
+
+/* Forward declarations */
+struct ZSpan;
+struct DrawBufPixel;
+void zbuf_accumulate_vecblur(
+		NodeBlurData *nbd, int xsize, int ysize, float *newrect,
+		const float *imgrect, float *vecbufrect, const float *zbufrect);
+void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop);
+void zbuf_free_span(ZSpan *zspan);
+void antialias_tagbuf(int xsize, int ysize, char *rectmove);
+
+
+/* VectorBlurOperation */
 VectorBlurOperation::VectorBlurOperation() : NodeOperation()
 {
 	this->addInputSocket(COM_DT_COLOR);
@@ -51,7 +65,7 @@ void VectorBlurOperation::initExecution()
 	this->m_inputSpeedProgram = getInputSocketReader(2);
 	this->m_cachedInstance = NULL;
 	QualityStepHelper::initExecution(COM_QH_INCREASE);
-	
+
 }
 
 void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
@@ -77,7 +91,7 @@ void *VectorBlurOperation::initializeTileData(rcti *rect)
 	if (this->m_cachedInstance) {
 		return this->m_cachedInstance;
 	}
-	
+
 	lockMutex();
 	if (this->m_cachedInstance == NULL) {
 		MemoryBuffer *tile = (MemoryBuffer *)this->m_inputImageProgram->initializeTileData(rect);
@@ -114,6 +128,690 @@ void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputIma
 	blurdata.minspeed = this->m_settings->minspeed;
 	blurdata.curved = this->m_settings->curved;
 	blurdata.fac = this->m_settings->fac;
-	RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
+	zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
 	return;
 }
+
+/* ****************** Spans ******************************* */
+/* span fill in method, is also used to localize data for zbuffering */
+typedef struct ZSpan {
+	/* range for clipping */
+	int rectx, recty;
+
+	/* actual filled in range */
+	int miny1, maxy1, miny2, maxy2;
+	/* vertex pointers detect min/max range in */
+	const float *minp1, *maxp1, *minp2, *maxp2;
+	float *span1, *span2;
+
+	/* transform from hoco to zbuf co */
+	float zmulx, zmuly, zofsx, zofsy;
+
+	int *rectz;
+	DrawBufPixel* rectdraw;
+	float clipcrop;
+
+} ZSpan;
+
+/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
+void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
+{
+	memset(zspan, 0, sizeof(ZSpan));
+
+	zspan->rectx= rectx;
+	zspan->recty= recty;
+
+	zspan->span1= (float*)MEM_mallocN(recty*sizeof(float), "zspan");
+	zspan->span2= (float*)MEM_mallocN(recty*sizeof(float), "zspan");
+
+	zspan->clipcrop= clipcrop;
+}
+
+void zbuf_free_span(ZSpan *zspan)
+{
+	if (zspan) {
+		if (zspan->span1) MEM_freeN(zspan->span1);
+		if (zspan->span2) MEM_freeN(zspan->span2);
+		zspan->span1= zspan->span2= NULL;
+	}
+}
+
+/* reset range for clipping */
+static void zbuf_init_span(ZSpan *zspan)
+{
+	zspan->miny1= zspan->miny2= zspan->recty+1;
+	zspan->maxy1= zspan->maxy2= -1;
+	zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL;
+}
+
+static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
+{
+	const float *minv, *maxv;
+	float *span;
+	float xx1, dx0, xs0;
+	int y, my0, my2;
+
+	if (v1[1]<v2[1]) {
+		minv= v1; maxv= v2;
+	}
+	else {
+		minv= v2; maxv= v1;
+	}
+
+	my0= ceil(minv[1]);
+	my2= floor(maxv[1]);
+
+	if (my2<0 || my0>= zspan->recty) return;
+
+	/* clip top */
+	if (my2>=zspan->recty) my2= zspan->recty-1;
+	/* clip bottom */
+	if (my0<0) my0= 0;
+
+	if (my0>my2) return;
+	/* if (my0>my2) should still fill in, that way we get spans that skip nicely */
+
+	xx1= maxv[1]-minv[1];
+	if (xx1>FLT_EPSILON) {
+		dx0= (minv[0]-maxv[0])/xx1;
+		xs0= dx0*(minv[1]-my2) + minv[0];
+	}
+	else {
+		dx0 = 0.0f;
+		xs0 = min_ff(minv[0], maxv[0]);
+	}
+
+	/* empty span */
+	if (zspan->maxp1 == NULL) {
+		span= zspan->span1;
+	}
+	else {	/* does it complete left span? */
+		if ( maxv == zspan->minp1 || minv==zspan->maxp1) {
+			span= zspan->span1;
+		}
+		else {
+			span= zspan->span2;
+		}
+	}
+
+	if (span==zspan->span1) {
+//		printf("left span my0 %d my2 %d\n", my0, my2);
+		if (zspan->minp1==NULL || zspan->minp1[1] > minv[1] ) {
+			zspan->minp1= minv;
+		}
+		if (zspan->maxp1==NULL || zspan->maxp1[1] < maxv[1] ) {
+			zspan->maxp1= maxv;
+		}
+		if (my0<zspan->miny1) zspan->miny1= my0;
+		if (my2>zspan->maxy1) zspan->maxy1= my2;
+	}
+	else {
+//		printf("right span my0 %d my2 %d\n", my0, my2);
+		if (zspan->minp2==NULL || zspan->minp2[1] > minv[1] ) {
+			zspan->minp2= minv;
+		}
+		if (zspan->maxp2==NULL || zspan->maxp2[1] < maxv[1] ) {
+			zspan->maxp2= maxv;
+		}
+		if (my0<zspan->miny2) zspan->miny2= my0;
+		if (my2>zspan->maxy2) zspan->maxy2= my2;
+	}
+
+	for (y=my2; y>=my0; y--, xs0+= dx0) {
+		/* xs0 is the xcoord! */
+		span[y]= xs0;
+	}
+}
+
+/* ******************** VECBLUR ACCUM BUF ************************* */
+
+typedef struct DrawBufPixel {
+	const float *colpoin;
+	float alpha;
+} DrawBufPixel;
+
+
+static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4)
+{
+	DrawBufPixel *rectpofs, *rp;
+	double zxd, zyd, zy0, zverg;
+	float x0, y0, z0;
+	float x1, y1, z1, x2, y2, z2, xx1;
+	const float *span1, *span2;
+	float *rectzofs, *rz;
+	int x, y;
+	int sn1, sn2, rectx, my0, my2;
+
+	/* init */
+	zbuf_init_span(zspan);
+
+	/* set spans */
+	zbuf_add_to_span(zspan, v1, v2);
+	zbuf_add_to_span(zspan, v2, v3);
+	zbuf_add_to_span(zspan, v3, v4);
+	zbuf_add_to_span(zspan, v4, v1);
+
+	/* clipped */
+	if (zspan->minp2==NULL || zspan->maxp2==NULL) return;
+
+	my0 = max_ii(zspan->miny1, zspan->miny2);
+	my2 = min_ii(zspan->maxy1, zspan->maxy2);
+
+	//	printf("my %d %d\n", my0, my2);
+	if (my2<my0) return;
+
+	/* ZBUF DX DY, in floats still */
+	x1= v1[0]- v2[0];
+	x2= v2[0]- v3[0];
+	y1= v1[1]- v2[1];
+	y2= v2[1]- v3[1];
+	z1= v1[2]- v2[2];
+	z2= v2[2]- v3[2];
+	x0= y1*z2-z1*y2;
+	y0= z1*x2-x1*z2;
+	z0= x1*y2-y1*x2;
+
+	if (z0==0.0f) return;
+
+	xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
+
+	zxd= -(double)x0/(double)z0;
+	zyd= -(double)y0/(double)z0;
+	zy0= ((double)my2)*zyd + (double)xx1;
+
+	/* start-offset in rect */
+	rectx= zspan->rectx;
+	rectzofs= (float *)(zspan->rectz + rectx*my2);
+	rectpofs= ((DrawBufPixel *)zspan->rectdraw) + rectx*my2;
+
+	/* correct span */
+	sn1= (my0 + my2)/2;
+	if (zspan->span1[sn1] < zspan->span2[sn1]) {
+		span1= zspan->span1+my2;
+		span2= zspan->span2+my2;
+	}
+	else {
+		span1= zspan->span2+my2;
+		span2= zspan->span1+my2;
+	}
+
+	for (y=my2; y>=my0; y--, span1--, span2--) {
+
+		sn1= floor(*span1);
+		sn2= floor(*span2);
+		sn1++;
+
+		if (sn2>=rectx) sn2= rectx-1;
+		if (sn1<0) sn1= 0;
+
+		if (sn2>=sn1) {
+			zverg= (double)sn1*zxd + zy0;
+			rz= rectzofs+sn1;
+			rp= rectpofs+sn1;
+			x= sn2-sn1;
+
+			while (x>=0) {
+				if (zverg < (double)*rz) {
+					*rz= zverg;
+					*rp= *col;
+				}
+				zverg+= zxd;
+				rz++;
+				rp++;
+				x--;
+			}
+		}
+
+		zy0-=zyd;
+		rectzofs-= rectx;
+		rectpofs-= rectx;
+	}
+}
+
+/* char value==255 is filled in, rest should be zero */
+/* returns alpha values, but sets alpha to 1 for zero alpha pixels that have an alpha value as neighbor */
+void antialias_tagbuf(int xsize, int ysize, char *rectmove)
+{
+	char *row1, *row2, *row3;
+	char prev, next;
+	int a, x, y, step;
+
+	/* 1: tag pixels to be candidate for AA */
+	for (y=2; y<ysize; y++) {
+		/* setup rows */
+		row1= rectmove + (y-2)*xsize;
+		row2= row1 + xsize;
+		row3= row2 + xsize;
+		for (x=2; x<xsize; x++, row1++, row2++, row3++) {
+			if (row2[1]) {
+				if (row2[0]==0 || row2[2]==0 || row1[1]==0 || row3[1]==0)
+					row2[1]= 128;
+			}
+		}
+	}
+
+	/* 2: evaluate horizontal scanlines and calculate alphas */
+	row1= rectmove;
+	for (y=0; y<ysize; y++) {
+		row1++;
+		for (x=1; x<xsize; x++, row1++) {
+			if (row1[0]==128 && row1[1]==128) {
+				/* find previous color and next color and amount of steps to blend */
+				prev= row1[-1];
+				step= 1;
+				while (x+step<xsize && row1[step]==128)
+					step++;
+
+				if (x+step!=xsize) {
+					/* now we can blend values */
+					next= row1[step];
+
+					/* note, prev value can be next value, but we

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list