Add procedural skybox scene coverage

This commit is contained in:
2026-04-05 23:44:32 +08:00
parent be2013f3c4
commit 8151be0f45
27 changed files with 1092 additions and 5 deletions

View File

@@ -0,0 +1,35 @@
// XC_BUILTIN_SKYBOX_OPENGL_PS
#version 430
layout(std140, binding = 0) uniform EnvironmentConstants {
vec4 gSkyboxTopColor;
vec4 gSkyboxHorizonColor;
vec4 gSkyboxBottomColor;
vec4 gCameraRightAndTanHalfFov;
vec4 gCameraUpAndAspect;
vec4 gCameraForwardAndUnused;
};
in vec2 vNdc;
layout(location = 0) out vec4 fragColor;
void main() {
float tanHalfFov = gCameraRightAndTanHalfFov.w;
float aspect = gCameraUpAndAspect.w;
vec3 viewRay = normalize(
gCameraForwardAndUnused.xyz +
vNdc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
vNdc.y * tanHalfFov * gCameraUpAndAspect.xyz);
float vertical = clamp(viewRay.y, -1.0, 1.0);
vec3 color = gSkyboxHorizonColor.rgb;
if (vertical >= 0.0) {
color = mix(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(clamp(vertical, 0.0, 1.0), 0.65));
} else {
color = mix(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(clamp(-vertical, 0.0, 1.0), 0.55));
}
fragColor = vec4(color, 1.0);
}

View File

@@ -0,0 +1,35 @@
// XC_BUILTIN_SKYBOX_VULKAN_PS
#version 450
layout(set = 0, binding = 0, std140) uniform EnvironmentConstants {
vec4 gSkyboxTopColor;
vec4 gSkyboxHorizonColor;
vec4 gSkyboxBottomColor;
vec4 gCameraRightAndTanHalfFov;
vec4 gCameraUpAndAspect;
vec4 gCameraForwardAndUnused;
};
layout(location = 0) in vec2 vNdc;
layout(location = 0) out vec4 fragColor;
void main() {
float tanHalfFov = gCameraRightAndTanHalfFov.w;
float aspect = gCameraUpAndAspect.w;
vec3 viewRay = normalize(
gCameraForwardAndUnused.xyz +
vNdc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
vNdc.y * tanHalfFov * gCameraUpAndAspect.xyz);
float vertical = clamp(viewRay.y, -1.0, 1.0);
vec3 color = gSkyboxHorizonColor.rgb;
if (vertical >= 0.0) {
color = mix(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(clamp(vertical, 0.0, 1.0), 0.65));
} else {
color = mix(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(clamp(-vertical, 0.0, 1.0), 0.55));
}
fragColor = vec4(color, 1.0);
}

View File

@@ -0,0 +1,34 @@
// XC_BUILTIN_SKYBOX_D3D12_PS
cbuffer EnvironmentConstants : register(b0) {
float4 gSkyboxTopColor;
float4 gSkyboxHorizonColor;
float4 gSkyboxBottomColor;
float4 gCameraRightAndTanHalfFov;
float4 gCameraUpAndAspect;
float4 gCameraForwardAndUnused;
}
struct PSInput {
float4 position : SV_POSITION;
float2 ndc : TEXCOORD0;
};
float4 MainPS(PSInput input) : SV_Target {
const float tanHalfFov = gCameraRightAndTanHalfFov.w;
const float aspect = gCameraUpAndAspect.w;
float3 viewRay = normalize(
gCameraForwardAndUnused.xyz +
input.ndc.x * aspect * tanHalfFov * gCameraRightAndTanHalfFov.xyz +
input.ndc.y * tanHalfFov * gCameraUpAndAspect.xyz);
const float vertical = clamp(viewRay.y, -1.0f, 1.0f);
float3 color = gSkyboxHorizonColor.rgb;
if (vertical >= 0.0f) {
color = lerp(gSkyboxHorizonColor.rgb, gSkyboxTopColor.rgb, pow(saturate(vertical), 0.65f));
} else {
color = lerp(gSkyboxHorizonColor.rgb, gSkyboxBottomColor.rgb, pow(saturate(-vertical), 0.55f));
}
return float4(color, 1.0f);
}

View File

@@ -0,0 +1,22 @@
Shader "Builtin Skybox"
{
SubShader
{
Pass
{
Name "Skybox"
Tags { "LightMode" = "Skybox" }
Resources
{
EnvironmentConstants (ConstantBuffer, 0, 0) [Semantic(Environment)]
}
HLSLPROGRAM
#pragma vertex MainVS
#pragma fragment MainPS
#pragma backend D3D12 HLSL "skybox.vs.hlsl" "skybox.ps.hlsl" vs_5_0 ps_5_0
#pragma backend OpenGL GLSL "skybox.vert.glsl" "skybox.frag.glsl"
#pragma backend Vulkan GLSL "skybox.vert.vk.glsl" "skybox.frag.vk.glsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,16 @@
// XC_BUILTIN_SKYBOX_OPENGL_VS
#version 430
out vec2 vNdc;
void main() {
const vec2 positions[3] = vec2[3](
vec2(-1.0, -1.0),
vec2(-1.0, 3.0),
vec2( 3.0, -1.0)
);
vec2 position = positions[gl_VertexID];
gl_Position = vec4(position, 1.0, 1.0);
vNdc = position;
}

View File

@@ -0,0 +1,16 @@
// XC_BUILTIN_SKYBOX_VULKAN_VS
#version 450
layout(location = 0) out vec2 vNdc;
void main() {
const vec2 positions[3] = vec2[3](
vec2(-1.0, -1.0),
vec2(-1.0, 3.0),
vec2( 3.0, -1.0)
);
vec2 position = positions[gl_VertexIndex];
gl_Position = vec4(position, 1.0, 1.0);
vNdc = position;
}

View File

@@ -0,0 +1,18 @@
// XC_BUILTIN_SKYBOX_D3D12_VS
struct VSOutput {
float4 position : SV_POSITION;
float2 ndc : TEXCOORD0;
};
VSOutput MainVS(uint vertexId : SV_VertexID) {
const float2 positions[3] = {
float2(-1.0f, -1.0f),
float2(-1.0f, 3.0f),
float2( 3.0f, -1.0f)
};
VSOutput output;
output.position = float4(positions[vertexId], 1.0f, 1.0f);
output.ndc = positions[vertexId];
return output;
}