Editor/ShaderGraphPlus/Compiler/Templates/ShaderTemplateSky.cs
using static ShaderGraphPlus.ShaderTemplate;
namespace ShaderGraphPlus;
public static class ShaderTemplateSky
{
public static string Code { get; set; } = @"HEADER
{
Description = ""/*sgp_shader_description*/"";
}
FEATURES
{
/*sgp_shader_feature_defines*/
}
MODES
{
Forward();
}
COMMON
{
/*sgp_shader_common*/
}
struct VertexInput
{
float4 vPositionOs : POSITION < Semantic( PosXyz ); >;
/*sgp_vertex_input_data*/
};
struct PixelInput
{
// Graph nodes (World Position, view vector, triplanar, ...) emit
// ""i.vPositionWithOffsetWs.xyz + g_vHighPrecisionLightingOffsetWs.xyz"",
// so this field has to exist even though the sky builds its own position.
float3 vPositionWithOffsetWs : TEXCOORD1;
float3 vRayWs : TEXCOORD2;
#if ( PROGRAM == VFX_PROGRAM_VS )
float4 vPositionPs : SV_Position;
#endif
#if ( PROGRAM == VFX_PROGRAM_PS )
float4 vPositionSs : SV_Position;
#endif
/*sgp_pixel_input_data*/
};
VS
{
// NOTE: no ""common/vertex.hlsl"" here -- it defines ProcessVertex/FinalizeVertex
// in terms of VS_CommonProcessing, which only exists for the standard vertex
// input path. The sky box builds its own position, so it isn't needed.
#include ""system.fxc""
/*sgp_vertex_globals*/
/*sgp_vertex_combo_rules*/
/*sgp_vertex_functions*/
PixelInput MainVs( VertexInput v )
{
PixelInput i;
// Push the box out to the far plane and keep it centred on the camera
// so the sky never intersects world geometry.
float flSkyboxScale = g_flNearPlane + g_flFarPlane;
float3 vPositionWs = g_vCameraPositionWs.xyz + v.vPositionOs.xyz * flSkyboxScale;
i.vPositionPs = Position3WsToPs( vPositionWs );
// Camera-relative, matching the standard vertex path -- graph nodes add
// g_vHighPrecisionLightingOffsetWs back on to recover absolute world space.
i.vPositionWithOffsetWs = vPositionWs - g_vHighPrecisionLightingOffsetWs.xyz;
i.vRayWs = normalize( v.vPositionOs.xyz );
/*sgp_vertex_code*/
return i;
}
}
PS
{
// PixelInput in this shader has none of the standard mesh fields (normals, tangents,
// lightmap UVs), so Material::Init( PixelInput ) can't read them. This
// switches it to the empty Material::Init() -- see common/material.hlsl.
#define CUSTOM_MATERIAL_INPUTS 1
#include ""common/pixel.hlsl""
/*sgp_pixel_globals*/
/*sgp_pixel_combo_rules*/
/*sgp_pixel_functions*/
// Sky renders behind everything: no depth write, reversed-Z far plane test.
RenderState( DepthWriteEnable, false );
RenderState( DepthEnable, true );
RenderState( DepthFunc, GREATER_EQUAL );
// Let the MaterialSystem know this is a sky shader
BoolAttribute( sky, true );
float4 MainPs( PixelInput i ) : SV_Target0
{
/*sgp_pixel_code*/
return /*sgp_pixel_output*/;
}
}
";
internal static ShaderTypeInfo ShaderTypeInfo => new( "Sky", "nights_stay", ShaderDomain.Sky, new List<string>(), DefaultInputs );
internal static Dictionary<string, TemplateInputPlugInfo> DefaultInputs => new()
{
// Pixel Stage Inputs
{ "Albedo", new( TemplateInputPlugType.Vector3, "Albedo", GraphCompiler.ShaderStage.Pixel ) }
};
}