diff options
author | Mai Lavelle <mai.lavelle@gmail.com> | 2016-04-11 23:49:09 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2016-04-12 00:12:11 +0300 |
commit | ebfdd7da83200f2890b28dd5ef9a0fc8c6ab9137 (patch) | |
tree | 8ccb1ad1af787ccf3d186b687324e4056f9665df /intern/cycles/subd | |
parent | 7d033717ad52bf92235e65224b6b3940de7ec473 (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/cycles/subd')
-rw-r--r-- | intern/cycles/subd/subd_dice.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/subd/subd_dice.h | 1 | ||||
-rw-r--r-- | intern/cycles/subd/subd_split.cpp | 54 | ||||
-rw-r--r-- | intern/cycles/subd/subd_split.h | 2 |
4 files changed, 54 insertions, 8 deletions
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(¶ms.camera->worldtoraster, P); + P = transform_point(¶ms.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); |