// [新增] 相机背景天空盒。 // 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 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); }