mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	renderer_opengl: Implement HW fragment lighting distance attenuation.
This commit is contained in:
		
							parent
							
								
									e9af70eaf3
								
							
						
					
					
						commit
						e34fa6365f
					
				@ -78,9 +78,13 @@ struct PicaShaderConfig {
 | 
			
		||||
 | 
			
		||||
        for (unsigned light_index = 0; light_index < res.num_lights; ++light_index) {
 | 
			
		||||
            unsigned num = regs.lighting.light_enable.GetNum(light_index);
 | 
			
		||||
            const auto& light = regs.lighting.light[num];
 | 
			
		||||
            res.light_src[light_index].num = num;
 | 
			
		||||
            res.light_src[light_index].directional = regs.lighting.light[num].w;
 | 
			
		||||
            res.light_src[light_index].two_sided_diffuse = regs.lighting.light[num].two_sided_diffuse;
 | 
			
		||||
            res.light_src[light_index].directional = light.w;
 | 
			
		||||
            res.light_src[light_index].two_sided_diffuse = light.two_sided_diffuse;
 | 
			
		||||
            res.light_src[light_index].dist_atten_enabled = regs.lighting.dist_atten_enable.IsEnabled(num);
 | 
			
		||||
            res.light_src[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();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return res;
 | 
			
		||||
@ -98,19 +102,23 @@ struct PicaShaderConfig {
 | 
			
		||||
        return std::memcmp(this, &o, sizeof(PicaShaderConfig)) == 0;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Pica::Regs::CompareFunc alpha_test_func;
 | 
			
		||||
    std::array<Pica::Regs::TevStageConfig, 6> tev_stages = {};
 | 
			
		||||
    u8 combiner_buffer_input;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        unsigned num;
 | 
			
		||||
        bool directional;
 | 
			
		||||
        bool two_sided_diffuse;
 | 
			
		||||
        bool dist_atten_enabled;
 | 
			
		||||
    } light_src[8];
 | 
			
		||||
        Pica::Regs::CompareFunc alpha_test_func = Pica::Regs::CompareFunc::Never;
 | 
			
		||||
        std::array<Pica::Regs::TevStageConfig, 6> tev_stages = {};
 | 
			
		||||
        u8 combiner_buffer_input = 0;
 | 
			
		||||
 | 
			
		||||
    bool lighting_enabled;
 | 
			
		||||
    unsigned num_lights;
 | 
			
		||||
        struct {
 | 
			
		||||
            unsigned num = 0;
 | 
			
		||||
            bool directional = false;
 | 
			
		||||
            bool two_sided_diffuse = false;
 | 
			
		||||
            bool dist_atten_enabled = false;
 | 
			
		||||
            GLfloat dist_atten_scale = 0.0f;
 | 
			
		||||
            GLfloat dist_atten_bias = 0.0f;
 | 
			
		||||
        } light_src[8];
 | 
			
		||||
 | 
			
		||||
        bool lighting_enabled = false;
 | 
			
		||||
        unsigned num_lights = 0;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace std {
 | 
			
		||||
 | 
			
		||||
@ -371,12 +371,13 @@ vec4 primary_fragment_color = vec4(0.0);
 | 
			
		||||
 | 
			
		||||
        for (unsigned light_index = 0; light_index < config.num_lights; ++light_index) {
 | 
			
		||||
            unsigned num = config.light_src[light_index].num;
 | 
			
		||||
            std::string light_src = "light_src[" + std::to_string(num) + "]";
 | 
			
		||||
 | 
			
		||||
            std::string light_vector;
 | 
			
		||||
            if (config.light_src[light_index].directional)
 | 
			
		||||
                light_vector = "normalize(-light_src[" + std::to_string(num) + "].position)";
 | 
			
		||||
                light_vector = "normalize(-" + light_src + ".position)";
 | 
			
		||||
            else
 | 
			
		||||
                light_vector = "normalize(light_src[" + std::to_string(num) + "].position - fragment_position)";
 | 
			
		||||
                light_vector = "normalize(" + light_src + ".position - fragment_position)";
 | 
			
		||||
 | 
			
		||||
            std::string dot_product;
 | 
			
		||||
            if (config.light_src[light_index].two_sided_diffuse)
 | 
			
		||||
@ -384,7 +385,19 @@ vec4 primary_fragment_color = vec4(0.0);
 | 
			
		||||
            else
 | 
			
		||||
                dot_product = "max(dot(" + light_vector + ", normal), 0.0)";
 | 
			
		||||
 | 
			
		||||
            out += "diffuse_sum += ((light_src[" + std::to_string(num) + "].diffuse * " + dot_product + ") + light_src[" + std::to_string(num) + "].ambient) * 1.0;\n";
 | 
			
		||||
            std::string dist_atten = "1.0";
 | 
			
		||||
            if (config.light_src[light_index].dist_atten_enabled) {
 | 
			
		||||
                std::string scale = std::to_string(config.light_src[light_index].dist_atten_scale);
 | 
			
		||||
                std::string bias = std::to_string(config.light_src[light_index].dist_atten_bias);
 | 
			
		||||
                std::string lut_index = "(" + scale + " * length(fragment_position - " + light_src + ".position) + " + bias + ")";
 | 
			
		||||
                std::string clamped_lut_index = "((clamp(int(" + lut_index + " * 256.0), 0, 255)))";
 | 
			
		||||
 | 
			
		||||
                unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + num);
 | 
			
		||||
 | 
			
		||||
                dist_atten = "lighting_lut_" + std::to_string(lut_num /4) + "[" + clamped_lut_index + "][" + std::to_string(lut_num & 3) + "]";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            out += "diffuse_sum += ((light_src[" + std::to_string(num) + "].diffuse * " + dot_product + ") + light_src[" + std::to_string(num) + "].ambient) * " + dist_atten + ";\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        out += "diffuse_sum += lighting_global_ambient;\n";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user