Replace pow function

This commit is contained in:
Luke Benstead 2020-02-20 09:44:45 +00:00
parent 6b43244a1e
commit 497ba28b4c

View File

@ -1,3 +1,4 @@
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
@ -259,69 +260,32 @@ GL_FORCE_INLINE void initVec3(struct vec3f* v, const GLfloat* src) {
memcpy(v, src, sizeof(GLfloat) * 3); memcpy(v, src, sizeof(GLfloat) * 3);
} }
/* Fast POW Implementation - Less accurate, but much faster than math.h */ /*
#define EXP_A 184 * Implementation from here (MIT):
#define EXP_C 16249 * https://github.com/appleseedhq/appleseed/blob/master/src/appleseed/foundation/math/fastmath.h
*/
GL_FORCE_INLINE float faster_pow2(const float p) {
// Underflow of exponential is common practice in numerical routines, so handle it here.
const float clipp = p < -126.0f ? -126.0f : p;
const union { uint32_t i; float f; } v =
{
(uint32_t) ((1 << 23) * (clipp + 126.94269504f))
};
GL_FORCE_INLINE float FEXP(float y) { return v.f;
union {
float d;
struct {
short j, i;
} n;
} eco;
eco.n.i = EXP_A * (y) + (EXP_C);
eco.n.j = 0;
return eco.d;
} }
/* Inspired by: https://web.archive.org/web/20180423090243/www.dctsystems.co.uk/Software/power.html */ GL_FORCE_INLINE float faster_log2(const float x) {
#define SHIFT23 (1 << 23) assert(x >= 0.0f);
#define INVSHIFT23 (1.0f / SHIFT23)
#define LOGBODGE 0.346607f
#define POWBODGE 0.33971f
const static float FINT_MAX = ((float) INT_MAX) + 1.0f; const union { float f; uint32_t i; } vx = { x };
const float y = (float) (vx.i) * 1.1920928955078125e-7f;
GL_FORCE_INLINE float FFLOOR(float x) { return y - 126.94269504f;
return ((int)(x + FINT_MAX) + INT_MIN);
} }
GL_FORCE_INLINE float FLOG2(float i) { GL_FORCE_INLINE float faster_pow(const float x, const float p) {
float y; return faster_pow2(p * faster_log2(x));
union {
float f;
int i;
} x;
x.i = i;
x.f *= INVSHIFT23;
x.f = x.f - 127;
y = x.f - FFLOOR(x.f);
y = (y - y * y) * LOGBODGE;
return x.f + y;
}
GL_FORCE_INLINE float FPOW2(float i) {
float y = i - FFLOOR(i);
y = (y - y * y) * POWBODGE;
union {
float f;
float i;
} x;
x.f = i + 127 - y;
x.f *= SHIFT23;
return x.i;
}
GL_FORCE_INLINE float FPOW(float a, float b) {
return FPOW2(b * FLOG2(a));
} }
GL_FORCE_INLINE float vec3_dot_limited( GL_FORCE_INLINE float vec3_dot_limited(
@ -341,7 +305,7 @@ GL_FORCE_INLINE void _glLightVertexDirectional(
float F; float F;
uint8_t FO; uint8_t FO;
float FI = (LdotN != 0.0f); float FI = (LdotN != 0.0f);
FI = (MATERIAL.exponent) ? FPOW(FI * NdotH, MATERIAL.exponent) : 1.0f; FI = (MATERIAL.exponent) ? faster_pow(FI * NdotH, MATERIAL.exponent) : 1.0f;
#define _PROCESS_COMPONENT(T, X) \ #define _PROCESS_COMPONENT(T, X) \
F = (ambient[X] * LIGHTS[lid].ambient[X]); \ F = (ambient[X] * LIGHTS[lid].ambient[X]); \
@ -365,7 +329,7 @@ GL_FORCE_INLINE void _glLightVertexPoint(
float F; float F;
uint8_t FO; uint8_t FO;
float FI = (LdotN != 0.0f); float FI = (LdotN != 0.0f);
FI = (MATERIAL.exponent) ? FPOW(FI * NdotH, MATERIAL.exponent) : 1.0f; FI = (MATERIAL.exponent) ? faster_pow(FI * NdotH, MATERIAL.exponent) : 1.0f;
#define _PROCESS_COMPONENT(T, X) \ #define _PROCESS_COMPONENT(T, X) \
F = (ambient[X] * LIGHTS[lid].ambient[X]); \ F = (ambient[X] * LIGHTS[lid].ambient[X]); \