This commit is contained in:
2021-06-13 10:28:03 +02:00
parent eb70603c85
commit df2d24cbd3
7487 changed files with 943244 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
#if !defined(COMBINED_SHAPE_LIGHT_PASS)
#define COMBINED_SHAPE_LIGHT_PASS
half _HDREmulationScale;
half _UseSceneLighting;
half4 _RendererColor;
half4 CombinedShapeLightShared(half4 color, half4 mask, half2 lightingUV)
{
if (color.a == 0.0)
discard;
color = color * _RendererColor; // This is needed for sprite shape
#if USE_SHAPE_LIGHT_TYPE_0
half4 shapeLight0 = SAMPLE_TEXTURE2D(_ShapeLightTexture0, sampler_ShapeLightTexture0, lightingUV);
if (any(_ShapeLightMaskFilter0))
{
half4 processedMask = (1 - _ShapeLightInvertedFilter0) * mask + _ShapeLightInvertedFilter0 * (1 - mask);
shapeLight0 *= dot(processedMask, _ShapeLightMaskFilter0);
}
half4 shapeLight0Modulate = shapeLight0 * _ShapeLightBlendFactors0.x;
half4 shapeLight0Additive = shapeLight0 * _ShapeLightBlendFactors0.y;
#else
half4 shapeLight0Modulate = 0;
half4 shapeLight0Additive = 0;
#endif
#if USE_SHAPE_LIGHT_TYPE_1
half4 shapeLight1 = SAMPLE_TEXTURE2D(_ShapeLightTexture1, sampler_ShapeLightTexture1, lightingUV);
if (any(_ShapeLightMaskFilter1))
{
half4 processedMask = (1 - _ShapeLightInvertedFilter1) * mask + _ShapeLightInvertedFilter1 * (1 - mask);
shapeLight1 *= dot(processedMask, _ShapeLightMaskFilter1);
}
half4 shapeLight1Modulate = shapeLight1 * _ShapeLightBlendFactors1.x;
half4 shapeLight1Additive = shapeLight1 * _ShapeLightBlendFactors1.y;
#else
half4 shapeLight1Modulate = 0;
half4 shapeLight1Additive = 0;
#endif
#if USE_SHAPE_LIGHT_TYPE_2
half4 shapeLight2 = SAMPLE_TEXTURE2D(_ShapeLightTexture2, sampler_ShapeLightTexture2, lightingUV);
if (any(_ShapeLightMaskFilter2))
{
half4 processedMask = (1 - _ShapeLightInvertedFilter2) * mask + _ShapeLightInvertedFilter2 * (1 - mask);
shapeLight2 *= dot(processedMask, _ShapeLightMaskFilter2);
}
half4 shapeLight2Modulate = shapeLight2 * _ShapeLightBlendFactors2.x;
half4 shapeLight2Additive = shapeLight2 * _ShapeLightBlendFactors2.y;
#else
half4 shapeLight2Modulate = 0;
half4 shapeLight2Additive = 0;
#endif
#if USE_SHAPE_LIGHT_TYPE_3
half4 shapeLight3 = SAMPLE_TEXTURE2D(_ShapeLightTexture3, sampler_ShapeLightTexture3, lightingUV);
if (any(_ShapeLightMaskFilter3))
{
half4 processedMask = (1 - _ShapeLightInvertedFilter3) * mask + _ShapeLightInvertedFilter3 * (1 - mask);
shapeLight3 *= dot(processedMask, _ShapeLightMaskFilter3);
}
half4 shapeLight3Modulate = shapeLight3 * _ShapeLightBlendFactors3.x;
half4 shapeLight3Additive = shapeLight3 * _ShapeLightBlendFactors3.y;
#else
half4 shapeLight3Modulate = 0;
half4 shapeLight3Additive = 0;
#endif
half4 finalOutput;
#if !USE_SHAPE_LIGHT_TYPE_0 && !USE_SHAPE_LIGHT_TYPE_1 && !USE_SHAPE_LIGHT_TYPE_2 && ! USE_SHAPE_LIGHT_TYPE_3
finalOutput = color;
#else
half4 finalModulate = shapeLight0Modulate + shapeLight1Modulate + shapeLight2Modulate + shapeLight3Modulate;
half4 finalAdditve = shapeLight0Additive + shapeLight1Additive + shapeLight2Additive + shapeLight3Additive;
finalOutput = _HDREmulationScale * (color * finalModulate + finalAdditve);
#endif
finalOutput.a = color.a;
finalOutput = finalOutput *_UseSceneLighting + (1 - _UseSceneLighting)*color;
return max(0, finalOutput);
}
#endif

View File

@@ -0,0 +1,75 @@
#if USE_NORMAL_MAP
#if LIGHT_QUALITY_FAST
#define NORMALS_LIGHTING_COORDS(TEXCOORDA, TEXCOORDB) \
half4 lightDirection : TEXCOORDA;\
half2 screenUV : TEXCOORDB;
#define TRANSFER_NORMALS_LIGHTING(output, worldSpacePos)\
output.screenUV = ComputeNormalizedDeviceCoordinates(output.positionCS.xyz / output.positionCS.w);\
half3 planeNormal = -GetViewForwardDir();\
half3 projLightPos = _LightPosition.xyz - (dot(_LightPosition.xyz - worldSpacePos.xyz, planeNormal) - _LightZDistance) * planeNormal;\
output.lightDirection.xyz = normalize(projLightPos - worldSpacePos.xyz);\
output.lightDirection.w = 0;
#define APPLY_NORMALS_LIGHTING(input, lightColor)\
half4 normal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.screenUV);\
half3 normalUnpacked = UnpackNormalRGBNoScale(normal);\
lightColor = lightColor * saturate(dot(input.lightDirection.xyz, normalUnpacked));
#else
#define NORMALS_LIGHTING_COORDS(TEXCOORDA, TEXCOORDB) \
half4 positionWS : TEXCOORDA;\
half2 screenUV : TEXCOORDB;
#define TRANSFER_NORMALS_LIGHTING(output, worldSpacePos) \
output.screenUV = ComputeNormalizedDeviceCoordinates(output.positionCS.xyz / output.positionCS.w); \
output.positionWS = worldSpacePos;
#define APPLY_NORMALS_LIGHTING(input, lightColor)\
half4 normal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.screenUV);\
half3 normalUnpacked = UnpackNormalRGBNoScale(normal);\
half3 planeNormal = -GetViewForwardDir();\
half3 projLightPos = _LightPosition.xyz - (dot(_LightPosition.xyz - input.positionWS.xyz, planeNormal) - _LightZDistance) * planeNormal;\
half3 dirToLight = normalize(projLightPos - input.positionWS.xyz);\
lightColor = lightColor * saturate(dot(dirToLight, normalUnpacked));
#endif
#define NORMALS_LIGHTING_VARIABLES \
TEXTURE2D(_NormalMap); \
SAMPLER(sampler_NormalMap); \
half4 _LightPosition;\
half _LightZDistance;
#else
#define NORMALS_LIGHTING_COORDS(TEXCOORDA, TEXCOORDB)
#define NORMALS_LIGHTING_VARIABLES
#define TRANSFER_NORMALS_LIGHTING(output, worldSpacePos)
#define APPLY_NORMALS_LIGHTING(input, lightColor)
#endif
#define SHADOW_COORDS(TEXCOORDA)\
float2 shadowUV : TEXCOORDA;
#define SHADOW_VARIABLES\
float _ShadowIntensity;\
float _ShadowVolumeIntensity;\
TEXTURE2D(_ShadowTex);\
SAMPLER(sampler_ShadowTex);
#define APPLY_SHADOWS(input, color, intensity)\
if(intensity < 1)\
{\
half4 shadow = saturate(SAMPLE_TEXTURE2D(_ShadowTex, sampler_ShadowTex, input.shadowUV)); \
half shadowIntensity = 1 - (shadow.r * saturate(2 * (shadow.g - 0.5f * shadow.b))); \
color.rgb = (color.rgb * shadowIntensity) + (color.rgb * intensity*(1 - shadowIntensity));\
}
#define TRANSFER_SHADOWS(output)\
output.shadowUV = ComputeNormalizedDeviceCoordinates(output.positionCS.xyz);
#define SHAPE_LIGHT(index)\
TEXTURE2D(_ShapeLightTexture##index);\
SAMPLER(sampler_ShapeLightTexture##index);\
half2 _ShapeLightBlendFactors##index;\
half4 _ShapeLightMaskFilter##index;\
half4 _ShapeLightInvertedFilter##index;

View File

@@ -0,0 +1,16 @@
#if !defined(NORMALS_RENDERING_PASS)
#define NORMALS_RENDERING_PASS
half4 NormalsRenderingShared(half4 color, half3 normalTS, half3 tangent, half3 bitangent, half3 normal)
{
half4 normalColor;
half3 normalWS = TransformTangentToWorld(normalTS, half3x3(tangent.xyz, bitangent.xyz, normal.xyz));
normalColor.rgb = 0.5 * ((normalWS)+1);
normalColor.a = color.a; // used for blending
return normalColor;
}
#endif

View File

@@ -0,0 +1,113 @@
Shader "Hidden/Light2d-Point-Volumetric"
{
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Pass
{
Blend One One
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local USE_POINT_LIGHT_COOKIES __
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"
struct Attributes
{
float3 positionOS : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half2 uv : TEXCOORD0;
half2 lookupUV : TEXCOORD2; // This is used for light relative direction
SHADOW_COORDS(TEXCOORD5)
};
#if USE_POINT_LIGHT_COOKIES
TEXTURE2D(_PointLightCookieTex);
SAMPLER(sampler_PointLightCookieTex);
#endif
TEXTURE2D(_FalloffLookup);
SAMPLER(sampler_FalloffLookup);
half _FalloffIntensity;
TEXTURE2D(_LightLookup);
SAMPLER(sampler_LightLookup);
half4 _LightLookup_TexelSize;
half4 _LightColor;
half _VolumeOpacity;
float4 _LightPosition;
float4x4 _LightInvMatrix;
float4x4 _LightNoRotInvMatrix;
half _LightZDistance;
half _OuterAngle; // 1-0 where 1 is the value at 0 degrees and 1 is the value at 180 degrees
half _InnerAngleMult; // 1-0 where 1 is the value at 0 degrees and 1 is the value at 180 degrees
half _InnerRadiusMult; // 1-0 where 1 is the value at the center and 0 is the value at the outer radius
half _InverseHDREmulationScale;
half _IsFullSpotlight;
SHADOW_VARIABLES
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
output.positionCS = TransformObjectToHClip(input.positionOS);
output.uv = input.texcoord;
float4 worldSpacePos;
worldSpacePos.xyz = TransformObjectToWorld(input.positionOS);
worldSpacePos.w = 1;
float4 lightSpacePos = mul(_LightInvMatrix, worldSpacePos);
float4 lightSpaceNoRotPos = mul(_LightNoRotInvMatrix, worldSpacePos);
float halfTexelOffset = 0.5 * _LightLookup_TexelSize.x;
output.lookupUV = 0.5 * (lightSpacePos.xy + 1) + halfTexelOffset;
TRANSFER_SHADOWS(output)
return output;
}
half4 frag(Varyings input) : SV_Target
{
half4 lookupValue = SAMPLE_TEXTURE2D(_LightLookup, sampler_LightLookup, input.lookupUV); // r = distance, g = angle, b = x direction, a = y direction
// Inner Radius
half attenuation = saturate(_InnerRadiusMult * lookupValue.r); // This is the code to take care of our inner radius
// Spotlight
half spotAttenuation = saturate((_OuterAngle - lookupValue.g + _IsFullSpotlight) * _InnerAngleMult);
attenuation = attenuation * spotAttenuation;
half2 mappedUV;
mappedUV.x = attenuation;
mappedUV.y = _FalloffIntensity;
attenuation = SAMPLE_TEXTURE2D(_FalloffLookup, sampler_FalloffLookup, mappedUV).r;
#if USE_POINT_LIGHT_COOKIES
half4 cookieColor = SAMPLE_TEXTURE2D(_PointLightCookieTex, sampler_PointLightCookieTex, input.lookupUV);
half4 lightColor = cookieColor * _LightColor * attenuation;
#else
half4 lightColor = _LightColor * attenuation;
#endif
APPLY_SHADOWS(input, lightColor, _ShadowVolumeIntensity);
return _VolumeOpacity * lightColor * _InverseHDREmulationScale;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,129 @@
Shader "Hidden/Light2D-Point"
{
Properties
{
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Pass
{
Blend [_SrcBlend][_DstBlend]
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local USE_POINT_LIGHT_COOKIES __
#pragma multi_compile_local LIGHT_QUALITY_FAST __
#pragma multi_compile_local USE_NORMAL_MAP __
#pragma multi_compile_local USE_ADDITIVE_BLENDING __
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"
struct Attributes
{
float3 positionOS : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half2 uv : TEXCOORD0;
half2 lookupUV : TEXCOORD2; // This is used for light relative direction
NORMALS_LIGHTING_COORDS(TEXCOORD4, TEXCOORD5)
SHADOW_COORDS(TEXCOORD6)
};
#if USE_POINT_LIGHT_COOKIES
TEXTURE2D(_PointLightCookieTex);
SAMPLER(sampler_PointLightCookieTex);
#endif
TEXTURE2D(_FalloffLookup);
SAMPLER(sampler_FalloffLookup);
half _FalloffIntensity;
TEXTURE2D(_LightLookup);
SAMPLER(sampler_LightLookup);
half4 _LightLookup_TexelSize;
NORMALS_LIGHTING_VARIABLES
SHADOW_VARIABLES
half4 _LightColor;
float4x4 _LightInvMatrix;
float4x4 _LightNoRotInvMatrix;
half _OuterAngle; // 1-0 where 1 is the value at 0 degrees and 1 is the value at 180 degrees
half _InnerAngleMult; // 1-0 where 1 is the value at 0 degrees and 1 is the value at 180 degrees
half _InnerRadiusMult; // 1-0 where 1 is the value at the center and 0 is the value at the outer radius
half _InverseHDREmulationScale;
half _IsFullSpotlight;
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
output.positionCS = TransformObjectToHClip(input.positionOS);
output.uv = input.texcoord;
float4 worldSpacePos;
worldSpacePos.xyz = TransformObjectToWorld(input.positionOS);
worldSpacePos.w = 1;
float4 lightSpacePos = mul(_LightInvMatrix, worldSpacePos);
float4 lightSpaceNoRotPos = mul(_LightNoRotInvMatrix, worldSpacePos);
float halfTexelOffset = 0.5 * _LightLookup_TexelSize.x;
output.lookupUV = 0.5 * (lightSpacePos.xy + 1) + halfTexelOffset;
TRANSFER_NORMALS_LIGHTING(output, worldSpacePos)
TRANSFER_SHADOWS(output)
return output;
}
half4 frag(Varyings input) : SV_Target
{
half4 lookupValue = SAMPLE_TEXTURE2D(_LightLookup, sampler_LightLookup, input.lookupUV); // r = distance, g = angle, b = x direction, a = y direction
// Inner Radius
half attenuation = saturate(_InnerRadiusMult * lookupValue.r); // This is the code to take care of our inner radius
// Spotlight
half spotAttenuation = saturate((_OuterAngle - lookupValue.g + _IsFullSpotlight) * _InnerAngleMult);
attenuation = attenuation * spotAttenuation;
half2 mappedUV;
mappedUV.x = attenuation;
mappedUV.y = _FalloffIntensity;
attenuation = SAMPLE_TEXTURE2D(_FalloffLookup, sampler_FalloffLookup, mappedUV).r;
#if USE_POINT_LIGHT_COOKIES
half4 cookieColor = SAMPLE_TEXTURE2D(_PointLightCookieTex, sampler_PointLightCookieTex, input.lookupUV);
half4 lightColor = cookieColor * _LightColor;
#else
half4 lightColor = _LightColor;
#endif
#if USE_ADDITIVE_BLENDING
lightColor *= attenuation;
#else
lightColor.a = attenuation;
#endif
APPLY_NORMALS_LIGHTING(input, lightColor);
APPLY_SHADOWS(input, lightColor, _ShadowIntensity);
return lightColor * _InverseHDREmulationScale;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,95 @@
Shader "Hidden/Light2D-Shape-Volumetric"
{
SubShader
{
Tags { "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Pass
{
Blend SrcAlpha One
ZWrite Off
ZTest Off
Cull Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local SPRITE_LIGHT __
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
half2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : COLOR;
half2 uv : TEXCOORD0;
SHADOW_COORDS(TEXCOORD1)
};
half4 _LightColor;
half _FalloffDistance;
half _VolumeOpacity;
half _InverseHDREmulationScale;
#ifdef SPRITE_LIGHT
TEXTURE2D(_CookieTex); // This can either be a sprite texture uv or a falloff texture
SAMPLER(sampler_CookieTex);
#else
uniform half _FalloffIntensity;
TEXTURE2D(_FalloffLookup);
SAMPLER(sampler_FalloffLookup);
#endif
SHADOW_VARIABLES
Varyings vert(Attributes attributes)
{
Varyings o = (Varyings)0;
float3 positionOS = attributes.positionOS;
positionOS.x = positionOS.x + _FalloffDistance * attributes.color.r;
positionOS.y = positionOS.y + _FalloffDistance * attributes.color.g;
o.positionCS = TransformObjectToHClip(positionOS);
o.color = _LightColor * _InverseHDREmulationScale;
o.color.a = _LightColor.a * _VolumeOpacity;
#ifdef SPRITE_LIGHT
o.uv = attributes.uv;
#else
o.uv = float2(attributes.color.a, _FalloffIntensity);
#endif
TRANSFER_SHADOWS(o)
return o;
}
half4 frag(Varyings i) : SV_Target
{
half4 color = i.color;
#if SPRITE_LIGHT
color *= SAMPLE_TEXTURE2D(_CookieTex, sampler_CookieTex, i.uv);
#else
color.a = i.color.a * SAMPLE_TEXTURE2D(_FalloffLookup, sampler_FalloffLookup, i.uv).r;
#endif
APPLY_SHADOWS(i, color, _ShadowVolumeIntensity);
return color;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,115 @@
Shader "Hidden/Light2D-Shape"
{
Properties
{
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Pass
{
Blend[_SrcBlend][_DstBlend]
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local SPRITE_LIGHT __
#pragma multi_compile_local USE_NORMAL_MAP __
#pragma multi_compile_local USE_ADDITIVE_BLENDING __
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : COLOR;
half2 uv : TEXCOORD0;
SHADOW_COORDS(TEXCOORD1)
NORMALS_LIGHTING_COORDS(TEXCOORD2, TEXCOORD3)
};
half _InverseHDREmulationScale;
half4 _LightColor;
half _FalloffDistance;
#ifdef SPRITE_LIGHT
TEXTURE2D(_CookieTex); // This can either be a sprite texture uv or a falloff texture
SAMPLER(sampler_CookieTex);
#else
half _FalloffIntensity;
TEXTURE2D(_FalloffLookup);
SAMPLER(sampler_FalloffLookup);
#endif
NORMALS_LIGHTING_VARIABLES
SHADOW_VARIABLES
Varyings vert(Attributes attributes)
{
Varyings o = (Varyings)0;
float3 positionOS = attributes.positionOS;
positionOS.x = positionOS.x + _FalloffDistance * attributes.color.r;
positionOS.y = positionOS.y + _FalloffDistance * attributes.color.g;
o.positionCS = TransformObjectToHClip(positionOS);
o.color = _LightColor * _InverseHDREmulationScale;
o.color.a = attributes.color.a;
#ifdef SPRITE_LIGHT
o.uv = attributes.uv;
#else
o.uv = float2(o.color.a, _FalloffIntensity);
#endif
float4 worldSpacePos;
worldSpacePos.xyz = TransformObjectToWorld(positionOS);
worldSpacePos.w = 1;
TRANSFER_NORMALS_LIGHTING(o, worldSpacePos)
TRANSFER_SHADOWS(o)
return o;
}
half4 frag(Varyings i) : SV_Target
{
half4 color = i.color;
#if SPRITE_LIGHT
half4 cookie = SAMPLE_TEXTURE2D(_CookieTex, sampler_CookieTex, i.uv);
#if USE_ADDITIVE_BLENDING
color *= cookie * cookie.a;
#else
color *= cookie;
#endif
#else
#if USE_ADDITIVE_BLENDING
color *= SAMPLE_TEXTURE2D(_FalloffLookup, sampler_FalloffLookup, i.uv).r;
#else
color.a = SAMPLE_TEXTURE2D(_FalloffLookup, sampler_FalloffLookup, i.uv).r;
#endif
#endif
APPLY_NORMALS_LIGHTING(i, color);
APPLY_SHADOWS(i, color, _ShadowIntensity);
return color;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,71 @@
Shader "Hidden/Shadow2DRemoveSelf"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[PerRendererData][HideInInspector] _ShadowStencilGroup("__ShadowStencilGroup", Float) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
Cull Off
BlendOp Add
Blend One One
ZWrite Off
Pass
{
Stencil
{
Ref [_ShadowStencilGroup]
Comp Equal
Pass Keep
Fail Keep
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _ReceivesShadows;
Varyings vert (Attributes v)
{
Varyings o;
o.vertex = TransformObjectToHClip(v.vertex.xyz);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
half4 frag(Varyings i) : SV_Target
{
half4 main = tex2D(_MainTex, i.uv);
half4 col;
col.r = 0;
col.g = 0;
col.b = main.a;
col.a = 0;
return col;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,169 @@
Shader "Hidden/ShadowGroup2D"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_ShadowStencilGroup("__ShadowStencilGroup", Float) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
Cull Off
BlendOp Add
Blend One One
ZWrite Off
Pass
{
Stencil
{
Ref [_ShadowStencilGroup]
Comp NotEqual
Pass Replace
Fail Keep
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float3 vertex : POSITION;
float4 tangent: TANGENT;
float2 uv : TEXCOORD0;
float4 extrusion : COLOR;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
uniform float3 _LightPos;
uniform float _ShadowRadius;
Varyings vert (Attributes v)
{
Varyings o;
float3 vertexWS = TransformObjectToWorld(v.vertex); // This should be in world space
float3 lightDir = _LightPos - vertexWS;
lightDir.z = 0;
// Start of code to see if this point should be extruded
float3 lightDirection = normalize(lightDir);
float3 endpoint = vertexWS + (_ShadowRadius * -lightDirection);
float3 worldTangent = TransformObjectToWorldDir(v.tangent.xyz);
float sharedShadowTest = saturate(ceil(dot(lightDirection, worldTangent)));
// Start of code to calculate offset
float3 vertexWS0 = TransformObjectToWorld(float3(v.extrusion.xy, 0));
float3 vertexWS1 = TransformObjectToWorld(float3(v.extrusion.zw, 0));
float3 shadowDir0 = vertexWS0 - _LightPos;
shadowDir0.z = 0;
shadowDir0 = normalize(shadowDir0);
float3 shadowDir1 = vertexWS1 -_LightPos;
shadowDir1.z = 0;
shadowDir1 = normalize(shadowDir1);
float3 shadowDir = normalize(shadowDir0 + shadowDir1);
float3 sharedShadowOffset = sharedShadowTest * _ShadowRadius * shadowDir;
float3 position;
position = vertexWS + sharedShadowOffset;
o.vertex = TransformWorldToHClip(position);
// RGB - R is shadow value (to support soft shadows), G is Self Shadow Mask, B is No Shadow Mask
o.color = 1; // v.color;
o.color.g = 0.5;
o.color.b = 0;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
float4 frag (Varyings i) : SV_Target
{
float4 main = tex2D(_MainTex, i.uv);
float4 col = i.color;
col.g = main.a * col.g;
return col;
}
ENDHLSL
}
Pass
{
Stencil
{
Ref [_ShadowStencilGroup]
Comp NotEqual
Pass Replace
Fail Keep
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float3 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
Varyings vert (Attributes v)
{
Varyings o;
o.vertex = TransformObjectToHClip(v.vertex);
// RGB - R is shadow value (to support soft shadows), G is Self Shadow Mask, B is No Shadow Mask
o.color = 1;
o.color.g = 0.5;
o.color.b = 1;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
half4 frag (Varyings i) : SV_Target
{
half4 main = tex2D(_MainTex, i.uv);
half4 color = i.color;
color.b = 1 - main.a;
return color;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,214 @@
Shader "Universal Render Pipeline/2D/Sprite-Lit-Default"
{
Properties
{
_MainTex("Diffuse", 2D) = "white" {}
_MaskTex("Mask", 2D) = "white" {}
_NormalMap("Normal Map", 2D) = "bump" {}
// Legacy properties. They're here so that materials using this shader can gracefully fallback to the legacy sprite shader.
[HideInInspector] _Color("Tint", Color) = (1,1,1,1)
[HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
[HideInInspector] _AlphaTex("External Alpha", 2D) = "white" {}
[HideInInspector] _EnableExternalAlpha("Enable External Alpha", Float) = 0
}
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
ENDHLSL
SubShader
{
Tags {"Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
Pass
{
Tags { "LightMode" = "Universal2D" }
HLSLPROGRAM
#pragma vertex CombinedShapeLightVertex
#pragma fragment CombinedShapeLightFragment
#pragma multi_compile USE_SHAPE_LIGHT_TYPE_0 __
#pragma multi_compile USE_SHAPE_LIGHT_TYPE_1 __
#pragma multi_compile USE_SHAPE_LIGHT_TYPE_2 __
#pragma multi_compile USE_SHAPE_LIGHT_TYPE_3 __
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : COLOR;
float2 uv : TEXCOORD0;
half2 lightingUV : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl"
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_MaskTex);
SAMPLER(sampler_MaskTex);
half4 _MainTex_ST;
#if USE_SHAPE_LIGHT_TYPE_0
SHAPE_LIGHT(0)
#endif
#if USE_SHAPE_LIGHT_TYPE_1
SHAPE_LIGHT(1)
#endif
#if USE_SHAPE_LIGHT_TYPE_2
SHAPE_LIGHT(2)
#endif
#if USE_SHAPE_LIGHT_TYPE_3
SHAPE_LIGHT(3)
#endif
Varyings CombinedShapeLightVertex(Attributes v)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.positionCS = TransformObjectToHClip(v.positionOS);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.lightingUV = ComputeNormalizedDeviceCoordinates(o.positionCS.xyz / o.positionCS.w);
o.color = v.color;
return o;
}
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/CombinedShapeLightShared.hlsl"
half4 CombinedShapeLightFragment(Varyings i) : SV_Target
{
half4 main = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
half4 mask = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, i.uv);
return CombinedShapeLightShared(main, mask, i.lightingUV);
}
ENDHLSL
}
Pass
{
Tags { "LightMode" = "NormalsRendering"}
HLSLPROGRAM
#pragma vertex NormalsRenderingVertex
#pragma fragment NormalsRenderingFragment
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
float4 tangent : TANGENT;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
half4 color : COLOR;
float2 uv : TEXCOORD0;
half3 normalWS : TEXCOORD1;
half3 tangentWS : TEXCOORD2;
half3 bitangentWS : TEXCOORD3;
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
half4 _NormalMap_ST; // Is this the right way to do this?
Varyings NormalsRenderingVertex(Attributes attributes)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(attributes);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.positionCS = TransformObjectToHClip(attributes.positionOS);
o.uv = TRANSFORM_TEX(attributes.uv, _NormalMap);
o.color = attributes.color;
o.normalWS = -GetViewForwardDir();
o.tangentWS = TransformObjectToWorldDir(attributes.tangent.xyz);
o.bitangentWS = cross(o.normalWS, o.tangentWS) * attributes.tangent.w;
return o;
}
#include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/NormalsRenderingShared.hlsl"
half4 NormalsRenderingFragment(Varyings i) : SV_Target
{
half4 mainTex = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
half3 normalTS = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv));
return NormalsRenderingShared(mainTex, normalTS, i.tangentWS.xyz, i.bitangentWS.xyz, i.normalWS.xyz);
}
ENDHLSL
}
Pass
{
Tags { "LightMode" = "UniversalForward" "Queue"="Transparent" "RenderType"="Transparent"}
HLSLPROGRAM
#pragma vertex UnlitVertex
#pragma fragment UnlitFragment
struct Attributes
{
float3 positionOS : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
float4 _MainTex_ST;
Varyings UnlitVertex(Attributes attributes)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(attributes);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.positionCS = TransformObjectToHClip(attributes.positionOS);
o.uv = TRANSFORM_TEX(attributes.uv, _MainTex);
o.color = attributes.color;
return o;
}
float4 UnlitFragment(Varyings i) : SV_Target
{
float4 mainTex = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
return mainTex;
}
ENDHLSL
}
}
Fallback "Sprites/Default"
}

View File

@@ -0,0 +1,510 @@
Shader "Universal Render Pipeline/Baked Lit"
{
Properties
{
[MainTexture] _BaseMap("Texture", 2D) = "white" {}
[MainColor] _BaseColor("Color", Color) = (1, 1, 1, 1)
_Cutoff("AlphaCutout", Range(0.0, 1.0)) = 0.5
_BumpMap("Normal Map", 2D) = "bump" {}
// BlendMode
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("Src", Float) = 1.0
[HideInInspector] _DstBlend("Dst", Float) = 0.0
[HideInInspector] _ZWrite("ZWrite", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
[HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="4.5"}
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "BakedLit"
Tags{ "LightMode" = "UniversalForwardOnly" }
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
// Lighting include is needed because of GI
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float3 uv0AndFogCoord : TEXCOORD0; // xy: uv0, z: fogCoord
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
half3 normalWS : TEXCOORD2;
#if defined(_NORMALMAP)
half4 tangentWS : TEXCOORD3;
#endif
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv0AndFogCoord.xy = TRANSFORM_TEX(input.uv, _BaseMap);
output.uv0AndFogCoord.z = ComputeFogFactor(vertexInput.positionCS.z);
// normalWS and tangentWS already normalize.
// this is required to avoid skewing the direction during interpolation
// also required for per-vertex SH evaluation
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
output.normalWS = normalInput.normalWS;
#if defined(_NORMALMAP)
real sign = input.tangentOS.w * GetOddNegativeScale();
output.tangentWS = half4(normalInput.tangentWS.xyz, sign);
#endif
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
OUTPUT_SH(output.normalWS, output.vertexSH);
return output;
}
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv0AndFogCoord.xy;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
#if defined(_NORMALMAP)
half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)).xyz;
float sgn = input.tangentWS.w; // should be either +1 or -1
float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent, input.normalWS));
#else
half3 normalWS = input.normalWS;
#endif
normalWS = NormalizeNormalPerPixel(normalWS);
color *= SAMPLE_GI(input.lightmapUV, input.vertexSH, normalWS);
#if defined(_SCREEN_SPACE_OCCLUSION)
float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.vertex);
color *= SampleAmbientOcclusion(normalizedScreenSpaceUV);
#endif
color = MixFog(color, input.uv0AndFogCoord.z);
alpha = OutputAlpha(alpha, _Surface);
return half4(color, alpha);
}
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _ _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// Defines
#define BUMP_SCALE_NOT_SUPPORTED 1
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaBakedLit
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
SubShader
{
Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="2.0"}
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "BakedLit"
Tags{ "LightMode" = "UniversalForwardOnly" }
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
// Lighting include is needed because of GI
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float3 uv0AndFogCoord : TEXCOORD0; // xy: uv0, z: fogCoord
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
half3 normalWS : TEXCOORD2;
#if defined(_NORMALMAP)
half4 tangentWS : TEXCOORD3;
#endif
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv0AndFogCoord.xy = TRANSFORM_TEX(input.uv, _BaseMap);
output.uv0AndFogCoord.z = ComputeFogFactor(vertexInput.positionCS.z);
// normalWS and tangentWS already normalize.
// this is required to avoid skewing the direction during interpolation
// also required for per-vertex SH evaluation
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
output.normalWS = normalInput.normalWS;
#if defined(_NORMALMAP)
real sign = input.tangentOS.w * GetOddNegativeScale();
output.tangentWS = half4(normalInput.tangentWS.xyz, sign);
#endif
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
OUTPUT_SH(output.normalWS, output.vertexSH);
return output;
}
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv0AndFogCoord.xy;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
#if defined(_NORMALMAP)
half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)).xyz;
float sgn = input.tangentWS.w; // should be either +1 or -1
float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent, input.normalWS));
#else
half3 normalWS = input.normalWS;
#endif
normalWS = NormalizeNormalPerPixel(normalWS);
color *= SAMPLE_GI(input.lightmapUV, input.vertexSH, normalWS);
#if defined(_SCREEN_SPACE_OCCLUSION)
float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.vertex);
color *= SampleAmbientOcclusion(normalizedScreenSpaceUV);
#endif
color = MixFog(color, input.uv0AndFogCoord.z);
alpha = OutputAlpha(alpha, _Surface);
return half4(color, alpha);
}
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _ _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// Defines
#define BUMP_SCALE_NOT_SUPPORTED 1
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaBakedLit
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
FallBack "Universal Render Pipeline/Unlit"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.BakedLitShader"
}

View File

@@ -0,0 +1,31 @@
#ifndef UNIVERSAL_BAKEDLIT_INPUT_INCLUDED
#define UNIVERSAL_BAKEDLIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
half _Cutoff;
half _Glossiness;
half _Metallic;
half _Surface;
CBUFFER_END
#ifdef UNITY_DOTS_INSTANCING_ENABLED
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
UNITY_DOTS_INSTANCED_PROP(float , _Glossiness)
UNITY_DOTS_INSTANCED_PROP(float , _Metallic)
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__BaseColor)
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Cutoff)
#define _Glossiness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Glossiness)
#define _Metallic UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Metallic)
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Surface)
#endif
#endif

View File

@@ -0,0 +1,52 @@
#ifndef UNIVERSAL_BAKEDLIT_META_PASS_INCLUDED
#define UNIVERSAL_BAKEDLIT_META_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
#ifdef _TANGENT_TO_WORLD
float4 tangentOS : TANGENT;
#endif
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings UniversalVertexMeta(Attributes input)
{
Varyings output;
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2,
unity_LightmapST, unity_DynamicLightmapST);
output.uv = TRANSFORM_TEX(input.uv0, _BaseMap);
return output;
}
half4 UniversalFragmentMetaBakedLit(Varyings input) : SV_Target
{
MetaInput metaInput = (MetaInput)0;
metaInput.Albedo = _BaseColor.rgb * SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).rgb;
return MetaFragment(metaInput);
}
//LWRP -> Universal Backwards Compatibility
Varyings LightweightVertexMeta(Attributes input)
{
return UniversalVertexMeta(input);
}
half4 LightweightFragmentMetaBakedLit(Varyings input) : SV_Target
{
return UniversalFragmentMetaBakedLit(input);
}
#endif

View File

@@ -0,0 +1,511 @@
// Complex Lit is superset of Lit, but provides
// advanced material properties and is always forward rendered.
// It also has higher hardware and shader model requirements.
Shader "Universal Render Pipeline/Complex Lit"
{
Properties
{
// Specular vs Metallic workflow
[HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0
[MainTexture] _BaseMap("Albedo", 2D) = "white" {}
[MainColor] _BaseColor("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5
_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0
_SmoothnessTextureChannel("Smoothness texture channel", Float) = 0
_Metallic("Metallic", Range(0.0, 1.0)) = 0.0
_MetallicGlossMap("Metallic", 2D) = "white" {}
_SpecColor("Specular", Color) = (0.2, 0.2, 0.2)
_SpecGlossMap("Specular", 2D) = "white" {}
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0
[ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
_Parallax("Scale", Range(0.005, 0.08)) = 0.005
_ParallaxMap("Height Map", 2D) = "black" {}
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
_OcclusionMap("Occlusion", 2D) = "white" {}
[HDR] _EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_DetailMask("Detail Mask", 2D) = "white" {}
_DetailAlbedoMapScale("Scale", Range(0.0, 2.0)) = 1.0
_DetailAlbedoMap("Detail Albedo x2", 2D) = "linearGrey" {}
_DetailNormalMapScale("Scale", Range(0.0, 2.0)) = 1.0
[Normal] _DetailNormalMap("Normal Map", 2D) = "bump" {}
_ClearCoat("Clear Coat", Float) = 0.0
_ClearCoatMap("Clear Coat Map", 2D) = "white" {}
_ClearCoatMask("Clear Coat Mask", Range(0.0, 1.0)) = 0.0
_ClearCoatSmoothness("Clear Coat Smoothness", Range(0.0, 1.0)) = 1.0
// Blending state
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
_ReceiveShadows("Receive Shadows", Float) = 1.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
[HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}
}
SubShader
{
// Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
// this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
// material work with both Universal Render Pipeline and Builtin Unity Pipeline
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "ComplexLit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
LOD 300
// ------------------------------------------------------------------
// Forward only pass.
// Acts also as an opaque forward fallback for deferred rendering.
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "ForwardLit"
Tags{"LightMode" = "UniversalForwardOnly"}
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _PARALLAXMAP
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local_fragment _OCCLUSIONMAP
#pragma shader_feature_local_fragment _ _CLEARCOAT _CLEARCOATMAP
#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMeta
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
SubShader
{
// Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
// this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
// material work with both Universal Render Pipeline and Builtin Unity Pipeline
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True" "ShaderModel"="2.0"}
LOD 300
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "ForwardLit"
Tags{"LightMode" = "UniversalForwardOnly"}
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _PARALLAXMAP
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local_fragment _OCCLUSIONMAP
#pragma shader_feature_local_fragment _ _CLEARCOAT _CLEARCOATMAP
#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMeta
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
//////////////////////////////////////////////////////
FallBack "Hidden/Universal Render Pipeline/Lit"
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.LitShader"
}

View File

@@ -0,0 +1,47 @@
#ifndef UNIVERSAL_DEPTH_ONLY_PASS_INCLUDED
#define UNIVERSAL_DEPTH_ONLY_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD1;
float3 normalWS : TEXCOORD2;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings DepthNormalsVertex(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangentOS);
output.normalWS = NormalizeNormalPerVertex(normalInput.normalWS);
return output;
}
float4 DepthNormalsFragment(Varyings input) : SV_TARGET
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff);
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(input.normalWS, true)), 0.0, 0.0);
}
#endif

View File

@@ -0,0 +1,39 @@
#ifndef UNIVERSAL_DEPTH_ONLY_PASS_INCLUDED
#define UNIVERSAL_DEPTH_ONLY_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings DepthOnlyVertex(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.positionCS = TransformObjectToHClip(input.position.xyz);
return output;
}
half4 DepthOnlyFragment(Varyings input) : SV_TARGET
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff);
return 0;
}
#endif

