Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rickomax/e9a0cf263dab9b669dd98fb7d73fbb61 to your computer and use it in GitHub Desktop.
Save rickomax/e9a0cf263dab9b669dd98fb7d73fbb61 to your computer and use it in GitHub Desktop.
Shader "Hidden/SpecularDiffuseToAlbedo"
{
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma enable_d3d11_debug_symbols
#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;
const float3 dielectricSpecular = float3(0.04,0.04,0.04);
const float epsilon = 1e-10;
float solveMetallic(float diffuse, float specular, float oneMinusSpecularStrength) {
if (specular <= dielectricSpecular.x)
{
return 0.0;
}
float a = dielectricSpecular.x;
float b = diffuse * oneMinusSpecularStrength / (1.0 - dielectricSpecular.x) + specular - 2.0 * dielectricSpecular.x;
float c = dielectricSpecular.x - specular;
float D = b * b - 4.0 * a * c;
return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0);
}
fixed4 frag(v2f i) : SV_Target
{
float4 diffuse = tex2D(_DiffuseTexture, i.uv);
float3 specular = tex2D(_SpecularTexture, i.uv).xyz;
float diffuseBrightness =
0.299 * pow(diffuse.x, 2.0) +
0.587 * pow(diffuse.y, 2.0) +
0.114 * pow(diffuse.z, 2.0);
float specularBrightness =
0.299 * pow(specular.x, 2.0) +
0.587 * pow(specular.y, 2.0) +
0.114 * pow(specular.z, 2.0);
float specularStrength = max(max(specular.x, specular.y), specular.z);
float oneMinusSpecularStrength = 1.0 - specularStrength;
float metallic = solveMetallic(diffuseBrightness, specularBrightness, oneMinusSpecularStrength);
float3 baseColorFromDiffuse = diffuse.xyz * oneMinusSpecularStrength / ((1.0 - dielectricSpecular.x) * max(1.0 - metallic, epsilon));
float3 baseColorFromSpecular = (specular - dielectricSpecular * (1.0 - metallic)) / max(metallic, epsilon);
float3 baseColor = lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
return float4(baseColor, diffuse.w);
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment