skyMaterial: SkyMaterial {
iblSampleCount: 256
property color skyTopColor: "#A5D6F1"
property color skyHorizonColor: "#D6EAFA"
property real skyCurve: 0.09
property real skyEnergy: 1.0
property color groundBottomColor: "#282F36"
property color groundHorizonColor: "#6C655F"
property real groundCurve: 0.02
property real groundEnergy: 1.0
property color sunColor: "#ffffff"
property real sunLatitude: 35.0
property real sunLongitude: 0.0
property real sunAngleMin: 1.0
property real sunAngleMax: 100.0
property real sunCurve: 0.05
property real sunEnergy: 1.0
readonly property vector3d sunDirection: {
const latRad = sunLatitude * Math.PI / 180.0
const lonRad = sunLongitude * Math.PI / 180.0
return Qt.vector3d(
-Math.cos(lonRad) * Math.cos(latRad),
Math.sin(latRad),
-Math.sin(lonRad) * Math.cos(latRad)
)
}
fragmentShaderCode: `
const float PI = 3.14159265359;
const float HALF_PI = PI * 0.5;
float ease(float x, float c)
{
x = clamp(x, 0.0, 1.0);
if (c > 0.0) {
if (c < 1.0)
return 1.0 - pow(1.0 - x, 1.0 / c);
return pow(x, c);
}
if (c < 0.0) {
if (x < 0.5)
return pow(x * 2.0, -c) * 0.5;
return (1.0 - pow(1.0 - (x - 0.5) * 2.0, -c)) * 0.5 + 0.5;
}
return 0.0;
}
void MAIN()
{
vec3 direction = normalize(qt_eyeDir);
float vAngle = acos(clamp(direction.y, -1.0, 1.0));
vec3 color;
if (direction.y < 0.0) {
float t = ease((vAngle - HALF_PI) / HALF_PI, groundCurve);
color = mix(groundHorizonColor.rgb, groundBottomColor.rgb, t) * groundEnergy;
} else {
float t = ease(1.0 - vAngle / HALF_PI, skyCurve);
color = mix(skyHorizonColor.rgb, skyTopColor.rgb, t) * skyEnergy;
float sunAngle = degrees(acos(clamp(dot(normalize(sunDirection), direction), -1.0, 1.0)));
vec3 sunRadiance = sunColor.rgb * sunEnergy;
if (sunAngle < sunAngleMin) {
color = sunRadiance;
} else if (sunAngle < sunAngleMax) {
float tSun = ease(
(sunAngle - sunAngleMin) / (sunAngleMax - sunAngleMin),
sunCurve
);
color = mix(sunRadiance, color, tSun);
}
}
FRAGCOLOR = vec4(color, 1.0);
}
`
}