View File

@@ -0,0 +1,580 @@
Shader "Universal Render Pipeline/Lit"
{
Properties
{
// Specular vs Metallic workflow
[HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0
[MainTexture] _BaseMap("Albedo", 2D) = "white" {}
[MainColor] _BaseColor("Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5
_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0
_SmoothnessTextureChannel("Smoothness texture channel", Float) = 0
_Metallic("Metallic", Range(0.0, 1.0)) = 0.0
_MetallicGlossMap("Metallic", 2D) = "white" {}
_SpecColor("Specular", Color) = (0.2, 0.2, 0.2)
_SpecGlossMap("Specular", 2D) = "white" {}
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0
[ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
_Parallax("Scale", Range(0.005, 0.08)) = 0.005
_ParallaxMap("Height Map", 2D) = "black" {}
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
_OcclusionMap("Occlusion", 2D) = "white" {}
[HDR] _EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_DetailMask("Detail Mask", 2D) = "white" {}
_DetailAlbedoMapScale("Scale", Range(0.0, 2.0)) = 1.0
_DetailAlbedoMap("Detail Albedo x2", 2D) = "linearGrey" {}
_DetailNormalMapScale("Scale", Range(0.0, 2.0)) = 1.0
[Normal] _DetailNormalMap("Normal Map", 2D) = "bump" {}
// SRP batching compatibility for Clear Coat (Not used in Lit)
[HideInInspector] _ClearCoatMask("_ClearCoatMask", Float) = 0.0
[HideInInspector] _ClearCoatSmoothness("_ClearCoatSmoothness", Float) = 0.0
// Blending state
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
_ReceiveShadows("Receive Shadows", Float) = 1.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _MainTex("BaseMap", 2D) = "white" {}
[HideInInspector] _Color("Base Color", Color) = (1, 1, 1, 1)
[HideInInspector] _GlossMapScale("Smoothness", Float) = 0.0
[HideInInspector] _Glossiness("Smoothness", Float) = 0.0
[HideInInspector] _GlossyReflections("EnvironmentReflections", Float) = 0.0
[HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}
}
SubShader
{
// Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
// this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
// material work with both Universal Render Pipeline and Builtin Unity Pipeline
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
LOD 300
// ------------------------------------------------------------------
// Forward pass. Shades all light in a single pass. GI + emission + Fog
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "ForwardLit"
Tags{"LightMode" = "UniversalForward"}
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local_fragment _OCCLUSIONMAP
#pragma shader_feature_local _PARALLAXMAP
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
ZWrite[_ZWrite]
ZTest LEqual
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
//#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local_fragment _OCCLUSIONMAP
#pragma shader_feature_local _PARALLAXMAP
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma vertex LitGBufferPassVertex
#pragma fragment LitGBufferPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMeta
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
SubShader
{
// Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
// this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
// material work with both Universal Render Pipeline and Builtin Unity Pipeline
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True" "ShaderModel"="2.0"}
LOD 300
// ------------------------------------------------------------------
// Forward pass. Shades all light in a single pass. GI + emission + Fog
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "ForwardLit"
Tags{"LightMode" = "UniversalForward"}
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local_fragment _OCCLUSIONMAP
#pragma shader_feature_local _PARALLAXMAP
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma vertex LitPassVertex
#pragma fragment LitPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMeta
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.LitShader"
}

View File

@@ -0,0 +1,181 @@
#ifndef UNIVERSAL_FORWARD_LIT_PASS_INCLUDED
#define UNIVERSAL_FORWARD_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
// GLES2 has limited amount of interpolators
#if defined(_PARALLAXMAP) && !defined(SHADER_API_GLES)
#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR
#endif
#if (defined(_NORMALMAP) || (defined(_PARALLAXMAP) && !defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR))) || defined(_DETAIL)
#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR
#endif
// keep this file in sync with LitGBufferPass.hlsl
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
float3 positionWS : TEXCOORD2;
#endif
float3 normalWS : TEXCOORD3;
#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR)
float4 tangentWS : TEXCOORD4; // xyz: tangent, w: sign
#endif
float3 viewDirWS : TEXCOORD5;
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD7;
#endif
#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
float3 viewDirTS : TEXCOORD8;
#endif
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData)
{
inputData = (InputData)0;
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
inputData.positionWS = input.positionWS;
#endif
half3 viewDirWS = SafeNormalize(input.viewDirWS);
#if defined(_NORMALMAP) || defined(_DETAIL)
float sgn = input.tangentWS.w; // should be either +1 or -1
float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz));
#else
inputData.normalWS = input.normalWS;
#endif
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
inputData.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = input.fogFactorAndVertexLight.x;
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard (Physically Based) shader
Varyings LitPassVertex(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
// normalWS and tangentWS already normalize.
// this is required to avoid skewing the direction during interpolation
// also required for per-vertex lighting and SH evaluation
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
// already normalized from normal transform to WS.
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) || defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
real sign = input.tangentOS.w * GetOddNegativeScale();
half4 tangentWS = half4(normalInput.tangentWS.xyz, sign);
#endif
#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR)
output.tangentWS = tangentWS;
#endif
#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
half3 viewDirTS = GetViewDirectionTangentSpace(tangentWS, output.normalWS, viewDirWS);
output.viewDirTS = viewDirTS;
#endif
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
output.positionWS = vertexInput.positionWS;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
output.positionCS = vertexInput.positionCS;
return output;
}
// Used in Standard (Physically Based) shader
half4 LitPassFragment(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if defined(_PARALLAXMAP)
#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
half3 viewDirTS = input.viewDirTS;
#else
half3 viewDirTS = GetViewDirectionTangentSpace(input.tangentWS, input.normalWS, input.viewDirWS);
#endif
ApplyPerPixelDisplacement(viewDirTS, input.uv);
#endif
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(input.uv, surfaceData);
InputData inputData;
InitializeInputData(input, surfaceData.normalTS, inputData);
half4 color = UniversalFragmentPBR(inputData, surfaceData);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
}
#endif

View File

@@ -0,0 +1,196 @@
#ifndef UNIVERSAL_LIT_GBUFFER_PASS_INCLUDED
#define UNIVERSAL_LIT_GBUFFER_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
// TODO: Currently we support viewDirTS caclulated in vertex shader and in fragments shader.
// As both solutions have their advantages and disadvantages (etc. shader target 2.0 has only 8 interpolators).
// We need to find out if we can stick to one solution, which we needs testing.
// So keeping this until I get manaul QA pass.
#if defined(_PARALLAXMAP) && (SHADER_TARGET >= 30)
#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR
#endif
#if (defined(_NORMALMAP) || (defined(_PARALLAXMAP) && !defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR))) || defined(_DETAIL)
#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR
#endif
// keep this file in sync with LitForwardPass.hlsl
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
float3 positionWS : TEXCOORD2;
#endif
float3 normalWS : TEXCOORD3;
#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR)
float4 tangentWS : TEXCOORD4; // xyz: tangent, w: sign
#endif
float3 viewDirWS : TEXCOORD5;
half3 vertexLighting : TEXCOORD6; // xyz: vertex lighting
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD7;
#endif
#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
float3 viewDirTS : TEXCOORD8;
#endif
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData)
{
inputData = (InputData)0;
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
inputData.positionWS = input.positionWS;
#endif
half3 viewDirWS = SafeNormalize(input.viewDirWS);
#if defined(_NORMALMAP) || defined(_DETAIL)
float sgn = input.tangentWS.w; // should be either +1 or -1
float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz));
#else
inputData.normalWS = input.normalWS;
#endif
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
inputData.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = 0.0; // we don't apply fog in the guffer pass
inputData.vertexLighting = input.vertexLighting.xyz;
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard (Physically Based) shader
Varyings LitGBufferPassVertex(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
// normalWS and tangentWS already normalize.
// this is required to avoid skewing the direction during interpolation
// also required for per-vertex lighting and SH evaluation
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
// already normalized from normal transform to WS.
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) || defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
real sign = input.tangentOS.w * GetOddNegativeScale();
half4 tangentWS = half4(normalInput.tangentWS.xyz, sign);
#endif
#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR)
output.tangentWS = tangentWS;
#endif
#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
half3 viewDirTS = GetViewDirectionTangentSpace(tangentWS, output.normalWS, viewDirWS);
output.viewDirTS = viewDirTS;
#endif
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
output.vertexLighting = vertexLight;
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
output.positionWS = vertexInput.positionWS;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
output.positionCS = vertexInput.positionCS;
return output;
}
// Used in Standard (Physically Based) shader
FragmentOutput LitGBufferPassFragment(Varyings input)
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if defined(_PARALLAXMAP)
#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR)
half3 viewDirTS = input.viewDirTS;
#else
half3 viewDirTS = GetViewDirectionTangentSpace(input.tangentWS, input.normalWS, input.viewDirWS);
#endif
ApplyPerPixelDisplacement(viewDirTS, input.uv);
#endif
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(input.uv, surfaceData);
InputData inputData;
InitializeInputData(input, surfaceData.normalTS, inputData);
// Stripped down version of UniversalFragmentPBR().
#ifdef _SPECULARHIGHLIGHTS_OFF
bool specularHighlightsOff = true;
#else
bool specularHighlightsOff = false;
#endif
// in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR
// in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, surfaceData.occlusion, inputData.normalWS, inputData.viewDirectionWS);
return BRDFDataToGbuffer(brdfData, inputData, surfaceData.smoothness, surfaceData.emission + color);
}
#endif

View File

@@ -0,0 +1,244 @@
#ifndef UNIVERSAL_LIT_INPUT_INCLUDED
#define UNIVERSAL_LIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
#if defined(_DETAIL_MULX2) || defined(_DETAIL_SCALED)
#define _DETAIL
#endif
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
float4 _DetailAlbedoMap_ST;
half4 _BaseColor;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Smoothness;
half _Metallic;
half _BumpScale;
half _Parallax;
half _OcclusionStrength;
half _ClearCoatMask;
half _ClearCoatSmoothness;
half _DetailAlbedoMapScale;
half _DetailNormalMapScale;
half _Surface;
CBUFFER_END
// NOTE: Do not ifdef the properties for dots instancing, but ifdef the actual usage.
// Otherwise you might break CPU-side as property constant-buffer offsets change per variant.
// NOTE: Dots instancing is orthogonal to the constant buffer above.
#ifdef UNITY_DOTS_INSTANCING_ENABLED
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
UNITY_DOTS_INSTANCED_PROP(float4, _SpecColor)
UNITY_DOTS_INSTANCED_PROP(float4, _EmissionColor)
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
UNITY_DOTS_INSTANCED_PROP(float , _Smoothness)
UNITY_DOTS_INSTANCED_PROP(float , _Metallic)
UNITY_DOTS_INSTANCED_PROP(float , _BumpScale)
UNITY_DOTS_INSTANCED_PROP(float , _Parallax)
UNITY_DOTS_INSTANCED_PROP(float , _OcclusionStrength)
UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatMask)
UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatSmoothness)
UNITY_DOTS_INSTANCED_PROP(float , _DetailAlbedoMapScale)
UNITY_DOTS_INSTANCED_PROP(float , _DetailNormalMapScale)
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__BaseColor)
#define _SpecColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__SpecColor)
#define _EmissionColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__EmissionColor)
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Cutoff)
#define _Smoothness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Smoothness)
#define _Metallic UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Metallic)
#define _BumpScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__BumpScale)
#define _Parallax UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Parallax)
#define _OcclusionStrength UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__OcclusionStrength)
#define _ClearCoatMask UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__ClearCoatMask)
#define _ClearCoatSmoothness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__ClearCoatSmoothness)
#define _DetailAlbedoMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__DetailAlbedoMapScale)
#define _DetailNormalMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__DetailNormalMapScale)
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Surface)
#endif
TEXTURE2D(_ParallaxMap); SAMPLER(sampler_ParallaxMap);
TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap);
TEXTURE2D(_DetailMask); SAMPLER(sampler_DetailMask);
TEXTURE2D(_DetailAlbedoMap); SAMPLER(sampler_DetailAlbedoMap);
TEXTURE2D(_DetailNormalMap); SAMPLER(sampler_DetailNormalMap);
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
TEXTURE2D(_ClearCoatMap); SAMPLER(sampler_ClearCoatMap);
#ifdef _SPECULAR_SETUP
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv)
#else
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv)
#endif
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)
{
half4 specGloss;
#ifdef _METALLICSPECGLOSSMAP
specGloss = SAMPLE_METALLICSPECULAR(uv);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _Smoothness;
#else
specGloss.a *= _Smoothness;
#endif
#else // _METALLICSPECGLOSSMAP
#if _SPECULAR_SETUP
specGloss.rgb = _SpecColor.rgb;
#else
specGloss.rgb = _Metallic.rrr;
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
specGloss.a = albedoAlpha * _Smoothness;
#else
specGloss.a = _Smoothness;
#endif
#endif
return specGloss;
}
half SampleOcclusion(float2 uv)
{
#ifdef _OCCLUSIONMAP
// TODO: Controls things like these by exposing SHADER_QUALITY levels (low, medium, high)
#if defined(SHADER_API_GLES)
return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
#else
half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
return LerpWhiteTo(occ, _OcclusionStrength);
#endif
#else
return 1.0;
#endif
}
// Returns clear coat parameters
// .x/.r == mask
// .y/.g == smoothness
half2 SampleClearCoat(float2 uv)
{
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
half2 clearCoatMaskSmoothness = half2(_ClearCoatMask, _ClearCoatSmoothness);
#if defined(_CLEARCOATMAP)
clearCoatMaskSmoothness *= SAMPLE_TEXTURE2D(_ClearCoatMap, sampler_ClearCoatMap, uv).rg;
#endif
return clearCoatMaskSmoothness;
#else
return half2(0.0, 1.0);
#endif // _CLEARCOAT
}
void ApplyPerPixelDisplacement(half3 viewDirTS, inout float2 uv)
{
#if defined(_PARALLAXMAP)
uv += ParallaxMapping(TEXTURE2D_ARGS(_ParallaxMap, sampler_ParallaxMap), viewDirTS, _Parallax, uv);
#endif
}
// Used for scaling detail albedo. Main features:
// - Depending if detailAlbedo brightens or darkens, scale magnifies effect.
// - No effect is applied if detailAlbedo is 0.5.
half3 ScaleDetailAlbedo(half3 detailAlbedo, half scale)
{
// detailAlbedo = detailAlbedo * 2.0h - 1.0h;
// detailAlbedo *= _DetailAlbedoMapScale;
// detailAlbedo = detailAlbedo * 0.5h + 0.5h;
// return detailAlbedo * 2.0f;
// A bit more optimized
return 2.0h * detailAlbedo * scale - scale + 1.0h;
}
half3 ApplyDetailAlbedo(float2 detailUv, half3 albedo, half detailMask)
{
#if defined(_DETAIL)
half3 detailAlbedo = SAMPLE_TEXTURE2D(_DetailAlbedoMap, sampler_DetailAlbedoMap, detailUv).rgb;
// In order to have same performance as builtin, we do scaling only if scale is not 1.0 (Scaled version has 6 additional instructions)
#if defined(_DETAIL_SCALED)
detailAlbedo = ScaleDetailAlbedo(detailAlbedo, _DetailAlbedoMapScale);
#else
detailAlbedo = 2.0h * detailAlbedo;
#endif
return albedo * LerpWhiteTo(detailAlbedo, detailMask);
#else
return albedo;
#endif
}
half3 ApplyDetailNormal(float2 detailUv, half3 normalTS, half detailMask)
{
#if defined(_DETAIL)
#if BUMP_SCALE_NOT_SUPPORTED
half3 detailNormalTS = UnpackNormal(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv));
#else
half3 detailNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv), _DetailNormalMapScale);
#endif
// With UNITY_NO_DXT5nm unpacked vector is not normalized for BlendNormalRNM
// For visual consistancy we going to do in all cases
detailNormalTS = normalize(detailNormalTS);
return lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask); // todo: detailMask should lerp the angle of the quaternion rotation, not the normals
#else
return normalTS;
#endif
}
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff);
half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a);
outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
#if _SPECULAR_SETUP
outSurfaceData.metallic = 1.0h;
outSurfaceData.specular = specGloss.rgb;
#else
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
#endif
outSurfaceData.smoothness = specGloss.a;
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);
outSurfaceData.occlusion = SampleOcclusion(uv);
outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
half2 clearCoat = SampleClearCoat(uv);
outSurfaceData.clearCoatMask = clearCoat.r;
outSurfaceData.clearCoatSmoothness = clearCoat.g;
#else
outSurfaceData.clearCoatMask = 0.0h;
outSurfaceData.clearCoatSmoothness = 0.0h;
#endif
#if defined(_DETAIL)
half detailMask = SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, uv).a;
float2 detailUv = uv * _DetailAlbedoMap_ST.xy + _DetailAlbedoMap_ST.zw;
outSurfaceData.albedo = ApplyDetailAlbedo(detailUv, outSurfaceData.albedo, detailMask);
outSurfaceData.normalTS = ApplyDetailNormal(detailUv, outSurfaceData.normalTS, detailMask);
#endif
}
#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED

View File

@@ -0,0 +1,60 @@
#ifndef UNIVERSAL_LIT_META_PASS_INCLUDED
#define UNIVERSAL_LIT_META_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
#ifdef _TANGENT_TO_WORLD
float4 tangentOS : TANGENT;
#endif
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings UniversalVertexMeta(Attributes input)
{
Varyings output;
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2, unity_LightmapST, unity_DynamicLightmapST);
output.uv = TRANSFORM_TEX(input.uv0, _BaseMap);
return output;
}
half4 UniversalFragmentMeta(Varyings input) : SV_Target
{
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(input.uv, surfaceData);
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
MetaInput metaInput;
metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5;
metaInput.SpecularColor = surfaceData.specular;
metaInput.Emission = surfaceData.emission;
return MetaFragment(metaInput);
}
//LWRP -> Universal Backwards Compatibility
Varyings LightweightVertexMeta(Attributes input)
{
return UniversalVertexMeta(input);
}
half4 LightweightFragmentMeta(Varyings input) : SV_Target
{
return UniversalFragmentMeta(input);
}
#endif

View File

@@ -0,0 +1,213 @@
Shader "Universal Render Pipeline/Nature/SpeedTree7"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_HueVariation("Hue Variation", Color) = (1.0,0.5,0.0,0.1)
_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
_DetailTex("Detail", 2D) = "black" {}
_BumpMap("Normal Map", 2D) = "bump" {}
_Cutoff("Alpha Cutoff", Range(0,1)) = 0.333
[MaterialEnum(Off,0,Front,1,Back,2)] _Cull("Cull", Int) = 2
[MaterialEnum(None,0,Fastest,1,Fast,2,Better,3,Best,4,Palm,5)] _WindQuality("Wind Quality", Range(0,5)) = 0
}
SubShader
{
Tags
{
"Queue" = "Geometry"
"IgnoreProjector" = "True"
"RenderType" = "Opaque"
"DisableBatching" = "LODFading"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "SimpleLit"
}
LOD 400
Cull [_Cull]
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex SpeedTree7Vert
#pragma fragment SpeedTree7Frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
#pragma shader_feature_local EFFECT_BUMP
#pragma shader_feature_local EFFECT_HUE_VARIATION
#define ENABLE_WIND
#define VERTEX_COLOR
#include "SpeedTree7Input.hlsl"
#include "SpeedTree7Passes.hlsl"
ENDHLSL
}
Pass
{
Name "SceneSelectionPass"
Tags{"LightMode" = "SceneSelectionPass"}
HLSLPROGRAM
#pragma vertex SpeedTree7VertDepth
#pragma fragment SpeedTree7FragDepth
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
#define ENABLE_WIND
#define DEPTH_ONLY
#define SCENESELECTIONPASS
#include "SpeedTree7Input.hlsl"
#include "SpeedTree7Passes.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ColorMask 0
HLSLPROGRAM
#pragma vertex SpeedTree7VertDepth
#pragma fragment SpeedTree7FragDepth
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
#define ENABLE_WIND
#define DEPTH_ONLY
#define SHADOW_CASTER
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#include "SpeedTree7Input.hlsl"
#include "SpeedTree7Passes.hlsl"
ENDHLSL
}
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma vertex SpeedTree7Vert
#pragma fragment SpeedTree7Frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
#pragma shader_feature_local EFFECT_BUMP
#pragma shader_feature_local EFFECT_HUE_VARIATION
#define ENABLE_WIND
#define VERTEX_COLOR
#define GBUFFER
#include "SpeedTree7Input.hlsl"
#include "SpeedTree7Passes.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ColorMask 0
HLSLPROGRAM
#pragma vertex SpeedTree7VertDepth
#pragma fragment SpeedTree7FragDepth
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
#define ENABLE_WIND
#define DEPTH_ONLY
#include "SpeedTree7Input.hlsl"
#include "SpeedTree7Passes.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
HLSLPROGRAM
#pragma vertex SpeedTree7VertDepthNormal
#pragma fragment SpeedTree7FragDepthNormal
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local GEOM_TYPE_BRANCH GEOM_TYPE_BRANCH_DETAIL GEOM_TYPE_FROND GEOM_TYPE_LEAF GEOM_TYPE_MESH
#pragma shader_feature_local EFFECT_BUMP
#define ENABLE_WIND
#include "SpeedTree7Input.hlsl"
#include "SpeedTree7Passes.hlsl"
ENDHLSL
}
}
Dependency "BillboardShader" = "Universal Render Pipeline/Nature/SpeedTree7 Billboard"
CustomEditor "SpeedTreeMaterialInspector"
}

View File

@@ -0,0 +1,134 @@
Shader "Universal Render Pipeline/Nature/SpeedTree7 Billboard"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_HueVariation("Hue Variation", Color) = (1.0,0.5,0.0,0.1)
_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
_BumpMap("Normal Map", 2D) = "bump" {}
_Cutoff("Alpha Cutoff", Range(0,1)) = 0.333
[MaterialEnum(None,0,Fastest,1)] _WindQuality("Wind Quality", Range(0,1)) = 0
}
SubShader
{
Tags
{
"Queue" = "AlphaTest"
"IgnoreProjector" = "True"
"RenderType" = "TransparentCutout"
"DisableBatching" = "LODFading"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "SimpleLit"
}
LOD 400
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex SpeedTree7Vert
#pragma fragment SpeedTree7Frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_fog
#pragma shader_feature_local EFFECT_BUMP
#pragma shader_feature_local EFFECT_HUE_VARIATION
#define ENABLE_WIND
#include "SpeedTree7BillboardInput.hlsl"
#include "SpeedTree7BillboardPasses.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ColorMask 0
HLSLPROGRAM
#pragma vertex SpeedTree7VertDepth
#pragma fragment SpeedTree7FragDepth
#pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS
#pragma multi_compile __ LOD_FADE_CROSSFADE
#define ENABLE_WIND
#define DEPTH_ONLY
#define SHADOW_CASTER
#include "SpeedTree7BillboardInput.hlsl"
#include "SpeedTree7BillboardPasses.hlsl"
ENDHLSL
}
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma vertex SpeedTree7Vert
#pragma fragment SpeedTree7Frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma shader_feature_local EFFECT_BUMP
#pragma shader_feature_local EFFECT_HUE_VARIATION
#define ENABLE_WIND
#define GBUFFER
#include "SpeedTree7BillboardInput.hlsl"
#include "SpeedTree7BillboardPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ColorMask 0
HLSLPROGRAM
#pragma vertex SpeedTree7VertDepth
#pragma fragment SpeedTree7FragDepth
#pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS
#pragma multi_compile __ LOD_FADE_CROSSFADE
#define ENABLE_WIND
#define DEPTH_ONLY
#include "SpeedTree7BillboardInput.hlsl"
#include "SpeedTree7BillboardPasses.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,27 @@
#ifndef UNIVERSAL_SPEEDTREE7BILLBOARD_INPUT_INCLUDED
#define UNIVERSAL_SPEEDTREE7BILLBOARD_INPUT_INCLUDED
#define SPEEDTREE_PI 3.14159265359
#define SPEEDTREE_ALPHATEST
half _Cutoff;
#include "SpeedTree7CommonInput.hlsl"
CBUFFER_START(UnityBillboardPerCamera)
float3 unity_BillboardNormal;
float3 unity_BillboardTangent;
float4 unity_BillboardCameraParams;
#define unity_BillboardCameraPosition (unity_BillboardCameraParams.xyz)
#define unity_BillboardCameraXZAngle (unity_BillboardCameraParams.w)
CBUFFER_END
CBUFFER_START(UnityBillboardPerBatch)
float4 unity_BillboardInfo; // x: num of billboard slices; y: 1.0f / (delta angle between slices)
float4 unity_BillboardSize; // x: width; y: height; z: bottom
float4 unity_BillboardImageTexCoords[16];
CBUFFER_END
#define _Surface 0.0 // Speed Trees are always opaque
#endif

View File

@@ -0,0 +1,138 @@
#ifndef UNIVERSAL_SPEEDTREE7BILLBOARD_PASSES_INCLUDED
#define UNIVERSAL_SPEEDTREE7BILLBOARD_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "SpeedTree7CommonPasses.hlsl"
void InitializeData(inout SpeedTreeVertexInput input, out half2 outUV, out half outHueVariation)
{
// assume no scaling & rotation
float3 worldPos = input.vertex.xyz + float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
#ifdef BILLBOARD_FACE_CAMERA_POS
float3 eyeVec = normalize(unity_BillboardCameraPosition - worldPos);
float3 billboardTangent = normalize(float3(-eyeVec.z, 0, eyeVec.x)); // cross(eyeVec, {0,1,0})
float3 billboardNormal = float3(billboardTangent.z, 0, -billboardTangent.x); // cross({0,1,0},billboardTangent)
float angle = atan2(billboardNormal.z, billboardNormal.x); // signed angle between billboardNormal to {0,0,1}
angle += angle < 0 ? 2 * SPEEDTREE_PI : 0;
#else
float3 billboardTangent = unity_BillboardTangent;
float3 billboardNormal = unity_BillboardNormal;
float angle = unity_BillboardCameraXZAngle;
#endif
float widthScale = input.texcoord1.x;
float heightScale = input.texcoord1.y;
float rotation = input.texcoord1.z;
float2 percent = input.texcoord.xy;
float3 billboardPos = (percent.x - 0.5f) * unity_BillboardSize.x * widthScale * billboardTangent;
billboardPos.y += (percent.y * unity_BillboardSize.y + unity_BillboardSize.z) * heightScale;
#ifdef ENABLE_WIND
if (_WindQuality * _WindEnabled > 0)
{
billboardPos = GlobalWind(billboardPos, worldPos, true, _ST_WindVector.xyz, input.texcoord1.w);
}
#endif
input.vertex.xyz += billboardPos;
input.vertex.w = 1.0f;
input.normal = billboardNormal.xyz;
input.tangent = float4(billboardTangent.xyz, -1);
float slices = unity_BillboardInfo.x;
float invDelta = unity_BillboardInfo.y;
angle += rotation;
float imageIndex = fmod(floor(angle * invDelta + 0.5f), slices);
float4 imageTexCoords = unity_BillboardImageTexCoords[imageIndex];
if (imageTexCoords.w < 0)
{
outUV = imageTexCoords.xy - imageTexCoords.zw * percent.yx;
}
else
{
outUV = imageTexCoords.xy + imageTexCoords.zw * percent;
}
#ifdef EFFECT_HUE_VARIATION
float hueVariationAmount = frac(worldPos.x + worldPos.y + worldPos.z);
outHueVariation = saturate(hueVariationAmount * _HueVariation.a);
#else
outHueVariation = 0;
#endif
}
SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input)
{
SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, output.uvHueVariation.xy, output.uvHueVariation.z);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
half3 normalWS = input.normal; // Already calculated in world space. Can probably get rid of the world space transform in GetVertexPositionInputs too.
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#ifdef EFFECT_BUMP
real sign = input.tangent.w * GetOddNegativeScale();
output.normalWS.xyz = TransformObjectToWorldNormal(input.normal);
output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
// View dir packed in w.
output.normalWS.w = viewDirWS.x;
output.tangentWS.w = viewDirWS.y;
output.bitangentWS.w = viewDirWS.z;
#else
output.normalWS.xyz = TransformObjectToWorldNormal(input.normal);
output.viewDirWS = viewDirWS;
#endif
output.positionWS = vertexInput.positionWS;
output.clipPos = vertexInput.positionCS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
SpeedTreeVertexDepthOutput SpeedTree7VertDepth(SpeedTreeVertexInput input)
{
SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, output.uvHueVariation.xy, output.uvHueVariation.z);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
#ifdef SHADOW_CASTER
half3 normalWS = TransformObjectToWorldNormal(input.normal);
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - vertexInput.positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#endif
output.clipPos = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, lightDirectionWS));
#else
output.clipPos = vertexInput.positionCS;
#endif
return output;
}
#endif

View File

@@ -0,0 +1,40 @@
#ifndef UNIVERSAL_SPEEDTREE7COMMON_INPUT_INCLUDED
#define UNIVERSAL_SPEEDTREE7COMMON_INPUT_INCLUDED
#ifdef EFFECT_BUMP
#define _NORMALMAP
#endif
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#ifdef ENABLE_WIND
#define WIND_QUALITY_NONE 0
#define WIND_QUALITY_FASTEST 1
#define WIND_QUALITY_FAST 2
#define WIND_QUALITY_BETTER 3
#define WIND_QUALITY_BEST 4
#define WIND_QUALITY_PALM 5
uniform half _WindQuality;
uniform half _WindEnabled;
#include "SpeedTreeWind.cginc"
#endif
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
#ifdef EFFECT_HUE_VARIATION
half4 _HueVariation;
#endif
half4 _Color;
// Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
// For Directional lights, _LightDirection is used when applying shadow Normal Bias.
// For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
float3 _LightDirection;
float3 _LightPosition;
#endif

View File

@@ -0,0 +1,244 @@
#ifndef UNIVERSAL_SPEEDTREE7COMMON_PASSES_INCLUDED
#define UNIVERSAL_SPEEDTREE7COMMON_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl"
struct SpeedTreeVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float2 texcoord3 : TEXCOORD3;
half4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct SpeedTreeVertexOutput
{
#ifdef VERTEX_COLOR
half4 color : COLOR;
#endif
half3 uvHueVariation : TEXCOORD0;
#ifdef GEOM_TYPE_BRANCH_DETAIL
half3 detail : TEXCOORD1;
#endif
half4 fogFactorAndVertexLight : TEXCOORD2; // x: fogFactor, yzw: vertex light
#ifdef EFFECT_BUMP
half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x
half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y
half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
half3 normalWS : TEXCOORD3;
half3 viewDirWS : TEXCOORD4;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD6;
#endif
float3 positionWS : TEXCOORD7;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 8);
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
struct SpeedTreeVertexDepthOutput
{
half3 uvHueVariation : TEXCOORD0;
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
struct SpeedTreeVertexDepthNormalOutput
{
half3 uvHueVariation : TEXCOORD0;
float4 clipPos : SV_POSITION;
#ifdef GEOM_TYPE_BRANCH_DETAIL
half3 detail : TEXCOORD1;
#endif
#ifdef EFFECT_BUMP
half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x
half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y
half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z
#else
half3 normalWS : TEXCOORD2;
half3 viewDirWS : TEXCOORD3;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(SpeedTreeVertexOutput input, half3 normalTS, out InputData inputData)
{
inputData.positionWS = input.positionWS.xyz;
#ifdef EFFECT_BUMP
inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
inputData.viewDirectionWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);
#else
inputData.normalWS = NormalizeNormalPerPixel(input.normalWS);
inputData.viewDirectionWS = input.viewDirWS;
#endif
#if SHADER_HINT_NICE_QUALITY
inputData.viewDirectionWS = SafeNormalize(inputData.viewDirectionWS);
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = input.fogFactorAndVertexLight.x;
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
inputData.shadowMask = half4(1, 1, 1, 1); // No GI currently.
}
#ifdef GBUFFER
FragmentOutput SpeedTree7Frag(SpeedTreeVertexOutput input)
#else
half4 SpeedTree7Frag(SpeedTreeVertexOutput input) : SV_Target
#endif
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if !defined(SHADER_QUALITY_LOW)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(input.clipPos.xy, unity_LODFade.x);
#endif
#endif
half2 uv = input.uvHueVariation.xy;
half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
diffuse.a *= _Color.a;
#ifdef SPEEDTREE_ALPHATEST
clip(diffuse.a - _Cutoff);
#endif
half3 diffuseColor = diffuse.rgb;
#ifdef GEOM_TYPE_BRANCH_DETAIL
half4 detailColor = tex2D(_DetailTex, input.detail.xy);
diffuseColor.rgb = lerp(diffuseColor.rgb, detailColor.rgb, input.detail.z < 2.0f ? saturate(input.detail.z) : detailColor.a);
#endif
#ifdef EFFECT_HUE_VARIATION
half3 shiftedColor = lerp(diffuseColor.rgb, _HueVariation.rgb, input.uvHueVariation.z);
half maxBase = max(diffuseColor.r, max(diffuseColor.g, diffuseColor.b));
half newMaxBase = max(shiftedColor.r, max(shiftedColor.g, shiftedColor.b));
maxBase /= newMaxBase;
maxBase = maxBase * 0.5f + 0.5f;
// preserve vibrance
shiftedColor.rgb *= maxBase;
diffuseColor.rgb = saturate(shiftedColor);
#endif
#ifdef EFFECT_BUMP
half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
#ifdef GEOM_TYPE_BRANCH_DETAIL
half3 detailNormal = SampleNormal(input.detail.xy, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
normalTs = lerp(normalTs, detailNormal, input.detail.z < 2.0f ? saturate(input.detail.z) : detailColor.a);
#endif
#else
half3 normalTs = half3(0, 0, 1);
#endif
InputData inputData;
InitializeInputData(input, normalTs, inputData);
#ifdef VERTEX_COLOR
diffuseColor.rgb *= input.color.rgb;
#else
diffuseColor.rgb *= _Color.rgb;
#endif
#ifdef GBUFFER
half4 color = half4(inputData.bakedGI * diffuseColor.rgb, diffuse.a);
SurfaceData surfaceData;
surfaceData.smoothness = 0;
surfaceData.albedo = diffuseColor.rgb;
surfaceData.specular = half3(0, 0, 0);
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingSimpleLit);
#else
half4 color = UniversalFragmentBlinnPhong(inputData, diffuseColor.rgb, half4(0, 0, 0, 0), 0, 0, diffuse.a);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
#endif
}
half4 SpeedTree7FragDepth(SpeedTreeVertexDepthOutput input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if !defined(SHADER_QUALITY_LOW)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(input.clipPos.xy, unity_LODFade.x);
#endif
#endif
half2 uv = input.uvHueVariation.xy;
half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
diffuse.a *= _Color.a;
#ifdef SPEEDTREE_ALPHATEST
clip(diffuse.a - _Cutoff);
#endif
#if defined(SCENESELECTIONPASS)
// We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
return half4(_ObjectId, _PassValue, 1.0, 1.0);
#else
return half4(0, 0, 0, 0);
#endif
}
half4 SpeedTree7FragDepthNormal(SpeedTreeVertexDepthNormalOutput input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if !defined(SHADER_QUALITY_LOW)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(input.clipPos.xy, unity_LODFade.x);
#endif
#endif
half2 uv = input.uvHueVariation.xy;
half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
diffuse.a *= _Color.a;
#ifdef SPEEDTREE_ALPHATEST
clip(diffuse.a - _Cutoff);
#endif
float3 normalWS = input.normalWS;
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(normalWS, true)), 0.0, 0.0);
}
#endif

View File

@@ -0,0 +1,29 @@
#ifndef UNIVERSAL_SPEEDTREE7_INPUT_INCLUDED
#define UNIVERSAL_SPEEDTREE7_INPUT_INCLUDED
#define SPEEDTREE_Y_UP
#ifdef GEOM_TYPE_BRANCH_DETAIL
#define GEOM_TYPE_BRANCH
#endif
#if defined(GEOM_TYPE_FROND) || defined(GEOM_TYPE_LEAF) || defined(GEOM_TYPE_FACING_LEAF)
#define SPEEDTREE_ALPHATEST
half _Cutoff;
#endif
#ifdef SCENESELECTIONPASS
int _ObjectId;
int _PassValue;
#endif
#include "SpeedTree7CommonInput.hlsl"
#ifdef GEOM_TYPE_BRANCH_DETAIL
sampler2D _DetailTex;
#endif
#define _Surface 0.0 // Speed Trees are always opaque
#endif

View File

