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
path: root/intern
diff options
context:
space:
mode:
authorMai Lavelle <mai.lavelle@gmail.com>2016-04-11 23:49:09 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2016-04-12 00:12:11 +0300
commitebfdd7da83200f2890b28dd5ef9a0fc8c6ab9137 (patch)
tree8ccb1ad1af787ccf3d186b687324e4056f9665df /intern
parent7d033717ad52bf92235e65224b6b3940de7ec473 (diff)
Cycles microdisplacement: perform subdivision dicing in raster space
NOTE: this is only the first of many patches towards completing the subdivison and displacement system in Cycles. These patches will be reviewed and committed one by one over the coming weeks. Reviewed By: brecht, sergey Differential Revision: https://developer.blender.org/D1909
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/addon/properties.py4
-rw-r--r--intern/cycles/blender/blender_camera.cpp6
-rw-r--r--intern/cycles/blender/blender_mesh.cpp10
-rw-r--r--intern/cycles/render/camera.cpp40
-rw-r--r--intern/cycles/render/camera.h8
-rw-r--r--intern/cycles/subd/subd_dice.cpp5
-rw-r--r--intern/cycles/subd/subd_dice.h1
-rw-r--r--intern/cycles/subd/subd_split.cpp54
-rw-r--r--intern/cycles/subd/subd_split.h2
9 files changed, 117 insertions, 13 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 01aa619b306..3b5755e8062 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="Size 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 5bc9dfc7904..6b459ae575f 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->full_width = width;
+ cam->full_height = 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 9eb4626eb3c..48c14a34aad 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 0e343822223..028916c1b8f 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -158,12 +158,15 @@ void Camera::update()
/* ndc to raster */
Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
+ Transform full_ndctoraster = transform_scale(full_width, full_height, 1.0f) * bordertofull;
/* raster to screen */
Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
Transform screentoraster = ndctoraster * screentondc;
Transform rastertoscreen = transform_inverse(screentoraster);
+ Transform full_screentoraster = full_ndctoraster * screentondc;
+ Transform full_rastertoscreen = transform_inverse(full_screentoraster);
/* screen to camera */
Transform cameratoscreen;
@@ -177,6 +180,7 @@ void Camera::update()
Transform screentocamera = transform_inverse(cameratoscreen);
rastertocamera = screentocamera * rastertoscreen;
+ Transform full_rastertocamera = screentocamera * full_rastertoscreen;
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));
+ full_dx = transform_direction(&full_rastertocamera, make_float3(1, 0, 0));
+ full_dy = transform_direction(&full_rastertocamera, 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));
+ full_dx = transform_perspective(&full_rastertocamera, make_float3(1, 0, 0)) -
+ transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
+ full_dy = transform_perspective(&full_rastertocamera, make_float3(0, 1, 0)) -
+ transform_perspective(&full_rastertocamera, 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);
+ full_dx = transform_direction(&cameratoworld, full_dx);
+ full_dy = transform_direction(&cameratoworld, full_dy);
/* TODO(sergey): Support other types of camera. */
if(type == CAMERA_PERSPECTIVE) {
@@ -539,4 +551,32 @@ BoundBox Camera::viewplane_bounds_get()
return bounds;
}
+float Camera::world_to_raster_size(float3 P)
+{
+ if(type == CAMERA_ORTHOGRAPHIC) {
+ return min(len(full_dx), len(full_dy));
+ }
+ 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(full_dx) < len_squared(full_dy) ? full_dx : full_dy;
+ 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 6fbb1dc3bc8..684b4458dfc 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -120,6 +120,8 @@ public:
int width, height;
int resolution;
BoundBox2D viewplane;
+ /* width and height change during preview, so we need these for calculating dice rates. */
+ int full_width, full_height;
/* border */
BoundBox2D border;
@@ -151,6 +153,9 @@ public:
float3 dx;
float3 dy;
+ float3 full_dx;
+ float3 full_dy;
+
/* update */
bool need_update;
bool need_device_update;
@@ -176,6 +181,9 @@ public:
/* Public utility functions. */
BoundBox viewplane_bounds_get();
+ /* Calculates the width of a pixel at point in world space. */
+ float world_to_raster_size(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 44bab066dde..301f30c8d95 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 b7e61748779..2b11e4b0bf5 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 df4d451e8eb..095eefeab22 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -46,13 +46,13 @@ void DiagSplit::dispatch(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors&
edgefactors_triangle.push_back(ef);
}
-float3 DiagSplit::project(Patch *patch, float2 uv)
+float3 DiagSplit::to_world(Patch *patch, float2 uv)
{
float3 P;
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;
}
@@ -66,10 +66,21 @@ int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend)
for(int i = 0; i < params.test_steps; i++) {
float t = i/(float)(params.test_steps-1);
- float3 P = project(patch, Pstart + t*(Pend - Pstart));
+ float3 P = to_world(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->world_to_raster_size((P + Plast) * 0.5f);
+ L = len(P - Plast) / pixel_width;
+ }
+
Lsum += L;
Lmax = max(L, Lmax);
}
@@ -103,6 +114,16 @@ 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) {
+ /* We should never get here, but just in case end recursion safely. */
+ ef.tu = 1;
+ ef.tv = 1;
+ ef.tw = 1;
+
+ dispatch(sub, ef);
+ return;
+ }
+
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,25 @@ void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef
void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth)
{
- if((ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM)) {
+ if(depth > 32) {
+ /* We should never get here, but just in case end recursion safely. */
+ ef.tu0 = 1;
+ ef.tu1 = 1;
+ ef.tv0 = 1;
+ ef.tv1 = 1;
+
+ dispatch(sub, ef);
+ return;
+ }
+
+ bool split_u = (ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM);
+ bool split_v = (ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM);
+
+ if(split_u && split_v) {
+ split_u = depth % 2;
+ }
+
+ if(split_u) {
/* partition edges */
QuadDice::EdgeFactors ef0, ef1;
float2 Pu0, Pu1;
@@ -212,7 +251,7 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de
split(sub0, ef0, depth+1);
split(sub1, ef1, depth+1);
}
- else if(ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM) {
+ else if(split_v) {
/* partition edges */
QuadDice::EdgeFactors ef0, ef1;
float2 Pv0, Pv1;
@@ -237,8 +276,9 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de
split(sub0, ef0, depth+1);
split(sub1, ef1, depth+1);
}
- else
+ else {
dispatch(sub, ef);
+ }
}
void DiagSplit::split_triangle(Patch *patch)
diff --git a/intern/cycles/subd/subd_split.h b/intern/cycles/subd/subd_split.h
index df4935ee624..f04c51dedfe 100644
--- a/intern/cycles/subd/subd_split.h
+++ b/intern/cycles/subd/subd_split.h
@@ -45,7 +45,7 @@ public:
DiagSplit(const SubdParams& params);
- float3 project(Patch *patch, float2 uv);
+ float3 to_world(Patch *patch, float2 uv);
int T(Patch *patch, float2 Pstart, float2 Pend);
void partition_edge(Patch *patch, float2 *P, int *t0, int *t1,
float2 Pstart, float2 Pend, int t);