Cycles: principled absorption color now has more effect at lower values.
[blender.git] / intern / cycles / util / util_math_float3.h
index bb04c4aa2d929724c2e9fa78772bdd80d14fd45c..a0a62ae95df1926869e3642288501b676714fe17 100644 (file)
@@ -57,8 +57,10 @@ ccl_device_inline float3 clamp(const float3& a, const float3& mn, const float3&
 ccl_device_inline float3 fabs(const float3& a);
 ccl_device_inline float3 mix(const float3& a, const float3& b, float t);
 ccl_device_inline float3 rcp(const float3& a);
+ccl_device_inline float3 sqrt(const float3& a);
 #endif  /* !__KERNEL_OPENCL__ */
 
+ccl_device_inline float min3(float3 a);
 ccl_device_inline float max3(float3 a);
 ccl_device_inline float len(const float3 a);
 ccl_device_inline float len_squared(const float3 a);
@@ -108,8 +110,7 @@ ccl_device_inline float3 operator*(const float3& a, const float f)
 
 ccl_device_inline float3 operator*(const float f, const float3& a)
 {
-       /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
+#if defined(__KERNEL_SSE__)
        return float3(_mm_mul_ps(_mm_set1_ps(f), a.m128));
 #else
        return make_float3(a.x*f, a.y*f, a.z*f);
@@ -118,10 +119,8 @@ ccl_device_inline float3 operator*(const float f, const float3& a)
 
 ccl_device_inline float3 operator/(const float f, const float3& a)
 {
-       /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
-       __m128 rc = _mm_rcp_ps(a.m128);
-       return float3(_mm_mul_ps(_mm_set1_ps(f),rc));
+#if defined(__KERNEL_SSE__)
+       return float3(_mm_div_ps(_mm_set1_ps(f), a.m128));
 #else
        return make_float3(f / a.x, f / a.y, f / a.z);
 #endif
@@ -135,10 +134,8 @@ ccl_device_inline float3 operator/(const float3& a, const float f)
 
 ccl_device_inline float3 operator/(const float3& a, const float3& b)
 {
-       /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
-       __m128 rc = _mm_rcp_ps(b.m128);
-       return float3(_mm_mul_ps(a, rc));
+#if defined(__KERNEL_SSE__)
+       return float3(_mm_div_ps(a.m128, b.m128));
 #else
        return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
 #endif
@@ -274,6 +271,15 @@ ccl_device_inline float3 fabs(const float3& a)
 #endif
 }
 
+ccl_device_inline float3 sqrt(const float3& a)
+{
+#ifdef __KERNEL_SSE__
+       return float3(_mm_sqrt_ps(a));
+#else
+       return make_float3(sqrtf(a.x), sqrtf(a.y), sqrtf(a.z));
+#endif
+}
+
 ccl_device_inline float3 mix(const float3& a, const float3& b, float t)
 {
        return a + t*(b - a);
@@ -282,15 +288,19 @@ ccl_device_inline float3 mix(const float3& a, const float3& b, float t)
 ccl_device_inline float3 rcp(const float3& a)
 {
 #ifdef __KERNEL_SSE__
-       const float4 r(_mm_rcp_ps(a.m128));
-       return float3(_mm_sub_ps(_mm_add_ps(r, r),
-                                _mm_mul_ps(_mm_mul_ps(r, r), a)));
+       /* Don't use _mm_rcp_ps due to poor precision. */
+       return float3(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
 #else
        return make_float3(1.0f/a.x, 1.0f/a.y, 1.0f/a.z);
 #endif
 }
 #endif  /* !__KERNEL_OPENCL__ */
 
+ccl_device_inline float min3(float3 a)
+{
+       return min(min(a.x, a.y), a.z);
+}
+
 ccl_device_inline float max3(float3 a)
 {
        return max(max(a.x, a.y), a.z);