@@ -0,0 +1,231 @@
#ifndef UNIVERSAL_SPEEDTREE7_PASSES_INCLUDED
#define UNIVERSAL_SPEEDTREE7_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "SpeedTree7CommonPasses.hlsl"
void InitializeData(inout SpeedTreeVertexInput input, float lodValue)
{
float3 finalPosition = input.vertex.xyz;
#ifdef ENABLE_WIND
half windQuality = _WindQuality * _WindEnabled;
float3 rotatedWindVector, rotatedBranchAnchor;
if (windQuality <= WIND_QUALITY_NONE)
{
rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
}
else
{
// compute rotated wind parameters
rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)UNITY_MATRIX_M));
rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)UNITY_MATRIX_M)) * _ST_WindBranchAnchor.w;
}
#endif
#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
// smooth LOD
#ifdef LOD_FADE_PERCENTAGE
finalPosition = lerp(finalPosition, input.texcoord1.xyz, lodValue);
#endif
// frond wind, if needed
#if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
if (windQuality == WIND_QUALITY_PALM)
finalPosition = RippleFrond(finalPosition, input.normal, input.texcoord.x, input.texcoord.y, input.texcoord2.x, input.texcoord2.y, input.texcoord2.z);
#endif
#elif defined(GEOM_TYPE_LEAF)
// remove anchor position
finalPosition -= input.texcoord1.xyz;
bool isFacingLeaf = input.color.a == 0;
if (isFacingLeaf)
{
#ifdef LOD_FADE_PERCENTAGE
finalPosition *= lerp(1.0, input.texcoord1.w, lodValue);
#endif
// face camera-facing leaf to camera
float offsetLen = length(finalPosition);
finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition
finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
}
else
{
#ifdef LOD_FADE_PERCENTAGE
float3 lodPosition = float3(input.texcoord1.w, input.texcoord3.x, input.texcoord3.y);
finalPosition = lerp(finalPosition, lodPosition, lodValue);
#endif
}
#ifdef ENABLE_WIND
// leaf wind
if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
{
float leafWindTrigOffset = input.texcoord1.x + input.texcoord1.y;
finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, input.texcoord2.w > 0.0, finalPosition, input.normal, input.texcoord2.x, float3(0,0,0), input.texcoord2.y, input.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
}
#endif
// move back out to anchor
finalPosition += input.texcoord1.xyz;
#endif
#ifdef ENABLE_WIND
float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
#ifndef GEOM_TYPE_MESH
if (windQuality >= WIND_QUALITY_BETTER)
{
// branch wind (applies to all 3D geometry)
finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(input.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
}
#endif
// global wind
if (windQuality > WIND_QUALITY_NONE)
{
finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
}
#endif
input.vertex.xyz = finalPosition;
}
SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input)
{
SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, unity_LODFade.x);
#ifdef VERTEX_COLOR
output.color = _Color;
output.color.rgb *= input.color.r; // ambient occlusion factor
#endif
output.uvHueVariation.xy = input.texcoord.xy;
#ifdef EFFECT_HUE_VARIATION
half hueVariationAmount = frac(UNITY_MATRIX_M[0].w + UNITY_MATRIX_M[1].w + UNITY_MATRIX_M[2].w);
hueVariationAmount += frac(input.vertex.x + input.normal.y + input.normal.x) * 0.5 - 0.3;
output.uvHueVariation.z = saturate(hueVariationAmount * _HueVariation.a);
#endif
#ifdef GEOM_TYPE_BRANCH_DETAIL
// The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
output.detail.xy = input.texcoord2.xy;
output.detail.z = input.color.a == 0 ? input.texcoord2.z : 2.5; // stay out of Blend's .z range
#endif
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
half3 normalWS = TransformObjectToWorldNormal(input.normal);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#ifdef EFFECT_BUMP
real sign = input.tangent.w * GetOddNegativeScale();
output.normalWS.xyz = normalWS;
output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
// View dir packed in w.
output.normalWS.w = viewDirWS.x;
output.tangentWS.w = viewDirWS.y;
output.bitangentWS.w = viewDirWS.z;
#else
output.normalWS = normalWS;
output.viewDirWS = viewDirWS;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
output.positionWS = vertexInput.positionWS;
output.clipPos = vertexInput.positionCS;
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
return output;
}
SpeedTreeVertexDepthOutput SpeedTree7VertDepth(SpeedTreeVertexInput input)
{
SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, unity_LODFade.x);
output.uvHueVariation.xy = input.texcoord.xy;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
#ifdef SHADOW_CASTER
half3 normalWS = TransformObjectToWorldNormal(input.normal);
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - vertexInput.positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#endif
output.clipPos = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, lightDirectionWS));
#else
output.clipPos = vertexInput.positionCS;
#endif
return output;
}
SpeedTreeVertexDepthNormalOutput SpeedTree7VertDepthNormal(SpeedTreeVertexInput input)
{
SpeedTreeVertexDepthNormalOutput output = (SpeedTreeVertexDepthNormalOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, unity_LODFade.x);
output.uvHueVariation.xy = input.texcoord.xy;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
half3 normalWS = TransformObjectToWorldNormal(input.normal);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#ifdef GEOM_TYPE_BRANCH_DETAIL
// The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
output.detail.xy = input.texcoord2.xy;
output.detail.z = input.color.a == 0 ? input.texcoord2.z : 2.5; // stay out of Blend's .z range
#endif
#ifdef EFFECT_BUMP
real sign = input.tangent.w * GetOddNegativeScale();
output.normalWS.xyz = normalWS;
output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
// View dir packed in w.
output.normalWS.w = viewDirWS.x;
output.tangentWS.w = viewDirWS.y;
output.bitangentWS.w = viewDirWS.z;
#else
output.normalWS = normalWS;
#endif
output.clipPos = vertexInput.positionCS;
return output;
}
#endif

View File

@@ -0,0 +1,244 @@
Shader "Universal Render Pipeline/Nature/SpeedTree8"
{
Properties
{
_MainTex ("Base (RGB) Transparency (A)", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
[Toggle(EFFECT_HUE_VARIATION)] _HueVariationKwToggle("Hue Variation", Float) = 0
_HueVariationColor ("Hue Variation Color", Color) = (1.0,0.5,0.0,0.1)
[Toggle(EFFECT_BUMP)] _NormalMapKwToggle("Normal Mapping", Float) = 0
_BumpMap("Normal Map", 2D) = "bump" {}
_ExtraTex ("Smoothness (R), Metallic (G), AO (B)", 2D) = "(0.5, 0.0, 1.0)" {}
_Glossiness ("Smoothness", Range(0.0, 1.0)) = 0.5
_Metallic ("Metallic", Range(0.0, 1.0)) = 0.0
[Toggle(EFFECT_SUBSURFACE)] _SubsurfaceKwToggle("Subsurface", Float) = 0
_SubsurfaceTex ("Subsurface (RGB)", 2D) = "white" {}
_SubsurfaceColor ("Subsurface Color", Color) = (1,1,1,1)
_SubsurfaceIndirect ("Subsurface Indirect", Range(0.0, 1.0)) = 0.25
[Toggle(EFFECT_BILLBOARD)] _BillboardKwToggle("Billboard", Float) = 0
_BillboardShadowFade ("Billboard Shadow Fade", Range(0.0, 1.0)) = 0.5
[Enum(No,2,Yes,0)] _TwoSided ("Two Sided", Int) = 2 // enum matches cull mode
[KeywordEnum(None,Fastest,Fast,Better,Best,Palm)] _WindQuality ("Wind Quality", Range(0,5)) = 0
}
SubShader
{
Tags
{
"Queue"="AlphaTest"
"IgnoreProjector"="True"
"RenderType"="TransparentCutout"
"DisableBatching"="LODFading"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "Lit"
}
LOD 400
Cull [_TwoSided]
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma vertex SpeedTree8Vert
#pragma fragment SpeedTree8Frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local _WINDQUALITY_NONE _WINDQUALITY_FASTEST _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM
#pragma shader_feature_local EFFECT_BILLBOARD
#pragma shader_feature_local EFFECT_HUE_VARIATION
//#pragma shader_feature_local EFFECT_SUBSURFACE // GI dependent.
#pragma shader_feature_local EFFECT_BUMP
#pragma shader_feature_local EFFECT_EXTRA_TEX
#define ENABLE_WIND
#define EFFECT_BACKSIDE_NORMALS
#include "SpeedTree8Input.hlsl"
#include "SpeedTree8Passes.hlsl"
ENDHLSL
}
Pass
{
Name "SceneSelectionPass"
Tags{"LightMode" = "SceneSelectionPass"}
HLSLPROGRAM
#pragma vertex SpeedTree8VertDepth
#pragma fragment SpeedTree8FragDepth
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local _WINDQUALITY_NONE _WINDQUALITY_FASTEST _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM
#pragma shader_feature_local EFFECT_BILLBOARD
#define ENABLE_WIND
#define DEPTH_ONLY
#define SCENESELECTIONPASS
#include "SpeedTree8Input.hlsl"
#include "SpeedTree8Passes.hlsl"
ENDHLSL
}
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma vertex SpeedTree8Vert
#pragma fragment SpeedTree8Frag
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local _WINDQUALITY_NONE _WINDQUALITY_FASTEST _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM
#pragma shader_feature_local EFFECT_BILLBOARD
#pragma shader_feature_local EFFECT_HUE_VARIATION
//#pragma shader_feature_local EFFECT_SUBSURFACE // GI dependent.
#pragma shader_feature_local EFFECT_BUMP
#pragma shader_feature_local EFFECT_EXTRA_TEX
#define ENABLE_WIND
#define EFFECT_BACKSIDE_NORMALS
#define GBUFFER
#include "SpeedTree8Input.hlsl"
#include "SpeedTree8Passes.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ColorMask 0
HLSLPROGRAM
#pragma vertex SpeedTree8VertDepth
#pragma fragment SpeedTree8FragDepth
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local _WINDQUALITY_NONE _WINDQUALITY_FASTEST _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM
#pragma shader_feature_local EFFECT_BILLBOARD
#define ENABLE_WIND
#define DEPTH_ONLY
#define SHADOW_CASTER
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#include "SpeedTree8Input.hlsl"
#include "SpeedTree8Passes.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma vertex SpeedTree8VertDepth
#pragma fragment SpeedTree8FragDepth
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling maxcount:50
#pragma shader_feature_local _WINDQUALITY_NONE _WINDQUALITY_FASTEST _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM
#pragma shader_feature_local EFFECT_BILLBOARD
#define ENABLE_WIND
#define DEPTH_ONLY
#include "SpeedTree8Input.hlsl"
#include "SpeedTree8Passes.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
HLSLPROGRAM
#pragma vertex SpeedTree8VertDepthNormal
#pragma fragment SpeedTree8FragDepthNormal
#pragma shader_feature_local _WINDQUALITY_NONE _WINDQUALITY_FASTEST _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM
#pragma shader_feature_local EFFECT_BUMP
#pragma multi_compile_instancing
#pragma multi_compile_vertex LOD_FADE_PERCENTAGE
#pragma multi_compile __ LOD_FADE_CROSSFADE
#pragma instancing_options assumeuniformscaling maxcount:50
#define ENABLE_WIND
#define EFFECT_BACKSIDE_NORMALS
#include "SpeedTree8Input.hlsl"
#include "SpeedTree8Passes.hlsl"
ENDHLSL
}
}
CustomEditor "SpeedTree8ShaderGUI"
}

View File

@@ -0,0 +1,67 @@
#ifndef UNIVERSAL_SPEEDTREE8_INPUT_INCLUDED
#define UNIVERSAL_SPEEDTREE8_INPUT_INCLUDED
#ifdef EFFECT_BUMP
#define _NORMALMAP
#endif
#define _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#if defined(ENABLE_WIND) && !defined(_WINDQUALITY_NONE)
#define SPEEDTREE_Y_UP
#include "SpeedTreeWind.cginc"
float _WindEnabled;
UNITY_INSTANCING_BUFFER_START(STWind)
UNITY_DEFINE_INSTANCED_PROP(float, _GlobalWindTime)
UNITY_INSTANCING_BUFFER_END(STWind)
#endif
half4 _Color;
int _TwoSided;
#ifdef SCENESELECTIONPASS
int _ObjectId;
int _PassValue;
#endif
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
#ifdef EFFECT_EXTRA_TEX
sampler2D _ExtraTex;
#else
half _Glossiness;
half _Metallic;
#endif
#ifdef EFFECT_HUE_VARIATION
half4 _HueVariationColor;
#endif
#ifdef EFFECT_BILLBOARD
half _BillboardShadowFade;
#endif
#ifdef EFFECT_SUBSURFACE
sampler2D _SubsurfaceTex;
half4 _SubsurfaceColor;
half _SubsurfaceIndirect;
#endif
// Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
// For Directional lights, _LightDirection is used when applying shadow Normal Bias.
// For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
float3 _LightDirection;
float3 _LightPosition;
#define GEOM_TYPE_BRANCH 0
#define GEOM_TYPE_FROND 1
#define GEOM_TYPE_LEAF 2
#define GEOM_TYPE_FACINGLEAF 3
#define _Surface 0.0 // Speed Trees are always opaque
#endif

View File

@@ -0,0 +1,530 @@
#ifndef UNIVERSAL_SPEEDTREE8_PASSES_INCLUDED
#define UNIVERSAL_SPEEDTREE8_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
struct SpeedTreeVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float4 texcoord3 : TEXCOORD3;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct SpeedTreeVertexOutput
{
half2 uv : TEXCOORD0;
half4 color : TEXCOORD1;
half4 fogFactorAndVertexLight : TEXCOORD2; // x: fogFactor, yzw: vertex light
#ifdef EFFECT_BUMP
half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x
half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y
half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
half3 normalWS : TEXCOORD3;
half3 viewDirWS : TEXCOORD4;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD6;
#endif
float3 positionWS : TEXCOORD7;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 8);
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
struct SpeedTreeVertexDepthOutput
{
half2 uv : TEXCOORD0;
half4 color : TEXCOORD1;
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
struct SpeedTreeVertexDepthNormalOutput
{
half2 uv : TEXCOORD0;
half4 color : TEXCOORD1;
#ifdef EFFECT_BUMP
half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x
half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y
half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z
#else
half3 normalWS : TEXCOORD2;
half3 viewDirWS : TEXCOORD3;
#endif
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
struct SpeedTreeDepthNormalFragmentInput
{
SpeedTreeVertexDepthNormalOutput interpolated;
#ifdef EFFECT_BACKSIDE_NORMALS
half facing : VFACE;
#endif
};
struct SpeedTreeFragmentInput
{
SpeedTreeVertexOutput interpolated;
#ifdef EFFECT_BACKSIDE_NORMALS
half facing : VFACE;
#endif
};
void InitializeData(inout SpeedTreeVertexInput input, float lodValue)
{
// smooth LOD
#if defined(LOD_FADE_PERCENTAGE) && !defined(EFFECT_BILLBOARD)
input.vertex.xyz = lerp(input.vertex.xyz, input.texcoord2.xyz, lodValue);
#endif
// wind
#if defined(ENABLE_WIND) && !defined(_WINDQUALITY_NONE)
if (_WindEnabled > 0)
{
float3 rotatedWindVector = mul(_ST_WindVector.xyz, (float3x3)unity_ObjectToWorld);
float windLength = length(rotatedWindVector);
if (windLength < 1e-5)
{
// sanity check that wind data is available
return;
}
rotatedWindVector /= windLength;
float3 treePos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
float3 windyPosition = input.vertex.xyz;
#ifndef EFFECT_BILLBOARD
// geometry type
float geometryType = (int)(input.texcoord3.w + 0.25);
bool leafTwo = false;
if (geometryType > GEOM_TYPE_FACINGLEAF)
{
geometryType -= 2;
leafTwo = true;
}
// leaves
if (geometryType > GEOM_TYPE_FROND)
{
// remove anchor position
float3 anchor = float3(input.texcoord1.zw, input.texcoord2.w);
windyPosition -= anchor;
if (geometryType == GEOM_TYPE_FACINGLEAF)
{
// face camera-facing leaf to camera
float offsetLen = length(windyPosition);
windyPosition = mul(windyPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * windyPosition
windyPosition = normalize(windyPosition) * offsetLen; // make sure the offset vector is still scaled
}
// leaf wind
#if defined(_WINDQUALITY_FAST) || defined(_WINDQUALITY_BETTER) || defined(_WINDQUALITY_BEST)
#ifdef _WINDQUALITY_BEST
bool bBestWind = true;
#else
bool bBestWind = false;
#endif
float leafWindTrigOffset = anchor.x + anchor.y;
windyPosition = LeafWind(bBestWind, leafTwo, windyPosition, input.normal, input.texcoord3.x, float3(0,0,0), input.texcoord3.y, input.texcoord3.z, leafWindTrigOffset, rotatedWindVector);
#endif
// move back out to anchor
windyPosition += anchor;
}
// frond wind
bool bPalmWind = false;
#ifdef _WINDQUALITY_PALM
bPalmWind = true;
if (geometryType == GEOM_TYPE_FROND)
{
windyPosition = RippleFrond(windyPosition, input.normal, input.texcoord.x, input.texcoord.y, input.texcoord3.x, input.texcoord3.y, input.texcoord3.z);
}
#endif
// branch wind (applies to all 3D geometry)
#if defined(_WINDQUALITY_BETTER) || defined(_WINDQUALITY_BEST) || defined(_WINDQUALITY_PALM)
float3 rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)unity_ObjectToWorld)) * _ST_WindBranchAnchor.w;
windyPosition = BranchWind(bPalmWind, windyPosition, treePos, float4(input.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
#endif
#endif // !EFFECT_BILLBOARD
// global wind
float globalWindTime = _ST_WindGlobal.x;
#if defined(EFFECT_BILLBOARD) && defined(UNITY_INSTANCING_ENABLED)
globalWindTime += UNITY_ACCESS_INSTANCED_PROP(STWind, _GlobalWindTime);
#endif
windyPosition = GlobalWind(windyPosition, treePos, true, rotatedWindVector, globalWindTime);
input.vertex.xyz = windyPosition;
}
#endif
#if defined(EFFECT_BILLBOARD)
float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
// crossfade faces
bool topDown = (input.texcoord.z > 0.5);
float3 viewDir = UNITY_MATRIX_IT_MV[2].xyz;
float3 cameraDir = normalize(mul((float3x3)UNITY_MATRIX_M, _WorldSpaceCameraPos - treePos));
float viewDot = max(dot(viewDir, input.normal), dot(cameraDir, input.normal));
viewDot *= viewDot;
viewDot *= viewDot;
viewDot += topDown ? 0.38 : 0.18; // different scales for horz and vert billboards to fix transition zone
// if invisible, avoid overdraw
if (viewDot < 0.3333)
{
input.vertex.xyz = float3(0, 0, 0);
}
input.color = float4(1, 1, 1, clamp(viewDot, 0, 1));
// adjust lighting on billboards to prevent seams between the different faces
if (topDown)
{
input.normal += cameraDir;
}
else
{
half3 binormal = cross(input.normal, input.tangent.xyz) * input.tangent.w;
float3 right = cross(cameraDir, binormal);
input.normal = cross(binormal, right);
}
input.normal = normalize(input.normal);
#endif
}
SpeedTreeVertexOutput SpeedTree8Vert(SpeedTreeVertexInput input)
{
SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, unity_LODFade.x);
output.uv = input.texcoord.xy;
output.color = input.color;
// color already contains (ao, ao, ao, blend)
// put hue variation amount in there
#ifdef EFFECT_HUE_VARIATION
float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
float hueVariationAmount = frac(treePos.x + treePos.y + treePos.z);
output.color.g = saturate(hueVariationAmount * _HueVariationColor.a);
#endif
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
half3 normalWS = TransformObjectToWorldNormal(input.normal);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#ifdef EFFECT_BUMP
real sign = input.tangent.w * GetOddNegativeScale();
output.normalWS.xyz = normalWS;
output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
// View dir packed in w.
output.normalWS.w = viewDirWS.x;
output.tangentWS.w = viewDirWS.y;
output.bitangentWS.w = viewDirWS.z;
#else
output.normalWS = normalWS;
output.viewDirWS = viewDirWS;
#endif
output.positionWS = vertexInput.positionWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
output.clipPos = vertexInput.positionCS;
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
return output;
}
SpeedTreeVertexDepthOutput SpeedTree8VertDepth(SpeedTreeVertexInput input)
{
SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, unity_LODFade.x);
output.uv = input.texcoord.xy;
output.color = input.color;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
#ifdef SHADOW_CASTER
half3 normalWS = TransformObjectToWorldNormal(input.normal);
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - vertexInput.positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#endif
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, lightDirectionWS));
output.clipPos = positionCS;
#else
output.clipPos = vertexInput.positionCS;
#endif
return output;
}
void InitializeInputData(SpeedTreeFragmentInput input, half3 normalTS, out InputData inputData)
{
inputData.positionWS = input.interpolated.positionWS.xyz;
#ifdef EFFECT_BUMP
inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz));
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
inputData.viewDirectionWS = half3(input.interpolated.normalWS.w, input.interpolated.tangentWS.w, input.interpolated.bitangentWS.w);
#else
inputData.normalWS = NormalizeNormalPerPixel(input.interpolated.normalWS);
inputData.viewDirectionWS = input.interpolated.viewDirWS;
#endif
#if SHADER_HINT_NICE_QUALITY
inputData.viewDirectionWS = SafeNormalize(inputData.viewDirectionWS);
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.interpolated.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = input.interpolated.fogFactorAndVertexLight.x;
inputData.vertexLighting = input.interpolated.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(input.interpolated.lightmapUV, input.interpolated.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.interpolated.clipPos);
inputData.shadowMask = half4(1, 1, 1, 1); // No GI currently.
}
#ifdef GBUFFER
FragmentOutput SpeedTree8Frag(SpeedTreeFragmentInput input)
#else
half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target
#endif
{
UNITY_SETUP_INSTANCE_ID(input.interpolated);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated);
#if !defined(SHADER_QUALITY_LOW)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
#ifdef EFFECT_BILLBOARD
LODDitheringTransition(input.interpolated.clipPos.xy, unity_LODFade.x);
#endif
#endif
#endif
half2 uv = input.interpolated.uv;
half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
half alpha = diffuse.a * input.interpolated.color.a;
AlphaDiscard(alpha - 0.3333, 0.0);
half3 albedo = diffuse.rgb;
half3 emission = 0;
half metallic = 0;
half smoothness = 0;
half occlusion = 0;
half3 specular = 0;
// hue variation
#ifdef EFFECT_HUE_VARIATION
half3 shiftedColor = lerp(albedo, _HueVariationColor.rgb, input.interpolated.color.g);
// preserve vibrance
half maxBase = max(albedo.r, max(albedo.g, albedo.b));
half newMaxBase = max(shiftedColor.r, max(shiftedColor.g, shiftedColor.b));
maxBase /= newMaxBase;
maxBase = maxBase * 0.5f + 0.5f;
shiftedColor.rgb *= maxBase;
albedo = saturate(shiftedColor);
#endif
// normal
#ifdef EFFECT_BUMP
half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
#else
half3 normalTs = half3(0, 0, 1);
#endif
// flip normal on backsides
#ifdef EFFECT_BACKSIDE_NORMALS
if (input.facing < 0.5)
{
normalTs.z = -normalTs.z;
}
#endif
// adjust billboard normals to improve GI and matching
#ifdef EFFECT_BILLBOARD
normalTs.z *= 0.5;
normalTs = normalize(normalTs);
#endif
// extra
#ifdef EFFECT_EXTRA_TEX
half4 extra = tex2D(_ExtraTex, uv);
smoothness = extra.r;
metallic = extra.g;
occlusion = extra.b * input.interpolated.color.r;
#else
smoothness = _Glossiness;
metallic = _Metallic;
occlusion = input.interpolated.color.r;
#endif
// subsurface (hijack emissive)
#ifdef EFFECT_SUBSURFACE
emission = tex2D(_SubsurfaceTex, uv).rgb * _SubsurfaceColor.rgb;
#endif
InputData inputData;
InitializeInputData(input, normalTs, inputData);
#ifdef GBUFFER
// in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR
// in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer
BRDFData brdfData;
InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
return BRDFDataToGbuffer(brdfData, inputData, smoothness, emission + color);
#else
half4 color = UniversalFragmentPBR(inputData, albedo, metallic, specular, smoothness, occlusion, emission, alpha);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
#endif
}
half4 SpeedTree8FragDepth(SpeedTreeVertexDepthOutput input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if !defined(SHADER_QUALITY_LOW)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
#ifdef EFFECT_BILLBOARD
LODDitheringTransition(input.clipPos.xy, unity_LODFade.x);
#endif
#endif
#endif
half2 uv = input.uv;
half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
half alpha = diffuse.a * input.color.a;
AlphaDiscard(alpha - 0.3333, 0.0);
#if defined(SCENESELECTIONPASS)
// We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
return half4(_ObjectId, _PassValue, 1.0, 1.0);
#else
return half4(0, 0, 0, 0);
#endif
}
SpeedTreeVertexDepthNormalOutput SpeedTree8VertDepthNormal(SpeedTreeVertexInput input)
{
SpeedTreeVertexDepthNormalOutput output = (SpeedTreeVertexDepthNormalOutput)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// handle speedtree wind and lod
InitializeData(input, unity_LODFade.x);
output.uv = input.texcoord.xy;
output.color = input.color;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
half3 normalWS = TransformObjectToWorldNormal(input.normal);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#ifdef EFFECT_BUMP
real sign = input.tangent.w * GetOddNegativeScale();
output.normalWS.xyz = normalWS;
output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
// View dir packed in w.
output.normalWS.w = viewDirWS.x;
output.tangentWS.w = viewDirWS.y;
output.bitangentWS.w = viewDirWS.z;
#else
output.normalWS = normalWS;
#endif
output.clipPos = vertexInput.positionCS;
return output;
}
half4 SpeedTree8FragDepthNormal(SpeedTreeDepthNormalFragmentInput input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input.interpolated);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated);
#if !defined(SHADER_QUALITY_LOW)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
#ifdef EFFECT_BILLBOARD
LODDitheringTransition(input.interpolated.clipPos.xy, unity_LODFade.x);
#endif
#endif
#endif
half2 uv = input.interpolated.uv;
half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
half alpha = diffuse.a * input.interpolated.color.a;
AlphaDiscard(alpha - 0.3333, 0.0);
float3 normalWS = NormalizeNormalPerPixel(input.interpolated.normalWS);
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(normalWS, true)), 0.0, 0.0);
}
#endif

View File

@@ -0,0 +1,76 @@
#ifndef UNIVERSAL_PARTICLES_EDITOR_PASS_INCLUDED
#define UNIVERSAL_PARTICLES_EDITOR_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
#ifdef _ALPHATEST_ON
half _Cutoff;
#endif
float _ObjectId;
float _PassValue;
float4 _SelectionID;
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
VaryingsParticle vertParticleEditor(AttributesParticle input)
{
VaryingsParticle output = (VaryingsParticle)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
output.clipPos = vertexInput.positionCS;
output.color = GetParticleColor(input.color);
#if defined(_FLIPBOOKBLENDING_ON) && !defined(UNITY_PARTICLE_INSTANCING_ENABLED)
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords, input.texcoordBlend);
#else
GetParticleTexcoords(output.texcoord, input.texcoords.xy);
#endif
return output;
}
void fragParticleSceneClip(VaryingsParticle input)
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord;
float3 blendUv = float3(0, 0, 0);
#if defined(_FLIPBOOKBLENDING_ON)
blendUv = input.texcoord2AndBlend;
#endif
float4 projectedPosition = float4(0, 0, 0, 0);
half4 albedo = SampleAlbedo(uv, blendUv, _BaseColor, input.color, projectedPosition, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
half alpha = albedo.a;
#ifdef _ALPHATEST_ON
clip(alpha - _Cutoff);
#endif
}
half4 fragParticleSceneHighlight(VaryingsParticle input) : SV_Target
{
fragParticleSceneClip(input);
return float4(_ObjectId, _PassValue, 1, 1);
}
half4 fragParticleScenePicking(VaryingsParticle input) : SV_Target
{
fragParticleSceneClip(input);
return _SelectionID;
}
#endif // UNIVERSAL_PARTICLES_EDITOR_PASS_INCLUDED

View File

@@ -0,0 +1,62 @@
#ifndef UNIVERSAL_PARTICLES_INPUT_INCLUDED
#define UNIVERSAL_PARTICLES_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct AttributesParticle
{
float4 vertex : POSITION;
half4 color : COLOR;
#if defined(_FLIPBOOKBLENDING_ON) && !defined(UNITY_PARTICLE_INSTANCING_ENABLED)
float4 texcoords : TEXCOORD0;
float texcoordBlend : TEXCOORD1;
#else
float2 texcoords : TEXCOORD0;
#endif
#if !defined(PARTICLES_EDITOR_META_PASS)
float3 normal : NORMAL;
float4 tangent : TANGENT;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VaryingsParticle
{
float4 clipPos : SV_POSITION;
float2 texcoord : TEXCOORD0;
half4 color : COLOR;
#if defined(_FLIPBOOKBLENDING_ON)
float3 texcoord2AndBlend : TEXCOORD5;
#endif
#if !defined(PARTICLES_EDITOR_META_PASS)
float4 positionWS : TEXCOORD1;
#ifdef _NORMALMAP
float4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x
float4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y
float4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z
#else
float3 normalWS : TEXCOORD2;
float3 viewDirWS : TEXCOORD3;
#endif
#if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
float4 projectedPosition: TEXCOORD6;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD7;
#endif
float3 vertexSH : TEXCOORD8; // SH
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
#endif // UNIVERSAL_PARTICLES_INPUT_INCLUDED

View File

@@ -0,0 +1,265 @@
// ------------------------------------------
// No shadows
Shader "Universal Render Pipeline/Particles/Lit"
{
Properties
{
[MainTexture] _BaseMap("Base Map", 2D) = "white" {}
[MainColor] _BaseColor("Base Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_MetallicGlossMap("Metallic Map", 2D) = "white" {}
[Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
[HDR] _EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_ReceiveShadows("Receive Shadows", Float) = 1.0
// -------------------------------------
// Particle specific
_SoftParticlesNearFadeDistance("Soft Particles Near Fade", Float) = 0.0
_SoftParticlesFarFadeDistance("Soft Particles Far Fade", Float) = 1.0
_CameraNearFadeDistance("Camera Near Fade", Float) = 1.0
_CameraFarFadeDistance("Camera Far Fade", Float) = 2.0
_DistortionBlend("Distortion Blend", Float) = 0.5
_DistortionStrength("Distortion Strength", Float) = 1.0
// -------------------------------------
// Hidden properties - Generic
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__mode", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _BlendOp("__blendop", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Particle specific
[HideInInspector] _ColorMode("_ColorMode", Float) = 0.0
[HideInInspector] _BaseColorAddSubDiff("_ColorMode", Vector) = (0,0,0,0)
[ToggleOff] _FlipbookBlending("__flipbookblending", Float) = 0.0
[HideInInspector] _SoftParticlesEnabled("__softparticlesenabled", Float) = 0.0
[HideInInspector] _CameraFadingEnabled("__camerafadingenabled", Float) = 0.0
[HideInInspector] _SoftParticleFadeParams("__softparticlefadeparams", Vector) = (0,0,0,0)
[HideInInspector] _CameraFadeParams("__camerafadeparams", Vector) = (0,0,0,0)
[HideInInspector] _DistortionEnabled("__distortionenabled", Float) = 0.0
[HideInInspector] _DistortionStrengthScaled("Distortion Strength Scaled", Float) = 0.1
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _FlipbookMode("flipbook", Float) = 0
[HideInInspector] _Glossiness("gloss", Float) = 0
[HideInInspector] _Mode("mode", Float) = 0
[HideInInspector] _Color("color", Color) = (1,1,1,1)
}
SubShader
{
Tags{"RenderType" = "Opaque" "IgnoreProjector" = "True" "PreviewType" = "Plane" "PerformanceChecks" = "False" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit"}
// ------------------------------------------------------------------
// Forward pass.
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "ForwardLit"
Tags {"LightMode" = "UniversalForward"}
BlendOp[_BlendOp]
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
#pragma shader_feature_local _SOFTPARTICLES_ON
#pragma shader_feature_local _FADING_ON
#pragma shader_feature_local _DISTORTION_ON
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex ParticlesLitVertex
#pragma fragment ParticlesLitFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// GBuffer pass.
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Particle Keywords
//#pragma shader_feature _ _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
//#pragma shader_feature _SOFTPARTICLES_ON
//#pragma shader_feature _FADING_ON
//#pragma shader_feature _DISTORTION_ON
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex ParticlesGBufferVertex
#pragma fragment ParticlesGBufferFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Scene view outline pass.
Pass
{
Name "SceneSelectionPass"
Tags { "LightMode" = "SceneSelectionPass" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
HLSLPROGRAM
#define PARTICLES_EDITOR_META_PASS
#pragma target 2.0
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleEditor
#pragma fragment fragParticleSceneHighlight
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Scene picking buffer pass.
Pass
{
Name "ScenePickingPass"
Tags{ "LightMode" = "Picking" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
HLSLPROGRAM
#define PARTICLES_EDITOR_META_PASS
#pragma target 2.0
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleEditor
#pragma fragment fragParticleScenePicking
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
Fallback "Universal Render Pipeline/Particles/SimpleLit"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.ParticlesLitShader"
}

View File

@@ -0,0 +1,126 @@
#ifndef UNIVERSAL_PARTICLES_FORWARD_LIT_PASS_INCLUDED
#define UNIVERSAL_PARTICLES_FORWARD_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData output)
{
output = (InputData)0;
output.positionWS = input.positionWS.xyz;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);
output.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
#else
half3 viewDirWS = input.viewDirWS;
output.normalWS = input.normalWS;
#endif
output.normalWS = NormalizeNormalPerPixel(output.normalWS);
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
output.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
output.shadowCoord = TransformWorldToShadowCoord(output.positionWS);
#else
output.shadowCoord = float4(0, 0, 0, 0);
#endif
output.fogCoord = (half)input.positionWS.w;
output.vertexLighting = half3(0.0h, 0.0h, 0.0h);
output.bakedGI = SampleSHPixel(input.vertexSH, output.normalWS);
output.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
output.shadowMask = half4(1, 1, 1, 1);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
VaryingsParticle ParticlesLitVertex(AttributesParticle input)
{
VaryingsParticle output = (VaryingsParticle)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangent);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
#ifdef _NORMALMAP
output.normalWS = half4(normalInput.normalWS, viewDirWS.x);
output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#endif
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
output.positionWS.xyz = vertexInput.positionWS;
output.positionWS.w = fogFactor;
output.clipPos = vertexInput.positionCS;
output.color = GetParticleColor(input.color);
#if defined(_FLIPBOOKBLENDING_ON)
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords.xyxy, 0.0);
#else
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords, input.texcoordBlend);
#endif
#else
GetParticleTexcoords(output.texcoord, input.texcoords.xy);
#endif
#if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
output.projectedPosition = vertexInput.positionNDC;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
ParticleParams particleParams;
InitParticleParams(input, particleParams);
SurfaceData surfaceData;
InitializeParticleLitSurfaceData(particleParams, surfaceData);
InputData inputData = (InputData)0;
InitializeInputData(input, surfaceData.normalTS, inputData);
half4 color = UniversalFragmentPBR(inputData, surfaceData);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
}
#endif // UNIVERSAL_PARTICLES_FORWARD_LIT_PASS_INCLUDED

View File

@@ -0,0 +1,134 @@
#ifndef UNIVERSAL_PARTICLES_GBUFFER_LIT_PASS_INCLUDED
#define UNIVERSAL_PARTICLES_GBUFFER_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData output)
{
output = (InputData)0;
output.positionWS = input.positionWS.xyz;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);
output.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
#else
half3 viewDirWS = input.viewDirWS;
output.normalWS = input.normalWS;
#endif
output.normalWS = NormalizeNormalPerPixel(output.normalWS);
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
output.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
output.shadowCoord = TransformWorldToShadowCoord(output.positionWS);
#else
output.shadowCoord = float4(0, 0, 0, 0);
#endif
output.fogCoord = 0.0; // not used for deferred shading
output.vertexLighting = half3(0.0h, 0.0h, 0.0h);
output.bakedGI = SampleSHPixel(input.vertexSH, output.normalWS);
output.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
output.shadowMask = half4(1, 1, 1, 1);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
VaryingsParticle ParticlesGBufferVertex(AttributesParticle input)
{
VaryingsParticle output = (VaryingsParticle)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangent);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
#ifdef _NORMALMAP
output.normalWS = half4(normalInput.normalWS, viewDirWS.x);
output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#endif
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
output.positionWS.xyz = vertexInput.positionWS;
output.clipPos = vertexInput.positionCS;
output.color = input.color;
#if defined(_FLIPBOOKBLENDING_ON)
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords.xyxy, 0.0);
#else
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords, input.texcoordBlend);
#endif
#else
GetParticleTexcoords(output.texcoord, input.texcoords.xy);
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
FragmentOutput ParticlesGBufferFragment(VaryingsParticle input)
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float3 blendUv = float3(0, 0, 0);
#if defined(_FLIPBOOKBLENDING_ON)
blendUv = input.texcoord2AndBlend;
#endif
float4 projectedPosition = float4(0,0,0,0);
#if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
projectedPosition = input.projectedPosition;
#endif
SurfaceData surfaceData;
InitializeParticleLitSurfaceData(input.texcoord, blendUv, input.color, projectedPosition, surfaceData);
InputData inputData = (InputData)0;
InitializeInputData(input, surfaceData.normalTS, inputData);
// Stripped down version of UniversalFragmentPBR().
// in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR
// in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, surfaceData.occlusion, inputData.normalWS, inputData.viewDirectionWS);
return BRDFDataToGbuffer(brdfData, inputData, surfaceData.smoothness, surfaceData.emission + color);
}
#endif // UNIVERSAL_PARTICLES_GBUFFER_LIT_PASS_INCLUDED

View File

@@ -0,0 +1,165 @@
#ifndef UNIVERSAL_PARTICLES_LIT_INPUT_INCLUDED
#define UNIVERSAL_PARTICLES_LIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl"
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
float4 _SoftParticleFadeParams;
float4 _CameraFadeParams;
float4 _BaseMap_ST;
half4 _BaseColor;
half4 _EmissionColor;
half4 _BaseColorAddSubDiff;
half _Cutoff;
half _Metallic;
half _Smoothness;
half _BumpScale;
half _DistortionStrengthScaled;
half _DistortionBlend;
half _Surface;
CBUFFER_END
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
#define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x
#define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y
#define CAMERA_NEAR_FADE _CameraFadeParams.x
#define CAMERA_INV_FADE_DISTANCE _CameraFadeParams.y
// Pre-multiplied alpha helper
#if defined(_ALPHAPREMULTIPLY_ON)
#define ALBEDO_MUL albedo
#else
#define ALBEDO_MUL albedo.a
#endif
half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, TEXTURE2D_PARAM(albedoMap, sampler_albedoMap))
{
half4 albedo = BlendTexture(TEXTURE2D_ARGS(albedoMap, sampler_albedoMap), uv, blendUv) * color;
half4 colorAddSubDiff = half4(0, 0, 0, 0);
#if defined (_COLORADDSUBDIFF_ON)
colorAddSubDiff = _BaseColorAddSubDiff;
#endif
// No distortion Support
albedo = MixParticleColor(albedo, particleColor, colorAddSubDiff);
AlphaDiscard(albedo.a, _Cutoff);
#if defined(_SOFTPARTICLES_ON)
ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition);
#endif
#if defined(_FADING_ON)
ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition);
#endif
return albedo;
}
half4 SampleAlbedo(TEXTURE2D_PARAM(albedoMap, sampler_albedoMap), ParticleParams params)
{
half4 albedo = BlendTexture(TEXTURE2D_ARGS(albedoMap, sampler_albedoMap), params.uv, params.blendUv) * params.baseColor;
half4 colorAddSubDiff = half4(0, 0, 0, 0);
#if defined (_COLORADDSUBDIFF_ON)
colorAddSubDiff = _BaseColorAddSubDiff;
#endif
// No distortion Support
albedo = MixParticleColor(albedo, params.vertexColor, colorAddSubDiff);
AlphaDiscard(albedo.a, _Cutoff);
#if defined(_SOFTPARTICLES_ON)
ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params);
#endif
#if defined(_FADING_ON)
ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition);
#endif
return albedo;
}
inline void InitializeParticleLitSurfaceData(float2 uv, float3 blendUv, float4 particleColor, float4 projectedPosition, out SurfaceData outSurfaceData)
{
half4 albedo = SampleAlbedo(uv, blendUv, _BaseColor, particleColor, projectedPosition, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
#if defined(_METALLICSPECGLOSSMAP)
half2 metallicGloss = BlendTexture(TEXTURE2D_ARGS(_MetallicGlossMap, sampler_MetallicGlossMap), uv, blendUv).ra * half2(1.0, _Smoothness);
#else
half2 metallicGloss = half2(_Metallic, _Smoothness);
#endif
half3 normalTS = SampleNormalTS(uv, blendUv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);
#if defined(_EMISSION)
half3 emission = BlendTexture(TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap), uv, blendUv).rgb * _EmissionColor.rgb;
#else
half3 emission = half3(0, 0, 0);
#endif
#if defined(_DISTORTION_ON)
albedo.rgb = Distortion(albedo, normalTS, _DistortionStrengthScaled, _DistortionBlend, projectedPosition);
#endif
outSurfaceData = (SurfaceData)0;
outSurfaceData.albedo = albedo.rgb;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
outSurfaceData.normalTS = normalTS;
outSurfaceData.emission = emission;
outSurfaceData.metallic = metallicGloss.r;
outSurfaceData.smoothness = metallicGloss.g;
outSurfaceData.occlusion = 1.0;
outSurfaceData.albedo = AlphaModulate(outSurfaceData.albedo, albedo.a);
outSurfaceData.alpha = albedo.a;
outSurfaceData.clearCoatMask = 0.0h;
outSurfaceData.clearCoatSmoothness = 1.0h;
}
inline void InitializeParticleLitSurfaceData(ParticleParams params, out SurfaceData outSurfaceData)
{
half4 albedo = SampleAlbedo(TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap), params);
#if defined(_METALLICSPECGLOSSMAP)
half2 metallicGloss = BlendTexture(TEXTURE2D_ARGS(_MetallicGlossMap, sampler_MetallicGlossMap), params.uv, params.blendUv).ra * half2(1.0, _Smoothness);
#else
half2 metallicGloss = half2(_Metallic, _Smoothness);
#endif
half3 normalTS = SampleNormalTS(params.uv, params.blendUv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);
#if defined(_EMISSION)
half3 emission = BlendTexture(TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap), params.uv, params.blendUv).rgb * _EmissionColor.rgb;
#else
half3 emission = half3(0, 0, 0);
#endif
#if defined(_DISTORTION_ON)
albedo.rgb = Distortion(albedo, normalTS, _DistortionStrengthScaled, _DistortionBlend, params.projectedPosition);
#endif
outSurfaceData = (SurfaceData)0;
outSurfaceData.albedo = albedo.rgb;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
outSurfaceData.normalTS = normalTS;
outSurfaceData.emission = emission;
outSurfaceData.metallic = metallicGloss.r;
outSurfaceData.smoothness = metallicGloss.g;
outSurfaceData.occlusion = 1.0;
outSurfaceData.albedo = AlphaModulate(outSurfaceData.albedo, albedo.a);
outSurfaceData.alpha = albedo.a;
outSurfaceData.clearCoatMask = 0.0h;
outSurfaceData.clearCoatSmoothness = 1.0h;
}
#endif // UNIVERSAL_PARTICLES_LIT_INPUT_INCLUDED

