#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Core/DescentHandle.h" #include "DescentEnvironment.generated.h" class UDirectionalLightComponent; class UDescentLightPool; class UExponentialHeightFogComponent; class UMaterialParameterCollection; class UPostProcessComponent; /** Where the camera is: in the sea (the water post-process applies) or inside dry air (the carrier's interior). */ UENUM() enum class EDescentEnv : uint8 { Water, Dry, }; /** * The look of the world (DESIGN_UE.md section 7): there is no sky, no sky light and no global illumination. A pixel is lit * by local lights with an art-directed falloff, the surface sun (only near the top of the Throat), a small ambient term in * the materials, emissive surfaces, and one post-process material (PP_Water) that turns distance into water. Exposure is * manual and fixed. This actor owns the pieces of that: volumetric-only height fog, one unbound post-process component * (manual exposure, the reworked bloom of U12, vignette, grain), the surface sun, the light pool, and it writes * MPC_Descent once per frame in the Environment late step (after the camera has moved). * * Dry interiors (U6): when the environment query says the camera is dry (a carrier registers its hull), the volumetric fog * fades out over 0.3 s and marine snow is hidden; PP_Water itself leaves every pixel with custom stencil 1 alone, so the * interior is never fogged whichever way the camera looks. * * It is the ONLY authority for exposure, fog and post-process: nothing else (the showcase rig, the scenarios) brings an environment. */ UCLASS() class THEDESCENT_API ADescentEnvironment : public AActor { GENERATED_BODY() public: ADescentEnvironment(); static ADescentEnvironment* Get(const UWorld* World); virtual void BeginPlay() override; virtual void EndPlay(const EEndPlayReason::Type Reason) override; EDescentEnv GetEnvState() const { return EnvState; } UDescentLightPool* GetLightPool() const { return LightPool; } /** Descent.Look.Set: Exposure, Bloom, WaterPP, Volumetric, Snow, Lamp. False and an error text for an unknown parameter. */ bool SetLookParam(const FString& Name, double Value, FString& OutError); /** L(Z) of section 2.7. */ static double SurfaceLightAt(double ZMetres); // ---- numbers for the `env` state section ---- double SurfaceLight = 0.0; double FogDensityValue = 0.0; bool bVolumetricOn = true; bool bSunOn = false; double TemperatureC = 0.0; int32 SnowInstancesVisible = 0; bool bSnowSwitch = true; double WaterAmount = 1.0; bool bVolumetricSwitch = true; private: void UpdateLook(double Dt); void CommitLights(); UPROPERTY() TObjectPtr Fog; UPROPERTY() TObjectPtr PostProcess; UPROPERTY() TObjectPtr Sun; UPROPERTY() TObjectPtr LightPool; UPROPERTY() TObjectPtr Mpc; EDescentEnv EnvState = EDescentEnv::Water; double VolBlend = 1.0; // 1 = volumetric fog fully on, 0 = off (dry) FDescentHandle EnvHandle; FDescentHandle PoolHandle; FVector LastCameraUU = FVector::ZeroVector; bool bBlendableAdded = false; };