#ifndef LIGHTWEIGHT_LIT_INPUT_INCLUDED #define LIGHTWEIGHT_LIT_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" // Extended CBUFFER CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; half4 _BaseColor; half4 _SpecColor; half4 _EmissionColor; half _Cutoff; half _Smoothness; half _Metallic; half _BumpScale; half _OcclusionStrength; half4 _RimColor; half _RimPower; half _RimMinPower; half _RimFrequency; half _RimPerPositionFrequency; #if defined(_UBER) half _Parallax; half _ScreenSpaceVariance; half _SAAThreshold; half _GItoAO; half _GItoAOBias; half _HorizonOcclusion; float _CameraFadeDist; float _CameraShadowFadeDist; float4 _DetailAlbedoMap_ST; half _DetailAlbedoMapScale; half _DetailNormalMapScale; #endif float _Surface; CBUFFER_END TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap); TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap); TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); TEXTURE2D(_BentNormalMap); SAMPLER(sampler_BentNormalMap); #if defined(_PARALLAX) || defined(_PARALLAXSHADOWS) TEXTURE2D(_HeightMap); SAMPLER(sampler_HeightMap); #endif #if defined(_DETAIL) TEXTURE2D(_DetailMask); SAMPLER(sampler_DetailMask); TEXTURE2D(_DetailAlbedoMap); SAMPLER(sampler_DetailAlbedoMap); TEXTURE2D(_DetailNormalMap); SAMPLER(sampler_DetailNormalMap); #endif #ifdef _SPECULAR_SETUP #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv) #else #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv) #endif // Used by shadow caster and depth pass (parallax only) struct VertexInput { float3 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct VertexOutput { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 normalWS : TEXCOORD1; #if defined(_ALPHATEST_ON) // We have to use the same inputs... float4 tangentWS : TEXCOORD2; float screenPos : TEXCOORD3; // was float4 #endif float3 viewDirWS : TEXCOORD5; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) { half4 specGloss; #ifdef _METALLICSPECGLOSSMAP specGloss = SAMPLE_METALLICSPECULAR(uv); #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A specGloss.a = albedoAlpha * _Smoothness; #else specGloss.a *= _Smoothness; #endif #else // _METALLICSPECGLOSSMAP #if _SPECULAR_SETUP specGloss.rgb = _SpecColor.rgb; #else specGloss.rgb = _Metallic.rrr; #endif #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A specGloss.a = albedoAlpha * _Smoothness; #else specGloss.a = _Smoothness; #endif #endif return specGloss; } half SampleOcclusion(float2 uv) { #ifdef _OCCLUSIONMAP // TODO: Controls things like these by exposing SHADER_QUALITY levels (low, medium, high) #if defined(SHADER_API_GLES) return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; #else half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; return LerpWhiteTo(occ, _OcclusionStrength); #endif #else return 1.0; #endif } half3 SampleNormalExtended(float2 uv, TEXTURE2D_PARAM(bumpMap, sampler_bumpMap), half scale = 1.0h) { #if defined (_NORMALMAP) || defined (_BENTNORMAL) half4 n = SAMPLE_TEXTURE2D(bumpMap, sampler_bumpMap, uv); #if BUMP_SCALE_NOT_SUPPORTED return UnpackNormal(n); #else return UnpackNormalScale(n, scale); #endif #else return half3(0.0h, 0.0h, 1.0h); #endif } float Dither17(float2 Pos, float frameIndexMod4) { uint3 k0 = uint3(2, 7, 23); float Ret = dot( float3(Pos.xy, frameIndexMod4 + 0.5f), k0 / 17.0f); return frac(Ret); } float Dither32(float2 Pos, float frameIndexMod4) { uint3 k0 = uint3(13, 5, 15); //float Ret = dot( float3(Pos.xy, frameIndexMod4 + 0.5f), k0 / 32.0f); float Ret = dot( float3(Pos.xy, 0.5f), k0 / 32.0f); return frac(Ret); } float Dither64(float2 Pos, float frameIndexMod4) { uint3 k0 = uint3(33, 52, 25); //float Ret = dot( float3(Pos.xy, frameIndexMod4 + 0.5f), k0 / 32.0f); float Ret = dot( float3(Pos.xy, 1.0f), k0 / 64.0f); return frac(Ret); } float Dither5(float2 Pos, float frameIndexMod4) { float Dither = frac((Pos.x + Pos.y * 2 - 1.5 + frameIndexMod4) / 5 ); float Noise = frac( dot( float2(171.0f, 231.0f) / 71, Pos.xy) ); Dither = (Dither * 5 + Noise) * (1.0 / 6.0) - 0.5; return Dither; } inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData) { half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff); half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a); outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb; #if _SPECULAR_SETUP outSurfaceData.metallic = 1.0h; outSurfaceData.specular = specGloss.rgb; #else outSurfaceData.metallic = specGloss.r; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); #endif outSurfaceData.smoothness = specGloss.a; outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale); outSurfaceData.occlusion = SampleOcclusion(uv); outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); outSurfaceData.clearCoatMask = 0; outSurfaceData.clearCoatSmoothness = 0; } #if defined(_UBER) inline void InitializeStandardLitSurfaceDataUber(float2 uv, half3 viewDirTS, out SurfaceData outSurfaceData) { #if defined(_PARALLAX) // Parallax float3 v = viewDirTS; v.z += 0.42; v.xy /= v.z; float halfParallax = _Parallax * 0.5f; float parallax = SAMPLE_TEXTURE2D(_HeightMap, sampler_HeightMap, uv).g * _Parallax - halfParallax; float2 offset1 = parallax * v.xy; // Calculate 2nd height parallax = SAMPLE_TEXTURE2D(_HeightMap, sampler_HeightMap, uv + offset1).g * _Parallax - halfParallax; float2 offset2 = parallax * v.xy; // Final UVs uv += (offset1 + offset2) * 0.5f; #endif // Default stuff half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff); half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a); outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb; #if _SPECULAR_SETUP outSurfaceData.metallic = 1.0h; outSurfaceData.specular = specGloss.rgb; #else outSurfaceData.metallic = specGloss.r; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); #endif outSurfaceData.smoothness = specGloss.a; #if defined(_SAMPLENORMAL) outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale); #else outSurfaceData.normalTS = half3(0,0,1); #endif outSurfaceData.occlusion = SampleOcclusion(uv); #if defined (_EMISSION) outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); #else outSurfaceData.emission = 0; #endif // Detail Texturing #if defined(_DETAIL) half detailMask = SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, uv).a; float2 detailUV = uv * _DetailAlbedoMap_ST.xy + _DetailAlbedoMap_ST.zw; half3 detailAlbedo = SAMPLE_TEXTURE2D(_DetailAlbedoMap, sampler_DetailAlbedoMap, detailUV).rgb; detailAlbedo = 2.0h * detailAlbedo * _DetailAlbedoMapScale - _DetailAlbedoMapScale + 1.0h; outSurfaceData.albedo *= lerp(half3(1,1,1), detailAlbedo, detailMask.xxx); #if BUMP_SCALE_NOT_SUPPORTED half3 detailNormalTS = UnpackNormal(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUV)); #else half3 detailNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUV), _DetailNormalMapScale); #endif // With UNITY_NO_DXT5nm unpacked vector is not normalized for BlendNormalRNM // For visual consistancy we going to do in all cases detailNormalTS = normalize(detailNormalTS); outSurfaceData.normalTS = lerp(outSurfaceData.normalTS, BlendNormalRNM(outSurfaceData.normalTS, detailNormalTS), detailMask); #endif outSurfaceData.clearCoatMask = 0; outSurfaceData.clearCoatSmoothness = 0; } #endif #endif // LIGHTWEIGHT_INPUT_SURFACE_PBR_INCLUDED