View File

@@ -0,0 +1,277 @@
// ------------------------------------------
// Only directional light is supported for lit particles
// No shadow
// No distortion
Shader "Universal Render Pipeline/Particles/Simple Lit"
{
Properties
{
[MainTexture] _BaseMap("Base Map", 2D) = "white" {}
[MainColor] _BaseColor("Base Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_SpecGlossMap("Specular", 2D) = "white" {}
_SpecColor("Specular", Color) = (1.0, 1.0, 1.0)
_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
[HDR] _EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
[HideInInspector] _SmoothnessSource("Smoothness Source", Float) = 0.0
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0
_ReceiveShadows("Receive Shadows", Float) = 1.0
// -------------------------------------
// Particle specific
_SoftParticlesNearFadeDistance("Soft Particles Near Fade", Float) = 0.0
_SoftParticlesFarFadeDistance("Soft Particles Far Fade", Float) = 1.0
_CameraNearFadeDistance("Camera Near Fade", Float) = 1.0
_CameraFarFadeDistance("Camera Far Fade", Float) = 2.0
_DistortionBlend("Distortion Blend", Float) = 0.5
_DistortionStrength("Distortion Strength", Float) = 1.0
// -------------------------------------
// Hidden properties - Generic
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__mode", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _BlendOp("__blendop", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Particle specific
[HideInInspector] _ColorMode("_ColorMode", Float) = 0.0
[HideInInspector] _BaseColorAddSubDiff("_ColorMode", Vector) = (0,0,0,0)
[ToggleOff] _FlipbookBlending("__flipbookblending", Float) = 0.0
[HideInInspector] _SoftParticlesEnabled("__softparticlesenabled", Float) = 0.0
[HideInInspector] _CameraFadingEnabled("__camerafadingenabled", Float) = 0.0
[HideInInspector] _SoftParticleFadeParams("__softparticlefadeparams", Vector) = (0,0,0,0)
[HideInInspector] _CameraFadeParams("__camerafadeparams", Vector) = (0,0,0,0)
[HideInInspector] _DistortionEnabled("__distortionenabled", Float) = 0.0
[HideInInspector] _DistortionStrengthScaled("Distortion Strength Scaled", Float) = 0.1
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _FlipbookMode("flipbook", Float) = 0
[HideInInspector] _Glossiness("gloss", Float) = 0
[HideInInspector] _Mode("mode", Float) = 0
[HideInInspector] _Color("color", Color) = (1,1,1,1)
}
SubShader
{
Tags{"RenderType" = "Opaque" "IgnoreProjector" = "True" "PreviewType" = "Plane" "PerformanceChecks" = "False" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit"}
// ------------------------------------------------------------------
// Forward pass.
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "ForwardLit"
Tags {"LightMode" = "UniversalForward"}
BlendOp[_BlendOp]
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _ _SPECGLOSSMAP _SPECULAR_COLOR
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
#pragma shader_feature_local _SOFTPARTICLES_ON
#pragma shader_feature_local _FADING_ON
#pragma shader_feature_local _DISTORTION_ON
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex ParticlesLitVertex
#pragma fragment ParticlesLitFragment
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// GBuffer pass.
Pass
{
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Render Pipeline
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _ _SPECGLOSSMAP _SPECULAR_COLOR
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Particle Keywords
//#pragma shader_feature _ _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
//#pragma shader_feature _SOFTPARTICLES_ON
//#pragma shader_feature _FADING_ON
//#pragma shader_feature _DISTORTION_ON
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex ParticlesLitGBufferVertex
#pragma fragment ParticlesLitGBufferFragment
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Scene view outline pass.
Pass
{
Name "SceneSelectionPass"
Tags { "LightMode" = "SceneSelectionPass" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
HLSLPROGRAM
#define PARTICLES_EDITOR_META_PASS
#pragma target 2.0
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleEditor
#pragma fragment fragParticleSceneHighlight
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Scene picking buffer pass.
Pass
{
Name "ScenePickingPass"
Tags{ "LightMode" = "Picking" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
HLSLPROGRAM
#define PARTICLES_EDITOR_META_PASS
#pragma target 2.0
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleEditor
#pragma fragment fragParticleScenePicking
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
Fallback "Universal Render Pipeline/Particles/Unlit"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.ParticlesSimpleLitShader"
}

View File

@@ -0,0 +1,136 @@
#ifndef UNIVERSAL_PARTICLES_FORWARD_SIMPLE_LIT_PASS_INCLUDED
#define UNIVERSAL_PARTICLES_FORWARD_SIMPLE_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData output)
{
output = (InputData)0;
output.positionWS = input.positionWS.xyz;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);
output.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
#else
half3 viewDirWS = input.viewDirWS;
output.normalWS = input.normalWS;
#endif
output.normalWS = NormalizeNormalPerPixel(output.normalWS);
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
output.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
output.shadowCoord = TransformWorldToShadowCoord(output.positionWS);
#else
output.shadowCoord = float4(0, 0, 0, 0);
#endif
output.fogCoord = (half)input.positionWS.w;
output.vertexLighting = half3(0.0h, 0.0h, 0.0h);
output.bakedGI = SampleSHPixel(input.vertexSH, output.normalWS);
output.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
output.shadowMask = half4(1, 1, 1, 1);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
VaryingsParticle ParticlesLitVertex(AttributesParticle input)
{
VaryingsParticle output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangent);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
#ifdef _NORMALMAP
output.normalWS = half4(normalInput.normalWS, viewDirWS.x);
output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#endif
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
output.positionWS.xyz = vertexInput.positionWS.xyz;
output.positionWS.w = ComputeFogFactor(vertexInput.positionCS.z);
output.clipPos = vertexInput.positionCS;
output.color = GetParticleColor(input.color);
#if defined(_FLIPBOOKBLENDING_ON)
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords.xyxy, 0.0);
#else
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords, input.texcoordBlend);
#endif
#else
GetParticleTexcoords(output.texcoord, input.texcoords.xy);
#endif
#if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
output.projectedPosition = vertexInput.positionNDC;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
ParticleParams particleParams;
InitParticleParams(input, particleParams);
half3 normalTS = SampleNormalTS(particleParams.uv, particleParams.blendUv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
half4 albedo = SampleAlbedo(TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap), particleParams);
half3 diffuse = AlphaModulate(albedo.rgb, albedo.a);
half alpha = albedo.a;
#if defined(_EMISSION)
half3 emission = BlendTexture(TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap), particleParams.uv, particleParams.blendUv) * _EmissionColor.rgb;
#else
half3 emission = half3(0, 0, 0);
#endif
half4 specularGloss = SampleSpecularSmoothness(particleParams.uv, particleParams.blendUv, albedo.a, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
half shininess = specularGloss.a;
#if defined(_DISTORTION_ON)
diffuse = Distortion(half4(diffuse, alpha), normalTS, _DistortionStrengthScaled, _DistortionBlend, particleParams.projectedPosition);
#endif
InputData inputData;
InitializeInputData(input, normalTS, inputData);
half4 color = UniversalFragmentBlinnPhong(inputData, diffuse, specularGloss, shininess, emission, alpha);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
}
#endif // UNIVERSAL_PARTICLES_FORWARD_SIMPLE_LIT_PASS_INCLUDED

View File

@@ -0,0 +1,149 @@
#ifndef UNIVERSAL_PARTICLES_GBUFFER_SIMPLE_LIT_PASS_INCLUDED
#define UNIVERSAL_PARTICLES_GBUFFER_SIMPLE_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData output)
{
output = (InputData)0;
output.positionWS = input.positionWS.xyz;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);
output.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
#else
half3 viewDirWS = input.viewDirWS;
output.normalWS = input.normalWS;
#endif
output.normalWS = NormalizeNormalPerPixel(output.normalWS);
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
output.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
output.shadowCoord = TransformWorldToShadowCoord(output.positionWS);
#else
output.shadowCoord = float4(0, 0, 0, 0);
#endif
output.fogCoord = 0; // not used for deferred shading
output.vertexLighting = half3(0.0h, 0.0h, 0.0h);
output.bakedGI = SampleSHPixel(input.vertexSH, output.normalWS);
output.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
output.shadowMask = half4(1, 1, 1, 1);
}
inline void InitializeParticleSimpleLitSurfaceData(VaryingsParticle input, out SurfaceData outSurfaceData)
{
outSurfaceData = (SurfaceData)0;
ParticleParams particleParams;
InitParticleParams(input, particleParams);
outSurfaceData.normalTS = SampleNormalTS(particleParams.uv, particleParams.blendUv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
half4 albedo = SampleAlbedo(TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap), particleParams);
outSurfaceData.albedo = AlphaModulate(albedo.rgb, albedo.a);
outSurfaceData.alpha = albedo.a;
#if defined(_EMISSION)
outSurfaceData.emission = BlendTexture(TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap), particleParams.uv, particleParams.blendUv) * _EmissionColor.rgb;
#else
outSurfaceData.emission = half3(0, 0, 0);
#endif
half4 specularGloss = SampleSpecularSmoothness(particleParams.uv, particleParams.blendUv, albedo.a, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
outSurfaceData.specular = specularGloss.rgb;
outSurfaceData.smoothness = specularGloss.a;
#if defined(_DISTORTION_ON)
outSurfaceData.albedo = Distortion(half4(outSurfaceData.albedo, outSurfaceData.alpha), outSurfaceData.normalTS, _DistortionStrengthScaled, _DistortionBlend, projectedPosition);
#endif
outSurfaceData.metallic = 0.0; // unused
outSurfaceData.occlusion = 1.0; // unused
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
VaryingsParticle ParticlesLitGBufferVertex(AttributesParticle input)
{
VaryingsParticle output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangent);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
#ifdef _NORMALMAP
output.normalWS = half4(normalInput.normalWS, viewDirWS.x);
output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#endif
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
output.positionWS.xyz = vertexInput.positionWS.xyz;
output.positionWS.w = 0;
output.clipPos = vertexInput.positionCS;
output.color = GetParticleColor(input.color);
#if defined(_FLIPBOOKBLENDING_ON)
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords.xyxy, 0.0);
#else
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords, input.texcoordBlend);
#endif
#else
GetParticleTexcoords(output.texcoord, input.texcoords.xy);
#endif
#if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
output.projectedPosition = vertexInput.positionNDC;
#endif
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
FragmentOutput ParticlesLitGBufferFragment(VaryingsParticle input)
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
SurfaceData surfaceData;
InitializeParticleSimpleLitSurfaceData(input, surfaceData);
InputData inputData;
InitializeInputData(input, surfaceData.normalTS, inputData);
half4 color = half4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha);
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingSimpleLit);
}
#endif // UNIVERSAL_PARTICLES_GBUFFER_SIMPLE_LIT_PASS_INCLUDED

View File

@@ -0,0 +1,96 @@
#ifndef UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_INCLUDED
#define UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl"
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
float4 _SoftParticleFadeParams;
float4 _CameraFadeParams;
float4 _BaseMap_ST;
half4 _BaseColor;
half4 _EmissionColor;
half4 _BaseColorAddSubDiff;
half4 _SpecColor;
half _Cutoff;
half _Smoothness;
half _DistortionStrengthScaled;
half _DistortionBlend;
half _Surface;
CBUFFER_END
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
#define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x
#define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y
#define CAMERA_NEAR_FADE _CameraFadeParams.x
#define CAMERA_INV_FADE_DISTANCE _CameraFadeParams.y
half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, TEXTURE2D_PARAM(albedoMap, sampler_albedoMap))
{
half4 albedo = BlendTexture(TEXTURE2D_ARGS(albedoMap, sampler_albedoMap), uv, blendUv) * color;
half4 colorAddSubDiff = half4(0, 0, 0, 0);
#if defined (_COLORADDSUBDIFF_ON)
colorAddSubDiff = _BaseColorAddSubDiff;
#endif
albedo = MixParticleColor(albedo, particleColor, colorAddSubDiff);
AlphaDiscard(albedo.a, _Cutoff);
#if defined(_SOFTPARTICLES_ON)
ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition);
#endif
#if defined(_FADING_ON)
ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition);
#endif
return albedo;
}
half4 SampleAlbedo(TEXTURE2D_PARAM(albedoMap, sampler_albedoMap), ParticleParams params)
{
half4 albedo = BlendTexture(TEXTURE2D_ARGS(albedoMap, sampler_albedoMap), params.uv, params.blendUv) * params.baseColor;
half4 colorAddSubDiff = half4(0, 0, 0, 0);
#if defined (_COLORADDSUBDIFF_ON)
colorAddSubDiff = _BaseColorAddSubDiff;
#endif
albedo = MixParticleColor(albedo, params.vertexColor, colorAddSubDiff);
AlphaDiscard(albedo.a, _Cutoff);
#if defined(_SOFTPARTICLES_ON)
ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params);
#endif
#if defined(_FADING_ON)
ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition);
#endif
return albedo;
}
half4 SampleSpecularSmoothness(float2 uv, float3 blendUv, half alpha, half4 specColor, TEXTURE2D_PARAM(specGlossMap, sampler_specGlossMap))
{
half4 specularGloss = half4(0.0h, 0.0h, 0.0h, 1.0h);
#ifdef _SPECGLOSSMAP
specularGloss = BlendTexture(TEXTURE2D_ARGS(specGlossMap, sampler_specGlossMap), uv, blendUv);
#elif defined(_SPECULAR_COLOR)
specularGloss = specColor;
#endif
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
specularGloss.a = alpha;
#endif
specularGloss.a = exp2(10 * specularGloss.a + 1);
return specularGloss;
}
#endif // UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_INCLUDED

View File

@@ -0,0 +1,172 @@
Shader "Universal Render Pipeline/Particles/Unlit"
{
Properties
{
[MainTexture] _BaseMap("Base Map", 2D) = "white" {}
[MainColor] _BaseColor("Base Color", Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_BumpMap("Normal Map", 2D) = "bump" {}
[HDR] _EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
// -------------------------------------
// Particle specific
_SoftParticlesNearFadeDistance("Soft Particles Near Fade", Float) = 0.0
_SoftParticlesFarFadeDistance("Soft Particles Far Fade", Float) = 1.0
_CameraNearFadeDistance("Camera Near Fade", Float) = 1.0
_CameraFarFadeDistance("Camera Far Fade", Float) = 2.0
_DistortionBlend("Distortion Blend", Float) = 0.5
_DistortionStrength("Distortion Strength", Float) = 1.0
// -------------------------------------
// Hidden properties - Generic
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__mode", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _BlendOp("__blendop", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Particle specific
[HideInInspector] _ColorMode("_ColorMode", Float) = 0.0
[HideInInspector] _BaseColorAddSubDiff("_ColorMode", Vector) = (0,0,0,0)
[ToggleOff] _FlipbookBlending("__flipbookblending", Float) = 0.0
[HideInInspector] _SoftParticlesEnabled("__softparticlesenabled", Float) = 0.0
[HideInInspector] _CameraFadingEnabled("__camerafadingenabled", Float) = 0.0
[HideInInspector] _SoftParticleFadeParams("__softparticlefadeparams", Vector) = (0,0,0,0)
[HideInInspector] _CameraFadeParams("__camerafadeparams", Vector) = (0,0,0,0)
[HideInInspector] _DistortionEnabled("__distortionenabled", Float) = 0.0
[HideInInspector] _DistortionStrengthScaled("Distortion Strength Scaled", Float) = 0.1
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _FlipbookMode("flipbook", Float) = 0
[HideInInspector] _Mode("mode", Float) = 0
[HideInInspector] _Color("color", Color) = (1,1,1,1)
}
SubShader
{
Tags{"RenderType" = "Opaque" "IgnoreProjector" = "True" "PreviewType" = "Plane" "PerformanceChecks" = "False" "RenderPipeline" = "UniversalPipeline"}
// ------------------------------------------------------------------
// Forward pass.
Pass
{
Name "ForwardLit"
BlendOp[_BlendOp]
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
ColorMask RGB
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON _ALPHAMODULATE_ON
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
#pragma shader_feature_local _SOFTPARTICLES_ON
#pragma shader_feature_local _FADING_ON
#pragma shader_feature_local _DISTORTION_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleUnlit
#pragma fragment fragParticleUnlit
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Scene view outline pass.
Pass
{
Name "SceneSelectionPass"
Tags { "LightMode" = "SceneSelectionPass" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
HLSLPROGRAM
#define PARTICLES_EDITOR_META_PASS
#pragma target 2.0
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleEditor
#pragma fragment fragParticleSceneHighlight
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Scene picking buffer pass.
Pass
{
Name "ScenePickingPass"
Tags{ "LightMode" = "Picking" }
BlendOp Add
Blend One Zero
ZWrite On
Cull Off
HLSLPROGRAM
#define PARTICLES_EDITOR_META_PASS
#pragma target 2.0
// -------------------------------------
// Particle Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local _FLIPBOOKBLENDING_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_instancing
#pragma instancing_options procedural:ParticleInstancingSetup
#pragma vertex vertParticleEditor
#pragma fragment fragParticleScenePicking
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl"
ENDHLSL
}
}
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.ParticlesUnlitShader"
}

View File

@@ -0,0 +1,118 @@
#ifndef UNIVERSAL_PARTICLES_UNLIT_FORWARD_PASS_INCLUDED
#define UNIVERSAL_PARTICLES_UNLIT_FORWARD_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData output)
{
output = (InputData)0;
output.positionWS = input.positionWS.xyz;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);
output.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
#else
half3 viewDirWS = input.viewDirWS;
output.normalWS = input.normalWS;
#endif
output.normalWS = NormalizeNormalPerPixel(output.normalWS);
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
output.viewDirectionWS = viewDirWS;
output.fogCoord = (half)input.positionWS.w;
output.vertexLighting = half3(0.0h, 0.0h, 0.0h);
output.bakedGI = SampleSHPixel(input.vertexSH, output.normalWS);
output.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
output.shadowMask = half4(1, 1, 1, 1);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
VaryingsParticle vertParticleUnlit(AttributesParticle input)
{
VaryingsParticle output = (VaryingsParticle)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangent);
// position ws is used to compute eye depth in vertFading
output.positionWS.xyz = vertexInput.positionWS;
output.positionWS.w = ComputeFogFactor(vertexInput.positionCS.z);
output.clipPos = vertexInput.positionCS;
output.color = GetParticleColor(input.color);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
#ifdef _NORMALMAP
output.normalWS = half4(normalInput.normalWS, viewDirWS.x);
output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normalWS = normalInput.normalWS;
output.viewDirWS = viewDirWS;
#endif
#if defined(_FLIPBOOKBLENDING_ON)
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords.xyxy, 0.0);
#else
GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords, input.texcoordBlend);
#endif
#else
GetParticleTexcoords(output.texcoord, input.texcoords.xy);
#endif
#if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
output.projectedPosition = vertexInput.positionNDC;
#endif
return output;
}
half4 fragParticleUnlit(VaryingsParticle input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
ParticleParams particleParams;
InitParticleParams(input, particleParams);
half4 albedo = SampleAlbedo(TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap), particleParams);
half3 normalTS = SampleNormalTS(particleParams.uv, particleParams.blendUv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
#if defined (_DISTORTION_ON)
albedo.rgb = Distortion(albedo, normalTS, _DistortionStrengthScaled, _DistortionBlend, particleParams.projectedPosition);
#endif
#if defined(_EMISSION)
half3 emission = BlendTexture(TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb;
#else
half3 emission = half3(0, 0, 0);
#endif
half3 result = albedo.rgb + emission;
half fogFactor = input.positionWS.w;
result = MixFog(result, fogFactor);
albedo.a = OutputAlpha(albedo.a, _Surface);
return half4(result, albedo.a);
}
#endif // UNIVERSAL_PARTICLES_UNLIT_FORWARD_PASS_INCLUDED

View File

@@ -0,0 +1,82 @@
#ifndef UNIVERSAL_PARTICLES_UNLIT_INPUT_INCLUDED
#define UNIVERSAL_PARTICLES_UNLIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl"
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
float4 _SoftParticleFadeParams;
float4 _CameraFadeParams;
float4 _BaseMap_ST;
half4 _BaseColor;
half4 _EmissionColor;
half4 _BaseColorAddSubDiff;
half _Cutoff;
half _DistortionStrengthScaled;
half _DistortionBlend;
half _Surface;
CBUFFER_END
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl"
#define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x
#define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y
#define CAMERA_NEAR_FADE _CameraFadeParams.x
#define CAMERA_INV_FADE_DISTANCE _CameraFadeParams.y
half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, TEXTURE2D_PARAM(albedoMap, sampler_albedoMap))
{
half4 albedo = BlendTexture(TEXTURE2D_ARGS(albedoMap, sampler_albedoMap), uv, blendUv) * color;
// No distortion Support
half4 colorAddSubDiff = half4(0, 0, 0, 0);
#if defined (_COLORADDSUBDIFF_ON)
colorAddSubDiff = _BaseColorAddSubDiff;
#endif
albedo = MixParticleColor(albedo, particleColor, colorAddSubDiff);
AlphaDiscard(albedo.a, _Cutoff);
albedo.rgb = AlphaModulate(albedo.rgb, albedo.a);
#if defined(_SOFTPARTICLES_ON)
albedo = SOFT_PARTICLE_MUL_ALBEDO(albedo, SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition));
#endif
#if defined(_FADING_ON)
ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition);
#endif
return albedo;
}
half4 SampleAlbedo(TEXTURE2D_PARAM(albedoMap, sampler_albedoMap), ParticleParams params)
{
half4 albedo = BlendTexture(TEXTURE2D_ARGS(albedoMap, sampler_albedoMap), params.uv, params.blendUv) * params.baseColor;
// No distortion Support
#if defined (_COLORADDSUBDIFF_ON)
half4 colorAddSubDiff = _BaseColorAddSubDiff;
#else
half4 colorAddSubDiff = half4(0, 0, 0, 0);
#endif
albedo = MixParticleColor(albedo, params.vertexColor, colorAddSubDiff);
AlphaDiscard(albedo.a, _Cutoff);
albedo.rgb = AlphaModulate(albedo.rgb, albedo.a);
#if defined(_SOFTPARTICLES_ON)
albedo = SOFT_PARTICLE_MUL_ALBEDO(albedo, SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params));
#endif
#if defined(_FADING_ON)
ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition);
#endif
return albedo;
}
#endif // UNIVERSAL_PARTICLES_PBR_INCLUDED

View File

@@ -0,0 +1,214 @@
Shader "Hidden/Universal Render Pipeline/Bloom"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local _ _USE_RGBM
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
TEXTURE2D_X(_SourceTex);
float4 _SourceTex_TexelSize;
TEXTURE2D_X(_SourceTexLowMip);
float4 _SourceTexLowMip_TexelSize;
float4 _Params; // x: scatter, y: clamp, z: threshold (linear), w: threshold knee
#define Scatter _Params.x
#define ClampMax _Params.y
#define Threshold _Params.z
#define ThresholdKnee _Params.w
half4 EncodeHDR(half3 color)
{
#if _USE_RGBM
half4 outColor = EncodeRGBM(color);
#else
half4 outColor = half4(color, 1.0);
#endif
#if UNITY_COLORSPACE_GAMMA
return half4(sqrt(outColor.xyz), outColor.w); // linear to γ
#else
return outColor;
#endif
}
half3 DecodeHDR(half4 color)
{
#if UNITY_COLORSPACE_GAMMA
color.xyz *= color.xyz; // γ to linear
#endif
#if _USE_RGBM
return DecodeRGBM(color);
#else
return color.xyz;
#endif
}
half4 FragPrefilter(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#if _BLOOM_HQ
float texelSize = _SourceTex_TexelSize.x;
half4 A = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, -1.0));
half4 B = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.0, -1.0));
half4 C = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, -1.0));
half4 D = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-0.5, -0.5));
half4 E = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.5, -0.5));
half4 F = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, 0.0));
half4 G = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 H = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, 0.0));
half4 I = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-0.5, 0.5));
half4 J = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.5, 0.5));
half4 K = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(-1.0, 1.0));
half4 L = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(0.0, 1.0));
half4 M = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + texelSize * float2(1.0, 1.0));
half2 div = (1.0 / 4.0) * half2(0.5, 0.125);
half4 o = (D + E + I + J) * div.x;
o += (A + B + G + F) * div.y;
o += (B + C + H + G) * div.y;
o += (F + G + L + K) * div.y;
o += (G + H + M + L) * div.y;
half3 color = o.xyz;
#else
half3 color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv).xyz;
#endif
// User controlled clamp to limit crazy high broken spec
color = min(ClampMax, color);
// Thresholding
half brightness = Max3(color.r, color.g, color.b);
half softness = clamp(brightness - Threshold + ThresholdKnee, 0.0, 2.0 * ThresholdKnee);
softness = (softness * softness) / (4.0 * ThresholdKnee + 1e-4);
half multiplier = max(brightness - Threshold, softness) / max(brightness, 1e-4);
color *= multiplier;
return EncodeHDR(color);
}
half4 FragBlurH(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float texelSize = _SourceTex_TexelSize.x * 2.0;
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// 9-tap gaussian blur on the downsampled source
half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 4.0, 0.0)));
half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 3.0, 0.0)));
half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 2.0, 0.0)));
half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(texelSize * 1.0, 0.0)));
half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv ));
half3 c5 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 1.0, 0.0)));
half3 c6 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 2.0, 0.0)));
half3 c7 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 3.0, 0.0)));
half3 c8 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(texelSize * 4.0, 0.0)));
half3 color = c0 * 0.01621622 + c1 * 0.05405405 + c2 * 0.12162162 + c3 * 0.19459459
+ c4 * 0.22702703
+ c5 * 0.19459459 + c6 * 0.12162162 + c7 * 0.05405405 + c8 * 0.01621622;
return EncodeHDR(color);
}
half4 FragBlurV(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float texelSize = _SourceTex_TexelSize.y;
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// Optimized bilinear 5-tap gaussian on the same-sized source (9-tap equivalent)
half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(0.0, texelSize * 3.23076923)));
half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - float2(0.0, texelSize * 1.38461538)));
half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv ));
half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(0.0, texelSize * 1.38461538)));
half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + float2(0.0, texelSize * 3.23076923)));
half3 color = c0 * 0.07027027 + c1 * 0.31621622
+ c2 * 0.22702703
+ c3 * 0.31621622 + c4 * 0.07027027;
return EncodeHDR(color);
}
half3 Upsample(float2 uv)
{
half3 highMip = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv));
#if _BLOOM_HQ && !defined(SHADER_API_GLES)
half3 lowMip = DecodeHDR(SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_SourceTexLowMip, sampler_LinearClamp), uv, _SourceTexLowMip_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex));
#else
half3 lowMip = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTexLowMip, sampler_LinearClamp, uv));
#endif
return lerp(highMip, lowMip, Scatter);
}
half4 FragUpsample(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half3 color = Upsample(UnityStereoTransformScreenSpaceTex(input.uv));
return EncodeHDR(color);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Bloom Prefilter"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPrefilter
#pragma multi_compile_local _ _BLOOM_HQ
ENDHLSL
}
Pass
{
Name "Bloom Blur Horizontal"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurH
ENDHLSL
}
Pass
{
Name "Bloom Blur Vertical"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurV
ENDHLSL
}
Pass
{
Name "Bloom Upsample"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragUpsample
#pragma multi_compile_local _ _BLOOM_HQ
ENDHLSL
}
}
}

View File

@@ -0,0 +1,356 @@
Shader "Hidden/Universal Render Pipeline/BokehDepthOfField"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _USE_FAST_SRGB_LINEAR_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
// Do not change this without changing PostProcessPass.PrepareBokehKernel()
#define SAMPLE_COUNT 42
// Toggle this to reduce flickering - note that it will reduce overall bokeh energy and add
// a small cost to the pre-filtering pass
#define COC_LUMA_WEIGHTING 0
TEXTURE2D_X(_SourceTex);
TEXTURE2D_X(_DofTexture);
TEXTURE2D_X(_FullCoCTexture);
float4 _SourceSize;
float4 _HalfSourceSize;
float4 _DownSampleScaleFactor;
float4 _CoCParams;
float4 _BokehKernel[SAMPLE_COUNT];
#define FocusDist _CoCParams.x
#define MaxCoC _CoCParams.y
#define MaxRadius _CoCParams.z
#define RcpAspect _CoCParams.w
half FragCoC(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _SourceSize.xy * uv).x;
float linearEyeDepth = LinearEyeDepth(depth, _ZBufferParams);
half coc = (1.0 - FocusDist / linearEyeDepth) * MaxCoC;
half nearCoC = clamp(coc, -1.0, 0.0);
half farCoC = saturate(coc);
return saturate((farCoC + nearCoC + 1.0) * 0.5);
}
half4 FragPrefilter(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#if SHADER_TARGET >= 45 && defined(PLATFORM_SUPPORT_GATHER)
// Sample source colors
half4 cr = GATHER_RED_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 cg = GATHER_GREEN_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 cb = GATHER_BLUE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half3 c0 = half3(cr.x, cg.x, cb.x);
half3 c1 = half3(cr.y, cg.y, cb.y);
half3 c2 = half3(cr.z, cg.z, cb.z);
half3 c3 = half3(cr.w, cg.w, cb.w);
// Sample CoCs
half4 cocs = GATHER_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv) * 2.0 - 1.0;
half coc0 = cocs.x;
half coc1 = cocs.y;
half coc2 = cocs.z;
half coc3 = cocs.w;
#else
float3 duv = _SourceSize.zwz * float3(0.5, 0.5, -0.5);
float2 uv0 = uv - duv.xy;
float2 uv1 = uv - duv.zy;
float2 uv2 = uv + duv.zy;
float2 uv3 = uv + duv.xy;
// Sample source colors
half3 c0 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv0).xyz;
half3 c1 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv1).xyz;
half3 c2 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv2).xyz;
half3 c3 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv3).xyz;
// Sample CoCs
half coc0 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv0).x * 2.0 - 1.0;
half coc1 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv1).x * 2.0 - 1.0;
half coc2 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv2).x * 2.0 - 1.0;
half coc3 = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv3).x * 2.0 - 1.0;
#endif
#if COC_LUMA_WEIGHTING
// Apply CoC and luma weights to reduce bleeding and flickering
half w0 = abs(coc0) / (Max3(c0.x, c0.y, c0.z) + 1.0);
half w1 = abs(coc1) / (Max3(c1.x, c1.y, c1.z) + 1.0);
half w2 = abs(coc2) / (Max3(c2.x, c2.y, c2.z) + 1.0);
half w3 = abs(coc3) / (Max3(c3.x, c3.y, c3.z) + 1.0);
// Weighted average of the color samples
half3 avg = c0 * w0 + c1 * w1 + c2 * w2 + c3 * w3;
avg /= max(w0 + w1 + w2 + w3, 1e-5);
#else
half3 avg = (c0 + c1 + c2 + c3) / 4.0;
#endif
// Select the largest CoC value
half cocMin = min(coc0, Min3(coc1, coc2, coc3));
half cocMax = max(coc0, Max3(coc1, coc2, coc3));
half coc = (-cocMin > cocMax ? cocMin : cocMax) * MaxRadius;
// Premultiply CoC
avg *= smoothstep(0, _SourceSize.w * 2.0, abs(coc));
#if defined(UNITY_COLORSPACE_GAMMA)
avg = GetSRGBToLinear(avg);
#endif
return half4(avg, coc);
}
void Accumulate(float4 samp0, float2 uv, float2 disp, inout half4 farAcc, inout half4 nearAcc)
{
float dist = length(disp);
float2 duv = float2(disp.x * RcpAspect, disp.y);
half4 samp = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + duv);
// Compare CoC of the current sample and the center sample and select smaller one
half farCoC = max(min(samp0.a, samp.a), 0.0);
// Compare the CoC to the sample distance & add a small margin to smooth out
const half margin = _SourceSize.w * _DownSampleScaleFactor.w * 2.0;
half farWeight = saturate((farCoC - dist + margin) / margin);
half nearWeight = saturate((-samp.a - dist + margin) / margin);
// Cut influence from focused areas because they're darkened by CoC premultiplying. This is only
// needed for near field
nearWeight *= step(_SourceSize.w * _DownSampleScaleFactor.w, -samp.a);
// Accumulation
farAcc += half4(samp.rgb, 1.0) * farWeight;
nearAcc += half4(samp.rgb, 1.0) * nearWeight;
}
half4 FragBlur(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
half4 samp0 = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
half4 farAcc = 0.0; // Background: far field bokeh
half4 nearAcc = 0.0; // Foreground: near field bokeh
// Center sample isn't in the kernel array, accumulate it separately
Accumulate(samp0, uv, 0.0, farAcc, nearAcc);
UNITY_LOOP
for (int si = 0; si < SAMPLE_COUNT; si++)
{
float2 disp = _BokehKernel[si].xy * MaxRadius;
Accumulate(samp0, uv, disp, farAcc, nearAcc);
}
// Get the weighted average
farAcc.rgb /= farAcc.a + (farAcc.a == 0.0); // Zero-div guard
nearAcc.rgb /= nearAcc.a + (nearAcc.a == 0.0);
// Normalize the total of the weights for the near field
nearAcc.a *= PI / (SAMPLE_COUNT + 1);
// Alpha premultiplying
half alpha = saturate(nearAcc.a);
half3 rgb = lerp(farAcc.rgb, nearAcc.rgb, alpha);
return half4(rgb, alpha);
}
half4 FragPostBlur(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// 9-tap tent filter with 4 bilinear samples
float4 duv = _SourceSize.zwzw * _DownSampleScaleFactor.zwzw * float4(0.5, 0.5, -0.5, 0);
half4 acc;
acc = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - duv.xy);
acc += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv - duv.zy);
acc += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + duv.zy);
acc += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv + duv.xy);
return acc * 0.25;
}
half4 FragComposite(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
half4 dof = SAMPLE_TEXTURE2D_X(_DofTexture, sampler_LinearClamp, uv);
half coc = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv).r;
coc = (coc - 0.5) * 2.0 * MaxRadius;
// Convert CoC to far field alpha value
float ffa = smoothstep(_SourceSize.w * 2.0, _SourceSize.w * 4.0, coc);
half4 color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv);
#if defined(UNITY_COLORSPACE_GAMMA)
color = GetSRGBToLinear(color);
#endif
half alpha = Max3(dof.r, dof.g, dof.b);
color = lerp(color, half4(dof.rgb, alpha), ffa + dof.a - ffa * dof.a);
#if defined(UNITY_COLORSPACE_GAMMA)
color = GetLinearToSRGB(color);
#endif
return color;
}
ENDHLSL
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Bokeh Depth Of Field CoC"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragCoC
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Prefilter"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPrefilter
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlur
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Post Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPostBlur
#pragma target 4.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Composite"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragComposite
#pragma target 4.5
ENDHLSL
}
}
// SM3.5 fallbacks - needed because of the use of Gather
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Bokeh Depth Of Field CoC"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragCoC
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Prefilter"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPrefilter
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlur
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Post Blur"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragPostBlur
#pragma target 3.5
ENDHLSL
}
Pass
{
Name "Bokeh Depth Of Field Composite"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragComposite
#pragma target 3.5
ENDHLSL
}
}
}

