// #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 */ }