Folder clean up;
Added Emissive;
This commit is contained in:
127
Runtime/Shaders/Includes/ShaderPass/HDRPToonHairBlending.hlsl
Normal file
127
Runtime/Shaders/Includes/ShaderPass/HDRPToonHairBlending.hlsl
Normal file
@@ -0,0 +1,127 @@
|
||||
#undef unity_ObjectToWorld
|
||||
#undef unity_WorldToObject
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
|
||||
|
||||
// PackedVaryingsType
|
||||
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L120
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
|
||||
{
|
||||
// VaryingsType
|
||||
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118
|
||||
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
|
||||
return MotionVectorVS(varyingsType, inputMesh, inputPass);
|
||||
}
|
||||
|
||||
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
|
||||
return PackVaryingsType(varyingsType);
|
||||
}
|
||||
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
|
||||
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
#define VT_BUFFER_TARGET SV_Target1
|
||||
#define EXTRA_BUFFER_TARGET SV_Target2
|
||||
#else
|
||||
#define EXTRA_BUFFER_TARGET SV_Target1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void Frag(PackedVaryingsToPS packedInput,
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
out float4 outColor : SV_Target0, // outSpecularLighting
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
out float4 outVTFeedback : VT_BUFFER_TARGET,
|
||||
#endif
|
||||
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
|
||||
OUTPUT_SSSBUFFER(outSSSBuffer)
|
||||
#else
|
||||
out float4 outColor : SV_Target0
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
, out float4 outVTFeedback : VT_BUFFER_TARGET
|
||||
#endif
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#endif // OUTPUT_SPLIT_LIGHTING
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
, out float outputDepth : SV_Depth
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
|
||||
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
|
||||
#ifdef _IS_CLIPPING_MASK
|
||||
if (_ClippingMaskMode != 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
#ifdef _IS_CLIPPING_MATTE
|
||||
if (_ClippingMatteMode != 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif // _IS_CLIPPING_MATTE
|
||||
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
|
||||
discard;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//v.2.0.5
|
||||
if (_ZOverDrawMode > 0.99f)
|
||||
{
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
|
||||
return;
|
||||
}
|
||||
_Color = _BaseColor;
|
||||
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
|
||||
float4 Set_UV0 = input.texCoord0;
|
||||
|
||||
// The following temporary definition of unity_AmbientEquator is for HDRP only.
|
||||
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
|
||||
//v.2.0.9
|
||||
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
|
||||
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
|
||||
float3 envLightSource_SkyboxIntensity = max(
|
||||
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 0.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
|
||||
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
|
||||
).rgb;
|
||||
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
|
||||
ambientSkyColor *= GetCurrentExposureMultiplier();
|
||||
|
||||
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _MainTex));
|
||||
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a);
|
||||
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
}
|
||||
// End of File
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a528382509a1bca4b9da190eb68e40d4
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
224
Runtime/Shaders/Includes/ShaderPass/HDRPToonOutline.hlsl
Normal file
224
Runtime/Shaders/Includes/ShaderPass/HDRPToonOutline.hlsl
Normal file
@@ -0,0 +1,224 @@
|
||||
//Unity Toon Shader/HDRP
|
||||
//nobuyuki@unity3d.com
|
||||
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
||||
|
||||
#undef unity_ObjectToWorld
|
||||
#undef unity_WorldToObject
|
||||
|
||||
float4 _LightColor0; // not referenced in c# code ??
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
|
||||
|
||||
// PackedVaryingsType
|
||||
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L120
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
|
||||
{
|
||||
// VaryingsType
|
||||
// https://github.com/Unity-Technologies/Graphics/blob/e4117c07b479adafed38237f3407a363eefb4590/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl#L118
|
||||
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
varyingsType.vmesh.
|
||||
#include "HDRPToonOutlineVertMain.hlsl"
|
||||
|
||||
return MotionVectorVS(varyingsType, inputMesh, inputPass);
|
||||
}
|
||||
|
||||
#ifdef TESSELLATION_ON
|
||||
|
||||
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
|
||||
{
|
||||
VaryingsToPS output;
|
||||
output.vmesh = VertMeshTesselation(input.vmesh);
|
||||
MotionVectorPositionZBias(output);
|
||||
|
||||
output.vpass.positionCS = input.vpass.positionCS;
|
||||
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
|
||||
|
||||
return PackVaryingsToPS(output);
|
||||
}
|
||||
|
||||
#endif // TESSELLATION_ON
|
||||
|
||||
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
#include "HDRPToonOutlineVertMain.hlsl"
|
||||
|
||||
return PackVaryingsType(varyingsType);
|
||||
}
|
||||
|
||||
#ifdef TESSELLATION_ON
|
||||
|
||||
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
|
||||
{
|
||||
VaryingsToPS output;
|
||||
output.vmesh = VertMeshTesselation(input.vmesh);
|
||||
|
||||
return PackVaryingsToPS(output);
|
||||
}
|
||||
|
||||
|
||||
#endif // TESSELLATION_ON
|
||||
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
|
||||
#ifdef TESSELLATION_ON
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
#define VT_BUFFER_TARGET SV_Target1
|
||||
#define EXTRA_BUFFER_TARGET SV_Target2
|
||||
#else
|
||||
#define EXTRA_BUFFER_TARGET SV_Target1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void Frag(PackedVaryingsToPS packedInput,
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
out float4 outColor : SV_Target0, // outSpecularLighting
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
out float4 outVTFeedback : VT_BUFFER_TARGET,
|
||||
#endif
|
||||
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
|
||||
OUTPUT_SSSBUFFER(outSSSBuffer)
|
||||
#else
|
||||
out float4 outColor : SV_Target0
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
, out float4 outVTFeedback : VT_BUFFER_TARGET
|
||||
#endif
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#endif // OUTPUT_SPLIT_LIGHTING
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
, out float outputDepth : SV_Depth
|
||||
#endif
|
||||
)
|
||||
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
|
||||
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
|
||||
#ifdef _IS_CLIPPING_MASK
|
||||
if (_ClippingMaskMode != 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
#ifdef _IS_CLIPPING_MATTE
|
||||
if (_ClippingMatteMode != 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif // _IS_CLIPPING_MATTE
|
||||
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
|
||||
discard;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//v.2.0.5
|
||||
if (_ZOverDrawMode > 0.99f)
|
||||
{
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
|
||||
return;
|
||||
}
|
||||
_Color = _BaseColor;
|
||||
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
|
||||
float4 Set_UV0 = input.texCoord0;
|
||||
|
||||
// The following temporary definition of unity_AmbientEquator is for HDRP only.
|
||||
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
|
||||
//v.2.0.9
|
||||
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
|
||||
float3 envLightSource_GradientEquator = ShadeSH9(float4(0, 1, 0, 0));
|
||||
float3 envLightSource_SkyboxIntensity = max(
|
||||
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, 0.0, 0.0), input.texCoord1.xy, input.texCoord2.xy),
|
||||
SampleBakedGI_UTS_OutLine(objPos.xyz, float3(0.0, -1.0, 0.0), input.texCoord1.xy, input.texCoord2.xy)
|
||||
).rgb;
|
||||
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
|
||||
ambientSkyColor *= GetCurrentExposureMultiplier() * 5.0f;
|
||||
|
||||
float4 _MainTex_var = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _MainTex));
|
||||
float3 Set_BaseColor = _BaseColor.rgb*_MainTex_var.rgb;
|
||||
float3 _Is_BlendBaseColor_var = lerp(_Outline_Color.rgb * ambientSkyColor, (_Outline_Color.rgb * ambientSkyColor * Set_BaseColor * Set_BaseColor), _Is_BlendBaseColor);
|
||||
//
|
||||
float3 _OutlineTex_var = tex2D(_OutlineTex,TRANSFORM_TEX(Set_UV0, _OutlineTex)).xyz;
|
||||
|
||||
float4 overridingColor = lerp(_OutlineMaskColor, float4(_OutlineMaskColor.w, _OutlineMaskColor.w, _OutlineMaskColor.w, 1.0f), _ComposerMaskMode);
|
||||
float maskEnabled = max(_OutlineOverridden, _ComposerMaskMode);
|
||||
|
||||
//v.2.0.7.5
|
||||
#ifdef _IS_OUTLINE_CLIPPING_NO
|
||||
float3 Set_Outline_Color = lerp(_Is_BlendBaseColor_var, _OutlineTex_var.rgb*_Outline_Color.rgb * ambientSkyColor, _Is_OutlineTex );
|
||||
if (_OutlineVisible < 0.1)
|
||||
{
|
||||
// Todo.
|
||||
// without this, something is drawn even if _OutlineVisible = 0, in AngelRing(HDRP)
|
||||
discard;
|
||||
}
|
||||
Set_Outline_Color = lerp(Set_Outline_Color, overridingColor.xyz, maskEnabled);
|
||||
float3 volColor, volOpacity;
|
||||
|
||||
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
|
||||
// input.positionSS is SV_Position
|
||||
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
|
||||
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
|
||||
|
||||
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
|
||||
Set_Outline_Color.xyz = Set_Outline_Color.xyz * (1 - volOpacity) + volColor * _OutlineVisible;
|
||||
outColor =float4(Set_Outline_Color, _OutlineVisible );
|
||||
|
||||
|
||||
#elif _IS_OUTLINE_CLIPPING_YES
|
||||
float4 _ClippingMask_var = SAMPLE_TEXTURE2D(_ClippingMask, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _ClippingMask));
|
||||
float Set_MainTexAlpha = _MainTex_var.a;
|
||||
float _IsBaseMapAlphaAsClippingMask_var = lerp( _ClippingMask_var.r, Set_MainTexAlpha, _IsBaseMapAlphaAsClippingMask );
|
||||
float _Inverse_Clipping_var = lerp( _IsBaseMapAlphaAsClippingMask_var, (1.0 - _IsBaseMapAlphaAsClippingMask_var), _Inverse_Clipping );
|
||||
float Set_Clipping = saturate((_Inverse_Clipping_var+_Clipping_Level));
|
||||
clip(Set_Clipping - 0.5);
|
||||
float4 Set_Outline_Color = lerp( float4(_Is_BlendBaseColor_var, Set_Clipping), float4((_OutlineTex_var.rgb * _Outline_Color.rgb * ambientSkyColor),Set_Clipping), _Is_OutlineTex );
|
||||
Set_Outline_Color = lerp(Set_Outline_Color, overridingColor, maskEnabled);
|
||||
Set_Outline_Color.w *= _OutlineVisible;
|
||||
|
||||
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
|
||||
// input.positionSS is SV_Position
|
||||
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
|
||||
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
|
||||
|
||||
float3 volColor, volOpacity;
|
||||
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
|
||||
Set_Outline_Color.xyz = Set_Outline_Color.xyz * (1 - volOpacity.x) + volColor * Set_Outline_Color.w;
|
||||
outColor = Set_Outline_Color;
|
||||
#endif
|
||||
//outColor.rgb = ambientSkyColor;
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
}
|
||||
// End of File
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da01533aa573e30428720fa587ddbe94
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
//Unity Toon Shader/HDRP
|
||||
//nobuyuki@unity3d.com
|
||||
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
||||
|
||||
|
||||
#if 1
|
||||
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
|
||||
float2 Set_UV0 = inputMesh.uv0;
|
||||
float4 _Outline_Sampler_var = tex2Dlod(_Outline_Sampler, float4(TRANSFORM_TEX(Set_UV0, _Outline_Sampler), 0.0, 0));
|
||||
//v.2.0.4.3 baked Normal Texture for Outline
|
||||
float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS);
|
||||
float3 tangentDir = normalize(mul(unity_ObjectToWorld, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
|
||||
float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w);
|
||||
float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir);
|
||||
//UnpackNormal() can't be used, and so as follows. Do not specify a bump for the texture to be used.
|
||||
float4 _BakedNormal_var = (tex2Dlod(_BakedNormal, float4(TRANSFORM_TEX(Set_UV0, _BakedNormal), 0.0, 0)) * 2 - 1);
|
||||
float3 _BakedNormalDir = normalize(mul(_BakedNormal_var.rgb, tangentTransform));
|
||||
//end
|
||||
float Set_Outline_Width = (_Outline_Width * 0.01 * smoothstep(_Farthest_Distance, _Nearest_Distance, distance(objPos.rgb, _WorldSpaceCameraPos)) * _Outline_Sampler_var.rgb).r;
|
||||
Set_Outline_Width *= (1.0f - _ZOverDrawMode);
|
||||
//v.2.0.7.5
|
||||
float4 _ClipCameraPos = mul(UNITY_MATRIX_VP, float4(_WorldSpaceCameraPos.xyz, 1));
|
||||
//v.2.0.7
|
||||
#if defined(UNITY_REVERSED_Z)
|
||||
//v.2.0.4.2 (DX)
|
||||
_Offset_Z = _Offset_Z * -0.01;
|
||||
#else
|
||||
//OpenGL
|
||||
_Offset_Z = _Offset_Z * 0.01;
|
||||
#endif
|
||||
float3 FinalNormal;
|
||||
if(_UseSmoothedNormal == 1)
|
||||
{
|
||||
float3 normal = float3(inputMesh.uv1, 0);
|
||||
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
|
||||
FinalNormal = mul(normal, tangentTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
FinalNormal = lerp(inputMesh.normalOS, _BakedNormalDir, _Is_BakedNormal);
|
||||
}
|
||||
|
||||
//v2.0.4
|
||||
#ifdef _OUTLINE_NML
|
||||
//v.2.0.4.3 baked Normal Texture for Outline
|
||||
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), FinalNormal);
|
||||
#elif _OUTLINE_POS
|
||||
Set_Outline_Width = Set_Outline_Width * 2;
|
||||
float signVar = dot(normalize(inputMesh.positionOS), normalize(inputMesh.normalOS)) < 0 ? -1 : 1;
|
||||
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), signVar * normalize(inputMesh.positionOS));
|
||||
#endif
|
||||
// screen space width
|
||||
float2 extendDir = normalize(TransformWViewToHClip(normal).xy);
|
||||
float4 clipPos = UnityObjectToClipPos(inputMesh.positionOS);
|
||||
clipPos.xy += extendDir * min(_Outline_MaxWidth, (clipPos.w * Set_Outline_Width));
|
||||
clipPos.z = clipPos.z + _Offset_Z * _ClipCameraPos.z;
|
||||
|
||||
float4 rws = mul(UNITY_MATRIX_I_P, clipPos); // use UNITY_MATRIX_I_P instead of unity_CameraInvProjection.
|
||||
rws = mul(UNITY_MATRIX_I_V, rws); // use UNITY_MATRIX_I_V instead of unity_cameraToWorld.
|
||||
#ifndef TESSELLATION_ON
|
||||
varyingsType.vmesh.positionCS = clipPos;
|
||||
#endif // TESSELLATION_ON
|
||||
varyingsType.vmesh.positionRWS = rws.xyz;
|
||||
|
||||
#endif // #if 1
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 317af98a1c897dd46b2d3839bc92aaa5
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
269
Runtime/Shaders/Includes/ShaderPass/ShaderPassForward.hlsl
Normal file
269
Runtime/Shaders/Includes/ShaderPass/ShaderPassForward.hlsl
Normal file
@@ -0,0 +1,269 @@
|
||||
#if SHADERPASS != SHADERPASS_FORWARD
|
||||
#error SHADERPASS_is_not_correctly_define
|
||||
#endif
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
return MotionVectorVS(varyingsType, inputMesh, inputPass);
|
||||
}
|
||||
|
||||
#ifdef TESSELLATION_ON
|
||||
|
||||
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
|
||||
{
|
||||
VaryingsToPS output;
|
||||
output.vmesh = VertMeshTesselation(input.vmesh);
|
||||
MotionVectorPositionZBias(output);
|
||||
|
||||
output.vpass.positionCS = input.vpass.positionCS;
|
||||
output.vpass.previousPositionCS = input.vpass.previousPositionCS;
|
||||
|
||||
return PackVaryingsToPS(output);
|
||||
}
|
||||
|
||||
#endif // TESSELLATION_ON
|
||||
|
||||
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
|
||||
#if defined(HAVE_RECURSIVE_RENDERING)
|
||||
// If we have a recursive raytrace object, we will not render it.
|
||||
// As we don't want to rely on renderqueue to exclude the object from the list,
|
||||
// we cull it by settings position to NaN value.
|
||||
// TODO: provide a solution to filter dyanmically recursive raytrace object in the DrawRenderer
|
||||
if (_EnableRecursiveRayTracing && _RayTracing > 0.0)
|
||||
{
|
||||
ZERO_INITIALIZE(VaryingsType, varyingsType); // Divide by 0 should produce a NaN and thus cull the primitive.
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
}
|
||||
|
||||
return PackVaryingsType(varyingsType);
|
||||
}
|
||||
|
||||
#ifdef TESSELLATION_ON
|
||||
|
||||
PackedVaryingsToPS VertTesselation(VaryingsToDS input)
|
||||
{
|
||||
VaryingsToPS output;
|
||||
output.vmesh = VertMeshTesselation(input.vmesh);
|
||||
|
||||
return PackVaryingsToPS(output);
|
||||
}
|
||||
|
||||
|
||||
#endif // TESSELLATION_ON
|
||||
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
|
||||
#ifdef TESSELLATION_ON
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
|
||||
#endif
|
||||
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
#define VT_BUFFER_TARGET SV_Target1
|
||||
#define EXTRA_BUFFER_TARGET SV_Target2
|
||||
#else
|
||||
#define EXTRA_BUFFER_TARGET SV_Target1
|
||||
#endif
|
||||
|
||||
void Frag(PackedVaryingsToPS packedInput,
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
out float4 outColor : SV_Target0, // outSpecularLighting
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
out float4 outVTFeedback : VT_BUFFER_TARGET,
|
||||
#endif
|
||||
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
|
||||
OUTPUT_SSSBUFFER(outSSSBuffer)
|
||||
#else
|
||||
out float4 outColor : SV_Target0
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
,out float4 outVTFeedback : VT_BUFFER_TARGET
|
||||
#endif
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#endif // OUTPUT_SPLIT_LIGHTING
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
, out float outputDepth : SV_Depth
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
|
||||
// It is init to the value of forceNoMotion (with 2.0)
|
||||
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
|
||||
#endif
|
||||
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
|
||||
FragInputs input = UnpackVaryingsToFragInputs(packedInput);
|
||||
|
||||
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
|
||||
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
|
||||
|
||||
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
|
||||
|
||||
// input.positionSS is SV_Position
|
||||
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
|
||||
|
||||
#ifdef VARYINGS_NEED_POSITION_WS
|
||||
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
|
||||
#else
|
||||
// Unused
|
||||
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
|
||||
#endif
|
||||
|
||||
SurfaceData surfaceData;
|
||||
BuiltinData builtinData;
|
||||
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
|
||||
|
||||
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
|
||||
|
||||
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
|
||||
|
||||
outColor = float4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
// We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.
|
||||
|
||||
#ifdef DEBUG_DISPLAY
|
||||
// Init in debug display mode to quiet warning
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
outDiffuseLighting = 0;
|
||||
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
|
||||
#endif
|
||||
float4 Set_UV0 = input.texCoord0;
|
||||
float4 _MainTex_var = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _MainTex));
|
||||
|
||||
surfaceData.baseColor = _MainTex_var.xyz;
|
||||
|
||||
// Same code in ShaderPassForwardUnlit.shader
|
||||
// Reminder: _DebugViewMaterialArray[i]
|
||||
// i==0 -> the size used in the buffer
|
||||
// i>0 -> the index used (0 value means nothing)
|
||||
// The index stored in this buffer could either be
|
||||
// - a gBufferIndex (always stored in _DebugViewMaterialArray[1] as only one supported)
|
||||
// - a property index which is different for each kind of material even if reflecting the same thing (see MaterialSharedProperty)
|
||||
bool viewMaterial = false;
|
||||
int bufferSize = _DebugViewMaterialArray[0].x;
|
||||
if (bufferSize != 0)
|
||||
{
|
||||
bool needLinearToSRGB = false;
|
||||
float3 result = float3(1.0, 0.0, 1.0);
|
||||
|
||||
// Loop through the whole buffer
|
||||
// Works because GetSurfaceDataDebug will do nothing if the index is not a known one
|
||||
for (int index = 1; index <= bufferSize; index++)
|
||||
{
|
||||
int indexMaterialProperty = _DebugViewMaterialArray[index].x;
|
||||
|
||||
// skip if not really in use
|
||||
if (indexMaterialProperty != 0)
|
||||
{
|
||||
viewMaterial = true;
|
||||
|
||||
GetPropertiesDataDebug(indexMaterialProperty, result, needLinearToSRGB);
|
||||
GetVaryingsDataDebug(indexMaterialProperty, input, result, needLinearToSRGB);
|
||||
GetBuiltinDataDebug(indexMaterialProperty, builtinData, posInput, result, needLinearToSRGB);
|
||||
GetSurfaceDataDebug(indexMaterialProperty, surfaceData, result, needLinearToSRGB);
|
||||
GetBSDFDataDebug(indexMaterialProperty, bsdfData, result, needLinearToSRGB);
|
||||
}
|
||||
}
|
||||
|
||||
// TEMP!
|
||||
// For now, the final blit in the backbuffer performs an sRGB write
|
||||
// So in the meantime we apply the inverse transform to linear data to compensate, unless we output to AOVs.
|
||||
if (!needLinearToSRGB && _DebugAOVOutput == 0)
|
||||
result = SRGBToLinear(max(0, result));
|
||||
|
||||
outColor = float4(result, 1.0);
|
||||
}
|
||||
|
||||
if (!viewMaterial)
|
||||
{
|
||||
if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR || _DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR)
|
||||
{
|
||||
float3 result = float3(0.0, 0.0, 0.0);
|
||||
|
||||
GetPBRValidatorDebug(surfaceData, result);
|
||||
|
||||
outColor = float4(result, 1.0f);
|
||||
}
|
||||
else if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW)
|
||||
{
|
||||
float4 result = _DebugTransparencyOverdrawWeight * float4(TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_A);
|
||||
outColor = result;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef _SURFACE_TYPE_TRANSPARENT
|
||||
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
|
||||
#else
|
||||
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
|
||||
#endif
|
||||
LightLoopOutput lightLoopOutput;
|
||||
LightLoop(V, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);
|
||||
|
||||
// Alias
|
||||
float3 diffuseLighting = lightLoopOutput.diffuseLighting;
|
||||
float3 specularLighting = lightLoopOutput.specularLighting;
|
||||
|
||||
diffuseLighting *= GetCurrentExposureMultiplier();
|
||||
specularLighting *= GetCurrentExposureMultiplier();
|
||||
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
if (_EnableSubsurfaceScattering != 0 && ShouldOutputSplitLighting(bsdfData))
|
||||
{
|
||||
outColor = float4(specularLighting, 1.0);
|
||||
outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
outColor = float4(diffuseLighting + specularLighting, 1.0);
|
||||
outDiffuseLighting = 0;
|
||||
}
|
||||
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
|
||||
#else
|
||||
outColor = ApplyBlendMode(diffuseLighting, specularLighting, builtinData.opacity);
|
||||
outColor = EvaluateAtmosphericScattering(posInput, V, outColor);
|
||||
#endif
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
VaryingsPassToPS inputPass = UnpackVaryingsPassToPS(packedInput.vpass);
|
||||
bool forceNoMotion = any(unity_MotionVectorsParams.yw == 0.0);
|
||||
// outMotionVec is already initialize at the value of forceNoMotion (see above)
|
||||
if (!forceNoMotion)
|
||||
{
|
||||
float2 motionVec = CalculateMotionVector(inputPass.positionCS, inputPass.previousPositionCS);
|
||||
EncodeMotionVector(motionVec * 0.5, outMotionVec);
|
||||
outMotionVec.zw = 1.0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DISPLAY
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e90380c2b26b694b99ad3d90989105b
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
785
Runtime/Shaders/Includes/ShaderPass/ShaderPassForwardUTS.hlsl
Normal file
785
Runtime/Shaders/Includes/ShaderPass/ShaderPassForwardUTS.hlsl
Normal file
@@ -0,0 +1,785 @@
|
||||
//Unity Toon Shader/HDRP
|
||||
//nobuyuki@unity3d.com
|
||||
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
||||
|
||||
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
|
||||
|
||||
#if SHADERPASS != SHADERPASS_FORWARD
|
||||
#error SHADERPASS_is_not_correctly_define
|
||||
#endif
|
||||
|
||||
#ifndef SCALARIZE_LIGHT_LOOP
|
||||
// We perform scalarization only for forward rendering as for deferred loads will already be scalar since tiles will match waves and therefore all threads will read from the same tile.
|
||||
// More info on scalarization: https://flashypixels.wordpress.com/2018/11/10/intro-to-gpu-scalarization-part-2-scalarize-all-the-lights/ .
|
||||
// Note that it is currently disabled on gamecore platforms for issues with wave intrinsics and the new compiler, it will be soon investigated, but we disable it in the meantime.
|
||||
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER) && !defined(SHADER_API_GAMECORE) && SHADERPASS == SHADERPASS_FORWARD)
|
||||
#endif
|
||||
|
||||
//#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
|
||||
#include "Packages/com.misaki.hdrp-toon/Runtime/HDRP/Shaders/Includes/Common/UtsCommon.hlsl"
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
return MotionVectorVS(varyingsType, inputMesh, inputPass);
|
||||
}
|
||||
|
||||
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
|
||||
return PackVaryingsType(varyingsType);
|
||||
}
|
||||
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Attenuation Functions /
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Grafted from URP
|
||||
// Matches Unity Vanila attenuation
|
||||
// Attenuation smoothly decreases to light range.
|
||||
float DistanceAttenuation(float distanceSqr, half2 distanceAttenuation)
|
||||
{
|
||||
// We use a shared distance attenuation for additional directional and puctual lights
|
||||
// for directional lights attenuation will be 1
|
||||
float lightAtten = rcp(distanceSqr);
|
||||
|
||||
#if SHADER_HINT_NICE_QUALITY
|
||||
// Use the smoothing factor also used in the Unity lightmapper.
|
||||
half factor = distanceSqr * distanceAttenuation.x;
|
||||
half smoothFactor = saturate(1.0h - factor * factor);
|
||||
smoothFactor = smoothFactor * smoothFactor;
|
||||
#else
|
||||
// We need to smoothly fade attenuation to light range. We start fading linearly at 80% of light range
|
||||
// Therefore:
|
||||
// fadeDistance = (0.8 * 0.8 * lightRangeSq)
|
||||
// smoothFactor = (lightRangeSqr - distanceSqr) / (lightRangeSqr - fadeDistance)
|
||||
// We can rewrite that to fit a MAD by doing
|
||||
// distanceSqr * (1.0 / (fadeDistanceSqr - lightRangeSqr)) + (-lightRangeSqr / (fadeDistanceSqr - lightRangeSqr)
|
||||
// distanceSqr * distanceAttenuation.y + distanceAttenuation.z
|
||||
half smoothFactor = saturate(distanceSqr * distanceAttenuation.x + distanceAttenuation.y);
|
||||
#endif
|
||||
|
||||
return lightAtten * smoothFactor;
|
||||
}
|
||||
|
||||
float ApplyChannelAlpha( float alpha)
|
||||
{
|
||||
return lerp(1.0, alpha, _ComposerMaskMode);
|
||||
}
|
||||
|
||||
|
||||
bool UtsUseScreenSpaceShadow(DirectionalLightData light, float3 normalWS)
|
||||
{
|
||||
#if defined(RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG)
|
||||
// Two different options are possible here
|
||||
// - We have a ray trace shadow in which case we have no valid signal for a transmission and we need to fallback on the rasterized shadow
|
||||
// - We have a screen space shadow and it already contains the transmission shadow and we can use it straight away
|
||||
bool visibleLight = 0.5 * dot(normalWS, -light.forward) + 0.5 > 0.0;
|
||||
bool validScreenSpaceShadow = (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW;
|
||||
bool rayTracedShadow = (light.screenSpaceShadowIndex & RAY_TRACED_SCREEN_SPACE_SHADOW_FLAG) != 0.0;
|
||||
return (validScreenSpaceShadow && ((rayTracedShadow && visibleLight) || !rayTracedShadow));
|
||||
#else
|
||||
return ( (light.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
#define VT_BUFFER_TARGET SV_Target1
|
||||
#define EXTRA_BUFFER_TARGET SV_Target2
|
||||
#else
|
||||
#define EXTRA_BUFFER_TARGET SV_Target1
|
||||
#endif
|
||||
|
||||
uniform sampler2D _RaytracedHardShadow;
|
||||
float4 _RaytracedHardShadow_TexelSize;
|
||||
|
||||
|
||||
|
||||
void Frag(PackedVaryingsToPS packedInput,
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
out float4 outColor : SV_Target0, // outSpecularLighting
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
out float4 outVTFeedback : VT_BUFFER_TARGET,
|
||||
#endif
|
||||
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
|
||||
OUTPUT_SSSBUFFER(outSSSBuffer)
|
||||
#else
|
||||
out float4 outColor : SV_Target0
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
,out float4 outVTFeedback : VT_BUFFER_TARGET
|
||||
#endif
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#endif // OUTPUT_SPLIT_LIGHTING
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
, out float outputDepth : SV_Depth
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
|
||||
// It is init to the value of forceNoMotion (with 2.0)
|
||||
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
|
||||
#endif
|
||||
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
|
||||
|
||||
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
|
||||
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
|
||||
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
|
||||
input.primitiveID = packedInput.primitiveID;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
|
||||
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
|
||||
#endif
|
||||
|
||||
float4 Set_UV0 = input.texCoord0;
|
||||
UTSData utsData;
|
||||
|
||||
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
|
||||
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
|
||||
|
||||
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
|
||||
|
||||
// input.positionSS is SV_Position
|
||||
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
|
||||
|
||||
|
||||
#ifdef VARYINGS_NEED_POSITION_WS
|
||||
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
|
||||
|
||||
#ifdef _MATERIAL_TYPE_EYE
|
||||
// Must have view Dir to work
|
||||
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
|
||||
float2 parallaxOffset = viewT;
|
||||
parallaxOffset.y = -parallaxOffset.y;
|
||||
Set_UV0.xy = clamp(Set_UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Unused
|
||||
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
|
||||
#endif
|
||||
#ifdef _SURFACE_TYPE_TRANSPARENT
|
||||
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
|
||||
#else
|
||||
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
|
||||
#endif
|
||||
SurfaceData surfaceData; // used to get normalWS;
|
||||
BuiltinData builtinData; // used to get lightlayersAndSoOn
|
||||
GetSurfaceAndBuiltinData(input, V, posInput, surfaceData, builtinData);
|
||||
|
||||
outColor = float4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
float3x3 tangentTransform = input.tangentToWorld;
|
||||
float4 _MainTex_var = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
|
||||
float4 normalLocal = 0;
|
||||
if (_Use_SSSLut)
|
||||
{
|
||||
normalLocal = SAMPLE_TEXTURE2D_LOD(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap), _SSSIntensity);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalLocal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
|
||||
}
|
||||
normalLocal.rgb = UnpackNormalScale(normalLocal, _NormalScale);
|
||||
float3 _NormalMap_var = normalize(mul(normalLocal.rgb, tangentTransform));
|
||||
|
||||
float smoothness = _Smoothness;
|
||||
float coatRoughness = 1;
|
||||
float metallic = _Metallic;
|
||||
float ao = 1.0;
|
||||
float3 specularColor = 0;
|
||||
|
||||
#ifdef _MASKMAP
|
||||
float4 _MaskMap_var = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
|
||||
metallic = _MaskMap_var.x;
|
||||
metallic = lerp(_MetallicRemapMin, _MetallicRemapMax, metallic);
|
||||
ao = _MaskMap_var.y;
|
||||
ao = lerp(_AORemapMin, _AORemapMax, ao);
|
||||
smoothness = _MaskMap_var.w;
|
||||
smoothness = lerp(_SmoothnessRemapMin, _SmoothnessRemapMax, smoothness);
|
||||
#endif
|
||||
|
||||
#ifdef _ANISOTROPYMAP
|
||||
surfaceData.anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, TRANSFORM_TEX(Set_UV0, _AnisotropyMap)).r;
|
||||
#if _PBR_Mode_KK
|
||||
surfaceData.anisotropy += ADD_IDX(_Anisotropy) - 0.5;
|
||||
#else
|
||||
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
|
||||
#endif
|
||||
#else
|
||||
surfaceData.anisotropy = 1.0;
|
||||
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
|
||||
#endif
|
||||
|
||||
#ifdef _PBR_Mode_KK
|
||||
metallic = 0.0;
|
||||
coatRoughness = 1 - smoothness;
|
||||
smoothness *=_BSDFContribution;
|
||||
#endif
|
||||
|
||||
#ifdef _PBR_Mode_TOON
|
||||
float3 _SpecTex_var = 1;
|
||||
#ifdef _SPECULARCOLORMAP
|
||||
_SpecTex_var = SAMPLE_TEXTURE2D(_SpecularColorMap, sampler_SpecularColorMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap)).rgb;
|
||||
#endif
|
||||
specularColor = _SpecTex_var * _SpecularColor;
|
||||
#else
|
||||
specularColor = GetSpecularColor(_MainTex_var.rgb * _BaseColor.rgb, metallic);
|
||||
#endif
|
||||
|
||||
surfaceData.baseColor = _MainTex_var.rgb;
|
||||
surfaceData.coatMask = _MainTex_var.a;
|
||||
surfaceData.metallic = metallic;
|
||||
surfaceData.ambientOcclusion = ao;
|
||||
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(dot(_NormalMap_var, V), ao, PerceptualRoughnessToRoughness(1 - smoothness));
|
||||
surfaceData.perceptualSmoothness = smoothness;
|
||||
surfaceData.normalWS = _NormalMap_var;
|
||||
surfaceData.specularColor = specularColor;
|
||||
|
||||
float perceptualRoughness = 1 - surfaceData.perceptualSmoothness;
|
||||
float3 tangentDir = Orthonormalize(tangentTransform[0].rgb, surfaceData.normalWS);
|
||||
float3 bitangentDir = normalize(cross(surfaceData.normalWS, tangentDir));
|
||||
|
||||
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData); // used to calc shadow
|
||||
bsdfData.coatRoughness = coatRoughness;
|
||||
bsdfData.normalWS = surfaceData.normalWS;
|
||||
bsdfData.ambientOcclusion = surfaceData.ambientOcclusion;
|
||||
bsdfData.specularOcclusion = surfaceData.specularOcclusion;
|
||||
bsdfData.perceptualRoughness = perceptualRoughness;
|
||||
bsdfData.anisotropy = surfaceData.anisotropy;
|
||||
bsdfData.tangentWS = tangentDir;
|
||||
bsdfData.bitangentWS = bitangentDir;
|
||||
|
||||
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData); // used to calc shadow
|
||||
|
||||
UTSAggregateLighting utsAggregateLighting;
|
||||
ZERO_INITIALIZE(UTSAggregateLighting, utsAggregateLighting);
|
||||
|
||||
UTSLightData customMainLight;
|
||||
customMainLight.shadowValue = 1.0f;
|
||||
//UTSLightData mainPunctualLight;
|
||||
//mainPunctualLight.lightColor = float3(0, 0, 0);
|
||||
|
||||
#define UNITY_PROJ_COORD(a) a
|
||||
#define UNITY_SAMPLE_SCREEN_SHADOW(tex, uv) tex2Dproj( tex, UNITY_PROJ_COORD(uv) ).r
|
||||
float inverseClipping = 0.0;
|
||||
LightLoopContext context;
|
||||
context.shadowContext = InitShadowContext();
|
||||
context.shadowValue = 1;
|
||||
context.sampleReflection = 0.0;
|
||||
#if UNITY_VERSION >= 202120 && UNITY_VERSION < 202320
|
||||
context.splineVisibility = -1;
|
||||
#endif
|
||||
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
|
||||
context.positionWS = posInput.positionWS;
|
||||
#endif
|
||||
|
||||
// With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix).
|
||||
// This is required because there is only one list of lights generated on the CPU. Shadows are also generated once and shared between the instanced views.
|
||||
ApplyCameraRelativeXR(posInput.positionWS);
|
||||
|
||||
// Initialize the contactShadow and contactShadowFade fields
|
||||
InitContactShadow(posInput, context);
|
||||
|
||||
float3 i_normalDir = surfaceData.normalWS;
|
||||
|
||||
int mainLightIndex = -1;
|
||||
float channelAlpha = 0.0f;
|
||||
float3 finalColor = float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
|
||||
{
|
||||
// because of light culling or light layer, we can not adopt this
|
||||
// https://unity.slack.com/archives/C06V7HDDW/p1580959470180800
|
||||
// int mainLightIndex = _DirectionalShadowIndex;
|
||||
mainLightIndex = GetUtsMainLightIndex(builtinData);
|
||||
DirectionalLightData lightData;
|
||||
ZERO_INITIALIZE(DirectionalLightData, lightData);
|
||||
if (mainLightIndex >= 0)
|
||||
{
|
||||
lightData = _DirectionalLightDatas[mainLightIndex];
|
||||
}
|
||||
|
||||
float3 lightColor = ApplyCurrentExposureMultiplier(lightData.color);
|
||||
float3 lightDirection = -lightData.forward;
|
||||
|
||||
#ifndef LIGHT_EVALUATION_NO_COOKIE
|
||||
if (lightData.cookieMode != COOKIEMODE_NONE)
|
||||
{
|
||||
float3 lightToSample = input.positionRWS - lightData.positionRWS;
|
||||
lightColor *= EvaluateCookie_Directional(context, lightData, lightToSample);
|
||||
}
|
||||
#endif
|
||||
|
||||
UTSLightData utsLightData;
|
||||
utsLightData.lightDirection = lightDirection;
|
||||
utsLightData.lightColor = lightColor;
|
||||
utsLightData.diffuseDimmer = lightData.diffuseDimmer;
|
||||
utsLightData.specularDimmer = lightData.specularDimmer;
|
||||
utsLightData.shadowTint = lightData.shadowTint;
|
||||
utsLightData.penumbraTint = lightData.penumbraTint;
|
||||
|
||||
customMainLight = utsLightData;
|
||||
|
||||
// Evaluate sun shadows.
|
||||
if (_DirectionalShadowIndex >= 0)
|
||||
{
|
||||
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
|
||||
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT) && !defined(UTS_USE_RAYTRACING_SHADOW)
|
||||
if (UtsUseScreenSpaceShadow(light, bsdfData.normalWS))
|
||||
{
|
||||
// HDRP Contact Shadow
|
||||
context.shadowValue = GetScreenSpaceColorShadow(posInput, light.screenSpaceShadowIndex).SHADOW_TYPE_SWIZZLE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// TODO: this will cause us to load from the normal buffer first. Does this cause a performance problem?
|
||||
float3 L = -light.forward;
|
||||
|
||||
// Is it worth sampling the shadow map?
|
||||
if ((light.lightDimmer > 0) && (light.shadowDimmer > 0) && // Note: Volumetric can have different dimmer, thus why we test it here
|
||||
IsNonZeroBSDF(V, L, preLightData, bsdfData) &&
|
||||
!ShouldEvaluateThickObjectTransmission(V, L, preLightData, bsdfData, light.shadowIndex))
|
||||
{
|
||||
|
||||
#if defined(UTS_USE_RAYTRACING_SHADOW)
|
||||
{
|
||||
/*
|
||||
struct PositionInputs
|
||||
{
|
||||
float3 positionWS; // World space position (could be camera-relative)
|
||||
float2 positionNDC; // Normalized screen coordinates within the viewport : [0, 1) (with the half-pixel offset)
|
||||
uint2 positionSS; // Screen space pixel coordinates : [0, NumPixels)
|
||||
uint2 tileCoord; // Screen tile coordinates : [0, NumTiles)
|
||||
float deviceDepth; // Depth from the depth buffer : [0, 1] (typically reversed)
|
||||
float linearDepth; // View space Z coordinate : [Near, Far]
|
||||
};
|
||||
float4 size = _RaytracedHardShadow_TexelSize;
|
||||
*/
|
||||
|
||||
float r = UNITY_SAMPLE_SCREEN_SHADOW(_RaytracedHardShadow, float4(posInput.positionNDC.xy, lightDirection * _ShadowBias, 1));
|
||||
context.shadowValue = r;
|
||||
}
|
||||
#else
|
||||
{
|
||||
context.shadowValue = GetDirectionalShadowAttenuation(context.shadowContext,
|
||||
posInput.positionSS, posInput.positionWS + lightDirection * _ShadowBias, GetNormalForShadowBias(bsdfData),
|
||||
light.shadowIndex, L);
|
||||
|
||||
}
|
||||
#endif // UTS_USE_RAYTRACING_SHADOW
|
||||
|
||||
|
||||
}
|
||||
#if defined (UTS_USE_RAYTRACING_SHADOW)
|
||||
else
|
||||
{
|
||||
float r = UNITY_SAMPLE_SCREEN_SHADOW(_RaytracedHardShadow, float4(posInput.positionNDC.xy, lightDirection * _ShadowBias, 1));
|
||||
context.shadowValue = r;
|
||||
}
|
||||
#endif // UTS_USE_RAYTRACING_SHADOW
|
||||
}
|
||||
|
||||
context.shadowValue = lerp(1, context.shadowValue, lightData.shadowDimmer);
|
||||
customMainLight.shadowValue = context.shadowValue;
|
||||
}
|
||||
|
||||
#if defined(UTS_DEBUG_SELFSHADOW)
|
||||
if (_DirectionalShadowIndex >= 0)
|
||||
finalColor = UTS_SelfShdowMainLight(context, input, _DirectionalShadowIndex);
|
||||
#else
|
||||
UTS_MainLight(context, input, utsLightData, surfaceData, bsdfData, inverseClipping, channelAlpha, utsData, utsAggregateLighting);
|
||||
#endif
|
||||
|
||||
|
||||
int i = 0; // Declare once to avoid the D3D11 compiler warning.
|
||||
for (i = 0; i < (int) _DirectionalLightCount; ++i)
|
||||
{
|
||||
if (IsMatchingLightLayer(_DirectionalLightDatas[i].lightLayers, builtinData.renderingLayers))
|
||||
{
|
||||
if (mainLightIndex != i)
|
||||
{
|
||||
float notDirectional = 0.0f;
|
||||
UTSLightData utsLightData;
|
||||
utsLightData.lightColor = ApplyCurrentExposureMultiplier(_DirectionalLightDatas[i].color);
|
||||
utsLightData.lightDirection = -_DirectionalLightDatas[i].forward;
|
||||
utsLightData.diffuseDimmer = _DirectionalLightDatas[i].diffuseDimmer;
|
||||
utsLightData.specularDimmer = _DirectionalLightDatas[i].specularDimmer;
|
||||
utsLightData.shadowTint = _DirectionalLightDatas[i].shadowTint;
|
||||
utsLightData.penumbraTint = _DirectionalLightDatas[i].penumbraTint;
|
||||
|
||||
#if defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#else
|
||||
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, 0, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//#undef EVALUATE_BSDF_ENV
|
||||
//#undef EVALUATE_BSDF_ENV_SKY
|
||||
|
||||
if (featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
|
||||
{
|
||||
uint lightCount, lightStart;
|
||||
|
||||
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
||||
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
|
||||
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
||||
lightCount = _PunctualLightCount;
|
||||
lightStart = 0;
|
||||
#endif
|
||||
bool fastPath = false;
|
||||
#if SCALARIZE_LIGHT_LOOP
|
||||
uint lightStartLane0;
|
||||
fastPath = IsFastPath(lightStart, lightStartLane0);
|
||||
|
||||
if (fastPath)
|
||||
{
|
||||
lightStart = lightStartLane0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Scalarized loop. All lights that are in a tile/cluster touched by any pixel in the wave are loaded (scalar load), only the one relevant to current thread/pixel are processed.
|
||||
// For clarity, the following code will follow the convention: variables starting with s_ are meant to be wave uniform (meant for scalar register),
|
||||
// v_ are variables that might have different value for each thread in the wave (meant for vector registers).
|
||||
// This will perform more loads than it is supposed to, however, the benefits should offset the downside, especially given that light data accessed should be largely coherent.
|
||||
// Note that the above is valid only if wave intriniscs are supported.
|
||||
|
||||
uint v_lightListOffset = 0;
|
||||
uint v_lightIdx = lightStart;
|
||||
[loop] // vulkan shader compiler can not unroll.
|
||||
while (v_lightListOffset < lightCount)
|
||||
{
|
||||
v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
|
||||
#if SCALARIZE_LIGHT_LOOP
|
||||
uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
|
||||
#else
|
||||
uint s_lightIdx = v_lightIdx;
|
||||
#endif
|
||||
if (s_lightIdx == -1)
|
||||
break;
|
||||
|
||||
LightData s_lightData = FetchLight(s_lightIdx);
|
||||
|
||||
// If current scalar and vector light index match, we process the light. The v_lightListOffset for current thread is increased.
|
||||
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
|
||||
// end up with a unique v_lightIdx value that is smaller than s_lightIdx hence being stuck in a loop. All the active lanes will not have this problem.
|
||||
if (s_lightIdx >= v_lightIdx)
|
||||
{
|
||||
v_lightListOffset++;
|
||||
if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
|
||||
{
|
||||
float3 lightDirection;
|
||||
float4 distances; // {d, d^2, 1/d, d_proj}
|
||||
GetPunctualLightVectors(posInput.positionWS, s_lightData, lightDirection, distances);
|
||||
float4 lightColor = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirection, distances);
|
||||
float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb);
|
||||
const float notDirectional = 1.0f;
|
||||
|
||||
UTSLightData utsLightData;
|
||||
utsLightData.lightColor = additionalLightColor;
|
||||
utsLightData.lightDirection = lightDirection;
|
||||
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer * lightColor.a;
|
||||
utsLightData.specularDimmer = s_lightData.specularDimmer * lightColor.a;
|
||||
utsLightData.shadowTint = s_lightData.shadowTint;
|
||||
utsLightData.penumbraTint = s_lightData.penumbraTint;
|
||||
|
||||
#if defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#else
|
||||
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
|
||||
context.shadowValue = EvaluateShadow_Punctual(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), lightDirection, distances);
|
||||
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
|
||||
|
||||
if (length(utsLightData.lightColor) >= length(customMainLight.lightColor))
|
||||
{
|
||||
float3 lightDirectionToObject;
|
||||
float4 distancesToObject; // {d, d^2, 1/d, d_proj}
|
||||
float3 objectCenter = (TransformObjectToWorld(float3(0, 0, 0)));
|
||||
GetPunctualLightVectors(objectCenter, s_lightData, lightDirectionToObject, distancesToObject);
|
||||
float4 lightColorToObject = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirectionToObject, distancesToObject);
|
||||
float3 additionalLightColorToObject = ApplyCurrentExposureMultiplier(lightColorToObject.rgb) * lightColorToObject.a;
|
||||
|
||||
customMainLight = utsLightData;
|
||||
customMainLight.lightColor = additionalLightColorToObject;
|
||||
customMainLight.lightDirection = lightDirectionToObject;
|
||||
customMainLight.shadowValue = context.shadowValue;
|
||||
}
|
||||
|
||||
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//v.2.0.7
|
||||
|
||||
#if SHADEROPTIONS_AREA_LIGHTS
|
||||
if (featureFlags & LIGHTFEATUREFLAGS_AREA)
|
||||
{
|
||||
uint lightCount, lightStart;
|
||||
|
||||
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
||||
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, lightStart, lightCount);
|
||||
#else
|
||||
lightCount = _AreaLightCount;
|
||||
lightStart = _PunctualLightCount;
|
||||
#endif
|
||||
|
||||
if (lightCount > 0)
|
||||
{
|
||||
uint i = 0;
|
||||
uint last = lightCount - 1;
|
||||
LightData s_lightData = FetchLight(lightStart, i);
|
||||
|
||||
[loop] // vulkan shader compiler can not unroll.
|
||||
while (i <= last)
|
||||
{
|
||||
if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
|
||||
{
|
||||
float3 lightDirection = -s_lightData.forward;
|
||||
float3 areaLightColor = ApplyCurrentExposureMultiplier(s_lightData.color.rgb);
|
||||
const float notDirectional = 1.0f;
|
||||
|
||||
UTSLightData utsLightData;
|
||||
utsLightData.lightColor = areaLightColor;
|
||||
utsLightData.lightDirection = lightDirection;
|
||||
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer;
|
||||
utsLightData.specularDimmer = s_lightData.specularDimmer;
|
||||
utsLightData.shadowTint = s_lightData.shadowTint;
|
||||
utsLightData.penumbraTint = s_lightData.penumbraTint;
|
||||
|
||||
bool isRectLight = s_lightData.lightType == GPULIGHTTYPE_RECTANGLE;
|
||||
|
||||
float3 unL = s_lightData.positionRWS - posInput.positionWS;
|
||||
utsLightData.lightDirection = normalize(unL);
|
||||
float3 center = mul(preLightData.orthoBasisViewNormal, unL);
|
||||
float3 right = mul(preLightData.orthoBasisViewNormal, s_lightData.right);
|
||||
float3 up = mul(preLightData.orthoBasisViewNormal, s_lightData.up);
|
||||
|
||||
float halfWidth = s_lightData.size.x * 0.5;
|
||||
float halfHeight = s_lightData.size.y * 0.5;
|
||||
|
||||
float intensity = PillowWindowing(unL, s_lightData.right, s_lightData.up, halfWidth, halfHeight, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
|
||||
|
||||
// Make sure the light is front-facing (and has a non-zero effective area).
|
||||
intensity *= (isRectLight && dot(unL, s_lightData.forward) >= 0) ? 0 : 1;
|
||||
|
||||
float4 ltcValue;
|
||||
|
||||
// Diffuse
|
||||
ltcValue = UTS_EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformDiffuse), /*bsdfData.perceptualRoughness*/ 1.0f,
|
||||
true, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
|
||||
utsLightData.diffuseDimmer *= ltcValue.a * intensity;
|
||||
utsLightData.lightColor *= ltcValue.rgb;
|
||||
|
||||
// Specular
|
||||
ltcValue = UTS_EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformSpecular[0]), bsdfData.perceptualRoughness,
|
||||
false, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
|
||||
utsLightData.specularDimmer *= ltcValue.a * intensity;
|
||||
|
||||
if (isRectLight)
|
||||
{
|
||||
//Evaluate the shadow part
|
||||
float shadow;
|
||||
posInput.positionWS = posInput.positionWS + utsLightData.lightDirection * _ShadowBias;
|
||||
context.shadowValue = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
|
||||
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
|
||||
}
|
||||
|
||||
#if defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#else
|
||||
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
s_lightData = FetchLight(lightStart, min(++i, last));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SHADEROPTIONS_AREA_LIGHTS
|
||||
|
||||
#ifdef _EMISSIVE_SIMPLE
|
||||
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(Set_UV0, _Emissive_Tex));
|
||||
float emissiveMask = _Emissive_Tex_var.a;
|
||||
emissive = _Emissive_Tex_var.rgb * _Emissive_Color.rgb * emissiveMask;
|
||||
#elif _EMISSIVE_ANIMATION
|
||||
//v.2.0.7 Calculation View Coord UV for Scroll
|
||||
float3 viewNormal_Emissive = (mul(UNITY_MATRIX_V, float4(i_normalDir, 0))).xyz;
|
||||
float3 NormalBlend_Emissive_Detail = viewNormal_Emissive * float3(-1, -1, 1);
|
||||
float3 NormalBlend_Emissive_Base = (mul(UNITY_MATRIX_V, float4(utsData.viewDirection, 0)).xyz * float3(-1, -1, 1)) + float3(0, 0, 1);
|
||||
float3 noSknewViewNormal_Emissive = NormalBlend_Emissive_Base * dot(NormalBlend_Emissive_Base, NormalBlend_Emissive_Detail) / NormalBlend_Emissive_Base.z - NormalBlend_Emissive_Detail;
|
||||
float2 _ViewNormalAsEmissiveUV = noSknewViewNormal_Emissive.xy * 0.5 + 0.5;
|
||||
float2 _ViewCoord_UV = RotateUV(_ViewNormalAsEmissiveUV, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
|
||||
//Invert if it's "inside the mirror".
|
||||
if (utsData.signMirror < 0) {
|
||||
_ViewCoord_UV.x = 1 - _ViewCoord_UV.x;
|
||||
}
|
||||
else {
|
||||
_ViewCoord_UV = _ViewCoord_UV;
|
||||
}
|
||||
float2 emissive_uv = lerp(Set_UV0, _ViewCoord_UV, _Is_ViewCoord_Scroll);
|
||||
//
|
||||
float4 _time_var = _Time;
|
||||
float _base_Speed_var = (_time_var.g * _Base_Speed);
|
||||
float _Is_PingPong_Base_var = lerp(_base_Speed_var, sin(_base_Speed_var), _Is_PingPong_Base);
|
||||
float2 scrolledUV = emissive_uv + float2(_Scroll_EmissiveU, _Scroll_EmissiveV) * _Is_PingPong_Base_var;
|
||||
float rotateVelocity = _Rotate_EmissiveUV * 3.141592654;
|
||||
float2 _rotate_EmissiveUV_var = RotateUV(scrolledUV, rotateVelocity, float2(0.5, 0.5), _Is_PingPong_Base_var);
|
||||
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(Set_UV0, _Emissive_Tex));
|
||||
float emissiveMask = _Emissive_Tex_var.a;
|
||||
_Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(_rotate_EmissiveUV_var, _Emissive_Tex));
|
||||
float _colorShift_Speed_var = 1.0 - cos(_time_var.g * _ColorShift_Speed);
|
||||
float viewShift_var = smoothstep(0.0, 1.0, max(0, dot(utsData.normalDirection, utsData.viewDirection)));
|
||||
float4 colorShift_Color = lerp(_Emissive_Color, lerp(_Emissive_Color, _ColorShift, _colorShift_Speed_var), _Is_ColorShift);
|
||||
float4 viewShift_Color = lerp(_ViewShift, colorShift_Color, viewShift_var);
|
||||
float4 emissive_Color = lerp(colorShift_Color, viewShift_Color, _Is_ViewShift);
|
||||
emissive = emissive_Color.rgb * _Emissive_Tex_var.rgb * emissiveMask;
|
||||
|
||||
//
|
||||
//v.2.0.6: GI_Intensity with Intensity Multiplier Filter
|
||||
#endif
|
||||
|
||||
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation
|
||||
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
|
||||
|
||||
#if _SDFShadow || (_RECEIVE_HAIR_SHADOW && ENABLE_UTS_HAIR_SHAOW)
|
||||
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
|
||||
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
|
||||
|
||||
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
|
||||
float3 lightDirection = normalize(lerp(defaultLightDirection, customMainLight.lightDirection.xyz, any(customMainLight.lightDirection.xyz)));
|
||||
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
|
||||
float3 originalLightColor = customMainLight.lightColor.rgb;
|
||||
|
||||
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
|
||||
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
|
||||
|
||||
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(Set_UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
|
||||
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);
|
||||
|
||||
float systemShadowValue = lerp(1.0f, saturate(customMainLight.shadowValue * 2.0f), _Set_SystemShadowsToBase);
|
||||
#endif
|
||||
|
||||
#ifdef _SDFShadow
|
||||
// modified by Suomi @ 20230902 - SDFResult is used to sample SDF texture on the correct side
|
||||
|
||||
float angle;
|
||||
bool rightside;
|
||||
float2 SDF_UV = TRANSFORM_TEX(Set_UV0, _BaseColorMap);
|
||||
float4 sdfRes = SDFResult(rightside, angle, customMainLight.lightDirection, SDF_UV);
|
||||
float sdfShadowValue = 1.0f - SDFMask(angle, sdfRes.r);
|
||||
|
||||
utsAggregateLighting.directDiffuse = lerp(_1st_Shade_var, bsdfData.diffuseColor * _BaseColor.rgb * lightColor, sdfShadowValue * systemShadowValue);
|
||||
utsAggregateLighting.directSpecular = lerp(0, utsAggregateLighting.directSpecular, sdfShadowValue * systemShadowValue);
|
||||
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
|
||||
#endif
|
||||
|
||||
#if _RECEIVE_HAIR_SHADOW && ENABLE_UTS_HAIR_SHAOW
|
||||
// Push the face fragment view space position towards the light for a little bit
|
||||
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
|
||||
|
||||
float3 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
|
||||
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
|
||||
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
|
||||
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
|
||||
|
||||
float3 camDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
|
||||
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y);
|
||||
shadowLength.y *= camDirFactor;
|
||||
|
||||
float2 samplingPoint = (input.positionSS.xy + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2 (1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
|
||||
|
||||
// Then sample the hair buffer, to see if the fragment lands in shadow.
|
||||
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
|
||||
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
|
||||
float depthCorrect = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
|
||||
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
|
||||
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
|
||||
|
||||
utsAggregateLighting.directDiffuse = lerp(utsAggregateLighting.directDiffuse, _1st_Shade_var, hairShadow * systemShadowValue);
|
||||
utsAggregateLighting.directSpecular = lerp(utsAggregateLighting.directSpecular, 0, hairShadow * systemShadowValue);
|
||||
#endif
|
||||
|
||||
// Ambient
|
||||
utsAggregateLighting.indirectDiffuse = EvaluateIndirectDiffuse(posInput, bsdfData, V) * _ID_Intensity;
|
||||
utsAggregateLighting.indirectSpecular = EvaluateIndirectSpecular(context, posInput, preLightData, bsdfData, surfaceData, builtinData, V) * _IR_Intensity;
|
||||
|
||||
float3 finalColorWoEmissive = AccumulateUTSAggregateLighting(utsAggregateLighting);
|
||||
|
||||
finalColorWoEmissive = GetExposureAdjustedColor(finalColorWoEmissive);
|
||||
finalColorWoEmissive = ApplyCompensation(finalColorWoEmissive);
|
||||
|
||||
finalColor = finalColorWoEmissive + emissive;
|
||||
|
||||
#ifdef _IS_TRANSCLIPPING_OFF
|
||||
|
||||
outColor = float4(finalColor, 1 * ApplyChannelAlpha(channelAlpha));
|
||||
|
||||
#elif _IS_TRANSCLIPPING_ON
|
||||
|
||||
float Set_Opacity = saturate((inverseClipping + _Tweak_transparency));
|
||||
|
||||
outColor = EvaluateAtmosphericScattering(posInput, V, float4(finalColor, 1));
|
||||
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
|
||||
#endif
|
||||
|
||||
#if _MATERIAL_TYPE_FRONT_HAIR && ENABLE_UTS_HAIR_BLENDING
|
||||
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
|
||||
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
|
||||
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
|
||||
#endif
|
||||
|
||||
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
|
||||
outColor.rgb = 1;
|
||||
#ifdef UTS_DEBUG_SELFSHADOW
|
||||
outColor.rgb = min(finalColor, outColor.rgb);
|
||||
#endif
|
||||
|
||||
#ifdef UTS_DEBUG_SHADOWMAP
|
||||
#ifdef UTS_DEBUG_SHADOWMAP_BINALIZATION
|
||||
outColor.rgb = min(context.shadowValue < 0.9f ? clamp(context.shadowValue - 0.2, 0.0, 0.9) : 1.0f, outColor.rgb);
|
||||
#else
|
||||
outColor.rgb = min(context.shadowValue, outColor.rgb);
|
||||
#endif
|
||||
#endif // ifdef UTS_DEBUG_SHADOWMAP
|
||||
#endif // defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
|
||||
//outColor.rgb = customMainLight.shadowValue;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d797988f43f630944b3b0de4c7cfab37
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
314
Runtime/Shaders/Includes/ShaderPass/UtsShaderPassForward.hlsl
Normal file
314
Runtime/Shaders/Includes/ShaderPass/UtsShaderPassForward.hlsl
Normal file
@@ -0,0 +1,314 @@
|
||||
//Unity Toon Shader/HDRP
|
||||
//nobuyuki@unity3d.com
|
||||
//toshiyuki@unity3d.com (Universal RP/HDRP)
|
||||
|
||||
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
|
||||
|
||||
#if SHADERPASS != SHADERPASS_FORWARD
|
||||
#error SHADERPASS_is_not_correctly_define
|
||||
#endif
|
||||
|
||||
#ifndef SCALARIZE_LIGHT_LOOP
|
||||
// We perform scalarization only for forward rendering as for deferred loads will already be scalar since tiles will match waves and therefore all threads will read from the same tile.
|
||||
// More info on scalarization: https://flashypixels.wordpress.com/2018/11/10/intro-to-gpu-scalarization-part-2-scalarize-all-the-lights/ .
|
||||
// Note that it is currently disabled on gamecore platforms for issues with wave intrinsics and the new compiler, it will be soon investigated, but we disable it in the meantime.
|
||||
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER) && !defined(SHADER_API_GAMECORE) && SHADERPASS == SHADERPASS_FORWARD)
|
||||
#endif
|
||||
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
return MotionVectorVS(varyingsType, inputMesh, inputPass);
|
||||
}
|
||||
|
||||
#else // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"
|
||||
|
||||
PackedVaryingsType Vert(AttributesMesh inputMesh)
|
||||
{
|
||||
VaryingsType varyingsType;
|
||||
varyingsType.vmesh = VertMesh(inputMesh);
|
||||
|
||||
return PackVaryingsType(varyingsType);
|
||||
}
|
||||
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
|
||||
float ApplyChannelAlpha( float alpha)
|
||||
{
|
||||
return lerp(1.0, alpha, _ComposerMaskMode);
|
||||
}
|
||||
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
#define VT_BUFFER_TARGET SV_Target1
|
||||
#define EXTRA_BUFFER_TARGET SV_Target2
|
||||
#else
|
||||
#define EXTRA_BUFFER_TARGET SV_Target1
|
||||
#endif
|
||||
|
||||
void Frag(PackedVaryingsToPS packedInput,
|
||||
#ifdef OUTPUT_SPLIT_LIGHTING
|
||||
out float4 outColor : SV_Target0, // outSpecularLighting
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
out float4 outVTFeedback : VT_BUFFER_TARGET,
|
||||
#endif
|
||||
out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,
|
||||
OUTPUT_SSSBUFFER(outSSSBuffer)
|
||||
#else
|
||||
out float4 outColor : SV_Target0
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
,out float4 outVTFeedback : VT_BUFFER_TARGET
|
||||
#endif
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
|
||||
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
#endif // OUTPUT_SPLIT_LIGHTING
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
, out float outputDepth : SV_Depth
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
|
||||
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
|
||||
// It is init to the value of forceNoMotion (with 2.0)
|
||||
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
|
||||
#endif
|
||||
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
|
||||
|
||||
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
|
||||
#if defined(PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER) && SHADER_STAGE_FRAGMENT
|
||||
#if (defined(VARYINGS_NEED_PRIMITIVEID) || (SHADERPASS == SHADERPASS_FULL_SCREEN_DEBUG))
|
||||
input.primitiveID = packedInput.primitiveID;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(VARYINGS_NEED_CULLFACE) && SHADER_STAGE_FRAGMENT
|
||||
input.isFrontFace = IS_FRONT_VFACE(packedInput.cullFace, true, false);
|
||||
#endif
|
||||
|
||||
float4 UV0 = input.texCoord0;
|
||||
UTSData utsData;
|
||||
|
||||
// We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.
|
||||
input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;
|
||||
|
||||
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
|
||||
|
||||
// input.positionSS is SV_Position
|
||||
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
|
||||
|
||||
|
||||
#ifdef VARYINGS_NEED_POSITION_WS
|
||||
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
|
||||
|
||||
#ifdef MATERIAL_TYPE_EYE
|
||||
// Must have view Dir to work
|
||||
float2 viewT = TransformObjectToTangent(V, input.tangentToWorld);
|
||||
float2 parallaxOffset = viewT;
|
||||
parallaxOffset.y = -parallaxOffset.y;
|
||||
UV0.xy = clamp(UV0.xy -_EyeParallaxAmount * parallaxOffset, 0, 1);
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Unused
|
||||
float3 V = float3(1.0, 1.0, 1.0); // Avoid the division by 0
|
||||
#endif
|
||||
#ifdef _SURFACE_TYPE_TRANSPARENT
|
||||
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
|
||||
#else
|
||||
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
|
||||
#endif
|
||||
|
||||
SurfaceData tempSurfaceData;
|
||||
BuiltinData builtinData;
|
||||
GetSurfaceAndBuiltinData(input, V, posInput, tempSurfaceData, builtinData);
|
||||
UTSSurfaceData surfaceData = GetUTSSurfaceData(input, V);
|
||||
UtsBSDFData bsdfData = ConvertUTSSurfaceDataToUTSBSDFData(surfaceData);
|
||||
|
||||
#define UNITY_PROJ_COORD(a) a
|
||||
#define UNITY_SAMPLE_SCREEN_SHADOW(tex, uv) tex2Dproj( tex, UNITY_PROJ_COORD(uv) ).r
|
||||
float inverseClipping = 0.0;
|
||||
LightLoopContext context;
|
||||
context.shadowContext = InitShadowContext();
|
||||
context.shadowValue = 1;
|
||||
context.sampleReflection = 0.0;
|
||||
#if UNITY_VERSION >= 202120 && UNITY_VERSION < 202320
|
||||
context.splineVisibility = -1;
|
||||
#endif
|
||||
#ifdef APPLY_FOG_ON_SKY_REFLECTIONS
|
||||
context.positionWS = posInput.positionWS;
|
||||
#endif
|
||||
|
||||
// With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix).
|
||||
// This is required because there is only one list of lights generated on the CPU. Shadows are also generated once and shared between the instanced views.
|
||||
ApplyCameraRelativeXR(posInput.positionWS);
|
||||
|
||||
// Initialize the contactShadow and contactShadowFade fields
|
||||
InitContactShadow(posInput, context);
|
||||
|
||||
float channelAlpha = 0.0f;
|
||||
|
||||
LightLoopOutput lightLoopOutput;
|
||||
ZERO_INITIALIZE(LightLoopOutput, lightLoopOutput);
|
||||
|
||||
UtsLightLoop(input, posInput, bsdfData, builtinData, V, featureFlags, lightLoopOutput);
|
||||
|
||||
/*
|
||||
#ifdef _EMISSIVE_SIMPLE
|
||||
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
|
||||
float emissiveMask = _Emissive_Tex_var.a;
|
||||
emissive = _Emissive_Tex_var.rgb * _Emissive_Color.rgb * emissiveMask;
|
||||
#elif _EMISSIVE_ANIMATION
|
||||
//v.2.0.7 Calculation View Coord UV for Scroll
|
||||
float3 viewNormal_Emissive = (mul(UNITY_MATRIX_V, float4(i_normalDir, 0))).xyz;
|
||||
float3 NormalBlend_Emissive_Detail = viewNormal_Emissive * float3(-1, -1, 1);
|
||||
float3 NormalBlend_Emissive_Base = (mul(UNITY_MATRIX_V, float4(utsData.viewDirection, 0)).xyz * float3(-1, -1, 1)) + float3(0, 0, 1);
|
||||
float3 noSknewViewNormal_Emissive = NormalBlend_Emissive_Base * dot(NormalBlend_Emissive_Base, NormalBlend_Emissive_Detail) / NormalBlend_Emissive_Base.z - NormalBlend_Emissive_Detail;
|
||||
float2 _ViewNormalAsEmissiveUV = noSknewViewNormal_Emissive.xy * 0.5 + 0.5;
|
||||
float2 _ViewCoord_UV = RotateUV(_ViewNormalAsEmissiveUV, -(utsData.cameraDir * utsData.cameraRoll), float2(0.5, 0.5), 1.0);
|
||||
//Invert if it's "inside the mirror".
|
||||
if (utsData.signMirror < 0) {
|
||||
_ViewCoord_UV.x = 1 - _ViewCoord_UV.x;
|
||||
}
|
||||
else {
|
||||
_ViewCoord_UV = _ViewCoord_UV;
|
||||
}
|
||||
float2 emissive_uv = lerp(UV0, _ViewCoord_UV, _Is_ViewCoord_Scroll);
|
||||
//
|
||||
float4 _time_var = _Time;
|
||||
float _base_Speed_var = (_time_var.g * _Base_Speed);
|
||||
float _Is_PingPong_Base_var = lerp(_base_Speed_var, sin(_base_Speed_var), _Is_PingPong_Base);
|
||||
float2 scrolledUV = emissive_uv + float2(_Scroll_EmissiveU, _Scroll_EmissiveV) * _Is_PingPong_Base_var;
|
||||
float rotateVelocity = _Rotate_EmissiveUV * 3.141592654;
|
||||
float2 _rotate_EmissiveUV_var = RotateUV(scrolledUV, rotateVelocity, float2(0.5, 0.5), _Is_PingPong_Base_var);
|
||||
float4 _Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(UV0, _Emissive_Tex));
|
||||
float emissiveMask = _Emissive_Tex_var.a;
|
||||
_Emissive_Tex_var = tex2D(_Emissive_Tex, TRANSFORM_TEX(_rotate_EmissiveUV_var, _Emissive_Tex));
|
||||
float _colorShift_Speed_var = 1.0 - cos(_time_var.g * _ColorShift_Speed);
|
||||
float viewShift_var = smoothstep(0.0, 1.0, max(0, dot(utsData.normalDirection, utsData.viewDirection)));
|
||||
float4 colorShift_Color = lerp(_Emissive_Color, lerp(_Emissive_Color, _ColorShift, _colorShift_Speed_var), _Is_ColorShift);
|
||||
float4 viewShift_Color = lerp(_ViewShift, colorShift_Color, viewShift_var);
|
||||
float4 emissive_Color = lerp(colorShift_Color, viewShift_Color, _Is_ViewShift);
|
||||
emissive = emissive_Color.rgb * _Emissive_Tex_var.rgb * emissiveMask;
|
||||
|
||||
//
|
||||
//v.2.0.6: GI_Intensity with Intensity Multiplier Filter
|
||||
#endif
|
||||
*/
|
||||
|
||||
// We directly calculate custome main light during the light loop in upper code to avoid extra calculation
|
||||
//customMainLight = GetCustomMainLightData(builtinData, mainPunctualLight);
|
||||
|
||||
/*
|
||||
#if _SHADOW_MODE_SDF || (_RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW)
|
||||
float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
|
||||
float3 defaultLightColor = saturate(max(float3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(float4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(float4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
|
||||
|
||||
float3 customLightDirection = normalize(mul(UNITY_MATRIX_M, float4(((float3(1.0, 0.0, 0.0) * _Offset_X_Axis_BLD * 10) + (float3(0.0, 1.0, 0.0) * _Offset_Y_Axis_BLD * 10) + (float3(0.0, 0.0, -1.0) * lerp(-1.0, 1.0, _Inverse_Z_Axis_BLD))), 0)).xyz);
|
||||
float3 lightDirection = normalize(lerp(defaultLightDirection, customMainLight.lightDirection.xyz, any(customMainLight.lightDirection.xyz)));
|
||||
lightDirection = lerp(lightDirection, customLightDirection, _Is_BLD);
|
||||
float3 originalLightColor = customMainLight.lightColor.rgb;
|
||||
|
||||
originalLightColor = lerp(originalLightColor, clamp(originalLightColor, ConvertFromEV100(_ToonEvAdjustmentValueMin ), ConvertFromEV100(_ToonEvAdjustmentValueMax)), _ToonEvAdjustmentCurve) * _Light_Intensity_Multiplier;
|
||||
float3 lightColor = lerp(max(defaultLightColor, originalLightColor), max(defaultLightColor, saturate(originalLightColor)), max(_Is_Filter_LightColor, _ToonLightHiCutFilter));
|
||||
|
||||
float4 _1st_ShadeMap_var = lerp(SAMPLE_TEXTURE2D(_1st_ShadeMap, sampler_BaseColorMap,TRANSFORM_TEX(UV0, _1st_ShadeMap)), _MainTex_var, _Use_BaseAs1st);
|
||||
float3 _1st_Shade_var = lerp((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb), ((_1st_ShadeMap_var.rgb * _1st_ShadeColor.rgb) * lightColor), _Is_LightColor_1st_Shade);
|
||||
|
||||
float systemShadowValue = lerp(1.0f, saturate(customMainLight.shadowValue * 2.0f), _Set_SystemShadowsToBase);
|
||||
#endif
|
||||
|
||||
#if _SHADOW_MODE_SDF
|
||||
// modified by Suomi @ 20230902 - SDFResult is used to sample SDF texture on the correct side
|
||||
|
||||
float angle;
|
||||
bool rightside;
|
||||
float2 SDF_UV = TRANSFORM_TEX(UV0, _BaseColorMap);
|
||||
float4 sdfRes = SDFResult(rightside, angle, customMainLight.lightDirection, SDF_UV);
|
||||
float sdfShadowValue = 1.0f - SDFMask(angle, sdfRes.r);
|
||||
|
||||
utsAggregateLighting.directDiffuse = lerp(_1st_Shade_var, bsdfData.diffuseColor * _BaseColor.rgb * lightColor, sdfShadowValue * systemShadowValue);
|
||||
utsAggregateLighting.directSpecular = lerp(0, utsAggregateLighting.directSpecular, sdfShadowValue * systemShadowValue);
|
||||
utsAggregateLighting.directSpecular += _SDFNoseHighlightCoef * SDFNoseHighlight(angle, sdfRes.g, rightside, SDF_UV) * lightColor;
|
||||
#endif
|
||||
|
||||
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
|
||||
// Push the face fragment view space position towards the light for a little bit
|
||||
float hairShadowOpacity = saturate(Remap(length(posInput.positionWS), float2(_HairShadowFadeOutDistance, _HairShadowFadeInDistance), float2(0, 1)));
|
||||
|
||||
float3 viewLightDir = TransformWorldToViewDir(customMainLight.lightDirection); // / posInput.deviceDepth; when linearDepth grows large, the movement amount should be lower since we are getting further from the face.
|
||||
float3 cameraDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
|
||||
float shadowLengthY = _HairShadowDistance * 5.0 * max(0.5, posInput.linearDepth * _HairShadowDistanceScaleFactor) / posInput.linearDepth;
|
||||
float2 shadowLength = float2(shadowLengthY * 2.0f, shadowLengthY);
|
||||
|
||||
float3 camDirOS = normalize(TransformWorldToObject(GetCameraPositionWS()));
|
||||
float camDirFactor = 1 - smoothstep(0.1, 0.9, camDirOS.y);
|
||||
shadowLength.y *= camDirFactor;
|
||||
|
||||
float2 samplingPoint = (input.positionSS.xy + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2 (1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
|
||||
|
||||
// Then sample the hair buffer, to see if the fragment lands in shadow.
|
||||
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
|
||||
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
|
||||
float depthCorrect = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
|
||||
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.
|
||||
float hairShadow = lerp(0,hairShadowOpacity,depthCorrect);
|
||||
|
||||
utsAggregateLighting.directDiffuse = lerp(utsAggregateLighting.directDiffuse, _1st_Shade_var, hairShadow * systemShadowValue);
|
||||
utsAggregateLighting.directSpecular = lerp(utsAggregateLighting.directSpecular, 0, hairShadow * systemShadowValue);
|
||||
#endif
|
||||
*/
|
||||
//outColor.rgb = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
|
||||
//outColor.a = 1.0;
|
||||
//return;
|
||||
|
||||
float3 finalColor = lightLoopOutput.diffuseLighting + lightLoopOutput.specularLighting;
|
||||
|
||||
#ifdef _IS_TRANSCLIPPING_OFF
|
||||
|
||||
outColor = float4(finalColor, 1 * ApplyChannelAlpha(channelAlpha));
|
||||
|
||||
#elif _IS_TRANSCLIPPING_ON
|
||||
|
||||
float Set_Opacity = saturate((inverseClipping + _Tweak_transparency));
|
||||
|
||||
outColor = EvaluateAtmosphericScattering(posInput, V, float4(finalColor, 1));
|
||||
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
|
||||
#endif
|
||||
|
||||
#if MATERIAL_TYPE_FRONT_HAIR && ENABLE_UTS_HAIR_BLENDING
|
||||
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
|
||||
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
|
||||
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);
|
||||
#endif
|
||||
|
||||
#if UTS_DEBUG_SHADOWMAP || UTS_DEBUG_SELFSHADOW
|
||||
outColor.rgb = 1;
|
||||
#ifdef UTS_DEBUG_SELFSHADOW
|
||||
outColor.rgb = min(finalColor, outColor.rgb);
|
||||
#endif
|
||||
|
||||
#ifdef UTS_DEBUG_SHADOWMAP
|
||||
#ifdef UTS_DEBUG_SHADOWMAP_BINALIZATION
|
||||
outColor.rgb = min(context.shadowValue < 0.9f ? clamp(context.shadowValue - 0.2, 0.0, 0.9) : 1.0f, outColor.rgb);
|
||||
#else
|
||||
outColor.rgb = min(context.shadowValue, outColor.rgb);
|
||||
#endif
|
||||
#endif // ifdef UTS_DEBUG_SHADOWMAP
|
||||
#endif // defined(UTS_DEBUG_SHADOWMAP) || defined(UTS_DEBUG_SELFSHADOW)
|
||||
|
||||
#ifdef _DEPTHOFFSET_ON
|
||||
outputDepth = posInput.deviceDepth;
|
||||
#endif
|
||||
#ifdef UNITY_VIRTUAL_TEXTURING
|
||||
|
||||
outVTFeedback = builtinData.vtPackedFeedback;
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16998e89414639d48a07506456d69e1d
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user