[Bf-blender-cvs] [c71dd0c] temp-cycles-microdisplacement: Have dicing happen in screen space

Mai Lavelle noreply at git.blender.org
Mon Apr 11 14:54:16 CEST 2016


Commit: c71dd0c23eaa2f72a386fbba7f9fdc16a7c727a5
Author: Mai Lavelle
Date:   Sun Nov 29 04:41:41 2015 -0500
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBc71dd0c23eaa2f72a386fbba7f9fdc16a7c727a5

Have dicing happen in screen space

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

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/blender_camera.cpp
M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/render/camera.cpp
M	intern/cycles/render/camera.h
M	intern/cycles/subd/subd_dice.cpp
M	intern/cycles/subd/subd_dice.h
M	intern/cycles/subd/subd_split.cpp

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

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 01aa619..c8317d3 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -938,8 +938,8 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
                 )
         cls.dicing_rate = FloatProperty(
                 name="Dicing Rate",
-                description="",
-                min=0.001, max=1000.0,
+                description="Width of a micropolygon in pixels",
+                min=0.1, max=1000.0,
                 default=1.0,
                 )
 
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 5bc9dfc..74acfc1 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -360,6 +360,12 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
 	blender_camera_viewplane(bcam, width, height,
 		&cam->viewplane, &aspectratio, &sensor_size);
 