View File

@@ -0,0 +1,170 @@
Shader "Hidden/Universal Render Pipeline/CameraMotionBlur"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
TEXTURE2D_X(_SourceTex);
#if defined(USING_STEREO_MATRICES)
float4x4 _PrevViewProjMStereo[2];
#define _PrevViewProjM _PrevViewProjMStereo[unity_StereoEyeIndex]
#define _ViewProjM unity_MatrixVP
#else
float4x4 _ViewProjM;
float4x4 _PrevViewProjM;
#endif
float _Intensity;
float _Clamp;
float4 _SourceSize;
struct VaryingsCMB
{
float4 positionCS : SV_POSITION;
float4 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsCMB VertCMB(Attributes input)
{
VaryingsCMB output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv.xy);
#else
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv.xy = input.uv;
#endif
float4 projPos = output.positionCS * 0.5;
projPos.xy = projPos.xy + projPos.w;
output.uv.zw = projPos.xy;
return output;
}
float2 ClampVelocity(float2 velocity, float maxVelocity)
{
float len = length(velocity);
return (len > 0.0) ? min(len, maxVelocity) * (velocity * rcp(len)) : 0.0;
}
// Per-pixel camera velocity
float2 GetCameraVelocity(float4 uv)
{
float depth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, uv.xy).r;
#if UNITY_REVERSED_Z
depth = 1.0 - depth;
#endif
depth = 2.0 * depth - 1.0;
float3 viewPos = ComputeViewSpacePosition(uv.zw, depth, unity_CameraInvProjection);
float4 worldPos = float4(mul(unity_CameraToWorld, float4(viewPos, 1.0)).xyz, 1.0);
float4 prevPos = worldPos;
float4 prevClipPos = mul(_PrevViewProjM, prevPos);
float4 curClipPos = mul(_ViewProjM, worldPos);
float2 prevPosCS = prevClipPos.xy / prevClipPos.w;
float2 curPosCS = curClipPos.xy / curClipPos.w;
return ClampVelocity(prevPosCS - curPosCS, _Clamp);
}
float3 GatherSample(float sampleNumber, float2 velocity, float invSampleCount, float2 centerUV, float randomVal, float velocitySign)
{
float offsetLength = (sampleNumber + 0.5) + (velocitySign * (randomVal - 0.5));
float2 sampleUV = centerUV + (offsetLength * invSampleCount) * velocity * velocitySign;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_PointClamp, sampleUV).xyz;
}
half4 DoMotionBlur(VaryingsCMB input, int iterations)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv.xy);
float2 velocity = GetCameraVelocity(float4(uv, input.uv.zw)) * _Intensity;
float randomVal = InterleavedGradientNoise(uv * _SourceSize.xy, 0);
float invSampleCount = rcp(iterations * 2.0);
half3 color = 0.0;
UNITY_UNROLL
for (int i = 0; i < iterations; i++)
{
color += GatherSample(i, velocity, invSampleCount, uv, randomVal, -1.0);
color += GatherSample(i, velocity, invSampleCount, uv, randomVal, 1.0);
}
return half4(color * invSampleCount, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Camera Motion Blur - Low Quality"
HLSLPROGRAM
#pragma vertex VertCMB
#pragma fragment Frag
half4 Frag(VaryingsCMB input) : SV_Target
{
return DoMotionBlur(input, 2);
}
ENDHLSL
}
Pass
{
Name "Camera Motion Blur - Medium Quality"
HLSLPROGRAM
#pragma vertex VertCMB
#pragma fragment Frag
half4 Frag(VaryingsCMB input) : SV_Target
{
return DoMotionBlur(input, 3);
}
ENDHLSL
}
Pass
{
Name "Camera Motion Blur - High Quality"
HLSLPROGRAM
#pragma vertex VertCMB
#pragma fragment Frag
half4 Frag(VaryingsCMB input) : SV_Target
{
return DoMotionBlur(input, 4);
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,198 @@
#ifndef UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
#define UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Fullscreen.hlsl"
// ----------------------------------------------------------------------------------
// Render fullscreen mesh by using a matrix set directly by the pipeline instead of
// relying on the matrix set by the C++ engine to avoid issues with XR
float4x4 _FullscreenProjMat;
float4 TransformFullscreenMesh(half3 positionOS)
{
return mul(_FullscreenProjMat, half4(positionOS, 1));
}
Varyings VertFullscreenMesh(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = input.uv;
#endif
return output;
}
// ----------------------------------------------------------------------------------
// Samplers
SAMPLER(sampler_LinearClamp);
SAMPLER(sampler_LinearRepeat);
SAMPLER(sampler_PointClamp);
SAMPLER(sampler_PointRepeat);
// ----------------------------------------------------------------------------------
// Utility functions
half GetLuminance(half3 colorLinear)
{
#if _TONEMAP_ACES
return AcesLuminance(colorLinear);
#else
return Luminance(colorLinear);
#endif
}
real3 GetSRGBToLinear(real3 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastSRGBToLinear(c);
#else
return SRGBToLinear(c);
#endif
}
real4 GetSRGBToLinear(real4 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastSRGBToLinear(c);
#else
return SRGBToLinear(c);
#endif
}
real3 GetLinearToSRGB(real3 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastLinearToSRGB(c);
#else
return LinearToSRGB(c);
#endif
}
real4 GetLinearToSRGB(real4 c)
{
#if _USE_FAST_SRGB_LINEAR_CONVERSION
return FastLinearToSRGB(c);
#else
return LinearToSRGB(c);
#endif
}
// ----------------------------------------------------------------------------------
// Shared functions for uber & fast path (on-tile)
// These should only process an input color, don't sample in neighbor pixels!
half3 ApplyVignette(half3 input, float2 uv, float2 center, float intensity, float roundness, float smoothness, half3 color)
{
center = UnityStereoTransformScreenSpaceTex(center);
float2 dist = abs(uv - center) * intensity;
#if defined(UNITY_SINGLE_PASS_STEREO)
dist.x /= unity_StereoScaleOffset[unity_StereoEyeIndex].x;
#endif
dist.x *= roundness;
float vfactor = pow(saturate(1.0 - dot(dist, dist)), smoothness);
return input * lerp(color, (1.0).xxx, vfactor);
}
half3 ApplyTonemap(half3 input)
{
#if _TONEMAP_ACES
float3 aces = unity_to_ACES(input);
input = AcesTonemap(aces);
#elif _TONEMAP_NEUTRAL
input = NeutralTonemap(input);
#endif
return saturate(input);
}
half3 ApplyColorGrading(half3 input, float postExposure, TEXTURE2D_PARAM(lutTex, lutSampler), float3 lutParams, TEXTURE2D_PARAM(userLutTex, userLutSampler), float3 userLutParams, float userLutContrib)
{
// Artist request to fine tune exposure in post without affecting bloom, dof etc
input *= postExposure;
// HDR Grading:
// - Apply internal LogC LUT
// - (optional) Clamp result & apply user LUT
#if _HDR_GRADING
{
float3 inputLutSpace = saturate(LinearToLogC(input)); // LUT space is in LogC
input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), inputLutSpace, lutParams);
UNITY_BRANCH
if (userLutContrib > 0.0)
{
input = saturate(input);
input.rgb = GetLinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
input = lerp(input, outLut, userLutContrib);
input.rgb = GetSRGBToLinear(input.rgb);
}
}
// LDR Grading:
// - Apply tonemapping (result is clamped)
// - (optional) Apply user LUT
// - Apply internal linear LUT
#else
{
input = ApplyTonemap(input);
UNITY_BRANCH
if (userLutContrib > 0.0)
{
input.rgb = GetLinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
input = lerp(input, outLut, userLutContrib);
input.rgb = GetSRGBToLinear(input.rgb);
}
input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), input, lutParams);
}
#endif
return input;
}
half3 ApplyGrain(half3 input, float2 uv, TEXTURE2D_PARAM(GrainTexture, GrainSampler), float intensity, float response, float2 scale, float2 offset)
{
// Grain in range [0;1] with neutral at 0.5
half grain = SAMPLE_TEXTURE2D(GrainTexture, GrainSampler, uv * scale + offset).w;
// Remap [-1;1]
grain = (grain - 0.5) * 2.0;
// Noisiness response curve based on scene luminance
float lum = 1.0 - sqrt(Luminance(input));
lum = lerp(1.0, lum, response);
return input + input * grain * intensity * lum;
}
half3 ApplyDithering(half3 input, float2 uv, TEXTURE2D_PARAM(BlueNoiseTexture, BlueNoiseSampler), float2 scale, float2 offset)
{
// Symmetric triangular distribution on [-1,1] with maximal density at 0
float noise = SAMPLE_TEXTURE2D(BlueNoiseTexture, BlueNoiseSampler, uv * scale + offset).a * 2.0 - 1.0;
noise = FastSign(noise) * (1.0 - sqrt(1.0 - abs(noise)));
#if UNITY_COLORSPACE_GAMMA
input += noise / 255.0;
#else
input = GetSRGBToLinear(GetLinearToSRGB(input) + noise / 255.0);
#endif
return input;
}
#endif // UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED

View File

@@ -0,0 +1,155 @@
Shader "Hidden/Universal Render Pipeline/FinalPost"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _FXAA
#pragma multi_compile_local_fragment _ _FILM_GRAIN
#pragma multi_compile_local_fragment _ _DITHERING
#pragma multi_compile_local_fragment _ _LINEAR_TO_SRGB_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
TEXTURE2D_X(_SourceTex);
TEXTURE2D(_Grain_Texture);
TEXTURE2D(_BlueNoise_Texture);
float4 _SourceSize;
float2 _Grain_Params;
float4 _Grain_TilingParams;
float4 _Dithering_Params;
#define GrainIntensity _Grain_Params.x
#define GrainResponse _Grain_Params.y
#define GrainScale _Grain_TilingParams.xy
#define GrainOffset _Grain_TilingParams.zw
#define DitheringScale _Dithering_Params.xy
#define DitheringOffset _Dithering_Params.zw
#define FXAA_SPAN_MAX (8.0)
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#define FXAA_REDUCE_MIN (1.0 / 128.0)
half3 Fetch(float2 coords, float2 offset)
{
float2 uv = coords + offset;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv).xyz;
}
half3 Load(int2 icoords, int idx, int idy)
{
#if SHADER_API_GLES
float2 uv = (icoords + int2(idx, idy)) * _SourceSize.zw;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uv).xyz;
#else
return LOAD_TEXTURE2D_X(_SourceTex, clamp(icoords + int2(idx, idy), 0, _SourceSize.xy - 1.0)).xyz;
#endif
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float2 positionNDC = uv;
int2 positionSS = uv * _SourceSize.xy;
half3 color = Load(positionSS, 0, 0).xyz;
#if _FXAA
{
// Edge detection
half3 rgbNW = Load(positionSS, -1, -1);
half3 rgbNE = Load(positionSS, 1, -1);
half3 rgbSW = Load(positionSS, -1, 1);
half3 rgbSE = Load(positionSS, 1, 1);
rgbNW = saturate(rgbNW);
rgbNE = saturate(rgbNE);
rgbSW = saturate(rgbSW);
rgbSE = saturate(rgbSE);
color = saturate(color);
half lumaNW = Luminance(rgbNW);
half lumaNE = Luminance(rgbNE);
half lumaSW = Luminance(rgbSW);
half lumaSE = Luminance(rgbSE);
half lumaM = Luminance(color);
float2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
half lumaSum = lumaNW + lumaNE + lumaSW + lumaSE;
float dirReduce = max(lumaSum * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
float rcpDirMin = rcp(min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min((FXAA_SPAN_MAX).xx, max((-FXAA_SPAN_MAX).xx, dir * rcpDirMin)) * _SourceSize.zw;
// Blur
half3 rgb03 = Fetch(positionNDC, dir * (0.0 / 3.0 - 0.5));
half3 rgb13 = Fetch(positionNDC, dir * (1.0 / 3.0 - 0.5));
half3 rgb23 = Fetch(positionNDC, dir * (2.0 / 3.0 - 0.5));
half3 rgb33 = Fetch(positionNDC, dir * (3.0 / 3.0 - 0.5));
rgb03 = saturate(rgb03);
rgb13 = saturate(rgb13);
rgb23 = saturate(rgb23);
rgb33 = saturate(rgb33);
half3 rgbA = 0.5 * (rgb13 + rgb23);
half3 rgbB = rgbA * 0.5 + 0.25 * (rgb03 + rgb33);
half lumaB = Luminance(rgbB);
half lumaMin = Min3(lumaM, lumaNW, Min3(lumaNE, lumaSW, lumaSE));
half lumaMax = Max3(lumaM, lumaNW, Max3(lumaNE, lumaSW, lumaSE));
color = ((lumaB < lumaMin) || (lumaB > lumaMax)) ? rgbA : rgbB;
}
#endif
#if _FILM_GRAIN
{
color = ApplyGrain(color, positionNDC, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset);
}
#endif
#if _LINEAR_TO_SRGB_CONVERSION
{
color = LinearToSRGB(color);
}
#endif
#if _DITHERING
{
color = ApplyDithering(color, positionNDC, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset);
}
#endif
return half4(color, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "FinalPost"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,267 @@
Shader "Hidden/Universal Render Pipeline/GaussianDepthOfField"
{
HLSLINCLUDE
#pragma target 3.5
#pragma exclude_renderers gles
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
TEXTURE2D_X(_SourceTex);
TEXTURE2D_X(_ColorTexture);
TEXTURE2D_X(_FullCoCTexture);
TEXTURE2D_X(_HalfCoCTexture);
float4 _SourceSize;
float4 _DownSampleScaleFactor;
float3 _CoCParams;
#define FarStart _CoCParams.x
#define FarEnd _CoCParams.y
#define MaxRadius _CoCParams.z
#define BLUR_KERNEL 0
#if BLUR_KERNEL == 0
// Offsets & coeffs for optimized separable bilinear 3-tap gaussian (5-tap equivalent)
const static int kTapCount = 3;
const static float kOffsets[] = {
-1.33333333,
0.00000000,
1.33333333
};
const static half kCoeffs[] = {
0.35294118,
0.29411765,
0.35294118
};
#elif BLUR_KERNEL == 1
// Offsets & coeffs for optimized separable bilinear 5-tap gaussian (9-tap equivalent)
const static int kTapCount = 5;
const static float kOffsets[] = {
-3.23076923,
-1.38461538,
0.00000000,
1.38461538,
3.23076923
};
const static half kCoeffs[] = {
0.07027027,
0.31621622,
0.22702703,
0.31621622,
0.07027027
};
#endif
half FragCoC(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _SourceSize.xy * uv).x;
depth = LinearEyeDepth(depth, _ZBufferParams);
half coc = (depth - FarStart) / (FarEnd - FarStart);
return saturate(coc);
}
struct PrefilterOutput
{
half coc : SV_Target0;
half3 color : SV_Target1;
};
PrefilterOutput FragPrefilter(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#if _HIGH_QUALITY_SAMPLING
// Use a rotated grid to minimize artifacts coming from horizontal and vertical boundaries
// "High Quality Antialiasing" [Lorach07]
const int kCount = 5;
const float2 kTaps[] = {
float2( 0.0, 0.0),
float2( 0.9, -0.4),
float2(-0.9, 0.4),
float2( 0.4, 0.9),
float2(-0.4, -0.9)
};
half3 colorAcc = 0.0;
half farCoCAcc = 0.0;
UNITY_UNROLL
for (int i = 0; i < kCount; i++)
{
float2 tapCoord = _SourceSize.zw * kTaps[i] + uv;
half3 tapColor = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, tapCoord).xyz;
half coc = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, tapCoord).x;
// Pre-multiply CoC to reduce bleeding of background blur on focused areas
colorAcc += tapColor * coc;
farCoCAcc += coc;
}
half3 color = colorAcc * rcp(kCount);
half farCoC = farCoCAcc * rcp(kCount);
#else
// Bilinear sampling the coc is technically incorrect but we're aiming for speed here
half farCoC = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv).x;
// Fast bilinear downscale of the source target and pre-multiply the CoC to reduce
// bleeding of background blur on focused areas
half3 color = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, uv).xyz;
color *= farCoC;
#endif
PrefilterOutput o;
o.coc = farCoC;
o.color = color;
return o;
}
half4 Blur(Varyings input, float2 dir, float premultiply)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
// Use the center CoC as radius
int2 positionSS = int2(_SourceSize.xy * _DownSampleScaleFactor.xy * uv);
half samp0CoC = LOAD_TEXTURE2D_X(_HalfCoCTexture, positionSS).x;
float2 offset = _SourceSize.zw * _DownSampleScaleFactor.zw * dir * samp0CoC * MaxRadius;
half4 acc = 0.0;
UNITY_UNROLL
for (int i = 0; i < kTapCount; i++)
{
float2 sampCoord = uv + kOffsets[i] * offset;
half sampCoC = SAMPLE_TEXTURE2D_X(_HalfCoCTexture, sampler_LinearClamp, sampCoord).x;
half3 sampColor = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, sampCoord).xyz;
// Weight & pre-multiply to limit bleeding on the focused area
half weight = saturate(1.0 - (samp0CoC - sampCoC));
acc += half4(sampColor, premultiply ? sampCoC : 1.0) * kCoeffs[i] * weight;
}
acc.xyz /= acc.w + 1e-4; // Zero-div guard
return half4(acc.xyz, 1.0);
}
half4 FragBlurH(Varyings input) : SV_Target
{
return Blur(input, float2(1.0, 0.0), 1.0);
}
half4 FragBlurV(Varyings input) : SV_Target
{
return Blur(input, float2(0.0, 1.0), 0.0);
}
half4 FragComposite(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
half3 baseColor = LOAD_TEXTURE2D_X(_SourceTex, _SourceSize.xy * uv).xyz;
half coc = LOAD_TEXTURE2D_X(_FullCoCTexture, _SourceSize.xy * uv).x;
#if _HIGH_QUALITY_SAMPLING && !defined(SHADER_API_GLES)
half3 farColor = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_ColorTexture, sampler_LinearClamp), uv, _SourceSize * _DownSampleScaleFactor, 1.0, unity_StereoEyeIndex).xyz;
#else
half3 farColor = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, uv).xyz;
#endif
half3 dstColor = 0.0;
half dstAlpha = 1.0;
UNITY_BRANCH
if (coc > 0.0)
{
// Non-linear blend
// "CryEngine 3 Graphics Gems" [Sousa13]
half blend = sqrt(coc * TWO_PI);
dstColor = farColor * saturate(blend);
dstAlpha = saturate(1.0 - blend);
}
return half4(baseColor * dstAlpha + dstColor, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Gaussian Depth Of Field CoC"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragCoC
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Prefilter"
HLSLPROGRAM
#pragma vertex VertFullscreenMesh
#pragma fragment FragPrefilter
#pragma multi_compile_local _ _HIGH_QUALITY_SAMPLING
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Blur Horizontal"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurH
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Blur Vertical"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBlurV
ENDHLSL
}
Pass
{
Name "Gaussian Depth Of Field Composite"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragComposite
#pragma multi_compile_local _ _HIGH_QUALITY_SAMPLING
ENDHLSL
}
}
}

View File

@@ -0,0 +1,215 @@
Shader "Hidden/Universal Render Pipeline/LutBuilderHdr"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local _ _TONEMAP_ACES _TONEMAP_NEUTRAL
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ACES.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
float4 _ColorBalance; // xyz: LMS coeffs, w: unused
float4 _ColorFilter; // xyz: color, w: unused
float4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
float4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
float4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
float4 _Lift; // xyz: color, w: unused
float4 _Gamma; // xyz: color, w: unused
float4 _Gain; // xyz: color, w: unused
float4 _Shadows; // xyz: color, w: unused
float4 _Midtones; // xyz: color, w: unused
float4 _Highlights; // xyz: color, w: unused
float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
float4 _SplitShadows; // xyz: color, w: balance
float4 _SplitHighlights; // xyz: color, w: unused
TEXTURE2D(_CurveMaster);
TEXTURE2D(_CurveRed);
TEXTURE2D(_CurveGreen);
TEXTURE2D(_CurveBlue);
TEXTURE2D(_CurveHueVsHue);
TEXTURE2D(_CurveHueVsSat);
TEXTURE2D(_CurveSatVsSat);
TEXTURE2D(_CurveLumVsSat);
float EvaluateCurve(TEXTURE2D(curve), float t)
{
float x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
return saturate(x);
}
// Note: when the ACES tonemapper is selected the grading steps will be done using ACES spaces
float3 ColorGrade(float3 colorLutSpace)
{
// Switch back to linear
float3 colorLinear = LogCToLinear(colorLutSpace);
// White balance in LMS space
float3 colorLMS = LinearToLMS(colorLinear);
colorLMS *= _ColorBalance.xyz;
colorLinear = LMSToLinear(colorLMS);
// Do contrast in log after white balance
#if _TONEMAP_ACES
float3 colorLog = ACES_to_ACEScc(unity_to_ACES(colorLinear));
#else
float3 colorLog = LinearToLogC(colorLinear);
#endif
colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
#if _TONEMAP_ACES
colorLinear = ACES_to_ACEScg(ACEScc_to_ACES(colorLog));
#else
colorLinear = LogCToLinear(colorLog);
#endif
// Color filter is just an unclipped multiplier
colorLinear *= _ColorFilter.xyz;
// Do NOT feed negative values to the following color ops
colorLinear = max(0.0, colorLinear);
// Split toning
// As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
// products we have to do all the maths in gamma-space...
float balance = _SplitShadows.w;
float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
colorGamma = SoftLight(colorGamma, splitShadows);
colorGamma = SoftLight(colorGamma, splitHighlights);
colorLinear = PositivePow(colorGamma, 2.2);
// Channel mixing (Adobe style)
colorLinear = float3(
dot(colorLinear, _ChannelMixerRed.xyz),
dot(colorLinear, _ChannelMixerGreen.xyz),
dot(colorLinear, _ChannelMixerBlue.xyz)
);
// Shadows, midtones, highlights
luma = GetLuminance(colorLinear);
float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
+ colorLinear * _Midtones.xyz * midtonesFactor
+ colorLinear * _Highlights.xyz * highlightsFactor;
// Lift, gamma, gain
colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
// HSV operations
float satMult;
float3 hsv = RgbToHsv(colorLinear);
{
// Hue Vs Sat
satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
// Sat Vs Sat
satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
// Lum Vs Sat
satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
// Hue Shift & Hue Vs Hue
float hue = hsv.x + _HueSatCon.x;
float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
hue += offset;
hsv.x = RotateHue(hue, 0.0, 1.0);
}
colorLinear = HsvToRgb(hsv);
// Global saturation
luma = GetLuminance(colorLinear);
colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
// YRGB curves
// Conceptually these need to be in range [0;1] and from an artist-workflow perspective
// it's easier to deal with
colorLinear = FastTonemap(colorLinear);
{
const float kHalfPixel = (1.0 / 128.0) / 2.0;
float3 c = colorLinear;
// Y (master)
c += kHalfPixel.xxx;
float mr = EvaluateCurve(_CurveMaster, c.r);
float mg = EvaluateCurve(_CurveMaster, c.g);
float mb = EvaluateCurve(_CurveMaster, c.b);
c = float3(mr, mg, mb);
// RGB
c += kHalfPixel.xxx;
float r = EvaluateCurve(_CurveRed, c.r);
float g = EvaluateCurve(_CurveGreen, c.g);
float b = EvaluateCurve(_CurveBlue, c.b);
colorLinear = float3(r, g, b);
}
colorLinear = FastTonemapInvert(colorLinear);
colorLinear = max(0.0, colorLinear);
return colorLinear;
}
float3 Tonemap(float3 colorLinear)
{
#if _TONEMAP_NEUTRAL
{
colorLinear = NeutralTonemap(colorLinear);
}
#elif _TONEMAP_ACES
{
// Note: input is actually ACEScg (AP1 w/ linear encoding)
float3 aces = ACEScg_to_ACES(colorLinear);
colorLinear = AcesTonemap(aces);
}
#endif
return colorLinear;
}
float4 Frag(Varyings input) : SV_Target
{
// Lut space
// We use Alexa LogC (El 1000) to store the LUT as it provides a good enough range
// (~58.85666) and is good enough to be stored in fp16 without losing precision in the
// darks
float3 colorLutSpace = GetLutStripValue(input.uv, _Lut_Params);
// Color grade & tonemap
float3 gradedColor = ColorGrade(colorLutSpace);
gradedColor = Tonemap(gradedColor);
return float4(gradedColor, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "LutBuilderHdr"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,164 @@
Shader "Hidden/Universal Render Pipeline/LutBuilderLdr"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
float4 _Lut_Params; // x: lut_height, y: 0.5 / lut_width, z: 0.5 / lut_height, w: lut_height / lut_height - 1
float4 _ColorBalance; // xyz: LMS coeffs, w: unused
half4 _ColorFilter; // xyz: color, w: unused
half4 _ChannelMixerRed; // xyz: rgb coeffs, w: unused
half4 _ChannelMixerGreen; // xyz: rgb coeffs, w: unused
half4 _ChannelMixerBlue; // xyz: rgb coeffs, w: unused
float4 _HueSatCon; // x: hue shift, y: saturation, z: contrast, w: unused
float4 _Lift; // xyz: color, w: unused
float4 _Gamma; // xyz: color, w: unused
float4 _Gain; // xyz: color, w: unused
float4 _Shadows; // xyz: color, w: unused
float4 _Midtones; // xyz: color, w: unused
float4 _Highlights; // xyz: color, w: unused
float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
half4 _SplitShadows; // xyz: color, w: balance
half4 _SplitHighlights; // xyz: color, w: unused
TEXTURE2D(_CurveMaster);
TEXTURE2D(_CurveRed);
TEXTURE2D(_CurveGreen);
TEXTURE2D(_CurveBlue);
TEXTURE2D(_CurveHueVsHue);
TEXTURE2D(_CurveHueVsSat);
TEXTURE2D(_CurveSatVsSat);
TEXTURE2D(_CurveLumVsSat);
half EvaluateCurve(TEXTURE2D(curve), float t)
{
half x = SAMPLE_TEXTURE2D(curve, sampler_LinearClamp, float2(t, 0.0)).x;
return saturate(x);
}
half4 Frag(Varyings input) : SV_Target
{
float3 colorLinear = GetLutStripValue(input.uv, _Lut_Params);
// White balance in LMS space
float3 colorLMS = LinearToLMS(colorLinear);
colorLMS *= _ColorBalance.xyz;
colorLinear = LMSToLinear(colorLMS);
// Do contrast in log after white balance
float3 colorLog = LinearToLogC(colorLinear);
colorLog = (colorLog - ACEScc_MIDGRAY) * _HueSatCon.z + ACEScc_MIDGRAY;
colorLinear = LogCToLinear(colorLog);
// Color filter is just an unclipped multiplier
colorLinear *= _ColorFilter.xyz;
// Do NOT feed negative values to the following color ops
colorLinear = max(0.0, colorLinear);
// Split toning
// As counter-intuitive as it is, to make split-toning work the same way it does in Adobe
// products we have to do all the maths in gamma-space...
float balance = _SplitShadows.w;
float3 colorGamma = PositivePow(colorLinear, 1.0 / 2.2);
float luma = saturate(GetLuminance(saturate(colorGamma)) + balance);
float3 splitShadows = lerp((0.5).xxx, _SplitShadows.xyz, 1.0 - luma);
float3 splitHighlights = lerp((0.5).xxx, _SplitHighlights.xyz, luma);
colorGamma = SoftLight(colorGamma, splitShadows);
colorGamma = SoftLight(colorGamma, splitHighlights);
colorLinear = PositivePow(colorGamma, 2.2);
// Channel mixing (Adobe style)
colorLinear = float3(
dot(colorLinear, _ChannelMixerRed.xyz),
dot(colorLinear, _ChannelMixerGreen.xyz),
dot(colorLinear, _ChannelMixerBlue.xyz)
);
// Shadows, midtones, highlights
luma = GetLuminance(colorLinear);
float shadowsFactor = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, luma);
float highlightsFactor = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, luma);
float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor;
colorLinear = colorLinear * _Shadows.xyz * shadowsFactor
+ colorLinear * _Midtones.xyz * midtonesFactor
+ colorLinear * _Highlights.xyz * highlightsFactor;
// Lift, gamma, gain
colorLinear = colorLinear * _Gain.xyz + _Lift.xyz;
colorLinear = sign(colorLinear) * pow(abs(colorLinear), _Gamma.xyz);
// HSV operations
float satMult;
float3 hsv = RgbToHsv(colorLinear);
{
// Hue Vs Sat
satMult = EvaluateCurve(_CurveHueVsSat, hsv.x) * 2.0;
// Sat Vs Sat
satMult *= EvaluateCurve(_CurveSatVsSat, hsv.y) * 2.0;
// Lum Vs Sat
satMult *= EvaluateCurve(_CurveLumVsSat, Luminance(colorLinear)) * 2.0;
// Hue Shift & Hue Vs Hue
float hue = hsv.x + _HueSatCon.x;
float offset = EvaluateCurve(_CurveHueVsHue, hue) - 0.5;
hue += offset;
hsv.x = RotateHue(hue, 0.0, 1.0);
}
colorLinear = HsvToRgb(hsv);
// Global saturation
luma = GetLuminance(colorLinear);
colorLinear = luma.xxx + (_HueSatCon.yyy * satMult) * (colorLinear - luma.xxx);
// YRGB curves
{
const float kHalfPixel = (1.0 / 128.0) / 2.0;
float3 c = colorLinear;
// Y (master)
c += kHalfPixel.xxx;
float mr = EvaluateCurve(_CurveMaster, c.r);
float mg = EvaluateCurve(_CurveMaster, c.g);
float mb = EvaluateCurve(_CurveMaster, c.b);
c = float3(mr, mg, mb);
// RGB
c += kHalfPixel.xxx;
float r = EvaluateCurve(_CurveRed, c.r);
float g = EvaluateCurve(_CurveGreen, c.g);
float b = EvaluateCurve(_CurveBlue, c.b);
colorLinear = float3(r, g, b);
}
return half4(saturate(colorLinear), 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "LutBuilderLdr"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,134 @@
Shader "Hidden/Universal Render Pipeline/PaniniProjection"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local _GENERIC _UNIT_DISTANCE
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
TEXTURE2D_X(_SourceTex);
float4 _Params;
// Back-ported & adapted from the work of the Stockholm demo team - thanks Lasse
float2 Panini_UnitDistance(float2 view_pos)
{
// Given
// S----------- E--X-------
// | ` . /,´
// |-- --- Q
// 1 | ,´/ `
// | ,´ / ´
// | ,´ / `
// | ,´ / .
// O` / .
// | / `
// | / ´
// 1 | / ´
// | / ´
// |/_ . ´
// P
//
// Have E
// Want to find X
//
// First apply tangent-secant theorem to find Q
// PE*QE = SE*SE
// QE = PE-PQ
// PQ = PE-(SE*SE)/PE
// Q = E*(PQ/PE)
// Then project Q to find X
const float d = 1.0;
const float view_dist = 2.0;
const float view_dist_sq = 4.0;
float view_hyp = sqrt(view_pos.x * view_pos.x + view_dist_sq);
float cyl_hyp = view_hyp - (view_pos.x * view_pos.x) / view_hyp;
float cyl_hyp_frac = cyl_hyp / view_hyp;
float cyl_dist = view_dist * cyl_hyp_frac;
float2 cyl_pos = view_pos * cyl_hyp_frac;
return cyl_pos / (cyl_dist - d);
}
float2 Panini_Generic(float2 view_pos, float d)
{
// Given
// S----------- E--X-------
// | ` ~. /,´
// |-- --- Q
// | ,/ `
// 1 | ,´/ `
// | ,´ / ´
// | ,´ / ´
// |,` / ,
// O /
// | / ,
// d | /
// | / ,
// |/ .
// P
// | ´
// | , ´
// +- ´
//
// Have E
// Want to find X
//
// First compute line-circle intersection to find Q
// Then project Q to find X
float view_dist = 1.0 + d;
float view_hyp_sq = view_pos.x * view_pos.x + view_dist * view_dist;
float isect_D = view_pos.x * d;
float isect_discrim = view_hyp_sq - isect_D * isect_D;
float cyl_dist_minus_d = (-isect_D * view_pos.x + view_dist * sqrt(isect_discrim)) / view_hyp_sq;
float cyl_dist = cyl_dist_minus_d + d;
float2 cyl_pos = view_pos * (cyl_dist / view_dist);
return cyl_pos / (cyl_dist - d);
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if _GENERIC
float2 proj_pos = Panini_Generic((2.0 * input.uv - 1.0) * _Params.xy * _Params.w, _Params.z);
#else // _UNIT_DISTANCE
float2 proj_pos = Panini_UnitDistance((2.0 * input.uv - 1.0) * _Params.xy * _Params.w);
#endif
float2 proj_ndc = proj_pos / _Params.xy;
float2 coords = proj_ndc * 0.5 + 0.5;
return SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, coords);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Panini Projection"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,45 @@
Shader "Hidden/Universal Render Pipeline/Stop NaN"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#pragma exclude_renderers gles
#pragma target 3.5
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#define NAN_COLOR half3(0.0, 0.0, 0.0)
TEXTURE2D_X(_SourceTex);
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half3 color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_PointClamp, UnityStereoTransformScreenSpaceTex(input.uv)).xyz;
if (AnyIsNaN(color) || AnyIsInf(color))
color = NAN_COLOR;
return half4(color, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "Stop NaN"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,74 @@
Shader "Hidden/Universal Render Pipeline/SubpixelMorphologicalAntialiasing"
{
Properties
{
[HideInInspector] _StencilRef ("_StencilRef", Int) = 64
[HideInInspector] _StencilMask ("_StencilMask", Int) = 64
}
HLSLINCLUDE
#pragma multi_compile_local _SMAA_PRESET_LOW _SMAA_PRESET_MEDIUM _SMAA_PRESET_HIGH
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#pragma exclude_renderers gles
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
// Edge detection
Pass
{
Stencil
{
WriteMask [_StencilMask]
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM
#pragma vertex VertEdge
#pragma fragment FragEdge
#include "SubpixelMorphologicalAntialiasingBridge.hlsl"
ENDHLSL
}
// Blend Weights Calculation
Pass
{
Stencil
{
WriteMask [_StencilMask]
ReadMask [_StencilMask]
Ref [_StencilRef]
Comp Equal
Pass Replace
}
HLSLPROGRAM
#pragma vertex VertBlend
#pragma fragment FragBlend
#include "SubpixelMorphologicalAntialiasingBridge.hlsl"
ENDHLSL
}
// Neighborhood Blending
Pass
{
HLSLPROGRAM
#pragma vertex VertNeighbor
#pragma fragment FragNeighbor
#include "SubpixelMorphologicalAntialiasingBridge.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,136 @@
#ifndef UNIVERSAL_POSTPROCESSING_SMAA_BRIDGE
#define UNIVERSAL_POSTPROCESSING_SMAA_BRIDGE
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
#define SMAA_HLSL_4_1
#if _SMAA_PRESET_LOW
#define SMAA_PRESET_LOW
#elif _SMAA_PRESET_MEDIUM
#define SMAA_PRESET_MEDIUM
#else
#define SMAA_PRESET_HIGH
#endif
TEXTURE2D_X(_ColorTexture);
TEXTURE2D_X(_BlendTexture);
TEXTURE2D(_AreaTexture);
TEXTURE2D(_SearchTexture);
float4 _Metrics;
#define SMAA_RT_METRICS _Metrics
#define SMAA_AREATEX_SELECT(s) s.rg
#define SMAA_SEARCHTEX_SELECT(s) s.a
#define LinearSampler sampler_LinearClamp
#define PointSampler sampler_PointClamp
#if UNITY_COLORSPACE_GAMMA
#define GAMMA_FOR_EDGE_DETECTION (1)
#else
#define GAMMA_FOR_EDGE_DETECTION (1/2.2)
#endif
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/SubpixelMorphologicalAntialiasing.hlsl"
// ----------------------------------------------------------------------------------------
// Edge Detection
struct VaryingsEdge
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float4 offsets[3] : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsEdge VertEdge(Attributes input)
{
VaryingsEdge output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = UnityStereoTransformScreenSpaceTex(input.uv);
#endif
SMAAEdgeDetectionVS(output.uv, output.offsets);
return output;
}
float4 FragEdge(VaryingsEdge input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return float4(SMAAColorEdgeDetectionPS(input.uv, input.offsets, _ColorTexture), 0.0, 0.0);
}
// ----------------------------------------------------------------------------------------
// Blend Weights Calculation
struct VaryingsBlend
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float2 pixcoord : TEXCOORD1;
float4 offsets[3] : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsBlend VertBlend(Attributes input)
{
VaryingsBlend output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = UnityStereoTransformScreenSpaceTex(input.uv);
#endif
SMAABlendingWeightCalculationVS(output.uv, output.pixcoord, output.offsets);
return output;
}
float4 FragBlend(VaryingsBlend input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return SMAABlendingWeightCalculationPS(input.uv, input.pixcoord, input.offsets, _ColorTexture, _AreaTexture, _SearchTexture, 0);
}
// ----------------------------------------------------------------------------------------
// Neighborhood Blending
struct VaryingsNeighbor
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float4 offset : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsNeighbor VertNeighbor(Attributes input)
{
VaryingsNeighbor output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
GetProceduralQuad(input.vertexID, output.positionCS, output.uv);
#else
output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
output.uv = UnityStereoTransformScreenSpaceTex(input.uv);
#endif
SMAANeighborhoodBlendingVS(output.uv, output.offset);
return output;
}
float4 FragNeighbor(VaryingsNeighbor input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return SMAANeighborhoodBlendingPS(input.uv, input.offset, _ColorTexture, _BlendTexture);
}
#endif // UNIVERSAL_POSTPROCESSING_SMAA_BRIDGE

View File

@@ -0,0 +1,240 @@
Shader "Hidden/Universal Render Pipeline/UberPost"
{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _DISTORTION
#pragma multi_compile_local_fragment _ _CHROMATIC_ABERRATION
#pragma multi_compile_local_fragment _ _BLOOM_LQ _BLOOM_HQ _BLOOM_LQ_DIRT _BLOOM_HQ_DIRT
#pragma multi_compile_local_fragment _ _HDR_GRADING _TONEMAP_ACES _TONEMAP_NEUTRAL
#pragma multi_compile_local_fragment _ _FILM_GRAIN
#pragma multi_compile_local_fragment _ _DITHERING
#pragma multi_compile_local_fragment _ _LINEAR_TO_SRGB_CONVERSION
#pragma multi_compile_local_fragment _ _USE_FAST_SRGB_LINEAR_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"
// Hardcoded dependencies to reduce the number of variants
#if _BLOOM_LQ || _BLOOM_HQ || _BLOOM_LQ_DIRT || _BLOOM_HQ_DIRT
#define BLOOM
#if _BLOOM_LQ_DIRT || _BLOOM_HQ_DIRT
#define BLOOM_DIRT
#endif
#endif
TEXTURE2D_X(_SourceTex);
TEXTURE2D_X(_Bloom_Texture);
TEXTURE2D(_LensDirt_Texture);
TEXTURE2D(_Grain_Texture);
TEXTURE2D(_InternalLut);
TEXTURE2D(_UserLut);
TEXTURE2D(_BlueNoise_Texture);
float4 _Lut_Params;
float4 _UserLut_Params;
float4 _Bloom_Params;
float _Bloom_RGBM;
float4 _LensDirt_Params;
float _LensDirt_Intensity;
float4 _Distortion_Params1;
float4 _Distortion_Params2;
float _Chroma_Params;
half4 _Vignette_Params1;
float4 _Vignette_Params2;
float2 _Grain_Params;
float4 _Grain_TilingParams;
float4 _Bloom_Texture_TexelSize;
float4 _Dithering_Params;
#define DistCenter _Distortion_Params1.xy
#define DistAxis _Distortion_Params1.zw
#define DistTheta _Distortion_Params2.x
#define DistSigma _Distortion_Params2.y
#define DistScale _Distortion_Params2.z
#define DistIntensity _Distortion_Params2.w
#define ChromaAmount _Chroma_Params.x
#define BloomIntensity _Bloom_Params.x
#define BloomTint _Bloom_Params.yzw
#define BloomRGBM _Bloom_RGBM.x
#define LensDirtScale _LensDirt_Params.xy
#define LensDirtOffset _LensDirt_Params.zw
#define LensDirtIntensity _LensDirt_Intensity.x
#define VignetteColor _Vignette_Params1.xyz
#define VignetteCenter _Vignette_Params2.xy
#define VignetteIntensity _Vignette_Params2.z
#define VignetteSmoothness _Vignette_Params2.w
#define VignetteRoundness _Vignette_Params1.w
#define LutParams _Lut_Params.xyz
#define PostExposure _Lut_Params.w
#define UserLutParams _UserLut_Params.xyz
#define UserLutContribution _UserLut_Params.w
#define GrainIntensity _Grain_Params.x
#define GrainResponse _Grain_Params.y
#define GrainScale _Grain_TilingParams.xy
#define GrainOffset _Grain_TilingParams.zw
#define DitheringScale _Dithering_Params.xy
#define DitheringOffset _Dithering_Params.zw
float2 DistortUV(float2 uv)
{
// Note: this variant should never be set with XR
#if _DISTORTION
{
uv = (uv - 0.5) * DistScale + 0.5;
float2 ruv = DistAxis * (uv - 0.5 - DistCenter);
float ru = length(float2(ruv));
UNITY_BRANCH
if (DistIntensity > 0.0)
{
float wu = ru * DistTheta;
ru = tan(wu) * (rcp(ru * DistSigma));
uv = uv + ruv * (ru - 1.0);
}
else
{
ru = rcp(ru) * DistTheta * atan(ru * DistSigma);
uv = uv + ruv * (ru - 1.0);
}
}
#endif
return uv;
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
float2 uvDistorted = DistortUV(uv);
half3 color = (0.0).xxx;
#if _CHROMATIC_ABERRATION
{
// Very fast version of chromatic aberration from HDRP using 3 samples and hardcoded
// spectral lut. Performs significantly better on lower end GPUs.
float2 coords = 2.0 * uv - 1.0;
float2 end = uv - coords * dot(coords, coords) * ChromaAmount;
float2 delta = (end - uv) / 3.0;
half r = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uvDistorted ).x;
half g = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, DistortUV(delta + uv) ).y;
half b = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, DistortUV(delta * 2.0 + uv)).z;
color = half3(r, g, b);
}
#else
{
color = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_LinearClamp, uvDistorted).xyz;
}
#endif
// Gamma space... Just do the rest of Uber in linear and convert back to sRGB at the end
#if UNITY_COLORSPACE_GAMMA
{
color = GetSRGBToLinear(color);
}
#endif
#if defined(BLOOM)
{
#if _BLOOM_HQ && !defined(SHADER_API_GLES)
half4 bloom = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_Bloom_Texture, sampler_LinearClamp), uvDistorted, _Bloom_Texture_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex);
#else
half4 bloom = SAMPLE_TEXTURE2D_X(_Bloom_Texture, sampler_LinearClamp, uvDistorted);
#endif
#if UNITY_COLORSPACE_GAMMA
bloom.xyz *= bloom.xyz; // γ to linear
#endif
UNITY_BRANCH
if (BloomRGBM > 0)
{
bloom.xyz = DecodeRGBM(bloom);
}
bloom.xyz *= BloomIntensity;
color += bloom.xyz * BloomTint;
#if defined(BLOOM_DIRT)
{
// UVs for the dirt texture should be DistortUV(uv * DirtScale + DirtOffset) but
// considering we use a cover-style scale on the dirt texture the difference
// isn't massive so we chose to save a few ALUs here instead in case lens
// distortion is active.
half3 dirt = SAMPLE_TEXTURE2D(_LensDirt_Texture, sampler_LinearClamp, uvDistorted * LensDirtScale + LensDirtOffset).xyz;
dirt *= LensDirtIntensity;
color += dirt * bloom.xyz;
}
#endif
}
#endif
// To save on variants we'll use an uniform branch for vignette. Lower end platforms
// don't like these but if we're running Uber it means we're running more expensive
// effects anyway. Lower-end devices would limit themselves to on-tile compatible effect
// and thus this shouldn't too much of a problem (famous last words).
UNITY_BRANCH
if (VignetteIntensity > 0)
{
color = ApplyVignette(color, uvDistorted, VignetteCenter, VignetteIntensity, VignetteRoundness, VignetteSmoothness, VignetteColor);
}
// Color grading is always enabled when post-processing/uber is active
{
color = ApplyColorGrading(color, PostExposure, TEXTURE2D_ARGS(_InternalLut, sampler_LinearClamp), LutParams, TEXTURE2D_ARGS(_UserLut, sampler_LinearClamp), UserLutParams, UserLutContribution);
}
#if _FILM_GRAIN
{
color = ApplyGrain(color, uv, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset);
}
#endif
// Back to sRGB
#if UNITY_COLORSPACE_GAMMA || _LINEAR_TO_SRGB_CONVERSION
{
color = GetLinearToSRGB(color);
}
#endif
#if _DITHERING
{
color = ApplyDithering(color, uv, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset);
}
#endif
return half4(color, 1.0);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
ZTest Always ZWrite Off Cull Off
Pass
{
Name "UberPost"
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,3 @@
// UniversalRP Shaders folder need an Assembly Definition files to create a .cs project
// This is a dummy shader file so the Shaders assembly is not empty.
class ShadersDummy {}

View File

@@ -0,0 +1,65 @@
#ifndef UNIVERSAL_SHADOW_CASTER_PASS_INCLUDED
#define UNIVERSAL_SHADOW_CASTER_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
// Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
// For Directional lights, _LightDirection is used when applying shadow Normal Bias.
// For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
float3 _LightDirection;
float3 _LightPosition;
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
};
float4 GetShadowPositionHClip(Attributes input)
{
float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#endif
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
#if UNITY_REVERSED_Z
positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE);
#else
positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE);
#endif
return positionCS;
}
Varyings ShadowPassVertex(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.positionCS = GetShadowPositionHClip(input);
return output;
}
half4 ShadowPassFragment(Varyings input) : SV_TARGET
{
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff);
return 0;
}
#endif

