|
@@ -26,6 +26,16 @@ struct LightingRegs {
|
|
|
DistanceAttenuation = 16,
|
|
DistanceAttenuation = 16,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ static LightingSampler SpotlightAttenuationSampler(unsigned index) {
|
|
|
|
|
+ return static_cast<LightingSampler>(
|
|
|
|
|
+ static_cast<unsigned>(LightingSampler::SpotlightAttenuation) + index);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static LightingSampler DistanceAttenuationSampler(unsigned index) {
|
|
|
|
|
+ return static_cast<LightingSampler>(
|
|
|
|
|
+ static_cast<unsigned>(LightingSampler::DistanceAttenuation) + index);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Pica fragment lighting supports using different LUTs for each lighting component: Reflectance
|
|
* Pica fragment lighting supports using different LUTs for each lighting component: Reflectance
|
|
|
* R, G, and B channels, distribution function for specular components 0 and 1, fresnel factor,
|
|
* R, G, and B channels, distribution function for specular components 0 and 1, fresnel factor,
|
|
@@ -73,6 +83,8 @@ struct LightingRegs {
|
|
|
VH = 1, // Cosine of the angle between the view and half-angle vectors
|
|
VH = 1, // Cosine of the angle between the view and half-angle vectors
|
|
|
NV = 2, // Cosine of the angle between the normal and the view vector
|
|
NV = 2, // Cosine of the angle between the normal and the view vector
|
|
|
LN = 3, // Cosine of the angle between the light and the normal vectors
|
|
LN = 3, // Cosine of the angle between the light and the normal vectors
|
|
|
|
|
+ SP = 4, // Cosine of the angle between the light and the inverse spotlight vectors
|
|
|
|
|
+ CP = 5, // TODO: document and implement
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
enum class LightingBumpMode : u32 {
|
|
enum class LightingBumpMode : u32 {
|
|
@@ -104,6 +116,9 @@ struct LightingRegs {
|
|
|
return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) &&
|
|
return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) &&
|
|
|
(config != LightingConfig::Config5);
|
|
(config != LightingConfig::Config5);
|
|
|
|
|
|
|
|
|
|
+ case LightingSampler::SpotlightAttenuation:
|
|
|
|
|
+ return (config != LightingConfig::Config2) && (config != LightingConfig::Config3);
|
|
|
|
|
+
|
|
|
case LightingSampler::Fresnel:
|
|
case LightingSampler::Fresnel:
|
|
|
return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) &&
|
|
return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) &&
|
|
|
(config != LightingConfig::Config4);
|
|
(config != LightingConfig::Config4);
|
|
@@ -116,11 +131,10 @@ struct LightingRegs {
|
|
|
return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) ||
|
|
return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) ||
|
|
|
(config == LightingConfig::Config7);
|
|
(config == LightingConfig::Config7);
|
|
|
default:
|
|
default:
|
|
|
- UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached "
|
|
|
|
|
- "unreachable section, sampler should be one "
|
|
|
|
|
- "of Distribution0, Distribution1, Fresnel, "
|
|
|
|
|
- "ReflectRed, ReflectGreen or ReflectBlue, instead "
|
|
|
|
|
- "got %i",
|
|
|
|
|
|
|
+ UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached unreachable section, "
|
|
|
|
|
+ "sampler should be one of Distribution0, Distribution1, "
|
|
|
|
|
+ "SpotlightAttenuation, Fresnel, ReflectRed, ReflectGreen or "
|
|
|
|
|
+ "ReflectBlue, instead got %i",
|
|
|
static_cast<int>(config));
|
|
static_cast<int>(config));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -140,7 +154,16 @@ struct LightingRegs {
|
|
|
BitField<0, 16, u32> z;
|
|
BitField<0, 16, u32> z;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- INSERT_PADDING_WORDS(0x3);
|
|
|
|
|
|
|
+ // inverse spotlight direction vector, encoded as fixed1.1.11
|
|
|
|
|
+ union {
|
|
|
|
|
+ BitField<0, 13, s32> spot_x;
|
|
|
|
|
+ BitField<16, 13, s32> spot_y;
|
|
|
|
|
+ };
|
|
|
|
|
+ union {
|
|
|
|
|
+ BitField<0, 13, s32> spot_z;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ INSERT_PADDING_WORDS(0x1);
|
|
|
|
|
|
|
|
union {
|
|
union {
|
|
|
BitField<0, 1, u32> directional;
|
|
BitField<0, 1, u32> directional;
|
|
@@ -169,8 +192,16 @@ struct LightingRegs {
|
|
|
} config0;
|
|
} config0;
|
|
|
|
|
|
|
|
union {
|
|
union {
|
|
|
|
|
+ u32 raw;
|
|
|
|
|
+
|
|
|
|
|
+ // Each bit specifies whether spot light attenuation should be applied for the corresponding
|
|
|
|
|
+ // light.
|
|
|
|
|
+ BitField<8, 8, u32> disable_spot_atten;
|
|
|
|
|
+
|
|
|
BitField<16, 1, u32> disable_lut_d0;
|
|
BitField<16, 1, u32> disable_lut_d0;
|
|
|
BitField<17, 1, u32> disable_lut_d1;
|
|
BitField<17, 1, u32> disable_lut_d1;
|
|
|
|
|
+ // Note: by intuition, BitField<18, 1, u32> should be disable_lut_sp, but it is actually a
|
|
|
|
|
+ // dummy bit which is always set as 1.
|
|
|
BitField<19, 1, u32> disable_lut_fr;
|
|
BitField<19, 1, u32> disable_lut_fr;
|
|
|
BitField<20, 1, u32> disable_lut_rr;
|
|
BitField<20, 1, u32> disable_lut_rr;
|
|
|
BitField<21, 1, u32> disable_lut_rg;
|
|
BitField<21, 1, u32> disable_lut_rg;
|
|
@@ -178,23 +209,15 @@ struct LightingRegs {
|
|
|
|
|
|
|
|
// Each bit specifies whether distance attenuation should be applied for the corresponding
|
|
// Each bit specifies whether distance attenuation should be applied for the corresponding
|
|
|
// light.
|
|
// light.
|
|
|
- BitField<24, 1, u32> disable_dist_atten_light_0;
|
|
|
|
|
- BitField<25, 1, u32> disable_dist_atten_light_1;
|
|
|
|
|
- BitField<26, 1, u32> disable_dist_atten_light_2;
|
|
|
|
|
- BitField<27, 1, u32> disable_dist_atten_light_3;
|
|
|
|
|
- BitField<28, 1, u32> disable_dist_atten_light_4;
|
|
|
|
|
- BitField<29, 1, u32> disable_dist_atten_light_5;
|
|
|
|
|
- BitField<30, 1, u32> disable_dist_atten_light_6;
|
|
|
|
|
- BitField<31, 1, u32> disable_dist_atten_light_7;
|
|
|
|
|
|
|
+ BitField<24, 8, u32> disable_dist_atten;
|
|
|
} config1;
|
|
} config1;
|
|
|
|
|
|
|
|
bool IsDistAttenDisabled(unsigned index) const {
|
|
bool IsDistAttenDisabled(unsigned index) const {
|
|
|
- const unsigned disable[] = {
|
|
|
|
|
- config1.disable_dist_atten_light_0, config1.disable_dist_atten_light_1,
|
|
|
|
|
- config1.disable_dist_atten_light_2, config1.disable_dist_atten_light_3,
|
|
|
|
|
- config1.disable_dist_atten_light_4, config1.disable_dist_atten_light_5,
|
|
|
|
|
- config1.disable_dist_atten_light_6, config1.disable_dist_atten_light_7};
|
|
|
|
|
- return disable[index] != 0;
|
|
|
|
|
|
|
+ return (config1.disable_dist_atten & (1 << index)) != 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bool IsSpotAttenDisabled(unsigned index) const {
|
|
|
|
|
+ return (config1.disable_spot_atten & (1 << index)) != 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
union {
|
|
union {
|