/*
 * =======================================================================================
 *
 * COLORED PARTICLES SYSTEM MODULE
 * Lunara Shader - Dynamic Light Particles
 *
 * =======================================================================================
 *
 * Copyright (c) 2025 Lunara Development
 * All rights reserved. Unauthorized reproduction or distribution is prohibited.
 *
 * This module implements dynamic colored particle effects based on volumetric lighting
 * calculations. It creates atmospheric particle systems that respond to light sources
 * and environmental conditions for visual immersion.
 *
 * =======================================================================================
 */

//=======================================================================================
// COLORED PARTICLES RENDERING FUNCTION
//=======================================================================================

/**
 * Generates colored particle effects based on volumetric light calculations
 * @param nPlayerPos: Normalized player view direction vector
 * @param translucentMult: Transparency multiplier for particles behind objects
 * @param lViewPos: Current view distance for primary objects
 * @param lViewPos1: Extended view distance for particle calculations
 * @param dither: Temporal dithering value for smooth particle sampling
 * @return: Final colored particle contribution as RGB vector
 */
vec3 lu_GetColoredParticles(vec3 nPlayerPos, vec3 translucentMult, float lViewPos, float lViewPos1, float dither)
{
    // Initialize particle accumulator
    vec3 particleAccumulation = vec3(0.0);

    // Define sampling parameters for particle ray marching
    const float samplingStepSize = 8.0;

    // Calculate maximum sampling distance with performance limits
    float maxSamplingDistance = min(effectiveACLdistance * 0.5, far);
    int totalSamples = int(maxSamplingDistance / samplingStepSize + 0.001);

    // Setup ray marching vectors
    vec3 rayStepVector = nPlayerPos * samplingStepSize;
    vec3 currentRayPosition = rayStepVector * dither;

    // Main particle sampling loop
    for (int i = 0; i < totalSamples; i++) {
        float currentDistance = length(currentRayPosition);

        // Early exit conditions for performance optimization
        if (currentDistance > lViewPos1) break;
        if (any(greaterThan(abs(currentRayPosition * 2.0), vec3(voxelVolumeSize)))) break;

        // Transform world position to voxel coordinate space
        vec3 voxelCoordinates = SceneToVoxel(currentRayPosition);
        voxelCoordinates = lu_clamp01(voxelCoordinates / vec3(voxelVolumeSize));

        // Sample volumetric light data at current position
        vec4 volumetricLightData = GetLightVolume(voxelCoordinates);
        vec3 lightContribution = volumetricLightData.rgb;

        // Calculate distance-based attenuation with quality scaling
        float attenuationDistance = length(
            vec3(
                currentRayPosition.x,
                #if LU_COLORED_LIGHTING_INTERNAL <= 512
                    currentRayPosition.y * 2.0,    // Standard quality scaling
                #elif LU_COLORED_LIGHTING_INTERNAL == 768
                    currentRayPosition.y * 3.0,    // quality scaling
                #elif LU_COLORED_LIGHTING_INTERNAL == 1024
                    currentRayPosition.y * 4.0,    // Maximum quality scaling
                #endif
                currentRayPosition.z
            )
        );

        // Apply distance-based light falloff
        lightContribution *= lu_max0(1.0 - attenuationDistance / maxSamplingDistance);

        // Apply distance-based particle intensity scaling
        lightContribution *= lu_pow2(lu_min1(currentDistance * 0.03125));

        // Apply transparency effects for occluded particles
        if (currentDistance > lViewPos) {
            lightContribution *= translucentMult;
        }

        // Accumulate particle contribution
        particleAccumulation += lightContribution;

        // Advance ray position for next sample
        currentRayPosition += rayStepVector;
    }

    // Apply environment-specific particle modifications
    #ifdef NETHER
        particleAccumulation *= netherColor * 5.0;
    #endif

    // Apply global visibility modifiers
    particleAccumulation *= 1.0 - maxBlindnessDarkness;

    // Normalize and apply gamma correction for final output
    return pow(particleAccumulation / totalSamples, vec3(0.25));
}

//=======================================================================================
// LEGACY COMPATIBILITY
//=======================================================================================

// Maintain backward compatibility with existing shader code
#define LU_GetColoredLightFog GetColoredParticles