View File

@@ -0,0 +1,495 @@
// Shader targeted for low end devices. Single Pass Forward Rendering.
Shader "Universal Render Pipeline/Simple Lit"
{
// Keep properties of StandardSpecular shader for upgrade reasons.
Properties
{
[MainTexture] _BaseMap("Base Map (RGB) Smoothness / Alpha (A)", 2D) = "white" {}
[MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)
_Cutoff("Alpha Clipping", Range(0.0, 1.0)) = 0.5
_SpecColor("Specular Color", Color) = (0.5, 0.5, 0.5, 0.5)
_SpecGlossMap("Specular Map", 2D) = "white" {}
[Enum(Specular Alpha,0,Albedo Alpha,1)] _SmoothnessSource("Smoothness Source", Float) = 0.0
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0
[HideInInspector] _BumpScale("Scale", Float) = 1.0
[NoScaleOffset] _BumpMap("Normal Map", 2D) = "bump" {}
[HDR] _EmissionColor("Emission Color", Color) = (0,0,0)
[NoScaleOffset]_EmissionMap("Emission Map", 2D) = "white" {}
// Blending state
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
[ToggleOff] _ReceiveShadows("Receive Shadows", Float) = 1.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
[HideInInspector] _Smoothness("Smoothness", Float) = 0.5
// ObsoleteProperties
[HideInInspector] _MainTex("BaseMap", 2D) = "white" {}
[HideInInspector] _Color("Base Color", Color) = (1, 1, 1, 1)
[HideInInspector] _Shininess("Smoothness", Float) = 0.0
[HideInInspector] _GlossinessSource("GlossinessSource", Float) = 0.0
[HideInInspector] _SpecSource("SpecularHighlights", Float) = 0.0
[HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {}
[HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
LOD 300
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
// Use same blending / depth states as Standard shader
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _ _SPECGLOSSMAP _SPECULAR_COLOR
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma vertex LitPassVertexSimple
#pragma fragment LitPassFragmentSimple
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
ZWrite[_ZWrite]
ZTest LEqual
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//#pragma shader_feature _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _ _SPECGLOSSMAP _SPECULAR_COLOR
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#pragma vertex LitPassVertexSimple
#pragma fragment LitPassFragmentSimple
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{ "LightMode" = "Meta" }
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaSimple
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" "IgnoreProjector" = "True" "ShaderModel"="2.0"}
LOD 300
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
// Use same blending / depth states as Standard shader
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#pragma shader_feature_local_fragment _ _SPECGLOSSMAP _SPECULAR_COLOR
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local _RECEIVE_SHADOWS_OFF
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma vertex LitPassVertexSimple
#pragma fragment LitPassFragmentSimple
#define BUMP_SCALE_NOT_SUPPORTED 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull[_Cull]
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{ "LightMode" = "Meta" }
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaSimple
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl"
ENDHLSL
}
Pass
{
Name "Universal2D"
Tags{ "LightMode" = "Universal2D" }
Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl"
ENDHLSL
}
}
Fallback "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.SimpleLitShader"
}

View File

@@ -0,0 +1,152 @@
#ifndef UNIVERSAL_SIMPLE_LIT_PASS_INCLUDED
#define UNIVERSAL_SIMPLE_LIT_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
float3 posWS : TEXCOORD2; // xyz: posWS
#ifdef _NORMALMAP
float4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
float4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
float4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
float3 normal : TEXCOORD3;
float3 viewDir : TEXCOORD4;
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD7;
#endif
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData)
{
inputData.positionWS = input.posWS;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normal.w, input.tangent.w, input.bitangent.w);
inputData.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangent.xyz, input.bitangent.xyz, input.normal.xyz));
#else
half3 viewDirWS = input.viewDir;
inputData.normalWS = input.normal;
#endif
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
viewDirWS = SafeNormalize(viewDirWS);
inputData.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = input.fogFactorAndVertexLight.x;
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard (Simple Lighting) shader
Varyings LitPassVertexSimple(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.posWS.xyz = vertexInput.positionWS;
output.positionCS = vertexInput.positionCS;
#ifdef _NORMALMAP
output.normal = half4(normalInput.normalWS, viewDirWS.x);
output.tangent = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normal = NormalizeNormalPerVertex(normalInput.normalWS);
output.viewDir = viewDirWS;
#endif
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
OUTPUT_SH(output.normal.xyz, output.vertexSH);
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
// Used for StandardSimpleLighting shader
half4 LitPassFragmentSimple(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.uv;
half4 diffuseAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
half3 diffuse = diffuseAlpha.rgb * _BaseColor.rgb;
half alpha = diffuseAlpha.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
diffuse *= alpha;
#endif
half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
half3 emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
half4 specular = SampleSpecularSmoothness(uv, alpha, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
half smoothness = specular.a;
InputData inputData;
InitializeInputData(input, normalTS, inputData);
half4 color = UniversalFragmentBlinnPhong(inputData, diffuse, specular, smoothness, emission, alpha);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
color.a = OutputAlpha(color.a, _Surface);
return color;
}
#endif

View File

@@ -0,0 +1,143 @@
#ifndef UNIVERSAL_SIMPLELIT_GBUFFER_PASS_INCLUDED
#define UNIVERSAL_SIMPLELIT_GBUFFER_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
// keep this file in sync with LitForwardPass.hlsl
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
float3 posWS : TEXCOORD2; // xyz: posWS
#ifdef _NORMALMAP
float4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
float4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
float4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
float3 normal : TEXCOORD3;
float3 viewDir : TEXCOORD4;
#endif
half3 vertexLighting : TEXCOORD6; // xyz: vertex light
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD7;
#endif
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData)
{
inputData.positionWS = input.posWS;
#ifdef _NORMALMAP
half3 viewDirWS = half3(input.normal.w, input.tangent.w, input.bitangent.w);
inputData.normalWS = TransformTangentToWorld(normalTS,
half3x3(input.tangent.xyz, input.bitangent.xyz, input.normal.xyz));
#else
half3 viewDirWS = input.viewDir;
inputData.normalWS = input.normal;
#endif
inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
viewDirWS = SafeNormalize(viewDirWS);
inputData.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = 0; // we don't apply fog in the guffer pass
inputData.vertexLighting = input.vertexLighting.xyz;
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard (Simple Lighting) shader
Varyings LitPassVertexSimple(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS);
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
output.posWS.xyz = vertexInput.positionWS;
output.positionCS = vertexInput.positionCS;
#ifdef _NORMALMAP
output.normal = half4(normalInput.normalWS, viewDirWS.x);
output.tangent = half4(normalInput.tangentWS, viewDirWS.y);
output.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
#else
output.normal = NormalizeNormalPerVertex(normalInput.normalWS);
output.viewDir = viewDirWS;
#endif
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
OUTPUT_SH(output.normal.xyz, output.vertexSH);
output.vertexLighting = vertexLight;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
return output;
}
// Used for StandardSimpleLighting shader
FragmentOutput LitPassFragmentSimple(Varyings input)
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
SurfaceData surfaceData;
InitializeSimpleLitSurfaceData(input.uv, surfaceData);
InputData inputData;
InitializeInputData(input, surfaceData.normalTS, inputData);
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
half4 color = half4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha);
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingSimpleLit);
};
#endif

View File

@@ -0,0 +1,74 @@
#ifndef UNIVERSAL_SIMPLE_LIT_INPUT_INCLUDED
#define UNIVERSAL_SIMPLE_LIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Surface;
CBUFFER_END
#ifdef UNITY_DOTS_INSTANCING_ENABLED
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
UNITY_DOTS_INSTANCED_PROP(float4, _SpecColor)
UNITY_DOTS_INSTANCED_PROP(float4, _EmissionColor)
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__BaseColor)
#define _SpecColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__SpecColor)
#define _EmissionColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__EmissionColor)
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Cutoff)
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Surface)
#endif
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
half4 SampleSpecularSmoothness(half2 uv, half alpha, half4 specColor, TEXTURE2D_PARAM(specMap, sampler_specMap))
{
half4 specularSmoothness = half4(0.0h, 0.0h, 0.0h, 1.0h);
#ifdef _SPECGLOSSMAP
specularSmoothness = SAMPLE_TEXTURE2D(specMap, sampler_specMap, uv) * specColor;
#elif defined(_SPECULAR_COLOR)
specularSmoothness = specColor;
#endif
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
specularSmoothness.a = exp2(10 * alpha + 1);
#else
specularSmoothness.a = exp2(10 * specularSmoothness.a + 1);
#endif
return specularSmoothness;
}
inline void InitializeSimpleLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
outSurfaceData = (SurfaceData)0;
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
outSurfaceData.alpha = albedoAlpha.a * _BaseColor.a;
AlphaDiscard(outSurfaceData.alpha, _Cutoff);
outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
#ifdef _ALPHAPREMULTIPLY_ON
outSurfaceData.albedo *= outSurfaceData.alpha;
#endif
half4 specularSmoothness = SampleSpecularSmoothness(uv, outSurfaceData.alpha, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
outSurfaceData.metallic = 0.0; // unused
outSurfaceData.specular = specularSmoothness.rgb;
outSurfaceData.smoothness = specularSmoothness.a;
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
outSurfaceData.occlusion = 1.0; // unused
outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
}
#endif

View File

@@ -0,0 +1,56 @@
#ifndef UNIVERSAL_SIMPLE_LIT_META_PASS_INCLUDED
#define UNIVERSAL_SIMPLE_LIT_META_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
#ifdef _TANGENT_TO_WORLD
float4 tangentOS : TANGENT;
#endif
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings UniversalVertexMeta(Attributes input)
{
Varyings output;
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2,
unity_LightmapST, unity_DynamicLightmapST);
output.uv = TRANSFORM_TEX(input.uv0, _BaseMap);
return output;
}
half4 UniversalFragmentMetaSimple(Varyings input) : SV_Target
{
float2 uv = input.uv;
MetaInput metaInput;
metaInput.Albedo = _BaseColor.rgb * SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv).rgb;
metaInput.SpecularColor = SampleSpecularSmoothness(uv, 1.0h, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap)).xyz;
metaInput.Emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
return MetaFragment(metaInput);
}
//LWRP -> Universal Backwards Compatibility
Varyings LightweightVertexMeta(Attributes input)
{
return UniversalVertexMeta(input);
}
half4 LightweightFragmentMetaSimple(Varyings input) : SV_Target
{
return UniversalFragmentMetaSimple(input);
}
#endif

View File

@@ -0,0 +1,321 @@
Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit"
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" { }
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Unlit" "IgnoreProjector" = "True"}
LOD 100
ZWrite On
// Lightmapped
Pass
{
Name "TerrainDetailVertex"
HLSLPROGRAM
#pragma target 2.0
#pragma vertex Vert
#pragma fragment Frag
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
float4 _MainTex_ST;
struct Attributes
{
float4 PositionOS : POSITION;
float2 UV0 : TEXCOORD0;
float2 UV1 : TEXCOORD1;
float3 NormalOS : NORMAL;
half4 Color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 UV01 : TEXCOORD0; // UV0
float2 LightmapUV : TEXCOORD1; // Lightmap UVs
half4 Color : TEXCOORD2; // Vertex Color
half4 LightingFog : TEXCOORD3; // Vetex Lighting, Fog Factor
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
float4 ShadowCoords : TEXCOORD4; // Shadow UVs
#endif
float4 PositionCS : SV_POSITION; // Clip Position
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// Vertex attributes
output.UV01 = TRANSFORM_TEX(input.UV0, _MainTex);
output.LightmapUV = input.UV1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.PositionOS.xyz);
output.Color = input.Color;
output.PositionCS = vertexInput.positionCS;
// Shadow Coords
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
output.ShadowCoords = GetShadowCoord(vertexInput);
#endif
// Vertex Lighting
half3 NormalWS = input.NormalOS;
Light mainLight = GetMainLight();
half3 attenuatedLightColor = mainLight.color * mainLight.distanceAttenuation;
half3 diffuseColor = LightingLambert(attenuatedLightColor, mainLight.direction, NormalWS);
#if defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX)
int pixelLightCount = GetAdditionalLightsCount();
for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetAdditionalLight(i, vertexInput.positionWS);
half3 attenuatedLightColor = light.color * light.distanceAttenuation;
diffuseColor += LightingLambert(attenuatedLightColor, light.direction, NormalWS);
}
#endif
output.LightingFog.xyz = diffuseColor;
// Fog factor
output.LightingFog.w = ComputeFogFactor(output.PositionCS.z);
return output;
}
half4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half3 bakedGI = SampleLightmap(input.LightmapUV, half3(0.0, 1.0, 0.0));
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
half3 lighting = input.LightingFog.rgb * MainLightRealtimeShadow(input.ShadowCoords) + bakedGI;
#else
half3 lighting = input.LightingFog.rgb + bakedGI;
#endif
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.UV01);
half4 color = 1.0;
color.rgb = input.Color.rgb * tex.rgb * lighting;
color.rgb = MixFog(color.rgb, input.LightingFog.w);
return color;
}
ENDHLSL
}
// GBuffer
Pass
{
Name "TerrainDetailVertex - GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma target 2.0
#pragma vertex Vert
#pragma fragment Frag
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX //_ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
float4 _MainTex_ST;
struct Attributes
{
float4 PositionOS : POSITION;
float2 UV0 : TEXCOORD0;
float2 UV1 : TEXCOORD1;
float3 NormalOS : NORMAL;
half4 Color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 UV01 : TEXCOORD0; // UV0
float2 LightmapUV : TEXCOORD1; // Lightmap UVs
half4 Color : TEXCOORD2; // Vertex Color
half4 LightingFog : TEXCOORD3; // Vetex Lighting, Fog Factor
float4 ShadowCoords : TEXCOORD4; // Shadow UVs
float4 PositionCS : SV_POSITION; // Clip Position
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// Vertex attributes
output.UV01 = TRANSFORM_TEX(input.UV0, _MainTex);
output.LightmapUV = input.UV1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.PositionOS.xyz);
output.Color = input.Color;
output.PositionCS = vertexInput.positionCS;
// Shadow Coords
output.ShadowCoords = GetShadowCoord(vertexInput);
// Vertex Lighting
half3 NormalWS = input.NormalOS;
Light mainLight = GetMainLight();
half3 attenuatedLightColor = mainLight.color * mainLight.distanceAttenuation;
half3 diffuseColor = LightingLambert(attenuatedLightColor, mainLight.direction, NormalWS);
#ifdef _ADDITIONAL_LIGHTS
int pixelLightCount = GetAdditionalLightsCount();
for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetAdditionalLight(i, vertexInput.positionWS);
half3 attenuatedLightColor = light.color * light.distanceAttenuation;
diffuseColor += LightingLambert(attenuatedLightColor, light.direction, NormalWS);
}
#endif
output.LightingFog.xyz = diffuseColor;
// Fog factor
output.LightingFog.w = ComputeFogFactor(output.PositionCS.z);
return output;
}
FragmentOutput Frag(Varyings input)
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half3 bakedGI = SampleLightmap(input.LightmapUV, half3(0.0, 1.0, 0.0));
half3 lighting = input.LightingFog.rgb * MainLightRealtimeShadow(input.ShadowCoords) + bakedGI;
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.UV01);
half4 color = 1.0;
color.rgb = input.Color.rgb * tex.rgb * lighting;
SurfaceData surfaceData = (SurfaceData)0;
surfaceData.alpha = 1.0;
InputData inputData = (InputData)0;
inputData.normalWS = half3(0, 1, 0); // need some default to avoid division by 0.
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingInvalid);
}
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthNormalOnlyVertex
#pragma fragment DepthNormalOnlyFragment
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "Meta"
Tags{ "LightMode" = "Meta" }
Cull Off
HLSLPROGRAM
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaSimple
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl"
ENDHLSL
}
}
//Fallback "VertexLit"
}

View File

@@ -0,0 +1,239 @@
Shader "Universal Render Pipeline/Terrain/Lit"
{
Properties
{
[HideInInspector] [ToggleUI] _EnableHeightBlend("EnableHeightBlend", Float) = 0.0
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
// Layer count is passed down to guide height-blend enable/disable, due
// to the fact that heigh-based blend will be broken with multipass.
[HideInInspector] [PerRendererData] _NumLayersCount ("Total Layer Count", Float) = 1.0
// set by terrain engine
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "grey" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "grey" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "grey" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "grey" {}
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
[HideInInspector] _Mask3("Mask 3 (A)", 2D) = "grey" {}
[HideInInspector] _Mask2("Mask 2 (B)", 2D) = "grey" {}
[HideInInspector] _Mask1("Mask 1 (G)", 2D) = "grey" {}
[HideInInspector] _Mask0("Mask 0 (R)", 2D) = "grey" {}
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 0.5
// used in fallback on old cards & base map
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "grey" {}
[HideInInspector] _BaseColor("Main Color", Color) = (1,1,1,1)
[HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
[ToggleUI] _EnableInstancedPerPixelNormal("Enable Instanced per-pixel normal", Float) = 1.0
}
HLSLINCLUDE
#pragma multi_compile_fragment __ _ALPHATEST_ON
ENDHLSL
SubShader
{
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "False" "TerrainCompatible" = "True"}
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
HLSLPROGRAM
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma shader_feature_local_fragment _TERRAIN_BLEND_HEIGHT
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _MASKMAP
// Sample normal in pixel shader when doing instancing
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma target 2.0
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
// -------------------------------------
// Universal Pipeline keywords
// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
//#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma shader_feature_local _TERRAIN_BLEND_HEIGHT
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _MASKMAP
// Sample normal in pixel shader when doing instancing
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
#define TERRAIN_GBUFFER 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthNormalOnlyVertex
#pragma fragment DepthNormalOnlyFragment
#pragma shader_feature_local _NORMALMAP
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "SceneSelectionPass"
Tags { "LightMode" = "SceneSelectionPass" }
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#define SCENESELECTIONPASS
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
UsePass "Hidden/Nature/Terrain/Utilities/PICKING"
}
Dependency "AddPassShader" = "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)"
Dependency "BaseMapShader" = "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)"
Dependency "BaseMapGenShader" = "Hidden/Universal Render Pipeline/Terrain/Lit (Basemap Gen)"
CustomEditor "UnityEditor.Rendering.Universal.TerrainLitShaderGUI"
Fallback "Hidden/Universal Render Pipeline/FallbackError"
}

View File

