Shader "Hidden/TriLib/BuildMetallicTexture" { SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } sampler2D _MetallicTexture; sampler2D _DiffuseTexture; sampler2D _SpecularTexture; sampler2D _GlossinessTexture; float3 _DefaultDiffuse; float3 _DefaultSpecular; float _DefaultRoughness; float _DefaultMetallic; float _ShininessExponent; int _HasMetallicTexture; int _HasDiffuseTexture; int _HasSpecularTexture; int _HasGlossinessTexture; int _HasDefaultRoughness; int _HasDefaultMetallic; int _UsingRoughness; int _MixTextureChannelsWithColors; int _MetallicComponentIndex; int _GlossinessComponentIndex; float GetGlossiness() { return 1 - (_HasDefaultRoughness > 0 ? _DefaultRoughness : 1); } // Reference: // https://docs.microsoft.com/en-us/azure/remote-rendering/reference/material-mapping float4 frag(v2f i) : SV_Target { const float dielectricSpecular = 0.04; float3 specularBase = _HasSpecularTexture > 0 ? tex2D(_SpecularTexture, i.uv).xyz * _DefaultSpecular : _DefaultSpecular; //Metalness float metalness; if (_HasMetallicTexture > 0) { metalness = tex2D(_MetallicTexture, i.uv)[_MetallicComponentIndex]; if (_HasDefaultMetallic && _MixTextureChannelsWithColors > 0) { metalness *= _DefaultMetallic; } } else if (_HasSpecularTexture > 0) { float3 diffuseBase = _DefaultDiffuse; float diffuseBrightness = 0.299 * pow(diffuseBase.r, 2) + 0.587 * pow(diffuseBase.g, 2) + 0.114 * pow(diffuseBase.b, 2); float specularBrightness = 0.299 * pow(specularBase.r, 2) + 0.587 * pow(specularBase.g, 2) + 0.114 * pow(specularBase.b, 2); float specularStrength = max(specularBase.r, max(specularBase.g, specularBase.b)); float oneMinusSpecularStrength = 1 - specularStrength; float A = dielectricSpecular; float B = (diffuseBrightness * (oneMinusSpecularStrength / (1 - A)) + specularBrightness) - 2 * A; float C = A - specularBrightness; float squareRoot = sqrt(max(0, B * B - 4 * A * C)); float value = (-B + squareRoot) / (2 * A); metalness = clamp(value, 0, 1); if (_HasDefaultMetallic && _MixTextureChannelsWithColors > 0) { metalness *= _DefaultMetallic; } } else { metalness = _DefaultMetallic; } //Glossiness float glossiness; if (_HasGlossinessTexture > 0) { glossiness = _UsingRoughness > 0 ? 1 - tex2D(_GlossinessTexture, i.uv)[_GlossinessComponentIndex] : tex2D(_GlossinessTexture, i.uv)[_GlossinessComponentIndex]; if (_HasDefaultRoughness && _MixTextureChannelsWithColors > 0) { glossiness *= GetGlossiness(); } } else if (_HasSpecularTexture > 0) { float specularIntensity = specularBase.r * 0.2125 + specularBase.g * 0.7154 + specularBase.b * 0.0721; glossiness = 1 - sqrt(2 / (_ShininessExponent * specularIntensity + 2)); if (_HasDefaultRoughness && _MixTextureChannelsWithColors > 0) { glossiness *= GetGlossiness(); } } else { glossiness = GetGlossiness(); } return float4(metalness, metalness, metalness, glossiness); } ENDCG } } }