258 lines
9.1 KiB
HLSL
258 lines
9.1 KiB
HLSL
// #if defined(LOD_FADE_CROSSFADE)
|
|
// #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl"
|
|
// #endif
|
|
|
|
// Structs
|
|
struct Attributes
|
|
{
|
|
float3 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
float4 tangentOS : TANGENT;
|
|
float2 texcoord : TEXCOORD0;
|
|
float2 dynamicLightmapUV : TEXCOORD1;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float2 uv : TEXCOORD0;
|
|
float3 positionWS : TEXCOORD1;
|
|
|
|
half3 normalWS : TEXCOORD2;
|
|
|
|
half4 tangentWS : TEXCOORD3;
|
|
|
|
#ifdef _ADDITIONAL_LIGHTS_VERTEX
|
|
half4 fogFactorAndVertexLight : TEXCOORD4;
|
|
#else
|
|
half fogFactor : TEXCOORD4;
|
|
#endif
|
|
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
|
float4 shadowCoord : TEXCOORD5;
|
|
#endif
|
|
DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 6);
|
|
|
|
float2 dynamicLightmapUV : TEXCOORD7;
|
|
|
|
float4 positionCS : SV_POSITION;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
//--------------------------------------
|
|
// Vertex 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);
|
|
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
|
|
|
|
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
|
|
half fogFactor = 0.0;
|
|
//#if !defined(_FOG_FRAGMENT)
|
|
fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
|
|
//#endif
|
|
|
|
output.uv = input.texcoord;
|
|
// already normalized from normal transform to WS.
|
|
output.normalWS = normalInput.normalWS;
|
|
|
|
real sign = input.tangentOS.w * GetOddNegativeScale();
|
|
output.tangentWS = float4(normalInput.tangentWS.xyz, sign);
|
|
|
|
|
|
output.dynamicLightmapUV = input.dynamicLightmapUV.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
|
|
|
|
OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
|
|
|
|
#ifdef _ADDITIONAL_LIGHTS_VERTEX
|
|
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
|
|
#else
|
|
output.fogFactor = fogFactor;
|
|
#endif
|
|
|
|
output.positionWS = vertexInput.positionWS;
|
|
|
|
|
|
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
|
|
// tweak the sampling position
|
|
vertexInput.positionWS += output.normalWS.xyz * _SkinShadowSamplingBias;
|
|
output.shadowCoord = GetShadowCoord(vertexInput);
|
|
#endif
|
|
output.positionCS = vertexInput.positionCS;
|
|
|
|
return output;
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Fragment shader and functions
|
|
|
|
inline void InitializeSurfaceData(float2 uv, out SurfaceData outSurfaceData, out AdditionalSurfaceData outAdditionalSurfaceData)
|
|
{
|
|
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)) * _BaseColor * _BaseColor.a;
|
|
#if defined(_ALPHATEST_ON)
|
|
outSurfaceData.alpha = Alpha(albedoAlpha.a, 1, _Cutoff);
|
|
#else
|
|
outSurfaceData.alpha = 1;
|
|
#endif
|
|
outSurfaceData.albedo = albedoAlpha.rgb;
|
|
//outSurfaceData.metallic = half(0.0);
|
|
outSurfaceData.specular = _SpecularColor;
|
|
|
|
/* #if defined(_NORMALMAPDIFFUSE)
|
|
half4 sampleNormalDiffuse = SAMPLE_TEXTURE2D_BIAS(_BumpMap, sampler_BumpMap, uv, _Bias);
|
|
// Do not manually unpack the normal map as it might use RGB.
|
|
outAdditionalSurfaceData.diffuseNormalTS = UnpackNormal(sampleNormalDiffuse);
|
|
#else
|
|
outAdditionalSurfaceData.diffuseNormalTS = half3(0,0,1);
|
|
#endif */
|
|
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);
|
|
//outAdditionalSurfaceData.diffuseNormalTS = half3(0,0,1);
|
|
|
|
|
|
half4 SSSAOSample = SAMPLE_TEXTURE2D(_SSSAOMap, sampler_SSSAOMap, uv);
|
|
outAdditionalSurfaceData.translucency = 1.0;
|
|
outAdditionalSurfaceData.skinMask = SSSAOSample.r;
|
|
outSurfaceData.occlusion = lerp(half(1.0), SSSAOSample.a, _OcclusionStrength);
|
|
outAdditionalSurfaceData.curvature = half(1.0);
|
|
|
|
outSurfaceData.smoothness = SSSAOSample.b * _Smoothness;
|
|
outSurfaceData.emission = half(0.0);
|
|
|
|
outSurfaceData.clearCoatMask = half(0.0);
|
|
outSurfaceData.clearCoatSmoothness = half(0.0);
|
|
|
|
outSurfaceData.metallic = SSSAOSample.g * _Metallic;
|
|
|
|
}
|
|
|
|
void InitializeInputData(Varyings input, half3 normalTS, half facing, out InputData inputData)
|
|
{
|
|
inputData = (InputData)0;
|
|
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
|
|
inputData.positionWS = input.positionWS;
|
|
#endif
|
|
|
|
half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
|
|
normalTS.z *= facing;
|
|
float sgn = input.tangentWS.w; // should be either +1 or -1
|
|
float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
|
|
half3x3 ToW = half3x3(input.tangentWS.xyz, bitangent, input.normalWS.xyz);
|
|
inputData.normalWS = TransformTangentToWorld(normalTS, ToW);
|
|
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 + input.normalWS * _SkinShadowSamplingBias);
|
|
#else
|
|
inputData.shadowCoord = float4(0, 0, 0, 0);
|
|
#endif
|
|
|
|
#ifdef _ADDITIONAL_LIGHTS_VERTEX
|
|
inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactorAndVertexLight.x);
|
|
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
|
|
#else
|
|
inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactor);
|
|
#endif
|
|
|
|
#if defined(DYNAMICLIGHTMAP_ON)
|
|
inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS);
|
|
//inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, diffuseNormalWS);
|
|
#else
|
|
inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS);
|
|
//inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, diffuseNormalWS);
|
|
#endif
|
|
|
|
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
|
|
inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);
|
|
|
|
#if defined(DEBUG_DISPLAY)
|
|
inputData.dynamicLightmapUV = input.dynamicLightmapUV;
|
|
inputData.vertexSH = input.vertexSH;
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
//half4 LitPassFragment(Varyings input) : SV_Target
|
|
//{
|
|
void LitPassFragment(
|
|
Varyings input, half facing : VFACE
|
|
, out half4 outColor : SV_Target0
|
|
/* #ifdef _WRITE_RENDERING_LAYERS
|
|
, out float4 outRenderingLayers : SV_Target1
|
|
#endif */
|
|
)
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
|
|
#ifdef LOD_FADE_CROSSFADE
|
|
LODFadeCrossFade(input.positionCS);
|
|
#endif
|
|
|
|
// Get the surface description
|
|
SurfaceData surfaceData;
|
|
AdditionalSurfaceData additionalSurfaceData;
|
|
|
|
InitializeSurfaceData(input.uv.xy, surfaceData, additionalSurfaceData);
|
|
|
|
// Prepare surface data (like bring normal into world space and get missing inputs like gi
|
|
/* half3 diffuseNormalWS; */
|
|
InputData inputData;
|
|
|
|
InitializeInputData(input, surfaceData.normalTS, facing, inputData);
|
|
|
|
// Apply lighting
|
|
half4 SkinColor = URPSkinFragmentPBR(
|
|
inputData,
|
|
surfaceData,
|
|
// Subsurface Scattering
|
|
half4(_TranslucencyStrength * additionalSurfaceData.translucency, _TranslucencyPower, _ShadowStrength, _Distortion),
|
|
// AmbientReflection Strength
|
|
_AmbientReflectionStrength,
|
|
// Diffuse Normal
|
|
// #if defined(_NORMALMAP) && defined(_NORMALMAPDIFFUSE)
|
|
// NormalizeNormalPerPixel( TransformTangentToWorld(surfaceData.diffuseNormalTS, half3x3(input.tangentWS.xyz, bitangent, input.normalWS.xyz)) )
|
|
// #else
|
|
// input.normalWS
|
|
// #endif
|
|
_SubsurfaceColor.rgb,
|
|
(_SampleCurvature) ? additionalSurfaceData.curvature * _Curvature : lerp(additionalSurfaceData.translucency, 1.0, _Curvature),
|
|
additionalSurfaceData.skinMask,
|
|
_MaskByShadowStrength,
|
|
_Backscatter
|
|
);
|
|
|
|
// Apply Cloth Lighting
|
|
half4 ClothColor = LuxURPClothFragmentPBR(
|
|
inputData,
|
|
surfaceData,
|
|
//sheen
|
|
input.tangentWS.xyz,
|
|
_Anisotropy,
|
|
//scatter
|
|
half4(0,0,0,0),
|
|
_clothSpecIntensity
|
|
);
|
|
|
|
// Add fog
|
|
SkinColor.rgb = MixFog(SkinColor.rgb, inputData.fogCoord);
|
|
|
|
outColor = lerp(ClothColor, SkinColor, additionalSurfaceData.skinMask);
|
|
//outColor = float4(inputData.normalWS, 1);
|
|
|
|
/* #ifdef _WRITE_RENDERING_LAYERS
|
|
uint renderingLayers = GetMeshRenderingLayer();
|
|
outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);
|
|
#endif */
|
|
} |