#version 300 es
precision highp float;

uniform sampler2D uMainTex;
uniform float uBokehRadius;  // 控制散景效果的半径
uniform float uScreenRatio;  // 屏幕宽高比
uniform float uIntensity;    // 光斑强度
uniform float uRotation;     // 旋转角度

in vec2 v_originTexCoord;
out vec4 fragColor;

// 散景效果参数
const int SAMPLE_COUNT = 150;            // 采样次数
const float HIGHLIGHT_POWER = 4.0;       // 高光强度
const float SAFE_MARGIN = 0.01;          // 安全边距

// 安全的纹理采样
vec4 sampleTextureSafe(sampler2D tex, vec2 uv) {
    if (uv.x < SAFE_MARGIN || uv.x > (1.0 - SAFE_MARGIN) || 
        uv.y < SAFE_MARGIN || uv.y > (1.0 - SAFE_MARGIN)) {
        return texture(uMainTex, v_originTexCoord);
    }
    return texture(tex, uv);
}

// 计算散景效果
vec3 calculateBokeh(vec2 uv) {
    // 构建旋转矩阵
    mat2 rotationMatrix = mat2(
        cos(uRotation), sin(uRotation),
        -sin(uRotation), cos(uRotation)
    );
    
    // 累积颜色和权重
    vec3 totalColor = vec3(0.0);
    vec3 totalWeight = vec3(0.0);
    
    // 计算初始采样步长，考虑屏幕比例进行补偿
    float stepLength = 1.0;
    float baseRadius = uBokehRadius * 0.01 / sqrt(float(SAMPLE_COUNT));
    
    // 初始采样偏移，确保圆形光斑
    vec2 offset = vec2(0.0, baseRadius);
    
    // 进行旋转采样
    for(int i = 0; i < SAMPLE_COUNT; i++) {
        // 更新步长
        stepLength += 1.0/stepLength;
        
        // 旋转采样向量
        offset = rotationMatrix * offset;
        
        // 计算实际采样位置，对x方向进行屏幕比例补偿
        vec2 sampleOffset = offset * vec2(1.0/uScreenRatio, 1.0);
        
        // 采样并处理颜色
        vec3 sampledColor = sampleTextureSafe(uMainTex, uv + (stepLength - 1.0) * sampleOffset).rgb;
        sampledColor *= sampledColor * uIntensity;  // 使用传入的强度参数
        
        // 计算权重
        vec3 weight = pow(sampledColor, vec3(HIGHLIGHT_POWER));
        
        // 累积结果
        totalColor += sampledColor * weight;
        totalWeight += weight;
    }
    
    // 返回加权平均结果
    return totalColor / totalWeight;
}

void main() {
    // 根据散景半径决定是否应用效果
    if(uBokehRadius <= 0.0) {
        fragColor = texture(uMainTex, v_originTexCoord);
    } else {
        fragColor = vec4(calculateBokeh(v_originTexCoord), 1.0);
    }
}