1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- Shader "Hidden/TriLib/SpecularDiffuseToAlbedo"
- {
- 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 _DiffuseTexture;
- sampler2D _SpecularTexture;
- float getPerceivedBrightness(float3 linearColor)
- {
- float r = linearColor.x;
- float b = linearColor.y;
- float g = linearColor.z;
- return sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b);
- }
- float solveMetallic(float diffuseBrightness, float specularBrightness, float oneMinusSpecularStrength) {
- const float3 dielectricSpecular = float3(0.04, 0.04, 0.04);
- const float epsilon = 1e-6;
- specularBrightness = max(specularBrightness, dielectricSpecular.x);
- float a = dielectricSpecular.x;
- float b = diffuseBrightness * oneMinusSpecularStrength / (1.0 - dielectricSpecular.x) + specularBrightness - 2.0 * dielectricSpecular.x;
- float c = dielectricSpecular.x - specularBrightness;
- float D = b * b - 4.0 * a * c;
- return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0);
- }
- float4 frag(v2f i) : SV_Target
- {
- const float3 dielectricSpecular = float3(0.04,0.04,0.04);
- const float epsilon = 1e-6;
- float4 diffuse = tex2D(_DiffuseTexture, i.uv);
- float3 specular = tex2D(_SpecularTexture, i.uv).xyz;
- float diffuseBrightness = getPerceivedBrightness(diffuse);
- float specularBrightness = getPerceivedBrightness(specular);
- float specularStrength = max(max(specular.x, specular.y), specular.z);
- float oneMinusSpecularStrength = 1.0 - specularStrength;
- float metallic = solveMetallic(diffuseBrightness, specularBrightness, oneMinusSpecularStrength);
- float3 baseColorFromDiffuse = diffuse * oneMinusSpecularStrength / ((1.0 - dielectricSpecular.x) * max(1.0 - metallic, epsilon));
- float3 baseColorFromSpecular = (specular - dielectricSpecular * (1.0 - metallic)) / max(metallic, epsilon);
- float3 baseColor = clamp(lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic), 0.0, 1.0);
- return float4(baseColor, diffuse.w);
- }
- ENDCG
- }
- }
- }
|