diff --git a/src/components/Sky.tsx b/src/components/Sky.tsx
index 97639e4b..d75a7835 100644
--- a/src/components/Sky.tsx
+++ b/src/components/Sky.tsx
@@ -298,6 +298,157 @@ export function SkyBox({
);
}
+/**
+ * Solid color sky component for when useSkyTextures = 0.
+ * Renders SkySolidColor (ignoring alpha) with fog at the horizon.
+ * Uses the same fog logic as SkyBoxTexture for consistency.
+ */
+function SolidColorSky({
+ skyColor,
+ fogColor,
+ fogState,
+}: {
+ skyColor: Color;
+ fogColor?: Color;
+ fogState?: FogState;
+}) {
+ const { camera } = useThree();
+
+ const enableFog = !!fogColor;
+
+ const inverseProjectionMatrix = useMemo(() => {
+ return camera.projectionMatrixInverse;
+ }, [camera]);
+
+ const fogVolumeData = useMemo(
+ () =>
+ fogState ? packFogVolumeData(fogState.fogVolumes) : new Float32Array(12),
+ [fogState],
+ );
+
+ const horizonFogHeight = useMemo(() => {
+ if (!fogState) return 0.18;
+ const mRadius = fogState.visibleDistance * 0.95;
+ const skyBoxPtX = mRadius / Math.sqrt(3);
+ return HORIZON_FOG_HEIGHT / Math.sqrt(skyBoxPtX * skyBoxPtX + HORIZON_FOG_HEIGHT * HORIZON_FOG_HEIGHT);
+ }, [fogState]);
+
+ return (
+
+
+
+
+
+ = volMinH && cameraHeight <= volMaxH) {
+ float rayInfluence;
+ if (direction.y >= 0.0) {
+ rayInfluence = 1.0 - smoothstep(0.0, 0.3, direction.y);
+ } else {
+ rayInfluence = 1.0;
+ }
+ volumeFogInfluence += rayInfluence * volPct;
+ }
+ }
+
+ // Base fog factor from view direction
+ float baseFogFactor;
+ if (direction.y <= 0.0) {
+ baseFogFactor = 1.0;
+ } else if (direction.y >= horizonFogHeight) {
+ baseFogFactor = 0.0;
+ } else {
+ float t = direction.y / horizonFogHeight;
+ baseFogFactor = (1.0 - t) * (1.0 - t);
+ }
+
+ // Combine base fog with volume fog influence
+ float finalFogFactor = min(1.0, baseFogFactor + volumeFogInfluence * 0.5);
+
+ finalColor = mix(skyColor, fogColor, finalFogFactor);
+ } else {
+ finalColor = skyColor;
+ }
+
+ gl_FragColor = vec4(linearToSRGB(finalColor), 1.0);
+ }
+ `}
+ depthWrite={false}
+ depthTest={false}
+ />
+
+ );
+}
+
/**
* Get fog near/far parameters for the distance-based haze.
*
@@ -448,6 +599,9 @@ export function Sky({ object }: { object: TorqueObject }) {
};
}, [scene, gl, hasFogParams, effectiveFogColor, skyColor]);
+ // Get linear sky solid color for the solid color sky shader
+ const linearSkySolidColor = skySolidColor?.[1];
+
return (
<>
{materialList && useSkyTextures ? (
@@ -460,6 +614,13 @@ export function Sky({ object }: { object: TorqueObject }) {
fogState={hasFogParams ? fogState : undefined}
/>
+ ) : linearSkySolidColor ? (
+ /* When useSkyTextures = 0, render solid color sky with SkySolidColor */
+
) : null}
{/* Cloud layers render independently of skybox textures */}