gl_shader_gen: Implement lighting red, green, and blue reflection.
This commit is contained in:
parent
01b407638c
commit
348c9c9ff3
3 changed files with 77 additions and 21 deletions
|
@ -650,9 +650,9 @@ struct Regs {
|
||||||
Distribution0 = 0,
|
Distribution0 = 0,
|
||||||
Distribution1 = 1,
|
Distribution1 = 1,
|
||||||
Fresnel = 3,
|
Fresnel = 3,
|
||||||
Blue = 4,
|
ReflectBlue = 4,
|
||||||
Green = 5,
|
ReflectGreen = 5,
|
||||||
Red = 6,
|
ReflectRed = 6,
|
||||||
SpotlightAttenuation = 8,
|
SpotlightAttenuation = 8,
|
||||||
DistanceAttenuation = 16,
|
DistanceAttenuation = 16,
|
||||||
};
|
};
|
||||||
|
@ -718,10 +718,19 @@ struct Regs {
|
||||||
switch (sampler) {
|
switch (sampler) {
|
||||||
case LightingSampler::Distribution0:
|
case LightingSampler::Distribution0:
|
||||||
return (config != LightingConfig::Config1);
|
return (config != LightingConfig::Config1);
|
||||||
|
|
||||||
case LightingSampler::Distribution1:
|
case LightingSampler::Distribution1:
|
||||||
return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5);
|
return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5);
|
||||||
|
|
||||||
case LightingSampler::Fresnel:
|
case LightingSampler::Fresnel:
|
||||||
return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4);
|
return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4);
|
||||||
|
|
||||||
|
case LightingSampler::ReflectRed:
|
||||||
|
return (config != LightingConfig::Config3);
|
||||||
|
|
||||||
|
case LightingSampler::ReflectGreen:
|
||||||
|
case LightingSampler::ReflectBlue:
|
||||||
|
return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || (config == LightingConfig::Config7);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -773,6 +782,9 @@ struct Regs {
|
||||||
BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE
|
BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE
|
||||||
BitField<17, 1, u32> lut_enable_d1; // 0: GL_TRUE, 1: GL_FALSE
|
BitField<17, 1, u32> lut_enable_d1; // 0: GL_TRUE, 1: GL_FALSE
|
||||||
BitField<19, 1, u32> lut_enable_fr; // 0: GL_TRUE, 1: GL_FALSE
|
BitField<19, 1, u32> lut_enable_fr; // 0: GL_TRUE, 1: GL_FALSE
|
||||||
|
BitField<20, 1, u32> lut_enable_rr; // 0: GL_TRUE, 1: GL_FALSE
|
||||||
|
BitField<21, 1, u32> lut_enable_rg; // 0: GL_TRUE, 1: GL_FALSE
|
||||||
|
BitField<22, 1, u32> lut_enable_rb; // 0: GL_TRUE, 1: GL_FALSE
|
||||||
|
|
||||||
// Each bit specifies whether distance attenuation should be applied for the
|
// Each bit specifies whether distance attenuation should be applied for the
|
||||||
// corresponding light
|
// corresponding light
|
||||||
|
|
|
@ -102,6 +102,21 @@ struct PicaShaderConfig {
|
||||||
res.lighting.lut_fr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.fr.Value();
|
res.lighting.lut_fr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.fr.Value();
|
||||||
res.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr);
|
res.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr);
|
||||||
|
|
||||||
|
res.lighting.lut_rr.enable = regs.lighting.lut_enable_rr == 0;
|
||||||
|
res.lighting.lut_rr.abs_input = regs.lighting.abs_lut_input.rr == 0;
|
||||||
|
res.lighting.lut_rr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rr.Value();
|
||||||
|
res.lighting.lut_rr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rr);
|
||||||
|
|
||||||
|
res.lighting.lut_rg.enable = regs.lighting.lut_enable_rg == 0;
|
||||||
|
res.lighting.lut_rg.abs_input = regs.lighting.abs_lut_input.rg == 0;
|
||||||
|
res.lighting.lut_rg.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rg.Value();
|
||||||
|
res.lighting.lut_rg.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rg);
|
||||||
|
|
||||||
|
res.lighting.lut_rb.enable = regs.lighting.lut_enable_rb == 0;
|
||||||
|
res.lighting.lut_rb.abs_input = regs.lighting.abs_lut_input.rb == 0;
|
||||||
|
res.lighting.lut_rb.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rb.Value();
|
||||||
|
res.lighting.lut_rb.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rb);
|
||||||
|
|
||||||
res.lighting.config = regs.lighting.config;
|
res.lighting.config = regs.lighting.config;
|
||||||
res.lighting.fresnel_selector = regs.lighting.fresnel_selector;
|
res.lighting.fresnel_selector = regs.lighting.fresnel_selector;
|
||||||
res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0;
|
res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0;
|
||||||
|
@ -139,6 +154,7 @@ struct PicaShaderConfig {
|
||||||
bool enable = false;
|
bool enable = false;
|
||||||
unsigned src_num = 0;
|
unsigned src_num = 0;
|
||||||
bool clamp_highlights = false;
|
bool clamp_highlights = false;
|
||||||
|
|
||||||
Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0;
|
Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0;
|
||||||
Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None;
|
Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None;
|
||||||
|
|
||||||
|
@ -147,7 +163,7 @@ struct PicaShaderConfig {
|
||||||
bool abs_input = false;
|
bool abs_input = false;
|
||||||
Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH;
|
Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH;
|
||||||
float scale = 1.0f;
|
float scale = 1.0f;
|
||||||
} lut_d0, lut_d1, lut_fr;
|
} lut_d0, lut_d1, lut_fr, lut_rr, lut_rg, lut_rb;
|
||||||
} lighting;
|
} lighting;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -321,9 +321,10 @@ static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsi
|
||||||
/// Writes the code to emulate fragment lighting
|
/// Writes the code to emulate fragment lighting
|
||||||
static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
|
static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
|
||||||
// Define lighting globals
|
// Define lighting globals
|
||||||
out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n";
|
out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||||
out += "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n";
|
"vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
||||||
out += "vec3 light_vector = vec3(0.0);\n";
|
"vec3 light_vector = vec3(0.0);\n"
|
||||||
|
"vec3 refl_value = vec3(0.0);\n";
|
||||||
|
|
||||||
// Convert interpolated quaternion to a GL fragment normal
|
// Convert interpolated quaternion to a GL fragment normal
|
||||||
out += "vec3 normal = normalize(vec3(\n";
|
out += "vec3 normal = normalize(vec3(\n";
|
||||||
|
@ -396,10 +397,10 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
|
||||||
if (light_config.dist_atten_enable) {
|
if (light_config.dist_atten_enable) {
|
||||||
std::string scale = std::to_string(light_config.dist_atten_scale);
|
std::string scale = std::to_string(light_config.dist_atten_scale);
|
||||||
std::string bias = std::to_string(light_config.dist_atten_bias);
|
std::string bias = std::to_string(light_config.dist_atten_bias);
|
||||||
std::string lut_index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")";
|
std::string index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")";
|
||||||
lut_index = "((clamp(" + lut_index + ", 0.0, FLOAT_255)))";
|
index = "((clamp(" + index + ", 0.0, FLOAT_255)))";
|
||||||
const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num);
|
const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num);
|
||||||
dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index);
|
dist_atten = GetLutValue((Regs::LightingSampler)lut_num, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If enabled, clamp specular component if lighting result is negative
|
// If enabled, clamp specular component if lighting result is negative
|
||||||
|
@ -409,35 +410,62 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
|
||||||
std::string d0_lut_value = "1.0";
|
std::string d0_lut_value = "1.0";
|
||||||
if (config.lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution0)) {
|
if (config.lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution0)) {
|
||||||
// Lookup specular "distribution 0" LUT value
|
// Lookup specular "distribution 0" LUT value
|
||||||
std::string d0_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input);
|
std::string index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input);
|
||||||
d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index) + ")";
|
d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, index) + ")";
|
||||||
}
|
}
|
||||||
std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)";
|
std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)";
|
||||||
|
|
||||||
|
// If enabled, lookup ReflectRed value, otherwise, 1.0 is used
|
||||||
|
if (config.lighting.lut_rr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectRed)) {
|
||||||
|
std::string index = GetLutIndex(light_config.num, config.lighting.lut_rr.type, config.lighting.lut_rr.abs_input);
|
||||||
|
std::string value = "(" + std::to_string(config.lighting.lut_rr.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")";
|
||||||
|
out += "refl_value.r = " + value + ";\n";
|
||||||
|
} else {
|
||||||
|
out += "refl_value.r = 1.0;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If enabled, lookup ReflectGreen value, otherwise, ReflectRed value is used
|
||||||
|
if (config.lighting.lut_rg.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectGreen)) {
|
||||||
|
std::string index = GetLutIndex(light_config.num, config.lighting.lut_rg.type, config.lighting.lut_rg.abs_input);
|
||||||
|
std::string value = "(" + std::to_string(config.lighting.lut_rg.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")";
|
||||||
|
out += "refl_value.g = " + value + ";\n";
|
||||||
|
} else {
|
||||||
|
out += "refl_value.g = refl_value.r;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If enabled, lookup ReflectBlue value, otherwise, ReflectRed value is used
|
||||||
|
if (config.lighting.lut_rb.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectBlue)) {
|
||||||
|
std::string index = GetLutIndex(light_config.num, config.lighting.lut_rb.type, config.lighting.lut_rb.abs_input);
|
||||||
|
std::string value = "(" + std::to_string(config.lighting.lut_rb.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")";
|
||||||
|
out += "refl_value.b = " + value + ";\n";
|
||||||
|
} else {
|
||||||
|
out += "refl_value.b = refl_value.r;\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Specular 1 component
|
// Specular 1 component
|
||||||
std::string d1_lut_value = "1.0";
|
std::string d1_lut_value = "1.0";
|
||||||
if (config.lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution1)) {
|
if (config.lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution1)) {
|
||||||
// Lookup specular "distribution 1" LUT value
|
// Lookup specular "distribution 1" LUT value
|
||||||
std::string d1_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input);
|
std::string index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input);
|
||||||
d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, d1_lut_index) + ")";
|
d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, index) + ")";
|
||||||
}
|
}
|
||||||
std::string specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)";
|
std::string specular_1 = "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)";
|
||||||
|
|
||||||
// Fresnel
|
// Fresnel
|
||||||
if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) {
|
if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) {
|
||||||
// Lookup fresnel LUT value
|
// Lookup fresnel LUT value
|
||||||
std::string fr_lut_index = GetLutIndex(light_config.num, config.lighting.lut_fr.type, config.lighting.lut_fr.abs_input);
|
std::string index = GetLutIndex(light_config.num, config.lighting.lut_fr.type, config.lighting.lut_fr.abs_input);
|
||||||
std::string fr_lut_value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, fr_lut_index) + ")";
|
std::string value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, index) + ")";
|
||||||
|
|
||||||
// Enabled for difffuse lighting alpha component
|
// Enabled for difffuse lighting alpha component
|
||||||
if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha ||
|
if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha ||
|
||||||
config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha)
|
config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both)
|
||||||
out += "diffuse_sum.a *= " + fr_lut_value + ";\n";
|
out += "diffuse_sum.a *= " + value + ";\n";
|
||||||
|
|
||||||
// Enabled for the specular lighting alpha component
|
// Enabled for the specular lighting alpha component
|
||||||
if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha ||
|
if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha ||
|
||||||
config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha)
|
config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both)
|
||||||
out += "specular_sum.a *= " + fr_lut_value + ";\n";
|
out += "specular_sum.a *= " + value + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute primary fragment color (diffuse lighting) function
|
// Compute primary fragment color (diffuse lighting) function
|
||||||
|
|
Loading…
Reference in a new issue