289 lines
12 KiB
HLSL
289 lines
12 KiB
HLSL
#ifndef UNIVERSAL_LIT_INPUT_INCLUDED
|
|
#define UNIVERSAL_LIT_INPUT_INCLUDED
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
|
|
|
|
#if defined(_DETAIL_MULX2) || defined(_DETAIL_SCALED)
|
|
#define _DETAIL
|
|
#endif
|
|
|
|
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
|
|
CBUFFER_START(UnityPerMaterial)
|
|
float4 _BaseMap_ST;
|
|
float4 _DetailMap_ST;
|
|
half4 _BaseColor;
|
|
half4 _SpecColor;
|
|
half4 _EmissionColor;
|
|
half _Cutoff;
|
|
half _Smoothness;
|
|
half _Metallic;
|
|
half _BumpScale;
|
|
//half _Parallax;
|
|
//half _OcclusionStrength;
|
|
half _ClearCoatMask;
|
|
half _ClearCoatSmoothness;
|
|
half _DetailAlbedoMapScale;
|
|
half _DetailNormalMapScale;
|
|
half _DetailSmoothnessMapScale;
|
|
half _Surface;
|
|
CBUFFER_END
|
|
|
|
// NOTE: Do not ifdef the properties for dots instancing, but ifdef the actual usage.
|
|
// Otherwise you might break CPU-side as property constant-buffer offsets change per variant.
|
|
// NOTE: Dots instancing is orthogonal to the constant buffer above.
|
|
#ifdef UNITY_DOTS_INSTANCING_ENABLED
|
|
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
|
|
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
|
|
UNITY_DOTS_INSTANCED_PROP(float4, _SpecColor)
|
|
UNITY_DOTS_INSTANCED_PROP(float4, _EmissionColor)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _Smoothness)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _Metallic)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _BumpScale)
|
|
// UNITY_DOTS_INSTANCED_PROP(float , _Parallax)
|
|
// UNITY_DOTS_INSTANCED_PROP(float , _OcclusionStrength)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatMask)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatSmoothness)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _DetailAlbedoMapScale)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _DetailNormalMapScale)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _DetailSmoothnessMapScale)
|
|
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
|
|
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
|
|
|
|
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata_BaseColor)
|
|
#define _SpecColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata_SpecColor)
|
|
#define _EmissionColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata_EmissionColor)
|
|
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Cutoff)
|
|
#define _Smoothness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Smoothness)
|
|
#define _Metallic UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Metallic)
|
|
#define _BumpScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_BumpScale)
|
|
//#define _Parallax UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Parallax)
|
|
//#define _OcclusionStrength UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_OcclusionStrength)
|
|
#define _ClearCoatMask UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_ClearCoatMask)
|
|
#define _ClearCoatSmoothness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_ClearCoatSmoothness)
|
|
#define _DetailAlbedoMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_DetailAlbedoMapScale)
|
|
#define _DetailNormalMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_DetailNormalMapScale)
|
|
#define _DetailNormalMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_DetailSmoothnessMapScale)
|
|
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Surface)
|
|
#endif
|
|
//Converting Detail maps to HDRP's packing because of URP's TEXTURE2D bloat exceeding 16 samplers when using volumetrics and preventing compiling. Seriously, it's 2022, ditch specular workflow and optimze the packing.
|
|
//https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@10.2/manual/Mask-Map-and-Detail-Map.html
|
|
|
|
//TEXTURE2D(_ParallaxMap); SAMPLER(sampler_ParallaxMap);
|
|
//TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap);
|
|
//TEXTURE2D(_DetailMask); SAMPLER(sampler_DetailMask);
|
|
TEXTURE2D(_DetailMap); SAMPLER(sampler_DetailMap); //renamed
|
|
//TEXTURE2D(_DetailNormalMap); SAMPLER(sampler_DetailNormalMap);
|
|
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
|
|
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
|
|
TEXTURE2D(_ClearCoatMap); SAMPLER(sampler_ClearCoatMap);
|
|
|
|
#ifdef _SPECULAR_SETUP
|
|
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv)
|
|
#else
|
|
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv)
|
|
#endif
|
|
|
|
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)
|
|
{
|
|
half4 specGloss;
|
|
|
|
#ifdef _METALLICSPECGLOSSMAP
|
|
specGloss = half4(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.r = _Metallic;
|
|
specGloss.gb = 1;
|
|
#endif
|
|
|
|
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
|
|
specGloss.a = albedoAlpha * _Smoothness;
|
|
#else
|
|
specGloss.a = _Smoothness;
|
|
#endif
|
|
#endif
|
|
|
|
return specGloss;
|
|
}
|
|
|
|
half SampleOcclusion(float2 uv)
|
|
{
|
|
//Using Packed AO instead
|
|
// #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 half(1.0);
|
|
//#endif
|
|
}
|
|
|
|
|
|
// Returns clear coat parameters
|
|
// .x/.r == mask
|
|
// .y/.g == smoothness
|
|
half2 SampleClearCoat(float2 uv)
|
|
{
|
|
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
|
|
half2 clearCoatMaskSmoothness = half2(_ClearCoatMask, _ClearCoatSmoothness);
|
|
|
|
#if defined(_CLEARCOATMAP)
|
|
clearCoatMaskSmoothness *= SAMPLE_TEXTURE2D(_ClearCoatMap, sampler_ClearCoatMap, uv).rg;
|
|
#endif
|
|
|
|
return clearCoatMaskSmoothness;
|
|
#else
|
|
return half2(0.0, 1.0);
|
|
#endif // _CLEARCOAT
|
|
}
|
|
|
|
void ApplyPerPixelDisplacement(half3 viewDirTS, inout float2 uv)
|
|
{
|
|
// #if defined(_PARALLAXMAP)
|
|
// uv += ParallaxMapping(TEXTURE2D_ARGS(_ParallaxMap, sampler_ParallaxMap), viewDirTS, _Parallax, uv);
|
|
// #endif
|
|
}
|
|
|
|
// Used for scaling detail albedo. Main features:
|
|
// - Depending if detailAlbedo brightens or darkens, scale magnifies effect.
|
|
// - No effect is applied if detailAlbedo is 0.5.
|
|
half3 ScaleDetailAlbedo(half3 detailAlbedo, half scale)
|
|
{
|
|
// detailAlbedo = detailAlbedo * 2.0h - 1.0h;
|
|
// detailAlbedo *= _DetailAlbedoMapScale;
|
|
// detailAlbedo = detailAlbedo * 0.5h + 0.5h;
|
|
// return detailAlbedo * 2.0f;
|
|
|
|
// A bit more optimized
|
|
return half(2.0) * detailAlbedo * scale - scale + half(1.0);
|
|
}
|
|
|
|
half3 ApplyDetailAlbedo(float2 detailUv, half3 albedo, half detailMask)
|
|
{
|
|
#if defined(_DETAIL)
|
|
half3 detailAlbedo = 1;// SAMPLE_TEXTURE2D(_DetailAlbedoMap, sampler_DetailAlbedoMap, detailUv).rgb;
|
|
|
|
// In order to have same performance as builtin, we do scaling only if scale is not 1.0 (Scaled version has 6 additional instructions)
|
|
#if defined(_DETAIL_SCALED)
|
|
detailAlbedo = ScaleDetailAlbedo(detailAlbedo, _DetailAlbedoMapScale);
|
|
#else
|
|
detailAlbedo = half(2.0) * detailAlbedo;
|
|
#endif
|
|
|
|
return albedo * LerpWhiteTo(detailAlbedo, detailMask);
|
|
#else
|
|
return albedo;
|
|
#endif
|
|
}
|
|
|
|
half3 ApplyDetailNormal(float2 detailUv, half3 normalTS, half detailMask)
|
|
{
|
|
//Not using
|
|
//#if defined(_DETAIL)
|
|
//#if BUMP_SCALE_NOT_SUPPORTED
|
|
// half3 detailNormalTS = UnpackNormal(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv));
|
|
// #else
|
|
// half3 detailNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv), _DetailNormalMapScale);
|
|
// #endif
|
|
|
|
// // With UNITY_NO_DXT5nm unpacked vector is not normalized for BlendNormalRNM
|
|
// // For visual consistancy we going to do in all cases
|
|
// detailNormalTS = normalize(detailNormalTS);
|
|
|
|
// return lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask); // todo: detailMask should lerp the angle of the quaternion rotation, not the normals
|
|
////#else
|
|
return normalTS;
|
|
//#endif
|
|
}
|
|
|
|
half3 UnpackDetailNormal(half2 details )
|
|
{
|
|
return (half3(details,1) * 2) - 1 ;
|
|
}
|
|
|
|
//Combining all the detail calculations into one function and doing a single sample
|
|
void ApplyDetails( half2 detailUv, inout SurfaceData surfaceData, half detailMask ){
|
|
#if defined(_DETAIL)
|
|
|
|
half4 detailMap = SAMPLE_TEXTURE2D(_DetailMap, sampler_DetailMap, detailUv);
|
|
|
|
//Albedo
|
|
half3 detailAlbedo = detailMap.rrr;
|
|
// In order to have same performance as builtin, we do scaling only if scale is not 1.0 (Scaled version has 6 additional instructions)
|
|
#if defined(_DETAIL_SCALED)
|
|
detailAlbedo = ScaleDetailAlbedo(detailAlbedo, _DetailAlbedoMapScale);
|
|
#else
|
|
detailAlbedo = half(2.0) * detailAlbedo;
|
|
#endif
|
|
surfaceData.albedo = surfaceData.albedo * LerpWhiteTo(detailAlbedo, detailMask);
|
|
//
|
|
|
|
//Normal
|
|
half3 detailNormalTS = UnpackDetailNormal(detailMap.ag); //Assuming the packing of the detail normals
|
|
detailNormalTS = normalize(detailNormalTS);
|
|
//Likely better to scale the normal rather than multipling the lerp :P
|
|
surfaceData.normalTS = lerp(surfaceData.normalTS, BlendNormalRNM(surfaceData.normalTS, detailNormalTS), detailMask * _DetailNormalMapScale); // todo: detailMask should lerp the angle of the quaternion rotation, not the normals
|
|
//
|
|
|
|
//Smoothness
|
|
half detailSmoothness = half(2.0) * detailMap.b;
|
|
surfaceData.smoothness = surfaceData.smoothness * LerpWhiteTo( detailSmoothness, detailMask * _DetailSmoothnessMapScale);
|
|
//
|
|
#endif
|
|
}
|
|
|
|
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
|
|
{
|
|
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
|
|
outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff);
|
|
|
|
half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a);
|
|
outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
|
|
|
|
// #if _SPECULAR_SETUP
|
|
// outSurfaceData.metallic = half(1.0);
|
|
// outSurfaceData.specular = specGloss.rgb;
|
|
// #else
|
|
outSurfaceData.metallic = specGloss.r;
|
|
outSurfaceData.specular = half3(0.0, 0.0, 0.0);
|
|
//#endif
|
|
|
|
outSurfaceData.smoothness = specGloss.a;
|
|
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);
|
|
outSurfaceData.occlusion = specGloss.g;
|
|
outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));
|
|
|
|
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
|
|
half2 clearCoat = SampleClearCoat(uv);
|
|
outSurfaceData.clearCoatMask = clearCoat.r;
|
|
outSurfaceData.clearCoatSmoothness = clearCoat.g;
|
|
#else
|
|
outSurfaceData.clearCoatMask = half(0.0);
|
|
outSurfaceData.clearCoatSmoothness = half(0.0);
|
|
#endif
|
|
|
|
#if defined(_DETAIL)
|
|
half detailMask = specGloss.b;
|
|
float2 detailUv = uv * _DetailMap_ST.xy + _DetailMap_ST.zw;
|
|
ApplyDetails( detailUv , outSurfaceData, detailMask);
|
|
// outSurfaceData.albedo = ApplyDetailAlbedo(detailUv, outSurfaceData.albedo, detailMask);
|
|
// outSurfaceData.normalTS = ApplyDetailNormal(detailUv, outSurfaceData.normalTS, detailMask);
|
|
#endif
|
|
}
|
|
|
|
#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED
|