@@ -0,0 +1,134 @@
Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)"
{
Properties
{
// Layer count is passed down to guide height-blend enable/disable, due
// to the fact that heigh-based blend will be broken with multipass.
[HideInInspector] [PerRendererData] _NumLayersCount ("Total Layer Count", Float) = 1.0
// set by terrain engine
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Mask3("Mask 3 (A)", 2D) = "grey" {}
[HideInInspector] _Mask2("Mask 2 (B)", 2D) = "grey" {}
[HideInInspector] _Mask1("Mask 1 (G)", 2D) = "grey" {}
[HideInInspector] _Mask0("Mask 0 (R)", 2D) = "grey" {}
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 1.0
// used in fallback on old cards & base map
[HideInInspector] _BaseMap("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _BaseColor("Main Color", Color) = (1,1,1,1)
[HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
}
HLSLINCLUDE
#pragma multi_compile_fragment __ _ALPHATEST_ON
ENDHLSL
SubShader
{
Tags { "Queue" = "Geometry-99" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True"}
Pass
{
Name "TerrainAddLit"
Tags { "LightMode" = "UniversalForward" }
Blend One One
HLSLPROGRAM
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma shader_feature_local_fragment _TERRAIN_BLEND_HEIGHT
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local_fragment _MASKMAP
// Sample normal in pixel shader when doing instancing
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
#define TERRAIN_SPLAT_ADDPASS
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
Blend One One
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma target 3.0
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
//#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma shader_feature_local _TERRAIN_BLEND_HEIGHT
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _MASKMAP
// Sample normal in pixel shader when doing instancing
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
#define TERRAIN_SPLAT_ADDPASS 1
#define TERRAIN_GBUFFER 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
}
Fallback "Hidden/Universal Render Pipeline/FallbackError"
}

View File

@@ -0,0 +1,208 @@
Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)"
{
Properties
{
[MainColor] _BaseColor("Color", Color) = (1,1,1,1)
_MainTex("Albedo(RGB), Smoothness(A)", 2D) = "white" {}
_MetallicTex ("Metallic (R)", 2D) = "black" {}
[HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
}
HLSLINCLUDE
#pragma multi_compile_fragment __ _ALPHATEST_ON
ENDHLSL
SubShader
{
Tags { "Queue" = "Geometry-100" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True"}
LOD 200
// ------------------------------------------------------------------
// Forward pass. Shades all light in a single pass. GI + emission + Fog
Pass
{
Name "ForwardLit"
// Lightmode matches the ShaderPassName set in UniversalPipeline.cs. SRPDefaultUnlit and passes with
// no LightMode tag are also rendered by Universal Pipeline
Tags{"LightMode" = "UniversalForward"}
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Material Keywords
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
#pragma shader_feature_local _NORMALMAP
// Sample normal in pixel shader when doing instancing
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
#define TERRAIN_SPLAT_BASEPASS 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma target 2.0
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// GBuffer pass. Does GI + emission. All additional lights are done deferred as well as fog
Pass
{
Name "GBuffer"
Tags{"LightMode" = "UniversalGBuffer"}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma target 2.0
// -------------------------------------
// Material Keywords
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
//#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
//#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma vertex SplatmapVert
#pragma fragment SplatmapFragment
#pragma shader_feature_local _NORMALMAP
// Sample normal in pixel shader when doing instancing
#pragma shader_feature_local _TERRAIN_INSTANCED_PERPIXEL_NORMAL
#define TERRAIN_SPLAT_BASEPASS 1
#define TERRAIN_GBUFFER 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthNormalOnlyVertex
#pragma fragment DepthNormalOnlyFragment
#pragma multi_compile_instancing
#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap
#pragma shader_feature_local _NORMALMAP
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma vertex TerrainVertexMeta
#pragma fragment TerrainFragmentMeta
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitMetaPass.hlsl"
ENDHLSL
}
UsePass "Hidden/Nature/Terrain/Utilities/PICKING"
UsePass "Universal Render Pipeline/Terrain/Lit/SceneSelectionPass"
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
//CustomEditor "LitShaderGUI"
}

View File

@@ -0,0 +1,207 @@
Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Basemap Gen)"
{
Properties
{
// Layer count is passed down to guide height-blend enable/disable, due
// to the fact that heigh-based blend will be broken with multipass.
[HideInInspector] [PerRendererData] _NumLayersCount ("Total Layer Count", Float) = 1.0
[HideInInspector] _Control("AlphaMap", 2D) = "" {}
[HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Mask3("Mask 3 (A)", 2D) = "grey" {}
[HideInInspector] _Mask2("Mask 2 (B)", 2D) = "grey" {}
[HideInInspector] _Mask1("Mask 1 (G)", 2D) = "grey" {}
[HideInInspector] _Mask0("Mask 0 (R)", 2D) = "grey" {}
[HideInInspector] [Gamma] _Metallic0 ("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic1 ("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic2 ("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic3 ("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0 ("Smoothness 0", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness1 ("Smoothness 1", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness2 ("Smoothness 2", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness3 ("Smoothness 3", Range(0.0, 1.0)) = 1.0
[HideInInspector] _DstBlend("DstBlend", Float) = 0.0
}
Subshader
{
HLSLINCLUDE
#pragma target 3.0
#define _METALLICSPECGLOSSMAP 1
#define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1
#define _TERRAIN_BASEMAP_GEN
#pragma shader_feature_local _TERRAIN_BLEND_HEIGHT
#pragma shader_feature_local _MASKMAP
#include "TerrainLitInput.hlsl"
#include "TerrainLitPasses.hlsl"
ENDHLSL
Pass
{
Tags
{
"Name" = "_MainTex"
"Format" = "ARGB32"
"Size" = "1"
}
ZTest Always Cull Off ZWrite Off
Blend One [_DstBlend]
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
Varyings Vert(Attributes IN)
{
Varyings output = (Varyings) 0;
output.clipPos = TransformWorldToHClip(IN.positionOS.xyz);
// NOTE : This is basically coming from the vertex shader in TerrainLitPasses
// There are other plenty of other values that the original version computes, but for this
// pass, we are only interested in a few, so I'm just skipping the rest.
output.uvMainAndLM.xy = IN.texcoord;
output.uvSplat01.xy = TRANSFORM_TEX(IN.texcoord, _Splat0);
output.uvSplat01.zw = TRANSFORM_TEX(IN.texcoord, _Splat1);
output.uvSplat23.xy = TRANSFORM_TEX(IN.texcoord, _Splat2);
output.uvSplat23.zw = TRANSFORM_TEX(IN.texcoord, _Splat3);
return output;
}
half4 Frag(Varyings IN) : SV_Target
{
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
half4 splatControl;
half weight;
half4 mixedDiffuse = 0.0h;
half4 defaultSmoothness = 0.0h;
half4 masks[4];
float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
masks[0] = 1.0h;
masks[1] = 1.0h;
masks[2] = 1.0h;
masks[3] = 1.0h;
#ifdef _MASKMAP
masks[0] = SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy);
masks[1] = SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw);
masks[2] = SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy);
masks[3] = SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw);
#ifdef _TERRAIN_BLEND_HEIGHT
HeightBasedSplatModify(splatControl, masks);
#endif
#endif
SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
half4 maskSmoothness = half4(masks[0].a, masks[1].a, masks[2].a, masks[3].a);
maskSmoothness *= half4(_MaskMapRemapScale0.a, _MaskMapRemapScale1.a, _MaskMapRemapScale2.a, _MaskMapRemapScale3.a);
maskSmoothness += half4(_MaskMapRemapOffset0.a, _MaskMapRemapOffset1.a, _MaskMapRemapOffset2.a, _MaskMapRemapOffset3.a);
defaultSmoothness = lerp(defaultSmoothness, maskSmoothness, hasMask);
half smoothness = dot(splatControl, defaultSmoothness);
return half4(mixedDiffuse.rgb, smoothness);
}
ENDHLSL
}
Pass
{
Tags
{
"Name" = "_MetallicTex"
"Format" = "R8"
"Size" = "1/4"
"EmptyColor" = "FF000000"
}
ZTest Always Cull Off ZWrite Off
Blend One [_DstBlend]
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
Varyings Vert(Attributes IN)
{
Varyings output = (Varyings)0;
output.clipPos = TransformWorldToHClip(IN.positionOS.xyz);
// This is just like the other in that it is from TerrainLitPasses
output.uvMainAndLM.xy = IN.texcoord;
output.uvSplat01.xy = TRANSFORM_TEX(IN.texcoord, _Splat0);
output.uvSplat01.zw = TRANSFORM_TEX(IN.texcoord, _Splat1);
output.uvSplat23.xy = TRANSFORM_TEX(IN.texcoord, _Splat2);
output.uvSplat23.zw = TRANSFORM_TEX(IN.texcoord, _Splat3);
return output;
}
half4 Frag(Varyings IN) : SV_Target
{
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
half4 splatControl;
half weight;
half4 mixedDiffuse;
half4 defaultSmoothness;
half4 masks[4];
float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
masks[0] = 1.0h;
masks[1] = 1.0h;
masks[2] = 1.0h;
masks[3] = 1.0h;
#ifdef _MASKMAP
masks[0] = SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy);
masks[1] = SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw);
masks[2] = SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy);
masks[3] = SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw);
#ifdef _TERRAIN_BLEND_HEIGHT
HeightBasedSplatModify(splatControl, masks);
#endif
#endif
SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
half4 defaultMetallic = half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3);
half4 maskMetallic = half4(masks[0].r, masks[1].r, masks[2].r, masks[3].r);
maskMetallic *= half4(_MaskMapRemapScale0.r, _MaskMapRemapScale1.r, _MaskMapRemapScale3.r, _MaskMapRemapScale3.r);
maskMetallic += half4(_MaskMapRemapOffset0.r, _MaskMapRemapOffset1.r, _MaskMapRemapOffset2.r, _MaskMapRemapOffset3.r);
defaultMetallic = lerp(defaultMetallic, maskMetallic, hasMask);
half metallic = dot(splatControl, defaultMetallic);
return metallic;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,93 @@
#ifndef UNIVERSAL_TERRAIN_LIT_INPUT_INCLUDED
#define UNIVERSAL_TERRAIN_LIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _BaseColor;
half _Cutoff;
CBUFFER_END
#define _Surface 0.0 // Terrain is always opaque
CBUFFER_START(_Terrain)
half _NormalScale0, _NormalScale1, _NormalScale2, _NormalScale3;
half _Metallic0, _Metallic1, _Metallic2, _Metallic3;
half _Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3;
half4 _DiffuseRemapScale0, _DiffuseRemapScale1, _DiffuseRemapScale2, _DiffuseRemapScale3;
half4 _MaskMapRemapOffset0, _MaskMapRemapOffset1, _MaskMapRemapOffset2, _MaskMapRemapOffset3;
half4 _MaskMapRemapScale0, _MaskMapRemapScale1, _MaskMapRemapScale2, _MaskMapRemapScale3;
float4 _Control_ST;
float4 _Control_TexelSize;
half _DiffuseHasAlpha0, _DiffuseHasAlpha1, _DiffuseHasAlpha2, _DiffuseHasAlpha3;
half _LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3;
half4 _Splat0_ST, _Splat1_ST, _Splat2_ST, _Splat3_ST;
half _HeightTransition;
half _NumLayersCount;
#ifdef UNITY_INSTANCING_ENABLED
float4 _TerrainHeightmapRecipSize; // float4(1.0f/width, 1.0f/height, 1.0f/(width-1), 1.0f/(height-1))
float4 _TerrainHeightmapScale; // float4(hmScale.x, hmScale.y / (float)(kMaxHeight), hmScale.z, 0.0f)
#endif
#ifdef SCENESELECTIONPASS
int _ObjectId;
int _PassValue;
#endif
CBUFFER_END
TEXTURE2D(_Control); SAMPLER(sampler_Control);
TEXTURE2D(_Splat0); SAMPLER(sampler_Splat0);
TEXTURE2D(_Splat1);
TEXTURE2D(_Splat2);
TEXTURE2D(_Splat3);
#ifdef _NORMALMAP
TEXTURE2D(_Normal0); SAMPLER(sampler_Normal0);
TEXTURE2D(_Normal1);
TEXTURE2D(_Normal2);
TEXTURE2D(_Normal3);
#endif
#ifdef _MASKMAP
TEXTURE2D(_Mask0); SAMPLER(sampler_Mask0);
TEXTURE2D(_Mask1);
TEXTURE2D(_Mask2);
TEXTURE2D(_Mask3);
#endif
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
TEXTURE2D(_MetallicTex); SAMPLER(sampler_MetallicTex);
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)
{
half4 specGloss;
specGloss = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, uv);
specGloss.a = albedoAlpha;
return specGloss;
}
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
{
outSurfaceData = (SurfaceData)0;
half4 albedoSmoothness = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
outSurfaceData.alpha = 1;
half4 specGloss = SampleMetallicSpecGloss(uv, albedoSmoothness.a);
outSurfaceData.albedo = albedoSmoothness.rgb;
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
outSurfaceData.smoothness = specGloss.a;
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
outSurfaceData.occlusion = 1;
outSurfaceData.emission = 0;
}
#endif

View File

@@ -0,0 +1,45 @@
#ifndef TERRAIN_LIT_META_PASS_INCLUDED
#define TERRAIN_LIT_META_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings TerrainVertexMeta(Attributes input)
{
Varyings output;
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2,
unity_LightmapST, unity_DynamicLightmapST);
output.uv = TRANSFORM_TEX(input.uv0, _MainTex);
return output;
}
half4 TerrainFragmentMeta(Varyings input) : SV_Target
{
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(input.uv, surfaceData);
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
MetaInput metaInput;
metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5;
metaInput.SpecularColor = surfaceData.specular;
metaInput.Emission = surfaceData.emission;
return MetaFragment(metaInput);
}
#endif

View File

@@ -0,0 +1,592 @@
#ifndef UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED
#define UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
#if defined(UNITY_INSTANCING_ENABLED) && defined(_TERRAIN_INSTANCED_PERPIXEL_NORMAL)
#define ENABLE_TERRAIN_PERPIXEL_NORMAL
#endif
#ifdef UNITY_INSTANCING_ENABLED
TEXTURE2D(_TerrainHeightmapTexture);
TEXTURE2D(_TerrainNormalmapTexture);
SAMPLER(sampler_TerrainNormalmapTexture);
#endif
UNITY_INSTANCING_BUFFER_START(Terrain)
UNITY_DEFINE_INSTANCED_PROP(float4, _TerrainPatchInstanceData) // float4(xBase, yBase, skipScale, ~)
UNITY_INSTANCING_BUFFER_END(Terrain)
#ifdef _ALPHATEST_ON
TEXTURE2D(_TerrainHolesTexture);
SAMPLER(sampler_TerrainHolesTexture);
void ClipHoles(float2 uv)
{
float hole = SAMPLE_TEXTURE2D(_TerrainHolesTexture, sampler_TerrainHolesTexture, uv).r;
clip(hole == 0.0f ? -1 : 1);
}
#endif
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 uvMainAndLM : TEXCOORD0; // xy: control, zw: lightmap
#ifndef TERRAIN_SPLAT_BASEPASS
float4 uvSplat01 : TEXCOORD1; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD2; // xy: splat2, zw: splat3
#endif
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
float4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
float4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
float4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
float3 normal : TEXCOORD3;
float3 viewDir : TEXCOORD4;
half3 vertexSH : TEXCOORD5; // SH
#endif
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
float3 positionWS : TEXCOORD7;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD8;
#endif
float4 clipPos : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(Varyings IN, half3 normalTS, out InputData input)
{
input = (InputData)0;
input.positionWS = IN.positionWS;
half3 SH = half3(0, 0, 0);
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
half3 viewDirWS = half3(IN.normal.w, IN.tangent.w, IN.bitangent.w);
input.normalWS = TransformTangentToWorld(normalTS, half3x3(-IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz));
SH = SampleSH(input.normalWS.xyz);
#elif defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
half3 viewDirWS = IN.viewDir;
float2 sampleCoords = (IN.uvMainAndLM.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy;
half3 normalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1));
half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS);
input.normalWS = TransformTangentToWorld(normalTS, half3x3(-tangentWS, cross(normalWS, tangentWS), normalWS));
SH = SampleSH(input.normalWS.xyz);
#else
half3 viewDirWS = IN.viewDir;
input.normalWS = IN.normal;
SH = IN.vertexSH;
#endif
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
input.normalWS = NormalizeNormalPerPixel(input.normalWS);
input.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
input.shadowCoord = IN.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
input.shadowCoord = TransformWorldToShadowCoord(input.positionWS);
#else
input.shadowCoord = float4(0, 0, 0, 0);
#endif
input.fogCoord = IN.fogFactorAndVertexLight.x;
input.vertexLighting = IN.fogFactorAndVertexLight.yzw;
input.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, SH, input.normalWS);
input.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.clipPos);
input.shadowMask = SAMPLE_SHADOWMASK(IN.uvMainAndLM.zw)
}
#ifndef TERRAIN_SPLAT_BASEPASS
void SplatmapMix(float4 uvMainAndLM, float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, out half weight, out half4 mixedDiffuse, out half4 defaultSmoothness, inout half3 mixedNormal)
{
half4 diffAlbedo[4];
diffAlbedo[0] = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, uvSplat01.xy);
diffAlbedo[1] = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, uvSplat01.zw);
diffAlbedo[2] = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, uvSplat23.xy);
diffAlbedo[3] = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, uvSplat23.zw);
// This might be a bit of a gamble -- the assumption here is that if the diffuseMap has no
// alpha channel, then diffAlbedo[n].a = 1.0 (and _DiffuseHasAlphaN = 0.0)
// Prior to coming in, _SmoothnessN is actually set to max(_DiffuseHasAlphaN, _SmoothnessN)
// This means that if we have an alpha channel, _SmoothnessN is locked to 1.0 and
// otherwise, the true slider value is passed down and diffAlbedo[n].a == 1.0.
defaultSmoothness = half4(diffAlbedo[0].a, diffAlbedo[1].a, diffAlbedo[2].a, diffAlbedo[3].a);
defaultSmoothness *= half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
#ifndef _TERRAIN_BLEND_HEIGHT
// 20.0 is the number of steps in inputAlphaMask (Density mask. We decided 20 empirically)
half4 opacityAsDensity = saturate((half4(diffAlbedo[0].a, diffAlbedo[1].a, diffAlbedo[2].a, diffAlbedo[3].a) - (half4(1.0, 1.0, 1.0, 1.0) - splatControl)) * 20.0);
opacityAsDensity += 0.001h * splatControl; // if all weights are zero, default to what the blend mask says
half4 useOpacityAsDensityParam = { _DiffuseRemapScale0.w, _DiffuseRemapScale1.w, _DiffuseRemapScale2.w, _DiffuseRemapScale3.w }; // 1 is off
splatControl = lerp(opacityAsDensity, splatControl, useOpacityAsDensityParam);
#endif
// Now that splatControl has changed, we can compute the final weight and normalize
weight = dot(splatControl, 1.0h);
#ifdef TERRAIN_SPLAT_ADDPASS
clip(weight <= 0.005h ? -1.0h : 1.0h);
#endif
#ifndef _TERRAIN_BASEMAP_GEN
// Normalize weights before lighting and restore weights in final modifier functions so that the overal
// lighting result can be correctly weighted.
splatControl /= (weight + HALF_MIN);
#endif
mixedDiffuse = 0.0h;
mixedDiffuse += diffAlbedo[0] * half4(_DiffuseRemapScale0.rgb * splatControl.rrr, 1.0h);
mixedDiffuse += diffAlbedo[1] * half4(_DiffuseRemapScale1.rgb * splatControl.ggg, 1.0h);
mixedDiffuse += diffAlbedo[2] * half4(_DiffuseRemapScale2.rgb * splatControl.bbb, 1.0h);
mixedDiffuse += diffAlbedo[3] * half4(_DiffuseRemapScale3.rgb * splatControl.aaa, 1.0h);
#ifdef _NORMALMAP
half3 nrm = 0.0f;
nrm += splatControl.r * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, uvSplat01.xy), _NormalScale0);
nrm += splatControl.g * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, uvSplat01.zw), _NormalScale1);
nrm += splatControl.b * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal2, sampler_Normal0, uvSplat23.xy), _NormalScale2);
nrm += splatControl.a * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal3, sampler_Normal0, uvSplat23.zw), _NormalScale3);
// avoid risk of NaN when normalizing.
#if HAS_HALF
nrm.z += 0.01h;
#else
nrm.z += 1e-5f;
#endif
mixedNormal = normalize(nrm.xyz);
#endif
}
#endif
#ifdef _TERRAIN_BLEND_HEIGHT
void HeightBasedSplatModify(inout half4 splatControl, in half4 masks[4])
{
// heights are in mask blue channel, we multiply by the splat Control weights to get combined height
half4 splatHeight = half4(masks[0].b, masks[1].b, masks[2].b, masks[3].b) * splatControl.rgba;
half maxHeight = max(splatHeight.r, max(splatHeight.g, max(splatHeight.b, splatHeight.a)));
// Ensure that the transition height is not zero.
half transition = max(_HeightTransition, 1e-5);
// This sets the highest splat to "transition", and everything else to a lower value relative to that, clamping to zero
// Then we clamp this to zero and normalize everything
half4 weightedHeights = splatHeight + transition - maxHeight.xxxx;
weightedHeights = max(0, weightedHeights);
// We need to add an epsilon here for active layers (hence the blendMask again)
// so that at least a layer shows up if everything's too low.
weightedHeights = (weightedHeights + 1e-6) * splatControl;
// Normalize (and clamp to epsilon to keep from dividing by zero)
half sumHeight = max(dot(weightedHeights, half4(1, 1, 1, 1)), 1e-6);
splatControl = weightedHeights / sumHeight.xxxx;
}
#endif
void SplatmapFinalColor(inout half4 color, half fogCoord)
{
color.rgb *= color.a;
#ifndef TERRAIN_GBUFFER // Technically we don't need fogCoord, but it is still passed from the vertex shader.
#ifdef TERRAIN_SPLAT_ADDPASS
color.rgb = MixFogColor(color.rgb, half3(0,0,0), fogCoord);
#else
color.rgb = MixFog(color.rgb, fogCoord);
#endif
#endif
}
void TerrainInstancing(inout float4 positionOS, inout float3 normal, inout float2 uv)
{
#ifdef UNITY_INSTANCING_ENABLED
float2 patchVertex = positionOS.xy;
float4 instanceData = UNITY_ACCESS_INSTANCED_PROP(Terrain, _TerrainPatchInstanceData);
float2 sampleCoords = (patchVertex.xy + instanceData.xy) * instanceData.z; // (xy + float2(xBase,yBase)) * skipScale
float height = UnpackHeightmap(_TerrainHeightmapTexture.Load(int3(sampleCoords, 0)));
positionOS.xz = sampleCoords * _TerrainHeightmapScale.xz;
positionOS.y = height * _TerrainHeightmapScale.y;
#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL
normal = float3(0, 1, 0);
#else
normal = _TerrainNormalmapTexture.Load(int3(sampleCoords, 0)).rgb * 2 - 1;
#endif
uv = sampleCoords * _TerrainHeightmapRecipSize.zw;
#endif
}
void TerrainInstancing(inout float4 positionOS, inout float3 normal)
{
float2 uv = { 0, 0 };
TerrainInstancing(positionOS, normal, uv);
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Used in Standard Terrain shader
Varyings SplatmapVert(Attributes v)
{
Varyings o = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TerrainInstancing(v.positionOS, v.normalOS, v.texcoord);
VertexPositionInputs Attributes = GetVertexPositionInputs(v.positionOS.xyz);
o.uvMainAndLM.xy = v.texcoord;
o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
#ifndef TERRAIN_SPLAT_BASEPASS
o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
#endif
half3 viewDirWS = GetWorldSpaceViewDir(Attributes.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, vertexTangent);
o.normal = half4(normalInput.normalWS, viewDirWS.x);
o.tangent = half4(normalInput.tangentWS, viewDirWS.y);
o.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
#else
o.normal = TransformObjectToWorldNormal(v.normalOS);
o.viewDir = viewDirWS;
o.vertexSH = SampleSH(o.normal);
#endif
o.fogFactorAndVertexLight.x = ComputeFogFactor(Attributes.positionCS.z);
o.fogFactorAndVertexLight.yzw = VertexLighting(Attributes.positionWS, o.normal.xyz);
o.positionWS = Attributes.positionWS;
o.clipPos = Attributes.positionCS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
o.shadowCoord = GetShadowCoord(Attributes);
#endif
return o;
}
void ComputeMasks(out half4 masks[4], half4 hasMask, Varyings IN)
{
masks[0] = 0.5h;
masks[1] = 0.5h;
masks[2] = 0.5h;
masks[3] = 0.5h;
#ifdef _MASKMAP
masks[0] = lerp(masks[0], SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy), hasMask.x);
masks[1] = lerp(masks[1], SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw), hasMask.y);
masks[2] = lerp(masks[2], SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy), hasMask.z);
masks[3] = lerp(masks[3], SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw), hasMask.w);
#endif
masks[0] *= _MaskMapRemapScale0.rgba;
masks[0] += _MaskMapRemapOffset0.rgba;
masks[1] *= _MaskMapRemapScale1.rgba;
masks[1] += _MaskMapRemapOffset1.rgba;
masks[2] *= _MaskMapRemapScale2.rgba;
masks[2] += _MaskMapRemapOffset2.rgba;
masks[3] *= _MaskMapRemapScale3.rgba;
masks[3] += _MaskMapRemapOffset3.rgba;
}
// Used in Standard Terrain shader
#ifdef TERRAIN_GBUFFER
FragmentOutput SplatmapFragment(Varyings IN)
#else
half4 SplatmapFragment(Varyings IN) : SV_TARGET
#endif
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
#ifdef _ALPHATEST_ON
ClipHoles(IN.uvMainAndLM.xy);
#endif
half3 normalTS = half3(0.0h, 0.0h, 1.0h);
#ifdef TERRAIN_SPLAT_BASEPASS
half3 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).rgb;
half smoothness = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).a;
half metallic = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, IN.uvMainAndLM.xy).r;
half alpha = 1;
half occlusion = 1;
#else
half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
half4 masks[4];
ComputeMasks(masks, hasMask, IN);
float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
half4 splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
#ifdef _TERRAIN_BLEND_HEIGHT
// disable Height Based blend when there are more than 4 layers (multi-pass breaks the normalization)
if (_NumLayersCount <= 4)
HeightBasedSplatModify(splatControl, masks);
#endif
half weight;
half4 mixedDiffuse;
half4 defaultSmoothness;
SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
half3 albedo = mixedDiffuse.rgb;
half4 defaultMetallic = half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3);
half4 defaultOcclusion = half4(_MaskMapRemapScale0.g, _MaskMapRemapScale1.g, _MaskMapRemapScale2.g, _MaskMapRemapScale3.g) +
half4(_MaskMapRemapOffset0.g, _MaskMapRemapOffset1.g, _MaskMapRemapOffset2.g, _MaskMapRemapOffset3.g);
half4 maskSmoothness = half4(masks[0].a, masks[1].a, masks[2].a, masks[3].a);
defaultSmoothness = lerp(defaultSmoothness, maskSmoothness, hasMask);
half smoothness = dot(splatControl, defaultSmoothness);
half4 maskMetallic = half4(masks[0].r, masks[1].r, masks[2].r, masks[3].r);
defaultMetallic = lerp(defaultMetallic, maskMetallic, hasMask);
half metallic = dot(splatControl, defaultMetallic);
half4 maskOcclusion = half4(masks[0].g, masks[1].g, masks[2].g, masks[3].g);
defaultOcclusion = lerp(defaultOcclusion, maskOcclusion, hasMask);
half occlusion = dot(splatControl, defaultOcclusion);
half alpha = weight;
#endif
InputData inputData;
InitializeInputData(IN, normalTS, inputData);
#ifdef TERRAIN_GBUFFER
BRDFData brdfData;
InitializeBRDFData(albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, alpha, brdfData);
// Baked lighting.
half4 color;
Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
color.rgb = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
color.a = alpha;
SplatmapFinalColor(color, inputData.fogCoord);
// Dynamic lighting: emulate SplatmapFinalColor() by scaling gbuffer material properties. This will not give the same results
// as forward renderer because we apply blending pre-lighting instead of post-lighting.
// Blending of smoothness and normals is also not correct but close enough?
brdfData.diffuse.rgb *= alpha;
brdfData.specular.rgb *= alpha;
inputData.normalWS = inputData.normalWS * alpha;
smoothness *= alpha;
return BRDFDataToGbuffer(brdfData, inputData, smoothness, color.rgb);
#else
half4 color = UniversalFragmentPBR(inputData, albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, occlusion, /* emission */ half3(0, 0, 0), alpha);
SplatmapFinalColor(color, inputData.fogCoord);
return half4(color.rgb, 1.0h);
#endif
}
// Shadow pass
// Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
// For Directional lights, _LightDirection is used when applying shadow Normal Bias.
// For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
float3 _LightDirection;
float3 _LightPosition;
struct AttributesLean
{
float4 position : POSITION;
float3 normalOS : NORMAL;
#ifdef _ALPHATEST_ON
float2 texcoord : TEXCOORD0;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VaryingsLean
{
float4 clipPos : SV_POSITION;
#ifdef _ALPHATEST_ON
float2 texcoord : TEXCOORD0;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsLean ShadowPassVertex(AttributesLean v)
{
VaryingsLean o = (VaryingsLean)0;
UNITY_SETUP_INSTANCE_ID(v);
TerrainInstancing(v.position, v.normalOS);
float3 positionWS = TransformObjectToWorld(v.position.xyz);
float3 normalWS = TransformObjectToWorldNormal(v.normalOS);
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#endif
float4 clipPos = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
#if UNITY_REVERSED_Z
clipPos.z = min(clipPos.z, UNITY_NEAR_CLIP_VALUE);
#else
clipPos.z = max(clipPos.z, UNITY_NEAR_CLIP_VALUE);
#endif
o.clipPos = clipPos;
#ifdef _ALPHATEST_ON
o.texcoord = v.texcoord;
#endif
return o;
}
half4 ShadowPassFragment(VaryingsLean IN) : SV_TARGET
{
#ifdef _ALPHATEST_ON
ClipHoles(IN.texcoord);
#endif
return 0;
}
// Depth pass
VaryingsLean DepthOnlyVertex(AttributesLean v)
{
VaryingsLean o = (VaryingsLean)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TerrainInstancing(v.position, v.normalOS);
o.clipPos = TransformObjectToHClip(v.position.xyz);
#ifdef _ALPHATEST_ON
o.texcoord = v.texcoord;
#endif
return o;
}
half4 DepthOnlyFragment(VaryingsLean IN) : SV_TARGET
{
#ifdef _ALPHATEST_ON
ClipHoles(IN.texcoord);
#endif
#ifdef SCENESELECTIONPASS
// We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
return half4(_ObjectId, _PassValue, 1.0, 1.0);
#endif
return 0;
}
// DepthNormal pass
struct AttributesDepthNormal
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VaryingsDepthNormal
{
float4 uvMainAndLM : TEXCOORD0; // xy: control, zw: lightmap
#ifndef TERRAIN_SPLAT_BASEPASS
float4 uvSplat01 : TEXCOORD1; // xy: splat0, zw: splat1
float4 uvSplat23 : TEXCOORD2; // xy: splat2, zw: splat3
#endif
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
float4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
float4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
float4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
#else
float3 normal : TEXCOORD3;
#endif
float4 clipPos : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsDepthNormal DepthNormalOnlyVertex(AttributesDepthNormal v)
{
VaryingsDepthNormal o = (VaryingsDepthNormal)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TerrainInstancing(v.positionOS, v.normalOS, v.texcoord);
VertexPositionInputs Attributes = GetVertexPositionInputs(v.positionOS.xyz);
o.uvMainAndLM.xy = v.texcoord;
o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
#ifndef TERRAIN_SPLAT_BASEPASS
o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
#endif
#if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
half3 viewDirWS = GetWorldSpaceViewDir(Attributes.positionWS);
#if !SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0);
VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, vertexTangent);
o.normal = half4(normalInput.normalWS, viewDirWS.x);
o.tangent = half4(normalInput.tangentWS, viewDirWS.y);
o.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
#else
o.normal = TransformObjectToWorldNormal(v.normalOS);
#endif
o.clipPos = Attributes.positionCS;
return o;
}
half4 DepthNormalOnlyFragment(VaryingsDepthNormal IN) : SV_TARGET
{
#ifdef _ALPHATEST_ON
ClipHoles(IN.uvMainAndLM.xy);
#endif
half3 normalWS = IN.normal;
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(normalWS, true)), 0.0, 0.0);
}
#endif

View File

@@ -0,0 +1,112 @@
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Hidden/TerrainEngine/Details/UniversalPipeline/WavingDoublePass"
{
Properties
{
_WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
_Cutoff ("Cutoff", float) = 0.5
}
SubShader
{
Tags {"Queue" = "Geometry+200" "RenderType" = "Grass" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" }//"DisableBatching"="True"
Cull Off
LOD 200
AlphaTest Greater [_Cutoff]
ColorMask RGB
Pass
{
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex WavingGrassVert
#pragma fragment LitPassFragmentGrass
#define _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull Off
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#define _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
ENDHLSL
}
// This pass is used when drawing to a _CameraNormalsTexture texture
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull Off
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthNormalOnlyVertex
#pragma fragment DepthNormalOnlyFragment
// -------------------------------------
// Material Keywords
#define _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,109 @@
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Hidden/TerrainEngine/Details/UniversalPipeline/BillboardWavingDoublePass"
{
Properties
{
_WavingTint ("Fade Color", Color) = (.7,.6,.5, 0)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
_Cutoff ("Cutoff", float) = 0.5
}
SubShader
{
Tags {"Queue" = "Geometry+200" "RenderType" = "GrassBillBoard" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" }//"DisableBatching"="True"
Cull Off
LOD 200
AlphaTest Greater [_Cutoff]
ColorMask RGB
Pass
{
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
// -------------------------------------
// Unity defined keywords
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile_fog
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex WavingGrassBillboardVert
#pragma fragment LitPassFragmentGrass
#define _ALPHATEST_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
Cull Off
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#define _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
ENDHLSL
}
Pass
{
Name "DepthNormals"
Tags{"LightMode" = "DepthNormals"}
ZWrite On
Cull Off
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthNormalOnlyVertex
#pragma fragment DepthNormalOnlyFragment
// -------------------------------------
// Material Keywords
#define _ALPHATEST_ON
#pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,112 @@
#ifndef UNIVERSAL_WAVING_GRASS_INPUT_INCLUDED
#define UNIVERSAL_WAVING_GRASS_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _BaseColor;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Shininess;
CBUFFER_END
#define _Surface 0.0 // Grass is always opaque
// Terrain engine shader helpers
CBUFFER_START(TerrainGrass)
half4 _WavingTint;
float4 _WaveAndDistance; // wind speed, wave size, wind amount, max sqr distance
float4 _CameraPosition; // .xyz = camera position, .w = 1 / (max sqr distance)
float3 _CameraRight, _CameraUp;
CBUFFER_END
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
// ---- Grass helpers
// Calculate a 4 fast sine-cosine pairs
// val: the 4 input values - each must be in the range (0 to 1)
// s: The sine of each of the 4 values
// c: The cosine of each of the 4 values
void FastSinCos (float4 val, out float4 s, out float4 c) {
val = val * 6.408849 - 3.1415927;
// powers for taylor series
float4 r5 = val * val; // wavevec ^ 2
float4 r6 = r5 * r5; // wavevec ^ 4;
float4 r7 = r6 * r5; // wavevec ^ 6;
float4 r8 = r6 * r5; // wavevec ^ 8;
float4 r1 = r5 * val; // wavevec ^ 3
float4 r2 = r1 * r5; // wavevec ^ 5;
float4 r3 = r2 * r5; // wavevec ^ 7;
//Vectors for taylor's series expansion of sin and cos
float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841};
float4 cos8 = {-0.5, 0.041666666, -0.0013888889, 0.000024801587};
// sin
s = val + r1 * sin7.y + r2 * sin7.z + r3 * sin7.w;
// cos
c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
}
half4 TerrainWaveGrass (inout float4 vertex, float waveAmount, half4 color)
{
half4 _waveXSize = half4(0.012, 0.02, 0.06, 0.024) * _WaveAndDistance.y;
half4 _waveZSize = half4 (0.006, .02, 0.02, 0.05) * _WaveAndDistance.y;
half4 waveSpeed = half4 (1.2, 2, 1.6, 4.8);
half4 _waveXmove = half4(0.024, 0.04, -0.12, 0.096);
half4 _waveZmove = half4 (0.006, .02, -0.02, 0.1);
float4 waves;
waves = vertex.x * _waveXSize;
waves += vertex.z * _waveZSize;
// Add in time to model them over time
waves += _WaveAndDistance.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
s = s * s;
s = s * s;
half lighting = dot (s, normalize (half4 (1,1,.4,.2))) * 0.7;
s = s * waveAmount;
half3 waveMove = 0;
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
vertex.xz -= waveMove.xz * _WaveAndDistance.z;
// apply color animation
half3 waveColor = lerp (real3(0.5, 0.5, 0.5), _WavingTint.rgb, lighting);
// Fade the grass out before detail distance.
// Saturate because Radeon HD drivers on OS X 10.4.10 don't saturate vertex colors properly.
half3 offset = vertex.xyz - _CameraPosition.xyz;
color.a = saturate (2 * (_WaveAndDistance.w - dot (offset, offset)) * _CameraPosition.w);
return half4(2 * waveColor * color.rgb, color.a);
}
void TerrainBillboardGrass( inout float4 pos, float2 offset )
{
float3 grasspos = pos.xyz - _CameraPosition.xyz;
if (dot(grasspos, grasspos) > _WaveAndDistance.w)
offset = 0.0;
pos.xyz += offset.x * _CameraRight.xyz;
pos.y += offset.y;
}
#endif

View File

@@ -0,0 +1,297 @@
#ifndef UNIVERSAL_WAVING_GRASS_PASSES_INCLUDED
#define UNIVERSAL_WAVING_GRASS_PASSES_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl"
struct GrassVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
half4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct GrassVertexOutput
{
float2 uv : TEXCOORD0;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1);
float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128
half3 normal : TEXCOORD3;
half3 viewDir : TEXCOORD4;
half4 fogFactorAndVertexLight : TEXCOORD5; // x: fogFactor, yzw: vertex light
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
float4 shadowCoord : TEXCOORD6;
#endif
half4 color : TEXCOORD7;
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeInputData(GrassVertexOutput input, out InputData inputData)
{
inputData.positionWS = input.posWSShininess.xyz;
half3 viewDirWS = input.viewDir;
#if SHADER_HINT_NICE_QUALITY
viewDirWS = SafeNormalize(viewDirWS);
#endif
inputData.normalWS = NormalizeNormalPerPixel(input.normal);
inputData.viewDirectionWS = viewDirWS;
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
inputData.fogCoord = input.fogFactorAndVertexLight.x;
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos);
inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
}
void InitializeVertData(GrassVertexInput input, inout GrassVertexOutput vertData)
{
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
vertData.uv = input.texcoord;
vertData.posWSShininess.xyz = vertexInput.positionWS;
vertData.posWSShininess.w = 32;
vertData.clipPos = vertexInput.positionCS;
vertData.viewDir = GetCameraPositionWS() - vertexInput.positionWS;
#if !SHADER_QUALITY_NICE_HINT
vertData.viewDir = SafeNormalize(vertData.viewDir);
#endif
vertData.normal = TransformObjectToWorldNormal(input.normal);
// We either sample GI from lightmap or SH.
// Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH)
// see DECLARE_LIGHTMAP_OR_SH macro.
// The following funcions initialize the correct variable with correct data
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, vertData.lightmapUV);
OUTPUT_SH(vertData.normal, vertData.vertexSH);
half3 vertexLight = VertexLighting(vertexInput.positionWS, vertData.normal.xyz);
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
vertData.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
vertData.shadowCoord = GetShadowCoord(vertexInput);
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
// Grass: appdata_full usage
// color - .xyz = color, .w = wave scale
// normal - normal
// tangent.xy - billboard extrusion
// texcoord - UV coords
// texcoord1 - 2nd UV coords
GrassVertexOutput WavingGrassVert(GrassVertexInput v)
{
GrassVertexOutput o = (GrassVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
// _WaveAndDistance.z == 0 for MeshLit
float waveAmount = v.color.a * _WaveAndDistance.z;
o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
InitializeVertData(v, o);
return o;
}
GrassVertexOutput WavingGrassBillboardVert(GrassVertexInput v)
{
GrassVertexOutput o = (GrassVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TerrainBillboardGrass (v.vertex, v.tangent.xy);
// wave amount defined by the grass height
float waveAmount = v.tangent.y;
o.color = TerrainWaveGrass (v.vertex, waveAmount, v.color);
InitializeVertData(v, o);
return o;
}
inline void InitializeSimpleLitSurfaceData(GrassVertexOutput input, out SurfaceData outSurfaceData)
{
half4 diffuseAlpha = SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
half3 diffuse = diffuseAlpha.rgb * input.color.rgb;
half alpha = diffuseAlpha.a;
AlphaDiscard(alpha, _Cutoff);
alpha *= input.color.a;
outSurfaceData = (SurfaceData)0;
outSurfaceData.alpha = alpha;
outSurfaceData.albedo = diffuse;
outSurfaceData.metallic = 0.0; // unused
outSurfaceData.specular = 0.1;// SampleSpecularSmoothness(uv, diffuseAlpha.a, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap));
outSurfaceData.smoothness = input.posWSShininess.w;
outSurfaceData.normalTS = 0.0; // unused
outSurfaceData.occlusion = 1.0; // unused
outSurfaceData.emission = 0.0;
}
// Used for StandardSimpleLighting shader
#ifdef TERRAIN_GBUFFER
FragmentOutput LitPassFragmentGrass(GrassVertexOutput input)
#else
half4 LitPassFragmentGrass(GrassVertexOutput input) : SV_Target
#endif
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
SurfaceData surfaceData;
InitializeSimpleLitSurfaceData(input, surfaceData);
InputData inputData;
InitializeInputData(input, inputData);
#ifdef TERRAIN_GBUFFER
half4 color = half4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha);
return SurfaceDataToGbuffer(surfaceData, inputData, color.rgb, kLightingSimpleLit);
#else
half4 color = UniversalFragmentBlinnPhong(inputData, surfaceData.albedo, half4(surfaceData.specular, surfaceData.smoothness), surfaceData.smoothness, surfaceData.emission, surfaceData.alpha);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
return color;
#endif
};
struct GrassVertexDepthOnlyInput
{
float4 vertex : POSITION;
float4 tangent : TANGENT;
half4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct GrassVertexDepthOnlyOutput
{
float2 uv : TEXCOORD0;
half4 color : TEXCOORD1;
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeVertData(GrassVertexDepthOnlyInput input, inout GrassVertexDepthOnlyOutput vertData)
{
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
vertData.uv = input.texcoord;
vertData.clipPos = vertexInput.positionCS;
}
GrassVertexDepthOnlyOutput DepthOnlyVertex(GrassVertexDepthOnlyInput v)
{
GrassVertexDepthOnlyOutput o = (GrassVertexDepthOnlyOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
// _WaveAndDistance.z == 0 for MeshLit
float waveAmount = v.color.a * _WaveAndDistance.z;
o.color = TerrainWaveGrass(v.vertex, waveAmount, v.color);
InitializeVertData(v, o);
return o;
}
half4 DepthOnlyFragment(GrassVertexDepthOnlyOutput input) : SV_TARGET
{
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff);
return 0;
}
struct GrassVertexDepthNormalInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
half4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct GrassVertexDepthNormalOutput
{
float2 uv : TEXCOORD0;
half3 normal : TEXCOORD1;
half4 color : TEXCOORD2;
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
void InitializeVertData(GrassVertexDepthNormalInput input, inout GrassVertexDepthNormalOutput vertData)
{
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
vertData.uv = input.texcoord;
vertData.normal = TransformObjectToWorldNormal(input.normal);
vertData.clipPos = vertexInput.positionCS;
}
GrassVertexDepthNormalOutput DepthNormalOnlyVertex(GrassVertexDepthNormalInput v)
{
GrassVertexDepthNormalOutput o = (GrassVertexDepthNormalOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
// MeshGrass v.color.a: 1 on top vertices, 0 on bottom vertices
// _WaveAndDistance.z == 0 for MeshLit
float waveAmount = v.color.a * _WaveAndDistance.z;
o.color = TerrainWaveGrass(v.vertex, waveAmount, v.color);
InitializeVertData(v, o);
return o;
}
half4 DepthNormalOnlyFragment(GrassVertexDepthNormalOutput input) : SV_TARGET
{
Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff);
return float4(PackNormalOctRectEncode(TransformWorldToViewDir(NormalizeNormalPerPixel(input.normal), true)), 0.0, 0.0);
}
#endif

View File

@@ -0,0 +1,13 @@
{
"name": "Unity.RenderPipelines.Universal.Shaders",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,295 @@
Shader "Universal Render Pipeline/Unlit"
{
Properties
{
[MainTexture] _BaseMap("Texture", 2D) = "white" {}
[MainColor] _BaseColor("Color", Color) = (1, 1, 1, 1)
_Cutoff("AlphaCutout", Range(0.0, 1.0)) = 0.5
// BlendMode
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("Src", Float) = 1.0
[HideInInspector] _DstBlend("Dst", Float) = 0.0
[HideInInspector] _ZWrite("ZWrite", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _MainTex("BaseMap", 2D) = "white" {}
[HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1)
[HideInInspector] _SampleGI("SampleGI", float) = 0.0 // needed from bakedlit
}
SubShader
{
Tags {"RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="4.5"}
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "Unlit"
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "UnlitInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float fogCoord : TEXCOORD1;
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
color = MixFog(color, input.fogCoord);
return half4(color, alpha);
}
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaUnlit
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl"
ENDHLSL
}
}
SubShader
{
Tags {"RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="2.0"}
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "Unlit"
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#include "UnlitInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float fogCoord : TEXCOORD1;
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
color = MixFog(color, input.fogCoord);
alpha = OutputAlpha(alpha, _Surface);
return half4(color, alpha);
}
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaUnlit
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.UnlitShader"
}

View File

@@ -0,0 +1,25 @@
#ifndef UNIVERSAL_UNLIT_INPUT_INCLUDED
#define UNIVERSAL_UNLIT_INPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
half _Cutoff;
half _Surface;
CBUFFER_END
#ifdef UNITY_DOTS_INSTANCING_ENABLED
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata__BaseColor)
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Cutoff)
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata__Surface)
#endif
#endif

View File

@@ -0,0 +1,52 @@
#ifndef UNIVERSAL_UNLIT_META_PASS_INCLUDED
#define UNIVERSAL_UNLIT_META_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
#ifdef _TANGENT_TO_WORLD
float4 tangentOS : TANGENT;
#endif
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings UniversalVertexMeta(Attributes input)
{
Varyings output;
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2,
unity_LightmapST, unity_DynamicLightmapST);
output.uv = TRANSFORM_TEX(input.uv0, _BaseMap);
return output;
}
half4 UniversalFragmentMetaUnlit(Varyings input) : SV_Target
{
MetaInput metaInput = (MetaInput)0;
metaInput.Albedo = _BaseColor.rgb * SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).rgb;
return MetaFragment(metaInput);
}
//LWRP -> Universal Backwards Compatibility
Varyings LightweightVertexMeta(Attributes input)
{
return UniversalVertexMeta(input);
}
half4 LightweightFragmentMetaUnlit(Varyings input) : SV_Target
{
return UniversalFragmentMetaUnlit(input);
}
#endif

View File

@@ -0,0 +1,42 @@
Shader "Hidden/Universal Render Pipeline/Blit"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
Pass
{
Name "Blit"
ZTest Always
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment Fragment
#pragma multi_compile_fragment _ _LINEAR_TO_SRGB_CONVERSION
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Fullscreen.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
TEXTURE2D_X(_SourceTex);
SAMPLER(sampler_SourceTex);
half4 Fragment(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half4 col = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_SourceTex, input.uv);
#ifdef _LINEAR_TO_SRGB_CONVERSION
col = LinearToSRGB(col);
#endif
return col;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,25 @@
Shader "Hidden/Universal Render Pipeline/CopyDepth"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
Pass
{
Name "CopyDepth"
ZTest Always ZWrite On ColorMask 0
Cull Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ _DEPTH_MSAA_2 _DEPTH_MSAA_4 _DEPTH_MSAA_8
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/CopyDepthPass.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,115 @@
#ifndef UNIVERSAL_COPY_DEPTH_PASS_INCLUDED
#define UNIVERSAL_COPY_DEPTH_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#if defined(_DEPTH_MSAA_2)
#define MSAA_SAMPLES 2
#elif defined(_DEPTH_MSAA_4)
#define MSAA_SAMPLES 4
#elif defined(_DEPTH_MSAA_8)
#define MSAA_SAMPLES 8
#else
#define MSAA_SAMPLES 1
#endif
struct Attributes
{
#if _USE_DRAW_PROCEDURAL
uint vertexID : SV_VertexID;
#else
float4 positionHCS : POSITION;
float2 uv : TEXCOORD0;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// Note: CopyDepth pass is setup with a mesh already in CS
// Therefore, we can just output vertex position
// We need to handle y-flip in a way that all existing shaders using _ProjectionParams.x work.
// Otherwise we get flipping issues like this one (case https://issuetracker.unity3d.com/issues/lwrp-depth-texture-flipy)
// Unity flips projection matrix in non-OpenGL platforms and when rendering to a render texture.
// If URP is rendering to RT:
// - Source Depth is upside down. We need to copy depth by using a shader that has flipped matrix as well so we have same orientaiton for source and copy depth.
// - This also guarantess to be standard across if we are using a depth prepass.
// - When shaders (including shader graph) render objects that sample depth they adjust uv sign with _ProjectionParams.x. (https://docs.unity3d.com/Manual/SL-PlatformDifferences.html)
// - All good.
// If URP is NOT rendering to RT neither rendering with OpenGL:
// - Source Depth is NOT fliped. We CANNOT flip when copying depth and don't flip when sampling. (ProjectionParams.x == 1)
#if _USE_DRAW_PROCEDURAL
output.positionCS = GetQuadVertexPosition(input.vertexID);
output.positionCS.xy = output.positionCS.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f); //convert to -1..1
output.uv = GetQuadTexCoord(input.vertexID);
#else
output.positionCS = float4(input.positionHCS.xyz, 1.0);
output.uv = input.uv;
#endif
output.positionCS.y *= _ScaleBiasRt.x;
return output;
}
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
#define DEPTH_TEXTURE_MS(name, samples) Texture2DMSArray<float, samples> name
#define DEPTH_TEXTURE(name) TEXTURE2D_ARRAY_FLOAT(name)
#define LOAD(uv, sampleIndex) LOAD_TEXTURE2D_ARRAY_MSAA(_CameraDepthAttachment, uv, unity_StereoEyeIndex, sampleIndex)
#define SAMPLE(uv) SAMPLE_TEXTURE2D_ARRAY(_CameraDepthAttachment, sampler_CameraDepthAttachment, uv, unity_StereoEyeIndex).r
#else
#define DEPTH_TEXTURE_MS(name, samples) Texture2DMS<float, samples> name
#define DEPTH_TEXTURE(name) TEXTURE2D_FLOAT(name)
#define LOAD(uv, sampleIndex) LOAD_TEXTURE2D_MSAA(_CameraDepthAttachment, uv, sampleIndex)
#define SAMPLE(uv) SAMPLE_DEPTH_TEXTURE(_CameraDepthAttachment, sampler_CameraDepthAttachment, uv)
#endif
#if MSAA_SAMPLES == 1
DEPTH_TEXTURE(_CameraDepthAttachment);
SAMPLER(sampler_CameraDepthAttachment);
#else
DEPTH_TEXTURE_MS(_CameraDepthAttachment, MSAA_SAMPLES);
float4 _CameraDepthAttachment_TexelSize;
#endif
#if UNITY_REVERSED_Z
#define DEPTH_DEFAULT_VALUE 1.0
#define DEPTH_OP min
#else
#define DEPTH_DEFAULT_VALUE 0.0
#define DEPTH_OP max
#endif
float SampleDepth(float2 uv)
{
#if MSAA_SAMPLES == 1
return SAMPLE(uv);
#else
int2 coord = int2(uv * _CameraDepthAttachment_TexelSize.zw);
float outDepth = DEPTH_DEFAULT_VALUE;
UNITY_UNROLL
for (int i = 0; i < MSAA_SAMPLES; ++i)
outDepth = DEPTH_OP(LOAD(coord, i), outDepth);
return outDepth;
#endif
}
float frag(Varyings input) : SV_Depth
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return SampleDepth(input.uv);
}
#endif

View File

@@ -0,0 +1,79 @@
#ifndef UNIVERSAL_DEFERRED_INCLUDED
#define UNIVERSAL_DEFERRED_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
#define PREFERRED_CBUFFER_SIZE (64 * 1024)
#define SIZEOF_VEC4_TILEDATA 1 // uint4
#define SIZEOF_VEC4_PUNCTUALLIGHTDATA 5 // 5 * float4
#define MAX_DEPTHRANGE_PER_CBUFFER_BATCH (PREFERRED_CBUFFER_SIZE / 4) // Should be ushort, but extra unpacking code is "too expensive"
#define MAX_TILES_PER_CBUFFER_PATCH (PREFERRED_CBUFFER_SIZE / (16 * SIZEOF_VEC4_TILEDATA))
#define MAX_PUNCTUALLIGHT_PER_CBUFFER_BATCH (PREFERRED_CBUFFER_SIZE / (16 * SIZEOF_VEC4_PUNCTUALLIGHTDATA))
#define MAX_REL_LIGHT_INDICES_PER_CBUFFER_BATCH (PREFERRED_CBUFFER_SIZE / 4) // Should be ushort, but extra unpacking code is "too expensive"
// Keep in sync with kUseCBufferForDepthRange.
// Keep in sync with kUseCBufferForTileData.
// Keep in sync with kUseCBufferForLightData.
// Keep in sync with kUseCBufferForLightList.
#if defined(SHADER_API_SWITCH)
#define USE_CBUFFER_FOR_DEPTHRANGE 0
#define USE_CBUFFER_FOR_TILELIST 0
#define USE_CBUFFER_FOR_LIGHTDATA 1
#define USE_CBUFFER_FOR_LIGHTLIST 0
#elif defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)
#define USE_CBUFFER_FOR_DEPTHRANGE 1
#define USE_CBUFFER_FOR_TILELIST 1
#define USE_CBUFFER_FOR_LIGHTDATA 1
#define USE_CBUFFER_FOR_LIGHTLIST 1
#else
#define USE_CBUFFER_FOR_DEPTHRANGE 0
#define USE_CBUFFER_FOR_TILELIST 0
#define USE_CBUFFER_FOR_LIGHTDATA 1
#define USE_CBUFFER_FOR_LIGHTLIST 0
#endif
// This structure is used in StructuredBuffer.
// TODO move some of the properties to half storage (color, attenuation, spotDirection, flag to 16bits, occlusionProbeInfo)
struct PunctualLightData
{
float3 posWS;
float radius2; // squared radius
float4 color;
float4 attenuation; // .xy are used by DistanceAttenuation - .zw are used by AngleAttenuation (for SpotLights)
float3 spotDirection; // spotLights support
int flags; // Light flags (enum kLightFlags and LightFlag in C# code)
float4 occlusionProbeInfo;
};
Light UnityLightFromPunctualLightDataAndWorldSpacePosition(PunctualLightData punctualLightData, float3 positionWS, half4 shadowMask, int shadowLightIndex, bool materialFlagReceiveShadowsOff)
{
// Keep in sync with GetAdditionalPerObjectLight in Lighting.hlsl
half4 probesOcclusion = shadowMask;
Light light;
float3 lightVector = punctualLightData.posWS - positionWS.xyz;
float distanceSqr = max(dot(lightVector, lightVector), HALF_MIN);
half3 lightDirection = half3(lightVector * rsqrt(distanceSqr));
half attenuation = DistanceAttenuation(distanceSqr, punctualLightData.attenuation.xy) * AngleAttenuation(punctualLightData.spotDirection.xyz, lightDirection, punctualLightData.attenuation.zw);
light.direction = lightDirection;
light.color = punctualLightData.color.rgb;
light.distanceAttenuation = attenuation;
[branch] if (materialFlagReceiveShadowsOff)
light.shadowAttenuation = 1.0;
else
{
light.shadowAttenuation = AdditionalLightShadow(shadowLightIndex, positionWS, lightDirection, shadowMask, punctualLightData.occlusionProbeInfo);
}
return light;
}
#endif

View File

@@ -0,0 +1,44 @@
// Shader to use as a fallback error when rendering UniversalRP materials with built-in pipeline
Shader "Hidden/Universal Render Pipeline/FallbackError"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return fixed4(1,0,1,1);
}
ENDCG
}
}
Fallback Off
}

View File

@@ -0,0 +1,56 @@
#ifndef UNIVERSAL_FULLSCREEN_INCLUDED
#define UNIVERSAL_FULLSCREEN_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#if _USE_DRAW_PROCEDURAL
void GetProceduralQuad(in uint vertexID, out float4 positionCS, out float2 uv)
{
positionCS = GetQuadVertexPosition(vertexID);
positionCS.xy = positionCS.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f);
uv = GetQuadTexCoord(vertexID) * _ScaleBias.xy + _ScaleBias.zw;
}
#endif
struct Attributes
{
#if _USE_DRAW_PROCEDURAL
uint vertexID : SV_VertexID;
#else
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings FullscreenVert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if _USE_DRAW_PROCEDURAL
output.positionCS = GetQuadVertexPosition(input.vertexID);
output.positionCS.xy = output.positionCS.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f); //convert to -1..1
output.uv = GetQuadTexCoord(input.vertexID) * _ScaleBias.xy + _ScaleBias.zw;
#else
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.uv;
#endif
return output;
}
Varyings Vert(Attributes input)
{
return FullscreenVert(input);
}
#endif

