Improve and correct support for light distance attenuation
This commit is contained in:
parent
b7daa13f59
commit
cd39c3b8d1
@ -118,5 +118,4 @@ void C3D_LightSpotEnable(C3D_Light* light, bool enable);
|
|||||||
void C3D_LightSpotDir(C3D_Light* light, float x, float y, float z);
|
void C3D_LightSpotDir(C3D_Light* light, float x, float y, float z);
|
||||||
void C3D_LightSpotLut(C3D_Light* light, C3D_LightLut* lut);
|
void C3D_LightSpotLut(C3D_Light* light, C3D_LightLut* lut);
|
||||||
void C3D_LightDistAttnEnable(C3D_Light* light, bool enable);
|
void C3D_LightDistAttnEnable(C3D_Light* light, bool enable);
|
||||||
void C3D_LightDistAttn(C3D_Light* light, float bias, float scale);
|
void C3D_LightDistAttn(C3D_Light* light, C3D_LightLutDA* lut);
|
||||||
void C3D_LightDistAttnLut(C3D_Light* light, C3D_LightLut* lut);
|
|
||||||
|
@ -7,9 +7,23 @@ typedef struct
|
|||||||
u32 data[256];
|
u32 data[256];
|
||||||
} C3D_LightLut;
|
} C3D_LightLut;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
C3D_LightLut lut;
|
||||||
|
float bias, scale;
|
||||||
|
} C3D_LightLutDA;
|
||||||
|
|
||||||
typedef float (* C3D_LightLutFunc)(float x, float param);
|
typedef float (* C3D_LightLutFunc)(float x, float param);
|
||||||
|
typedef float (* C3D_LightLutFuncDA)(float dist, float arg0, float arg1);
|
||||||
|
|
||||||
|
static inline float quadratic_dist_attn(float dist, float linear, float quad)
|
||||||
|
{
|
||||||
|
return 1.0f / (1.0f + linear*dist + quad*dist*dist);
|
||||||
|
}
|
||||||
|
|
||||||
void LightLut_FromArray(C3D_LightLut* lut, float* data);
|
void LightLut_FromArray(C3D_LightLut* lut, float* data);
|
||||||
void LightLut_FromFunc(C3D_LightLut* lut, C3D_LightLutFunc func, float param, bool negative);
|
void LightLut_FromFunc(C3D_LightLut* lut, C3D_LightLutFunc func, float param, bool negative);
|
||||||
|
void LightLutDA_Create(C3D_LightLutDA* lut, C3D_LightLutFuncDA func, float from, float to, float arg0, float arg1);
|
||||||
|
|
||||||
#define LightLut_Phong(lut, shininess) LightLut_FromFunc((lut), powf, (shininess), false)
|
#define LightLut_Phong(lut, shininess) LightLut_FromFunc((lut), powf, (shininess), false)
|
||||||
|
#define LightLutDA_Quadratic(lut, from, to, linear, quad) LightLutDA_Create((lut), quadratic_dist_attn, (from), (to), (linear), (quad))
|
||||||
|
@ -92,7 +92,7 @@ static void C3Di_EnableCommon(C3D_Light* light, bool enable, u32 bit)
|
|||||||
C3D_LightEnv* env = light->parent;
|
C3D_LightEnv* env = light->parent;
|
||||||
u32* var = &env->conf.config[1];
|
u32* var = &env->conf.config[1];
|
||||||
|
|
||||||
if ((*var & bit) ^ bit)
|
if (enable == !(*var & bit))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!enable)
|
if (!enable)
|
||||||
@ -134,19 +134,14 @@ void C3D_LightDistAttnEnable(C3D_Light* light, bool enable)
|
|||||||
C3Di_EnableCommon(light, enable, GPU_LC1_ATTNBIT(light->id));
|
C3Di_EnableCommon(light, enable, GPU_LC1_ATTNBIT(light->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void C3D_LightDistAttn(C3D_Light* light, float bias, float scale)
|
void C3D_LightDistAttn(C3D_Light* light, C3D_LightLutDA* lut)
|
||||||
{
|
|
||||||
C3Di_EnableCommon(light, true, GPU_LC1_ATTNBIT(light->id));
|
|
||||||
light->conf.distAttnBias = f32tof20(bias);
|
|
||||||
light->conf.distAttnScale = f32tof20(scale);
|
|
||||||
light->flags |= C3DF_Light_Dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
void C3D_LightDistAttnLut(C3D_Light* light, C3D_LightLut* lut)
|
|
||||||
{
|
{
|
||||||
bool hasLut = lut != NULL;
|
bool hasLut = lut != NULL;
|
||||||
C3Di_EnableCommon(light, hasLut, GPU_LC1_ATTNBIT(light->id));
|
C3Di_EnableCommon(light, hasLut, GPU_LC1_ATTNBIT(light->id));
|
||||||
light->lut_DA = lut;
|
if (!hasLut) return;
|
||||||
if (hasLut)
|
|
||||||
light->flags |= C3DF_Light_DADirty;
|
light->conf.distAttnBias = f32tof20(lut->bias);
|
||||||
|
light->conf.distAttnScale = f32tof20(lut->scale);
|
||||||
|
light->lut_DA = &lut->lut;
|
||||||
|
light->flags |= C3DF_Light_Dirty | C3DF_Light_DADirty;
|
||||||
}
|
}
|
||||||
|
@ -44,3 +44,23 @@ void LightLut_FromFunc(C3D_LightLut* lut, C3D_LightLutFunc func, float param, bo
|
|||||||
}
|
}
|
||||||
LightLut_FromArray(lut, data);
|
LightLut_FromArray(lut, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightLutDA_Create(C3D_LightLutDA* lut, C3D_LightLutFuncDA func, float from, float to, float arg0, float arg1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float data[512];
|
||||||
|
data[511] = 0;
|
||||||
|
|
||||||
|
lut->scale = 1.0f / (to-from);
|
||||||
|
lut->bias = -from*lut->scale;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i ++)
|
||||||
|
{
|
||||||
|
float dist = ((float)i/255 - lut->bias) / lut->scale;
|
||||||
|
data[i] = func(dist, arg0, arg1);
|
||||||
|
if (i > 0)
|
||||||
|
data[i+255] = data[i]-data[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
LightLut_FromArray(&lut->lut, data);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user