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:
authorStefan Werner <stefan.werner@tangent-animation.com>2018-11-23 15:08:15 +0300
committerStefan Werner <stefan.werner@tangent-animation.com>2018-11-23 15:19:53 +0300
commit071f4f4ce0b9520ab0c73d6d68365ad449ca8b80 (patch)
tree9f37bfcac669366b9ad5fb7605f2fbbed9b71b0a /intern/cycles/kernel/shaders/stdosl.h
parent0a2b2d59a5897212ba3771503feb6770fb636bc8 (diff)
Cycles: Improved robustness of hair motion blur.motion_curve_fix
In some instances, the number of control vertices of a hair could change mid-frame. Cycles would then be unable to calculate proper motion blur for those hairs. This adds interpolated CVs to fill in for the missing data. While this will not necessarily result in a fully accurate reconstruction of the guide hair, it preserves motion blur instead of disabling it. Reviewers: #cycles, sergey Reviewed By: #cycles, sergey Subscribers: sergey, brecht, #cycles Tags: #cycles Differential Revision: https://developer.blender.org/D3695
Diffstat (limited to 'intern/cycles/kernel/shaders/stdosl.h')
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h68
1 files changed, 49 insertions, 19 deletions
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 4a8378796ba..7136c746321 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -284,33 +284,63 @@ point rotate (point p, float angle, point a, point b)
normal ensure_valid_reflection(normal Ng, vector I, normal N)
{
+ /* The implementation here mirrors the one in kernel_montecarlo.h,
+ * check there for an explanation of the algorithm. */
+
float sqr(float x) { return x*x; }
vector R = 2*dot(N, I)*N - I;
- if (dot(Ng, R) >= 0.05) {
+
+ float threshold = min(0.9*dot(Ng, I), 0.01);
+ if(dot(Ng, R) >= threshold) {
return N;
}
- /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane.
- * The X axis is found by normalizing the component of N that's orthogonal to Ng.
- * The Y axis isn't actually needed.
- */
- vector X = normalize(N - dot(N, Ng)*Ng);
+ float NdotNg = dot(N, Ng);
+ vector X = normalize(N - NdotNg*Ng);
- /* Calculate N.z and N.x in the local coordinate system. */
float Ix = dot(I, X), Iz = dot(I, Ng);
- float Ix2 = sqr(dot(I, X)), Iz2 = sqr(dot(I, Ng));
- float Ix2Iz2 = Ix2 + Iz2;
-
- float a = sqrt(Ix2*(Ix2Iz2 - sqr(0.05)));
- float b = Iz*0.05 + Ix2Iz2;
- float c = (a + b > 0.0)? (a + b) : (-a + b);
+ float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
+ float a = Ix2 + Iz2;
+
+ float b = sqrt(Ix2*(a - sqr(threshold)));
+ float c = Iz*threshold + a;
+
+ float fac = 0.5/a;
+ float N1_z2 = fac*(b+c), N2_z2 = fac*(-b+c);
+ int valid1 = (N1_z2 > 1e-5) && (N1_z2 <= (1.0 + 1e-5));
+ int valid2 = (N2_z2 > 1e-5) && (N2_z2 <= (1.0 + 1e-5));
+
+ float N_new_x, N_new_z;
+ if(valid1 && valid2) {
+ float N1_x = sqrt(1.0 - N1_z2), N1_z = sqrt(N1_z2);
+ float N2_x = sqrt(1.0 - N2_z2), N2_z = sqrt(N2_z2);
+
+ float R1 = 2*(N1_x*Ix + N1_z*Iz)*N1_z - Iz;
+ float R2 = 2*(N2_x*Ix + N2_z*Iz)*N2_z - Iz;
+
+ valid1 = (R1 >= 1e-5);
+ valid2 = (R2 >= 1e-5);
+ if(valid1 && valid2) {
+ N_new_x = (R1 < R2)? N1_x : N2_x;
+ N_new_z = (R1 < R2)? N1_z : N2_z;
+ }
+ else {
+ N_new_x = (R1 > R2)? N1_x : N2_x;
+ N_new_z = (R1 > R2)? N1_z : N2_z;
+ }
- float Nz = sqrt(0.5 * c * (1.0 / Ix2Iz2));
- float Nx = sqrt(1.0 - sqr(Nz));
+ }
+ else if(valid1 || valid2) {
+ float Nz2 = valid1? N1_z2 : N2_z2;
+ N_new_x = sqrt(1.0 - Nz2);
+ N_new_z = sqrt(Nz2);
+ }
+ else {
+ return Ng;
+ }
- /* Transform back into global coordinates. */
- return Nx*X + Nz*Ng;
+ return N_new_x*X + N_new_z*Ng;
}
@@ -485,7 +515,7 @@ float smooth_linearstep (float edge0, float edge1, float x_, float eps_) {
else if (x >= eps && x <= 1.0-eps) result = x;
else if (x >= 1.0+eps) result = 1;
else if (x < eps) result = rampup (x+eps, 2.0*eps);
- else /* if (x < 1.0+eps) */ result = 1.0 - rampup (1.0+eps - x, 2.0*eps);
+ else /* if (x < 1.0+eps) */ result = 1.0 - rampup (1.0+eps - x, 2.0*eps);
} else {
result = step (edge0, x_);
}
@@ -656,4 +686,4 @@ int getmatrix (string fromspace, output matrix M) {
#undef PERCOMP2
#undef PERCOMP2F
-#endif /* CCL_STDOSL_H */
+#endif /* CCL_STDOSL_H */