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:
Diffstat (limited to 'intern/cycles/kernel/shaders/stdosl.h')
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index df9c2010872..4a8378796ba 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -282,6 +282,36 @@ point rotate (point p, float angle, point a, point b)
return transform (M, p-a) + a;
}
+normal ensure_valid_reflection(normal Ng, vector I, normal N)
+{
+ float sqr(float x) { return x*x; }
+
+ vector R = 2*dot(N, I)*N - I;
+ if (dot(Ng, R) >= 0.05) {
+ 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);
+
+ /* 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 Nz = sqrt(0.5 * c * (1.0 / Ix2Iz2));
+ float Nx = sqrt(1.0 - sqr(Nz));
+
+ /* Transform back into global coordinates. */
+ return Nx*X + Nz*Ng;
+}
// Color functions