80 lines
2.5 KiB
GLSL
80 lines
2.5 KiB
GLSL
// XC_BUILTIN_SKYBOX_OPENGL_PS
|
|
#version 430
|
|
|
|
layout(binding = 0) uniform sampler2D uSkyboxPanoramicTexture;
|
|
layout(binding = 1) uniform samplerCube uSkyboxTexture;
|
|
|
|
layout(std140, binding = 0) uniform EnvironmentConstants {
|
|
vec4 gSkyboxTopColor;
|
|
vec4 gSkyboxHorizonColor;
|
|
vec4 gSkyboxBottomColor;
|
|
vec4 gCameraRightAndTanHalfFov;
|
|
vec4 gCameraUpAndAspect;
|
|
vec4 gCameraForwardAndUnused;
|
|
};
|
|
|
|
layout(std140, binding = 1) uniform MaterialConstants {
|
|
vec4 gSkyboxTintAndExposure;
|
|
vec4 gSkyboxRotationAndMode;
|
|
};
|
|
|
|
in vec2 vNdc;
|
|
|
|
layout(location = 0) out vec4 fragColor;
|
|
|
|
const float XC_PI = 3.14159265358979323846;
|
|
const float XC_INV_PI = 0.31830988618379067154;
|
|
const float XC_INV_TWO_PI = 0.15915494309189533577;
|
|
|
|
vec3 EvaluateProceduralSkybox(vec3 viewRay) {
|
|
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));
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
vec3 RotateAroundY(vec3 viewRay) {
|
|
float rotation = gSkyboxRotationAndMode.x;
|
|
float sinTheta = sin(rotation);
|
|
float cosTheta = cos(rotation);
|
|
return normalize(vec3(
|
|
viewRay.x * cosTheta - viewRay.z * sinTheta,
|
|
viewRay.y,
|
|
viewRay.x * sinTheta + viewRay.z * cosTheta));
|
|
}
|
|
|
|
vec2 ComputePanoramicUv(vec3 viewRay) {
|
|
vec3 rotatedRay = RotateAroundY(viewRay);
|
|
float u = fract(atan(rotatedRay.z, rotatedRay.x) * XC_INV_TWO_PI + 0.5);
|
|
float v = acos(clamp(rotatedRay.y, -1.0, 1.0)) * XC_INV_PI;
|
|
return vec2(u, clamp(v, 0.0, 1.0));
|
|
}
|
|
|
|
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);
|
|
|
|
vec3 color = EvaluateProceduralSkybox(viewRay);
|
|
if (gSkyboxRotationAndMode.y > 1.5) {
|
|
color = texture(uSkyboxTexture, RotateAroundY(viewRay)).rgb *
|
|
gSkyboxTintAndExposure.rgb *
|
|
gSkyboxTintAndExposure.w;
|
|
} else if (gSkyboxRotationAndMode.y > 0.5) {
|
|
color = texture(uSkyboxPanoramicTexture, ComputePanoramicUv(viewRay)).rgb *
|
|
gSkyboxTintAndExposure.rgb *
|
|
gSkyboxTintAndExposure.w;
|
|
}
|
|
|
|
fragColor = vec4(color, 1.0);
|
|
}
|