+	cam->width = bcam->full_width;
+	cam->height = bcam->full_height;
+
+	cam->widthorig = width;
+	cam->heightorig = height;
+
 	/* panorama sensor */
 	if(bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
 		float fit_xratio = (float)bcam->full_width*bcam->pixelaspect.x;
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9eb4626..48c14a3 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -18,6 +18,7 @@
 #include "mesh.h"
 #include "object.h"
 #include "scene.h"
+#include "camera.h"
 
 #include "blender_sync.h"
 #include "blender_session.h"
@@ -655,6 +656,7 @@ static void create_mesh(Scene *scene,
 
 static void create_subd_mesh(Scene *scene,
                              Mesh *mesh,
+                             BL::Object b_ob,
                              BL::Mesh& b_mesh,
                              PointerRNA *cmesh,
                              const vector<uint>& used_shaders)
@@ -691,8 +693,10 @@ static void create_subd_mesh(Scene *scene,
 
 	SubdParams sdparams(mesh, used_shaders[0], true, need_ptex);
 	sdparams.dicing_rate = RNA_float_get(cmesh, "dicing_rate");
-	//scene->camera->update();
-	//sdparams.camera = scene->camera;
+
+	scene->camera->update();
+	sdparams.camera = scene->camera;
+	sdparams.objecttoworld = get_transform(b_ob.matrix_world());
 
 	/* tesselate */
 	DiagSplit dsplit(sdparams);
@@ -805,7 +809,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
 		if(b_mesh) {
 			if(render_layer.use_surfaces && !hide_tris) {
 				if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
-					create_subd_mesh(scene, mesh, b_mesh, &cmesh, used_shaders);
+					create_subd_mesh(scene, mesh, b_ob, b_mesh, &cmesh, used_shaders);
 				else
 					create_mesh(scene, mesh, b_mesh, used_shaders);
 
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 0e34382..a63b7c7 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -83,8 +83,8 @@ Camera::Camera()
 	nearclip = 1e-5f;
 	farclip = 1e5f;
 
-	width = 1024;
-	height = 512;
+	width = 0;
+	height = 0;
 	resolution = 1;
 
 	viewplane.left = -((float)width/(float)height);
@@ -158,12 +158,15 @@ void Camera::update()
 
 	/* ndc to raster */
 	Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
+	Transform ndctorasterorig = transform_scale(widthorig, heightorig, 1.0f) * bordertofull;
 
 	/* raster to screen */
 	Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
 
 	Transform screentoraster = ndctoraster * screentondc;
 	Transform rastertoscreen = transform_inverse(screentoraster);
+	Transform screentorasterorig = ndctorasterorig * screentondc;
+	Transform rasterorigtoscreen = transform_inverse(screentorasterorig);
 
 	/* screen to camera */
 	Transform cameratoscreen;
@@ -177,6 +180,7 @@ void Camera::update()
 	Transform screentocamera = transform_inverse(cameratoscreen);
 
 	rastertocamera = screentocamera * rastertoscreen;
+	Transform rasterorigtocamera = screentocamera * rasterorigtoscreen;
 	cameratoraster = screentoraster * cameratoscreen;
 
 	cameratoworld = matrix;
@@ -196,12 +200,18 @@ void Camera::update()
 	if(type == CAMERA_ORTHOGRAPHIC) {
 		dx = transform_direction(&rastertocamera, make_float3(1, 0, 0));
 		dy = transform_direction(&rastertocamera, make_float3(0, 1, 0));
+		dxorig = transform_direction(&rasterorigtocamera, make_float3(1, 0, 0));
+		dyorig = transform_direction(&rasterorigtocamera, make_float3(0, 1, 0));
 	}
 	else if(type == CAMERA_PERSPECTIVE) {
 		dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
 		     transform_perspective(&rastertocamera, make_float3(0, 0, 0));
 		dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
 		     transform_perspective(&rastertocamera, make_float3(0, 0, 0));
+		dxorig = transform_perspective(&rasterorigtocamera, make_float3(1, 0, 0)) -
+		     transform_perspective(&rasterorigtocamera, make_float3(0, 0, 0));
+		dyorig = transform_perspective(&rasterorigtocamera, make_float3(0, 1, 0)) -
+		     transform_perspective(&rasterorigtocamera, make_float3(0, 0, 0));
 	}
 	else {
 		dx = make_float3(0.0f, 0.0f, 0.0f);
@@ -210,6 +220,8 @@ void Camera::update()
 
 	dx = transform_direction(&cameratoworld, dx);
 	dy = transform_direction(&cameratoworld, dy);
+	dxorig = transform_direction(&cameratoworld, dxorig);
+	dyorig = transform_direction(&cameratoworld, dyorig);
 
 	/* TODO(sergey): Support other types of camera. */
 	if(type == CAMERA_PERSPECTIVE) {
@@ -539,4 +551,32 @@ BoundBox Camera::viewplane_bounds_get()
 	return bounds;
 }
 
+float Camera::pixel_width_at_point(float3 P)
+{
+	if(type == CAMERA_ORTHOGRAPHIC) {
+		return min(len(dxorig), len(dyorig));
+	}
+	else if(type == CAMERA_PERSPECTIVE) {
+		/* calculate as if point is directly ahead of the camera */
+		float3 raster = make_float3(0.5f*width, 0.5f*height, 0.0f);
+		float3 Pcamera = transform_perspective(&rastertocamera, raster);
+
+		/* dDdx */
+		float3 Ddiff = transform_direction(&cameratoworld, Pcamera);
+		float3 dx = len_squared(dxorig) < len_squared(dyorig) ? dxorig : dyorig;
+		float3 dDdx = normalize(Ddiff + dx) - normalize(Ddiff);
+
+		/* dPdx */
+		float dist = len(transform_point(&worldtocamera, P));
+		float3 D = normalize(Ddiff);
+		return len(dist*dDdx - dot(dist*dDdx, D)*D);
+	}
+	else {
+		// TODO(mai): implement for CAMERA_PANORAMA
+		assert(!"pixel width calculation for panoramic projection not implemented yet");
+	}
+
+	return 1.0f;
+}
+
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 6fbb1dc..28d4c7f 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -118,6 +118,7 @@ public:
 
 	/* screen */
 	int width, height;
+	int widthorig, heightorig; /* width and height change during preview, so we need these for calculating dice rates */
 	int resolution;
 	BoundBox2D viewplane;
 
@@ -151,6 +152,9 @@ public:
 	float3 dx;
 	float3 dy;
 
+	float3 dxorig;
+	float3 dyorig;
+
 	/* update */
 	bool need_update;
 	bool need_device_update;
@@ -176,6 +180,9 @@ public:
 	/* Public utility functions. */
 	BoundBox viewplane_bounds_get();
 
+	/* calculates the width of a pixel at point in world space */
+	float pixel_width_at_point(float3 P);
+
 private:
 	/* Private utility functions. */
 	float3 transform_raster_to_world(float raster_x, float raster_y);
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 44bab06..54f40de 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -305,7 +305,12 @@ void QuadDice::dice(SubPatch& sub, EdgeFactors& ef)
 	int Mu = max(ef.tu0, ef.tu1);
 	int Mv = max(ef.tv0, ef.tv1);
 
+#if 0 /* doesnt work very well, especially at grazing angles */
 	float S = scale_factor(sub, ef, Mu, Mv);
+#else
+	float S = 1.0f;
+#endif
+
 	Mu = max((int)ceil(S*Mu), 2); // XXX handle 0 & 1?
 	Mv = max((int)ceil(S*Mv), 2); // XXX handle 0 & 1?
 
diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h
index b7e6174..2b11e4b 100644
--- a/intern/cycles/subd/subd_dice.h
+++ b/intern/cycles/subd/subd_dice.h
@@ -41,6 +41,7 @@ struct SubdParams {
 	int split_threshold;
 	float dicing_rate;
 	Camera *camera;
+	Transform objecttoworld;
 
 	SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true, bool ptex_ = false)
 	{
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index df4d451..14a8931 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #include "camera.h"
 #include "mesh.h"
 
@@ -52,7 +55,7 @@ float3 DiagSplit::project(Patch *patch, float2 uv)
 
 	patch->eval(&P, NULL, NULL, uv.x, uv.y);
 	if(params.camera)
-		P = transform_perspective(&params.camera->worldtoraster, P);
+		P = transform_point(&params.objecttoworld, P);
 
 	return P;
 }
@@ -69,7 +72,18 @@ int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend)
 		float3 P = project(patch, Pstart + t*(Pend - Pstart));
 
 		if(i > 0) {
-			float L = len(P - Plast);
+			float L;
+
+			if(!params.camera) {
+				L = len(P - Plast);
+			}
+			else {
+				Camera* cam = params.camera;
+
+				float pixel_width = cam->pixel_width_at_point((P + Plast) * 0.5f);
+				L = len(P - Plast) / pixel_width;
+			}
+
 			Lsum += L;
 			Lmax = max(L, Lmax);
 		}
@@ -103,6 +117,13 @@ void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2
 
 void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef, int depth)
 {
+	if(depth > 32) {
+		fprintf(stderr, "overflow while splitting patches\n");
+#ifndef NDEBUG
+		abort();
+#endif
+	}
+
 	assert(ef.tu == T(sub.patch, sub.Pv, sub.Pw));
 	assert(ef.tv == T(sub.patch, sub.Pw, sub.Pu));
 	assert(ef.tw == T(sub.patch, sub.Pu, sub.Pv));
@@ -187,7 +208,21 @@ void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef
 
 void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFac

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list