View File

@@ -0,0 +1,50 @@
Shader "Hidden/Universal Render Pipeline/MaterialError"
{
SubShader
{
Pass
{
// Hybrid Renderer compatible error shader, which is used by Hybrid Renderer
// instead of the incompatible built-in error shader.
// TODO: Ideally this would be combined with FallbackError.shader, but it seems
// problematic because FallbackError needs to support SM2.0 and seems to use
// built-in shader headers, whereas Hybrid support needs SM4.5 and SRP shader headers.
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 4.5
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma multi_compile _ DOTS_INSTANCING_ON
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
struct appdata_t {
float4 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = TransformObjectToHClip(v.vertex.xyz);
return o;
}
float4 frag (v2f i) : SV_Target
{
return float4(1,0,1,1);
}
ENDHLSL
}
}
Fallback Off
}

View File

@@ -0,0 +1,47 @@
Shader "Hidden/Universal Render Pipeline/Sampling"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
LOD 100
// 0 - Downsample - Box filtering
Pass
{
Name "BoxDownsample"
ZTest Always
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex FullscreenVert
#pragma fragment FragBoxDownsample
#pragma multi_compile _ _USE_DRAW_PROCEDURAL
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Fullscreen.hlsl"
TEXTURE2D_X(_SourceTex);
SAMPLER(sampler_SourceTex);
float4 _SourceTex_TexelSize;
float _SampleOffset;
half4 FragBoxDownsample(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float4 d = _SourceTex_TexelSize.xyxy * float4(-_SampleOffset, -_SampleOffset, _SampleOffset, _SampleOffset);
half4 s;
s = SAMPLE_TEXTURE2D_X(_SourceTex, sampler_SourceTex, input.uv + d.xy);
s += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_SourceTex, input.uv + d.zy);
s += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_SourceTex, input.uv + d.xw);
s += SAMPLE_TEXTURE2D_X(_SourceTex, sampler_SourceTex, input.uv + d.zw);
return s * 0.25h;
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,113 @@
Shader "Hidden/Universal Render Pipeline/ScreenSpaceAmbientOcclusion"
{
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionHCS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings VertDefault(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
// Note: The pass is setup with a mesh already in CS
// Therefore, we can just output vertex position
output.positionCS = float4(input.positionHCS.xyz, 1.0);
#if UNITY_UV_STARTS_AT_TOP
output.positionCS.y *= -1;
#endif
output.uv = input.uv;
// Add a small epsilon to avoid artifacts when reconstructing the normals
output.uv += 1.0e-6;
return output;
}
ENDHLSL
SubShader
{
Tags{ "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
Cull Off ZWrite Off ZTest Always
// ------------------------------------------------------------------
// Depth only passes
// ------------------------------------------------------------------
// 0 - Occlusion estimation with CameraDepthTexture
Pass
{
Name "SSAO_Occlusion"
ZTest Always
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment SSAO
#pragma multi_compile_local _SOURCE_DEPTH _SOURCE_DEPTH_NORMALS _SOURCE_GBUFFER
#pragma multi_compile_local _RECONSTRUCT_NORMAL_LOW _RECONSTRUCT_NORMAL_MEDIUM _RECONSTRUCT_NORMAL_HIGH
#pragma multi_compile_local _ _ORTHOGRAPHIC
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SSAO.hlsl"
ENDHLSL
}
// 1 - Horizontal Blur
Pass
{
Name "SSAO_HorizontalBlur"
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment HorizontalBlur
#define BLUR_SAMPLE_CENTER_NORMAL
#pragma multi_compile_local _ _ORTHOGRAPHIC
#pragma multi_compile_local _SOURCE_DEPTH _SOURCE_DEPTH_NORMALS _SOURCE_GBUFFER
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SSAO.hlsl"
ENDHLSL
}
// 2 - Vertical Blur
Pass
{
Name "SSAO_VerticalBlur"
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment VerticalBlur
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SSAO.hlsl"
ENDHLSL
}
// 3 - Final Blur
Pass
{
Name "SSAO_FinalBlur"
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FinalBlur
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SSAO.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,88 @@
Shader "Hidden/Universal Render Pipeline/ScreenSpaceShadows"
{
SubShader
{
Tags{ "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True"}
HLSLINCLUDE
//Keep compiler quiet about Shadows.hlsl.
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
half4 positionCS : SV_POSITION;
half4 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vertex(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
float4 projPos = output.positionCS * 0.5;
projPos.xy = projPos.xy + projPos.w;
output.uv.xy = UnityStereoTransformScreenSpaceTex(input.texcoord);
output.uv.zw = projPos.xy;
return output;
}
half4 Fragment(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if UNITY_REVERSED_Z
float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, input.uv.xy).r;
#else
float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, input.uv.xy).r;
deviceDepth = deviceDepth * 2.0 - 1.0;
#endif
float3 wpos = ComputeWorldSpacePosition(input.uv.xy, deviceDepth, unity_MatrixInvVP);
//Fetch shadow coordinates for cascade.
float4 coords = TransformWorldToShadowCoord(wpos);
// Screenspace shadowmap is only used for directional lights which use orthogonal projection.
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
half4 shadowParams = GetMainLightShadowParams();
return SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), coords, shadowSamplingData, shadowParams, false);
}
ENDHLSL
Pass
{
Name "ScreenSpaceShadows"
ZTest Always
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma multi_compile _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _SHADOWS_SOFT
#pragma vertex Vertex
#pragma fragment Fragment
ENDHLSL
}
}
}

View File

@@ -0,0 +1,504 @@
Shader "Hidden/Universal Render Pipeline/StencilDeferred"
{
Properties {
_StencilRef ("StencilRef", Int) = 0
_StencilReadMask ("StencilReadMask", Int) = 0
_StencilWriteMask ("StencilWriteMask", Int) = 0
_LitPunctualStencilRef ("LitPunctualStencilWriteMask", Int) = 0
_LitPunctualStencilReadMask ("LitPunctualStencilReadMask", Int) = 0
_LitPunctualStencilWriteMask ("LitPunctualStencilWriteMask", Int) = 0
_SimpleLitPunctualStencilRef ("SimpleLitPunctualStencilWriteMask", Int) = 0
_SimpleLitPunctualStencilReadMask ("SimpleLitPunctualStencilReadMask", Int) = 0
_SimpleLitPunctualStencilWriteMask ("SimpleLitPunctualStencilWriteMask", Int) = 0
_LitDirStencilRef ("LitDirStencilRef", Int) = 0
_LitDirStencilReadMask ("LitDirStencilReadMask", Int) = 0
_LitDirStencilWriteMask ("LitDirStencilWriteMask", Int) = 0
_SimpleLitDirStencilRef ("SimpleLitDirStencilRef", Int) = 0
_SimpleLitDirStencilReadMask ("SimpleLitDirStencilReadMask", Int) = 0
_SimpleLitDirStencilWriteMask ("SimpleLitDirStencilWriteMask", Int) = 0
_ClearStencilRef ("ClearStencilRef", Int) = 0
_ClearStencilReadMask ("ClearStencilReadMask", Int) = 0
_ClearStencilWriteMask ("ClearStencilWriteMask", Int) = 0
}
HLSLINCLUDE
// _ADDITIONAL_LIGHT_SHADOWS is shader keyword globally enabled for a range of render-passes.
// When rendering deferred lights, we need to set/unset this flag dynamically for each deferred
// light, however there is no way to restore the value of the keyword, whch is needed by the
// forward transparent pass. The workaround is to use a new shader keyword
// _DEFERRED_ADDITIONAL_LIGHT_SHADOWS to set _ADDITIONAL_LIGHT_SHADOWS as a #define, so that
// the "state" of the keyword itself is unchanged.
#ifdef _DEFERRED_ADDITIONAL_LIGHT_SHADOWS
#define _ADDITIONAL_LIGHT_SHADOWS 1
#endif
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Deferred.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 screenUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
#if defined(_SPOT)
float4 _SpotLightScale;
float4 _SpotLightBias;
float4 _SpotLightGuard;
#endif
Varyings Vertex(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float3 positionOS = input.positionOS.xyz;
#if defined(_SPOT)
// Spot lights have an outer angle than can be up to 180 degrees, in which case the shape
// becomes a capped hemisphere. There is no affine transforms to handle the particular cone shape,
// so instead we will adjust the vertices positions in the vertex shader to get the tighest fit.
[flatten] if (any(positionOS.xyz))
{
// The hemisphere becomes the rounded cap of the cone.
positionOS.xyz = _SpotLightBias.xyz + _SpotLightScale.xyz * positionOS.xyz;
positionOS.xyz = normalize(positionOS.xyz) * _SpotLightScale.w;
// Slightly inflate the geometry to fit the analytic cone shape.
// We want the outer rim to be expanded along xy axis only, while the rounded cap is extended along all axis.
positionOS.xyz = (positionOS.xyz - float3(0, 0, _SpotLightGuard.w)) * _SpotLightGuard.xyz + float3(0, 0, _SpotLightGuard.w);
}
#endif
#if defined(_DIRECTIONAL) || defined(_FOG) || defined(_CLEAR_STENCIL_PARTIAL)
output.positionCS = float4(positionOS.xy, UNITY_RAW_FAR_CLIP_VALUE, 1.0); // Force triangle to be on zfar
#else
VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS.xyz);
output.positionCS = vertexInput.positionCS;
#endif
output.screenUV = output.positionCS.xyw;
#if UNITY_UV_STARTS_AT_TOP
output.screenUV.xy = output.screenUV.xy * float2(0.5, -0.5) + 0.5 * output.screenUV.z;
#else
output.screenUV.xy = output.screenUV.xy * 0.5 + 0.5 * output.screenUV.z;
#endif
return output;
}
TEXTURE2D_X(_CameraDepthTexture);
TEXTURE2D_X_HALF(_GBuffer0);
TEXTURE2D_X_HALF(_GBuffer1);
TEXTURE2D_X_HALF(_GBuffer2);
#ifdef _DEFERRED_MIXED_LIGHTING
TEXTURE2D_X_HALF(_GBuffer4);
#endif
float4x4 _ScreenToWorld[2];
SamplerState my_point_clamp_sampler;
float3 _LightPosWS;
half3 _LightColor;
half4 _LightAttenuation; // .xy are used by DistanceAttenuation - .zw are used by AngleAttenuation *for SpotLights)
half3 _LightDirection; // directional/spotLights support
half4 _LightOcclusionProbInfo;
int _LightFlags;
int _ShadowLightIndex;
half4 FragWhite(Varyings input) : SV_Target
{
return half4(1.0, 1.0, 1.0, 1.0);
}
half4 DeferredShading(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// Using SAMPLE_TEXTURE2D is faster than using LOAD_TEXTURE2D on iOS platforms (5% faster shader).
// Possible reason: HLSLcc upcasts Load() operation to float, which doesn't happen for Sample()?
float2 screen_uv = (input.screenUV.xy / input.screenUV.z);
float d = SAMPLE_TEXTURE2D_X_LOD(_CameraDepthTexture, my_point_clamp_sampler, screen_uv, 0).x; // raw depth value has UNITY_REVERSED_Z applied on most platforms.
half4 gbuffer0 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer0, my_point_clamp_sampler, screen_uv, 0);
half4 gbuffer1 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer1, my_point_clamp_sampler, screen_uv, 0);
half4 gbuffer2 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer2, my_point_clamp_sampler, screen_uv, 0);
#ifdef _DEFERRED_MIXED_LIGHTING
half4 gbuffer4 = SAMPLE_TEXTURE2D_X_LOD(_GBuffer4, my_point_clamp_sampler, screen_uv, 0);
half4 shadowMask = gbuffer4;
#else
half4 shadowMask = 1.0;
#endif
uint materialFlags = UnpackMaterialFlags(gbuffer0.a);
bool materialReceiveShadowsOff = (materialFlags & kMaterialFlagReceiveShadowsOff) != 0;
#if SHADER_API_MOBILE || SHADER_API_SWITCH
// Specular highlights are still silenced by setting specular to 0.0 during gbuffer pass and GPU timing is still reduced.
bool materialSpecularHighlightsOff = false;
#else
bool materialSpecularHighlightsOff = (materialFlags & kMaterialFlagSpecularHighlightsOff);
#endif
#if defined(_DEFERRED_MIXED_LIGHTING)
// If both lights and geometry are static, then no realtime lighting to perform for this combination.
[branch] if ((_LightFlags & materialFlags) == kMaterialFlagSubtractiveMixedLighting)
return half4(0.0, 0.0, 0.0, 0.0); // Cannot discard because stencil must be updated.
#endif
#if defined(USING_STEREO_MATRICES)
int eyeIndex = unity_StereoEyeIndex;
#else
int eyeIndex = 0;
#endif
float4 posWS = mul(_ScreenToWorld[eyeIndex], float4(input.positionCS.xy, d, 1.0));
posWS.xyz *= rcp(posWS.w);
InputData inputData = InputDataFromGbufferAndWorldPosition(gbuffer2, posWS.xyz);
Light unityLight;
#if defined(_DIRECTIONAL)
unityLight.direction = _LightDirection;
unityLight.color = _LightColor.rgb;
unityLight.distanceAttenuation = 1.0;
if (materialReceiveShadowsOff)
unityLight.shadowAttenuation = 1.0;
else
{
#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
#if defined(_MAIN_LIGHT_SHADOWS_SCREEN)
float4 shadowCoord = float4(screen_uv, 0.0, 1.0);
#else
float4 shadowCoord = TransformWorldToShadowCoord(posWS.xyz);
#endif
unityLight.shadowAttenuation = MainLightShadow(shadowCoord, posWS.xyz, shadowMask, _MainLightOcclusionProbes);
#elif defined(_DEFERRED_ADDITIONAL_LIGHT_SHADOWS)
unityLight.shadowAttenuation = AdditionalLightShadow(_ShadowLightIndex, posWS.xyz, _LightDirection, shadowMask, _LightOcclusionProbInfo);
#else
unityLight.shadowAttenuation = 1.0;
#endif
}
#else
PunctualLightData light;
light.posWS = _LightPosWS;
light.radius2 = 0.0; // only used by tile-lights.
light.color = float4(_LightColor, 0.0);
light.attenuation = _LightAttenuation;
light.spotDirection = _LightDirection;
light.occlusionProbeInfo = _LightOcclusionProbInfo;
light.flags = _LightFlags;
unityLight = UnityLightFromPunctualLightDataAndWorldSpacePosition(light, posWS.xyz, shadowMask, _ShadowLightIndex, materialReceiveShadowsOff);
#endif
half3 color = 0.0.xxx;
#if defined(_LIT)
BRDFData brdfData = BRDFDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2);
color = LightingPhysicallyBased(brdfData, unityLight, inputData.normalWS, inputData.viewDirectionWS, materialSpecularHighlightsOff);
#elif defined(_SIMPLELIT)
SurfaceData surfaceData = SurfaceDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2, kLightingSimpleLit);
half3 attenuatedLightColor = unityLight.color * (unityLight.distanceAttenuation * unityLight.shadowAttenuation);
half3 diffuseColor = LightingLambert(attenuatedLightColor, unityLight.direction, inputData.normalWS);
half3 specularColor = LightingSpecular(attenuatedLightColor, unityLight.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, surfaceData.smoothness), surfaceData.smoothness);
// TODO: if !defined(_SPECGLOSSMAP) && !defined(_SPECULAR_COLOR), force specularColor to 0 in gbuffer code
color = diffuseColor * surfaceData.albedo + specularColor;
#endif
return half4(color, 0.0);
}
half4 FragFog(Varyings input) : SV_Target
{
float d = LOAD_TEXTURE2D_X(_CameraDepthTexture, input.positionCS.xy).x;
float eye_z = LinearEyeDepth(d, _ZBufferParams);
float clip_z = UNITY_MATRIX_P[2][2] * -eye_z + UNITY_MATRIX_P[2][3];
half fogFactor = ComputeFogFactor(clip_z);
half fogIntensity = ComputeFogIntensity(fogFactor);
return half4(unity_FogColor.rgb, fogIntensity);
}
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
// 0 - Stencil pass
Pass
{
Name "Stencil Volume"
ZTest LEQual
ZWrite Off
ZClip false
Cull Off
ColorMask 0
Stencil {
Ref [_StencilRef]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
CompFront NotEqual
PassFront Keep
ZFailFront Invert
CompBack NotEqual
PassBack Keep
ZFailBack Invert
}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile_vertex _ _SPOT
#pragma vertex Vertex
#pragma fragment FragWhite
//#pragma enable_d3d11_debug_symbols
ENDHLSL
}
// 1 - Deferred Punctual Light (Lit)
Pass
{
Name "Deferred Punctual Light (Lit)"
ZTest GEqual
ZWrite Off
ZClip false
Cull Front
Blend One One, Zero One
BlendOp Add, Add
Stencil {
Ref [_LitPunctualStencilRef]
ReadMask [_LitPunctualStencilReadMask]
WriteMask [_LitPunctualStencilWriteMask]
Comp Equal
Pass Zero
Fail Keep
ZFail Keep
}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile _POINT _SPOT
#pragma multi_compile_fragment _LIT
#pragma multi_compile_fragment _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING
#pragma vertex Vertex
#pragma fragment DeferredShading
//#pragma enable_d3d11_debug_symbols
ENDHLSL
}
// 2 - Deferred Punctual Light (SimpleLit)
Pass
{
Name "Deferred Punctual Light (SimpleLit)"
ZTest GEqual
ZWrite Off
ZClip false
Cull Front
Blend One One, Zero One
BlendOp Add, Add
Stencil {
Ref [_SimpleLitPunctualStencilRef]
ReadMask [_SimpleLitPunctualStencilReadMask]
WriteMask [_SimpleLitPunctualStencilWriteMask]
CompBack Equal
PassBack Zero
FailBack Keep
ZFailBack Keep
}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile _POINT _SPOT
#pragma multi_compile_fragment _SIMPLELIT
#pragma multi_compile_fragment _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING
#pragma vertex Vertex
#pragma fragment DeferredShading
//#pragma enable_d3d11_debug_symbols
ENDHLSL
}
// 3 - Directional Light (Lit)
Pass
{
Name "Deferred Directional Light (Lit)"
ZTest NotEqual
ZWrite Off
Cull Off
Blend One One, Zero One
BlendOp Add, Add
Stencil {
Ref [_LitDirStencilRef]
ReadMask [_LitDirStencilReadMask]
WriteMask [_LitDirStencilWriteMask]
Comp Equal
Pass Keep
Fail Keep
ZFail Keep
}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile _DIRECTIONAL
#pragma multi_compile_fragment _LIT
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile_fragment _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING
#pragma vertex Vertex
#pragma fragment DeferredShading
//#pragma enable_d3d11_debug_symbols
ENDHLSL
}
// 4 - Directional Light (SimpleLit)
Pass
{
Name "Deferred Directional Light (SimpleLit)"
ZTest NotEqual
ZWrite Off
Cull Off
Blend One One, Zero One
BlendOp Add, Add
Stencil {
Ref [_SimpleLitDirStencilRef]
ReadMask [_SimpleLitDirStencilReadMask]
WriteMask [_SimpleLitDirStencilWriteMask]
Comp Equal
Pass Keep
Fail Keep
ZFail Keep
}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile _DIRECTIONAL
#pragma multi_compile_fragment _SIMPLELIT
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile_fragment _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _DEFERRED_ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_fragment _ _DEFERRED_MIXED_LIGHTING
#pragma vertex Vertex
#pragma fragment DeferredShading
//#pragma enable_d3d11_debug_symbols
ENDHLSL
}
// 5 - Legacy fog
Pass
{
Name "Fog"
ZTest NotEqual
ZWrite Off
Cull Off
Blend OneMinusSrcAlpha SrcAlpha, Zero One
BlendOp Add, Add
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile _FOG
#pragma multi_compile FOG_LINEAR FOG_EXP FOG_EXP2
#pragma vertex Vertex
#pragma fragment FragFog
//#pragma enable_d3d11_debug_symbols
ENDHLSL
}
// 6 - Clear stencil partial
Pass
{
Name "ClearStencilPartial"
ColorMask 0
ZTest NotEqual
ZWrite Off
Cull Off
Stencil {
Ref [_ClearStencilRef]
ReadMask [_ClearStencilReadMask]
WriteMask [_ClearStencilWriteMask]
Comp NotEqual
Pass Zero
Fail Keep
ZFail Keep
}
HLSLPROGRAM
#pragma exclude_renderers gles
#pragma multi_compile _CLEAR_STENCIL_PARTIAL
#pragma vertex Vertex
#pragma fragment FragWhite
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
}

View File

@@ -0,0 +1,41 @@
#ifndef UNIVERSAL_FALLBACK_2D_INCLUDED
#define UNIVERSAL_FALLBACK_2D_INCLUDED
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
return output;
}
half4 frag(Varyings input) : SV_Target
{
half2 uv = input.uv;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
return half4(color, alpha);
}
#endif

View File

@@ -0,0 +1,60 @@
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#if SRC_TEXTURE2D_X_ARRAY
TEXTURE2D_ARRAY(_SourceTex);
#else
TEXTURE2D(_SourceTex);
#endif
SamplerState sampler_LinearClamp;
uniform uint _SourceTexArraySlice;
uniform uint _SRGBRead;
uniform uint _SRGBWrite;
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
Varyings VertQuad(Attributes input)
{
Varyings output;
output.positionCS = GetQuadVertexPosition(input.vertexID) * float4(_ScaleBiasRt.x, _ScaleBiasRt.y, 1, 1) + float4(_ScaleBiasRt.z, _ScaleBiasRt.w, 0, 0);
output.positionCS.xy = output.positionCS.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f); //convert to -1..1
#if UNITY_UV_STARTS_AT_TOP
// Unity viewport convention is bottom left as origin. Adjust Scalebias to read the correct region.
_ScaleBias.w = 1 - _ScaleBias.w - _ScaleBias.y;
#endif
output.texcoord = GetQuadTexCoord(input.vertexID) * _ScaleBias.xy + _ScaleBias.zw;
return output;
}
float4 FragBilinear(Varyings input) : SV_Target
{
float4 outColor;
#if SRC_TEXTURE2D_X_ARRAY
outColor = SAMPLE_TEXTURE2D_ARRAY(_SourceTex, sampler_LinearClamp, input.texcoord.xy, _SourceTexArraySlice);
#else
outColor = SAMPLE_TEXTURE2D(_SourceTex, sampler_LinearClamp, input.texcoord.xy);
#endif
if (_SRGBRead && _SRGBWrite)
return outColor;
if (_SRGBRead)
outColor = SRGBToLinear(outColor);
if (_SRGBWrite)
outColor = LinearToSRGB(outColor);
return outColor;
}

View File

@@ -0,0 +1,41 @@
Shader "Hidden/Universal Render Pipeline/XR/XRMirrorView"
{
SubShader
{
Tags{ "RenderPipeline" = "UniversalPipeline" }
HLSLINCLUDE
#pragma exclude_renderers gles
ENDHLSL
// 0: TEXTURE2D
Pass
{
ZWrite Off ZTest Always Blend Off Cull Off
HLSLPROGRAM
#pragma vertex VertQuad
#pragma fragment FragBilinear
#define SRC_TEXTURE2D_X_ARRAY 0
#include "Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMirrorView.hlsl"
ENDHLSL
}
// 1: TEXTURE2D_ARRAY
Pass
{
ZWrite Off ZTest Always Blend Off Cull Off
HLSLPROGRAM
#pragma vertex VertQuad
#pragma fragment FragBilinear
#define SRC_TEXTURE2D_X_ARRAY 1
#include "Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMirrorView.hlsl"
ENDHLSL
}
}
Fallback Off
}

View File

@@ -0,0 +1,63 @@
Shader "Hidden/Universal Render Pipeline/XR/XROcclusionMesh"
{
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#pragma exclude_renderers d3d11_9x gles
#pragma multi_compile _ XR_OCCLUSION_MESH_COMBINED
// Not all platforms properly support SV_RenderTargetArrayIndex
#if defined(SHADER_API_D3D11) || defined(SHADER_API_VULKAN) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3) || defined(SHADER_API_PSSL)
#define USE_XR_OCCLUSION_MESH_COMBINED XR_OCCLUSION_MESH_COMBINED
#endif
struct Attributes
{
float4 vertex : POSITION;
};
struct Varyings
{
float4 vertex : SV_POSITION;
#if USE_XR_OCCLUSION_MESH_COMBINED
uint rtArrayIndex : SV_RenderTargetArrayIndex;
#endif
};
Varyings Vert(Attributes input)
{
Varyings output;
output.vertex = float4(input.vertex.xy * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), UNITY_NEAR_CLIP_VALUE, 1.0f);
#if USE_XR_OCCLUSION_MESH_COMBINED
output.rtArrayIndex = input.vertex.z;
#endif
return output;
}
float4 Frag() : SV_Target
{
return (0.0f).xxxx;
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "UniversalPipeline" }
Pass
{
ZWrite On ZTest Always Blend Off Cull Off
ColorMask 0
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
Fallback Off
}