namespace Sandbox.Rendering;
///
/// When manually rendering a camera this will let you override specific
/// elements of that render. This means you can use most of the camera's
/// properties, but override some without disturbing the camera itself.
///
public struct ViewSetup
{
///
/// Overrides the camera's position and rotation
///
public Transform? Transform;
///
/// Overrides the camera's field of view
///
public float? FieldOfView;
///
/// Overrides the camera's znear
///
public float? ZNear;
///
/// Overrides the camera's zfar
///
public float? ZFar;
///
/// Overrides the camera's clear color
///
public Color? ClearColor;
///
/// Overrides the camera's projection matrix
///
public Matrix? ProjectionMatrix;
///
/// Allows overriding gradient fog for this view
///
public GradientFogSetup? GradientFog;
///
/// If set then the regular scene's ambient light will be multiplied by this
///
public Color? AmbientLightTint;
///
/// If set then this will be added to the ambient light color
///
public Color? AmbientLightAdd;
///
/// Clipspace is usually used for rendering posters, or center-offsetting the view. You're basically zooming
/// into a subrect of the clipspace. So imagine you draw a smaller rect inside the first rect of the frustum..
/// that's what you're gonna render - that rect.
///
public Vector4? ClipSpaceBounds;
///
/// When rendering to a texture, this allows you to flip the view horizontally.
///
public bool? FlipX;
///
/// When rendering to a texture, this allows you to flip the view vertically.
///
public bool? FlipY;
///
/// Whether post processing should be enabled for this view. If null it will use the camera's setting.
///
public bool? EnablePostprocessing;
///
/// If you're rendering a subview this will allow the renderer to find the same view again next frame
///
public int ViewHash;
}
///
/// Setup for defining gradient fog in a view
///
public struct GradientFogSetup
{
///
/// Whether the fog is enabled.
///
public bool Enabled { get; set; }
///
/// Start distance of the fog.
///
public float StartDistance { get; set; }
///
/// End distance of the fog.
///
public float EndDistance { get; set; }
///
/// The starting height of the gradient fog.
///
public float StartHeight { get; set; }
///
/// The ending height of the gradient fog.
///
public float EndHeight { get; set; }
///
/// The maximum opacity of the gradient fog.
///
public float MaximumOpacity { get; set; }
///
/// The color of the gradient fog.
///
public Color Color { get; set; }
///
/// The exponent controlling the distance-based falloff of the fog.
///
public float DistanceFalloffExponent { get; set; }
///
/// The exponent controlling the vertical falloff of the fog.
///
public float VerticalFalloffExponent { get; set; }
internal void Apply( RenderAttributes attributes )
{
if ( !Enabled )
{
attributes.SetCombo( "D_ENABLE_GRADIENT_FOG", 0 );
return;
}
attributes.SetCombo( "D_ENABLE_GRADIENT_FOG", 1 );
attributes.Set( "GradientFogParams", new Vector4( StartDistance, EndDistance, StartHeight, EndHeight ) );
attributes.Set( "GradientFogParams2", new Vector4( MaximumOpacity, DistanceFalloffExponent, VerticalFalloffExponent, 0.0f ) );
attributes.Set( "GradientFogParams3", new Vector4( Color, 0.0f ) * Color.a );
}
///
/// Lerp this GradientFogSetup to a another, allowing transition states.
///
public GradientFogSetup LerpTo( GradientFogSetup desired, float delta, bool clamp = true )
{
if ( Enabled != desired.Enabled )
return desired;
GradientFogSetup newState = default;
newState.StartDistance = StartDistance.LerpTo( desired.StartDistance, delta, clamp );
newState.EndDistance = EndDistance.LerpTo( desired.EndDistance, delta, clamp );
newState.StartHeight = StartHeight.LerpTo( desired.StartHeight, delta, clamp );
newState.EndHeight = EndHeight.LerpTo( desired.EndHeight, delta, clamp );
newState.MaximumOpacity = MaximumOpacity.LerpTo( desired.MaximumOpacity, delta, clamp );
newState.DistanceFalloffExponent = DistanceFalloffExponent.LerpTo( desired.DistanceFalloffExponent, delta, clamp );
newState.VerticalFalloffExponent = VerticalFalloffExponent.LerpTo( desired.VerticalFalloffExponent, delta, clamp );
newState.Color = Color.Lerp( Color, desired.Color, delta );
return newState;
}
}
///
/// Allows special setup for reflections, such as offsetting the reflection plane
///
public struct ReflectionSetup
{
///
/// Allows overriding everything you normally can
///
public ViewSetup ViewSetup;
///
/// Offset the reflection plane's clip plane by this much
///
public float ClipOffset;
///
/// If true we'll render the reflection even if we're behind the plane
///
public bool RenderBehind;
///
/// If we can't render the reflection and this is set, we'll clear the render target to this color
///
public Color? FallbackColor { get; set; }
// TODO - stencil? clip rect?
}
///
/// Allows special setup for refraction, such as offsetting the clip plane
///
public struct RefractionSetup
{
///
/// Allows overriding everything you normally can
///
public ViewSetup ViewSetup;
///
/// Offset the reflection plane's clip plane by this much
///
public float ClipOffset;
///
/// If true we'll render the reflection even if we're behind the plane
///
public bool RenderBehind;
///
/// If we can't render the reflection and this is set, we'll clear the render target to this color
///
public Color? FallbackColor { get; set; }
// TODO - stencil? clip rect?
}
///
/// When manually rendering a Renderer this will let you override specific
/// elements of that render. This means you can use most of the Renderer's
/// properties, but override some without disturbing the Renderer itself.
///
public struct RendererSetup
{
///
/// Overrides the transform used for rendering
///
public Transform? Transform;
///
/// Overrides the color used for rendering
///
public Color? Color;
///
/// Overrides the material used for rendering
///
public Material Material;
}