// [新增] 相机背景天空盒。
// CPU 不创建天空盒网格；VS 使用 SV_VertexID 读取内置 36 个顶点。

#pragma pack_matrix(row_major)
#include "include/pbr_brdf.hlsli"

cbuffer CBScene : register(b0) {
    row_major float4x4 gView;
    row_major float4x4 gProjection;
    float4 gCameraPosition;
    float4 gLightDirection;
    float4 gLightColorIntensity;
    float4 gAmbientColorIntensity;
    float4 gRenderParams;            // x=exposure
};

cbuffer CBIBL : register(b4) {
    // x=intensity, y=prefilter max mip, z=Y rotation, w=enabled
    float4 gIblParams;
};

TextureCube<float4> gSkyboxCube : register(t12);
SamplerState gSkyboxSampler : register(s4);

static const float3 gCubeVertices[36] = {
    // -Z
    float3(-1.0f, -1.0f, -1.0f), float3(-1.0f,  1.0f, -1.0f), float3( 1.0f,  1.0f, -1.0f),
    float3(-1.0f, -1.0f, -1.0f), float3( 1.0f,  1.0f, -1.0f), float3( 1.0f, -1.0f, -1.0f),
    // +Z
    float3(-1.0f, -1.0f,  1.0f), float3( 1.0f,  1.0f,  1.0f), float3(-1.0f,  1.0f,  1.0f),
    float3(-1.0f, -1.0f,  1.0f), float3( 1.0f, -1.0f,  1.0f), float3( 1.0f,  1.0f,  1.0f),
    // -X
    float3(-1.0f, -1.0f, -1.0f), float3(-1.0f, -1.0f,  1.0f), float3(-1.0f,  1.0f,  1.0f),
    float3(-1.0f, -1.0f, -1.0f), float3(-1.0f,  1.0f,  1.0f), float3(-1.0f,  1.0f, -1.0f),
    // +X
    float3( 1.0f, -1.0f, -1.0f), float3( 1.0f,  1.0f,  1.0f), float3( 1.0f, -1.0f,  1.0f),
    float3( 1.0f, -1.0f, -1.0f), float3( 1.0f,  1.0f, -1.0f), float3( 1.0f,  1.0f,  1.0f),
    // -Y
    float3(-1.0f, -1.0f, -1.0f), float3( 1.0f, -1.0f,  1.0f), float3(-1.0f, -1.0f,  1.0f),
    float3(-1.0f, -1.0f, -1.0f), float3( 1.0f, -1.0f, -1.0f), float3( 1.0f, -1.0f,  1.0f),
    // +Y
    float3(-1.0f,  1.0f, -1.0f), float3(-1.0f,  1.0f,  1.0f), float3( 1.0f,  1.0f,  1.0f),
    float3(-1.0f,  1.0f, -1.0f), float3( 1.0f,  1.0f,  1.0f), float3( 1.0f,  1.0f, -1.0f)
};

struct VSOutput {
    float4 positionCS : SV_POSITION;
    float3 directionWS : TEXCOORD0;
};

VSOutput VSMain(uint vertexId : SV_VertexID) {
    VSOutput output;

    const float3 positionWS = gCubeVertices[vertexId];

    // [修改] w=0 只应用相机旋转，不应用相机平移；天空盒因此始终以相机为中心。
    const float3 positionVS = mul(float4(positionWS, 0.0f), gView).xyz;
    float4 positionCS = mul(float4(positionVS, 1.0f), gProjection);

    // [新增] 固定到远平面；配合 LESS_EQUAL 和深度不写入，仅覆盖背景像素。
    positionCS.z = positionCS.w;

    output.positionCS = positionCS;
    output.directionWS = positionWS;
    return output;
}

float3 RotateAroundY(float3 direction, float radians) {
    float sineValue;
    float cosineValue;
    sincos(radians, sineValue, cosineValue);

    return float3(
        cosineValue * direction.x + sineValue * direction.z,
        direction.y,
        -sineValue * direction.x + cosineValue * direction.z);
}

float4 PSMain(VSOutput input) : SV_TARGET {
    const float3 sampleDirection = RotateAroundY(
        normalize(input.directionWS), gIblParams.z);

    float3 color = gSkyboxCube.SampleLevel(
        gSkyboxSampler, sampleDirection, 0.0f).rgb;
    // [修改] enabled 只控制物体 IBL；天空背景在 Cube 已加载时始终显示。
    color *= max(gIblParams.x, 0.0f);

    // 与 PBR 物体使用相同曝光、色调映射和显示编码。
    color *= max(gRenderParams.x, 0.0f);
    color = ToneMapACES(color);
    color = pow(max(color, 0.0f), 1.0f / 2.2f);
    return float4(color, 1.0f);
}
