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:
authorMai Lavelle <mai.lavelle@gmail.com>2016-04-13 02:17:34 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2016-04-13 02:37:33 +0300
commitc1a27a76cf9f40ab9dabb5888ee535e585444fcd (patch)
treeda5610d92bae46bc9f5682ea934f23d689a20a3b /intern/cycles/subd
parent068ee2cd98fc987453cd50285c387c6480c6d99c (diff)
Cycles microdisplacement: preserve smooth normals for linear subdivison
This way we prevent cracks in the model due to discontinuous normals, by using smooth normals for displacement instead of always getting flat normals after linear subdivision. Reviewed By: brecht Differential Revision: https://developer.blender.org/D1916
Diffstat (limited to 'intern/cycles/subd')
-rw-r--r--intern/cycles/subd/subd_dice.cpp9
-rw-r--r--intern/cycles/subd/subd_patch.cpp29
-rw-r--r--intern/cycles/subd/subd_patch.h10
-rw-r--r--intern/cycles/subd/subd_split.cpp2
4 files changed, 36 insertions, 14 deletions
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 301f30c8d95..4f27eaf7d1b 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -58,10 +58,9 @@ void EdgeDice::reserve(int num_verts, int num_tris)
int EdgeDice::add_vert(Patch *patch, float2 uv)
{
- float3 P, N, dPdu, dPdv;
+ float3 P, N;
- patch->eval(&P, &dPdu, &dPdv, uv.x, uv.y);
- N = normalize(cross(dPdu, dPdv));
+ patch->eval(&P, NULL, NULL, &N, uv.x, uv.y);
assert(vert_offset < params.mesh->verts.size());
@@ -81,7 +80,7 @@ int EdgeDice::add_vert(Patch *patch, float2 uv)
void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2)
{
- params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth);
+ params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth, false);
if(params.ptex) {
Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
@@ -159,7 +158,7 @@ float3 QuadDice::eval_projected(SubPatch& sub, float u, float v)
float2 uv = map_uv(sub, u, v);
float3 P;
- sub.patch->eval(&P, NULL, NULL, uv.x, uv.y);
+ sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
if(params.camera)
P = transform_perspective(&params.camera->worldtoraster, P);
diff --git a/intern/cycles/subd/subd_patch.cpp b/intern/cycles/subd/subd_patch.cpp
index 0db46ec492d..3b0fb5b9f3a 100644
--- a/intern/cycles/subd/subd_patch.cpp
+++ b/intern/cycles/subd/subd_patch.cpp
@@ -57,7 +57,7 @@ static void decasteljau_bicubic(float3 *P, float3 *du, float3 *dv, const float3
/* Linear Quad Patch */
-void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v)
+void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
{
float3 d0 = interp(hull[0], hull[1], u);
float3 d1 = interp(hull[2], hull[3], u);
@@ -68,6 +68,10 @@ void LinearQuadPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float
*dPdu = interp(hull[1] - hull[0], hull[3] - hull[2], v);
*dPdv = interp(hull[2] - hull[0], hull[3] - hull[1], u);
}
+
+ if(N) {
+ *N = normalize(interp(interp(normals[0], normals[1], u), interp(normals[2], normals[3], u), v));
+ }
}
BoundBox LinearQuadPatch::bound()
@@ -82,7 +86,7 @@ BoundBox LinearQuadPatch::bound()
/* Linear Triangle Patch */
-void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v)
+void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
{
*P = u*hull[0] + v*hull[1] + (1.0f - u - v)*hull[2];
@@ -90,6 +94,10 @@ void LinearTrianglePatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, f
*dPdu = hull[0] - hull[2];
*dPdv = hull[1] - hull[2];
}
+
+ if(N) {
+ *N = normalize(u*normals[0] + v*normals[1] + (1.0f - u - v)*normals[2]);
+ }
}
BoundBox LinearTrianglePatch::bound()
@@ -104,9 +112,22 @@ BoundBox LinearTrianglePatch::bound()
/* Bicubic Patch */
-void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v)
+void BicubicPatch::eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
{
- decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
+ if (N) {
+ float3 dPdu_, dPdv_;
+ decasteljau_bicubic(P, &dPdu_, &dPdv_, hull, u, v);
+
+ if (dPdu && dPdv) {
+ *dPdu = dPdu_;
+ *dPdv = dPdv_;
+ }
+
+ *N = normalize(cross(dPdu_, dPdv_));
+ }
+ else {
+ decasteljau_bicubic(P, dPdu, dPdv, hull, u, v);
+ }
}
BoundBox BicubicPatch::bound()
diff --git a/intern/cycles/subd/subd_patch.h b/intern/cycles/subd/subd_patch.h
index 9be4606c248..bfa04412c66 100644
--- a/intern/cycles/subd/subd_patch.h
+++ b/intern/cycles/subd/subd_patch.h
@@ -25,7 +25,7 @@ CCL_NAMESPACE_BEGIN
class Patch {
public:
virtual ~Patch() {}
- virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v) = 0;
+ virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v) = 0;
virtual bool is_triangle() { return false; }
virtual BoundBox bound() = 0;
virtual int ptex_face_id() { return -1; }
@@ -36,8 +36,9 @@ public:
class LinearQuadPatch : public Patch {
public:
float3 hull[4];
+ float3 normals[4];
- void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v);
+ void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
bool is_triangle() { return false; }
BoundBox bound();
};
@@ -47,8 +48,9 @@ public:
class LinearTrianglePatch : public Patch {
public:
float3 hull[3];
+ float3 normals[3];
- void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v);
+ void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
bool is_triangle() { return true; }
BoundBox bound();
};
@@ -59,7 +61,7 @@ class BicubicPatch : public Patch {
public:
float3 hull[16];
- void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v);
+ void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v);
bool is_triangle() { return false; }
BoundBox bound();
};
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 095eefeab22..70081673597 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -50,7 +50,7 @@ float3 DiagSplit::to_world(Patch *patch, float2 uv)
{
float3 P;
- patch->eval(&P, NULL, NULL, uv.x, uv.y);
+ patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
if(params.camera)
P = transform_point(&params.objecttoworld, P);