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_LightSpotLut(C3D_Light* light, C3D_LightLut* lut);
|
||||
void C3D_LightDistAttnEnable(C3D_Light* light, bool enable);
|
||||
void C3D_LightDistAttn(C3D_Light* light, float bias, float scale);
|
||||
void C3D_LightDistAttnLut(C3D_Light* light, C3D_LightLut* lut);
|
||||
void C3D_LightDistAttn(C3D_Light* light, C3D_LightLutDA* lut);
|
||||
|
@ -7,9 +7,23 @@ typedef struct
|
||||
u32 data[256];
|
||||
} C3D_LightLut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
C3D_LightLut lut;
|
||||
float bias, scale;
|
||||
} C3D_LightLutDA;
|
||||
|
||||
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_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 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;
|
||||
u32* var = &env->conf.config[1];
|
||||
|
||||
if ((*var & bit) ^ bit)
|
||||
if (enable == !(*var & bit))
|
||||
return;
|
||||
|
||||
if (!enable)
|
||||
@ -134,19 +134,14 @@ void C3D_LightDistAttnEnable(C3D_Light* light, bool enable)
|
||||
C3Di_EnableCommon(light, enable, GPU_LC1_ATTNBIT(light->id));
|
||||
}
|
||||
|
||||
void C3D_LightDistAttn(C3D_Light* light, float bias, float scale)
|
||||
{
|
||||
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)
|
||||
void C3D_LightDistAttn(C3D_Light* light, C3D_LightLutDA* lut)
|
||||
{
|
||||
bool hasLut = lut != NULL;
|
||||
C3Di_EnableCommon(light, hasLut, GPU_LC1_ATTNBIT(light->id));
|
||||
light->lut_DA = lut;
|
||||
if (hasLut)
|
||||
light->flags |= C3DF_Light_DADirty;
|
||||
if (!hasLut) return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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