mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 12:34:39 +08:00 
			
		
		
		
	gl_shader_gen: Refactor lighting config to match Pica register naming.
- Also implement D0 LUT enable.
This commit is contained in:
		
							parent
							
								
									6307999116
								
							
						
					
					
						commit
						3d89dacd56
					
				@ -718,6 +718,8 @@ struct Regs {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        union {
 | 
					        union {
 | 
				
			||||||
 | 
					            BitField<16, 1, u32> lut_enable_d0; // 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -73,23 +73,24 @@ struct PicaShaderConfig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Fragment lighting
 | 
					        // Fragment lighting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res.lighting_enabled = !regs.lighting.disable;
 | 
					        res.lighting.enable = !regs.lighting.disable;
 | 
				
			||||||
        res.num_lights = regs.lighting.src_num + 1;
 | 
					        res.lighting.src_num = regs.lighting.src_num + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (unsigned light_index = 0; light_index < res.num_lights; ++light_index) {
 | 
					        for (unsigned light_index = 0; light_index < res.lighting.src_num; ++light_index) {
 | 
				
			||||||
            unsigned num = regs.lighting.light_enable.GetNum(light_index);
 | 
					            unsigned num = regs.lighting.light_enable.GetNum(light_index);
 | 
				
			||||||
            const auto& light = regs.lighting.light[num];
 | 
					            const auto& light = regs.lighting.light[num];
 | 
				
			||||||
            res.light_src[light_index].num = num;
 | 
					            res.lighting.light[light_index].num = num;
 | 
				
			||||||
            res.light_src[light_index].directional = light.directional != 0;
 | 
					            res.lighting.light[light_index].directional = light.directional != 0;
 | 
				
			||||||
            res.light_src[light_index].two_sided_diffuse = light.two_sided_diffuse != 0;
 | 
					            res.lighting.light[light_index].two_sided_diffuse = light.two_sided_diffuse != 0;
 | 
				
			||||||
            res.light_src[light_index].dist_atten_enabled = regs.lighting.IsDistAttenEnabled(num);
 | 
					            res.lighting.light[light_index].dist_atten_enable = regs.lighting.IsDistAttenEnabled(num);
 | 
				
			||||||
            res.light_src[light_index].dist_atten_bias = Pica::float20::FromRawFloat20(light.dist_atten_bias).ToFloat32();
 | 
					            res.lighting.light[light_index].dist_atten_bias = Pica::float20::FromRawFloat20(light.dist_atten_bias).ToFloat32();
 | 
				
			||||||
            res.light_src[light_index].dist_atten_scale = Pica::float20::FromRawFloat20(light.dist_atten_scale).ToFloat32();
 | 
					            res.lighting.light[light_index].dist_atten_scale = Pica::float20::FromRawFloat20(light.dist_atten_scale).ToFloat32();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res.lighting_lut.d0_abs = regs.lighting.abs_lut_input.d0 == 0;
 | 
					        res.lighting.lut_d0.enable = regs.lighting.lut_enable_d0 == 0;
 | 
				
			||||||
        res.lighting_lut.d0_type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d0.Value();
 | 
					        res.lighting.lut_d0.abs_input = regs.lighting.abs_lut_input.d0 == 0;
 | 
				
			||||||
        res.clamp_highlights = regs.lighting.clamp_highlights != 0;
 | 
					        res.lighting.lut_d0.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d0.Value();
 | 
				
			||||||
 | 
					        res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return res;
 | 
					        return res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -112,22 +113,25 @@ struct PicaShaderConfig {
 | 
				
			|||||||
        u8 combiner_buffer_input = 0;
 | 
					        u8 combiner_buffer_input = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct {
 | 
					        struct {
 | 
				
			||||||
            unsigned num = 0;
 | 
					            struct {
 | 
				
			||||||
            bool directional = false;
 | 
					                unsigned num = 0;
 | 
				
			||||||
            bool two_sided_diffuse = false;
 | 
					                bool directional = false;
 | 
				
			||||||
            bool dist_atten_enabled = false;
 | 
					                bool two_sided_diffuse = false;
 | 
				
			||||||
            GLfloat dist_atten_scale = 0.0f;
 | 
					                bool dist_atten_enable = false;
 | 
				
			||||||
            GLfloat dist_atten_bias = 0.0f;
 | 
					                GLfloat dist_atten_scale = 0.0f;
 | 
				
			||||||
        } light_src[8];
 | 
					                GLfloat dist_atten_bias = 0.0f;
 | 
				
			||||||
 | 
					            } light[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool lighting_enabled = false;
 | 
					            bool enable = false;
 | 
				
			||||||
        unsigned num_lights = 0;
 | 
					            unsigned src_num = 0;
 | 
				
			||||||
        bool clamp_highlights = false;
 | 
					            bool clamp_highlights = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct {
 | 
					            struct {
 | 
				
			||||||
            bool d0_abs = false;
 | 
					                bool enable = false;
 | 
				
			||||||
            Pica::Regs::LightingLutInput d0_type = Pica::Regs::LightingLutInput::NH;
 | 
					                bool abs_input = false;
 | 
				
			||||||
        } lighting_lut;
 | 
					                Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH;
 | 
				
			||||||
 | 
					            } lut_d0;
 | 
				
			||||||
 | 
					        } lighting;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -360,7 +360,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (abs) {
 | 
					        if (abs) {
 | 
				
			||||||
            // LUT index is in the range of (0.0, 1.0)
 | 
					            // LUT index is in the range of (0.0, 1.0)
 | 
				
			||||||
            index = config.light_src[light_num].two_sided_diffuse ? "abs(" + index + ")" : "max(" + index + ", 0.f)";
 | 
					            index = config.lighting.light[light_num].two_sided_diffuse ? "abs(" + index + ")" : "max(" + index + ", 0.f)";
 | 
				
			||||||
            return "clamp(" + index + ", 0.0, FLOAT_255)";
 | 
					            return "clamp(" + index + ", 0.0, FLOAT_255)";
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // LUT index is in the range of (-1.0, 1.0)
 | 
					            // LUT index is in the range of (-1.0, 1.0)
 | 
				
			||||||
@ -378,10 +378,9 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Write the code to emulate each enabled light
 | 
					    // Write the code to emulate each enabled light
 | 
				
			||||||
    for (unsigned light_index = 0; light_index < config.num_lights; ++light_index) {
 | 
					    for (unsigned light_index = 0; light_index < config.lighting.src_num; ++light_index) {
 | 
				
			||||||
        unsigned num = config.light_src[light_index].num;
 | 
					        const auto& light_config = config.lighting.light[light_index];
 | 
				
			||||||
        const auto& light_config = config.light_src[light_index];
 | 
					        std::string light_src = "light_src[" + std::to_string(light_config.num) + "]";
 | 
				
			||||||
        std::string light_src = "light_src[" + std::to_string(num) + "]";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Compute light vector (directional or positional)
 | 
					        // Compute light vector (directional or positional)
 | 
				
			||||||
        if (light_config.directional)
 | 
					        if (light_config.directional)
 | 
				
			||||||
@ -394,12 +393,12 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // If enabled, compute distance attenuation value
 | 
					        // If enabled, compute distance attenuation value
 | 
				
			||||||
        std::string dist_atten = "1.0";
 | 
					        std::string dist_atten = "1.0";
 | 
				
			||||||
        if (light_config.dist_atten_enabled) {
 | 
					        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 lut_index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")";
 | 
				
			||||||
            lut_index = "((clamp(" + lut_index + ", 0.0, FLOAT_255)))";
 | 
					            lut_index = "((clamp(" + lut_index + ", 0.0, FLOAT_255)))";
 | 
				
			||||||
            const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + 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, lut_index);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -407,11 +406,14 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
 | 
				
			|||||||
        out += "diffuse_sum += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n";
 | 
					        out += "diffuse_sum += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If enabled, clamp specular component if lighting result is negative
 | 
					        // If enabled, clamp specular component if lighting result is negative
 | 
				
			||||||
        std::string clamp_highlights = config.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0";
 | 
					        std::string clamp_highlights = config.lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Lookup specular distribution 0 LUT value
 | 
					        // Lookup specular "distribution 0" LUT value
 | 
				
			||||||
        std::string d0_lut_index = GetLutIndex(num, config.lighting_lut.d0_type, config.lighting_lut.d0_abs);
 | 
					        std::string d0_lut_value = "1.0";
 | 
				
			||||||
        std::string d0_lut_value = GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index);
 | 
					        if (config.lighting.lut_d0.enable) {
 | 
				
			||||||
 | 
					            std::string d0_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input);
 | 
				
			||||||
 | 
					            d0_lut_value = GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Compute secondary fragment color (specular lighting) function
 | 
					        // Compute secondary fragment color (specular lighting) function
 | 
				
			||||||
        out += "specular_sum += " + clamp_highlights + " * " + d0_lut_value + " * " + light_src + ".specular_0 * " + dist_atten + ";\n";
 | 
					        out += "specular_sum += " + clamp_highlights + " * " + d0_lut_value + " * " + light_src + ".specular_0 * " + dist_atten + ";\n";
 | 
				
			||||||
@ -463,15 +465,15 @@ vec4 primary_fragment_color = vec4(0.0);
 | 
				
			|||||||
vec4 secondary_fragment_color = vec4(0.0);
 | 
					vec4 secondary_fragment_color = vec4(0.0);
 | 
				
			||||||
)";
 | 
					)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.lighting_enabled)
 | 
					 | 
				
			||||||
        WriteLighting(out, config);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Do not do any sort of processing if it's obvious we're not going to pass the alpha test
 | 
					    // Do not do any sort of processing if it's obvious we're not going to pass the alpha test
 | 
				
			||||||
    if (config.alpha_test_func == Regs::CompareFunc::Never) {
 | 
					    if (config.alpha_test_func == Regs::CompareFunc::Never) {
 | 
				
			||||||
        out += "discard; }";
 | 
					        out += "discard; }";
 | 
				
			||||||
        return out;
 | 
					        return out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (config.lighting.enable)
 | 
				
			||||||
 | 
					        WriteLighting(out, config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    out += "vec4 combiner_buffer = vec4(0.0);\n";
 | 
					    out += "vec4 combiner_buffer = vec4(0.0);\n";
 | 
				
			||||||
    out += "vec4 next_combiner_buffer = tev_combiner_buffer_color;\n";
 | 
					    out += "vec4 next_combiner_buffer = tev_combiner_buffer_color;\n";
 | 
				
			||||||
    out += "vec4 last_tex_env_out = vec4(0.0);\n";
 | 
					    out += "vec4 last_tex_env_out = vec4(0.0);\n";
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user