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