Skip to content

Instantly share code, notes, and snippets.

@binaryfoundry
Last active March 12, 2025 08:46
Show Gist options
  • Select an option

  • Save binaryfoundry/a1eeca36922b71fe1942751879ab8ab6 to your computer and use it in GitHub Desktop.

Select an option

Save binaryfoundry/a1eeca36922b71fe1942751879ab8ab6 to your computer and use it in GitHub Desktop.

Revisions

  1. binaryfoundry revised this gist Mar 12, 2025. No changes.
  2. binaryfoundry revised this gist Feb 10, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -143,7 +143,7 @@ Shader "CustomPBRShader"

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (1.0 / 3.142) * (1.0 - _Metalness);
    float3 diffuse = diffuse_img(n) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));
  3. binaryfoundry revised this gist Feb 8, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -143,7 +143,7 @@ Shader "CustomPBRShader"

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (1.0 - _Metalness);
    float3 diffuse = diffuse_img(n) * (1.0 / 3.142) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));
  4. binaryfoundry revised this gist Feb 7, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -106,7 +106,7 @@ Shader "CustomPBRShader"
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.1
    float3 diffuse_img(float3 n)
    {
    return texCUBE(_IrradianceMap, n).rgb;
    return _Albedo.rgb * texCUBE(_IrradianceMap, n).rgb;
    }

    // https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Shaders/Private/ReflectionEnvironmentShared.ush
  5. binaryfoundry revised this gist Feb 7, 2021. 1 changed file with 4 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -120,7 +120,9 @@ Shader "CustomPBRShader"
    // half LevelFrom1x1 = REFLECTION_CAPTURE_ROUGHEST_MIP - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(Roughness);
    // return CubemapMaxMip - 1 - LevelFrom1x1;
    //}

    // Diffuse albedo must be divided by pi to be energy conserving.
    // https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading

    // Sample offline generated convolved environment map. MipLevels
    // should match the number of images output.
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    @@ -133,9 +135,6 @@ Shader "CustomPBRShader"
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
    }

    // Diffuse albedo must be divided by pi to be energy conserving.
    // https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading

    fixed4 frag (v2f i) : SV_Target
    {
    float3 n = normalize(i.normal);
    @@ -144,7 +143,7 @@ Shader "CustomPBRShader"

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (_Albedo.rgb / 3.1415926535) * (1.0 - _Metalness);
    float3 diffuse = diffuse_img(n) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));
  6. binaryfoundry revised this gist Feb 7, 2021. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -127,8 +127,9 @@ Shader "CustomPBRShader"
    // If not using a pre-convolved environment map, but instead one rendered
    // at runtime use UE4 heuristic mapping to calculate mip level above. This
    // mimics the offline convolution by biasing the mip level.
    float3 specular_img(float3 n, float3 v, float3 r)
    float3 specular_img(float3 n, float3 v)
    {
    float3 r = reflect(v, n);
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
    }

    @@ -139,13 +140,12 @@ Shader "CustomPBRShader"
    {
    float3 n = normalize(i.normal);
    float3 v = normalize(_WorldSpaceCameraPos - i.posWorld.xyz);
    float3 r = reflect(v, n);
    float NoV = dot(n, v);

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (_Albedo.rgb / 3.1415926535) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v, r);
    float3 specular = specular_img(n, v);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));

  7. binaryfoundry revised this gist Feb 7, 2021. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -54,6 +54,9 @@ Shader "CustomPBRShader"
    return o;
    }

    // Tone Mapping
    //https://mynameismjp.wordpress.com/2010/04/30/a-closer-look-at-tone-mapping/
    //https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
    static const float3x3 ACESInputMat =
    {
    {0.59719, 0.35458, 0.04823},
  8. binaryfoundry revised this gist Feb 3, 2021. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -23,8 +23,6 @@ Shader "CustomPBRShader"

    #include "UnityCG.cginc"

    const float pi = 3.141592653589793238462;

    float4 _Albedo;
    float _Metalness;
    float _Roughness;
    @@ -143,7 +141,7 @@ Shader "CustomPBRShader"

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (_Albedo.rgb / pi) * (1.0 - _Metalness);
    float3 diffuse = diffuse_img(n) * (_Albedo.rgb / 3.1415926535) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v, r);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));
  9. binaryfoundry revised this gist Feb 3, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -148,7 +148,7 @@ Shader "CustomPBRShader"

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));

    return float4(toneMapACES(c * exposure), _Albedo.a);
    return float4(toneMapACES(c * Exposure), _Albedo.a);
    }
    ENDCG
    }
  10. binaryfoundry revised this gist Apr 12, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -125,7 +125,7 @@ Shader "CustomPBRShader"
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    // If not using a pre-convolved environment map, but instead one rendered
    // at runtime use UE4 heuristic mapping to calculate mip level above. This
    // mimics the offline convolution vy biasing the mip level.
    // mimics the offline convolution by biasing the mip level.
    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
  11. binaryfoundry revised this gist Apr 12, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -125,7 +125,7 @@ Shader "CustomPBRShader"
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    // If not using a pre-convolved environment map, but instead one rendered
    // at runtime use UE4 heuristic mapping to calculate mip level above. This
    // heuristically mimics the offline convolution.
    // mimics the offline convolution vy biasing the mip level.
    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
  12. binaryfoundry revised this gist Mar 24, 2020. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -123,8 +123,9 @@ Shader "CustomPBRShader"
    // Sample offline generated convolved environment map. MipLevels
    // should match the number of images output.
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    // If not using a pre-convolved environment map which was rendered
    // at runtime use UE4 heuristic mapping to calculate mip level above.
    // If not using a pre-convolved environment map, but instead one rendered
    // at runtime use UE4 heuristic mapping to calculate mip level above. This
    // heuristically mimics the offline convolution.
    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
  13. binaryfoundry revised this gist Mar 24, 2020. 1 changed file with 6 additions and 1 deletion.
    7 changes: 6 additions & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -23,6 +23,8 @@ Shader "CustomPBRShader"

    #include "UnityCG.cginc"

    const float pi = 3.141592653589793238462;

    float4 _Albedo;
    float _Metalness;
    float _Roughness;
    @@ -128,6 +130,9 @@ Shader "CustomPBRShader"
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
    }

    // Diffuse albedo must be divided by pi to be energy conserving.
    // https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading

    fixed4 frag (v2f i) : SV_Target
    {
    float3 n = normalize(i.normal);
    @@ -137,7 +142,7 @@ Shader "CustomPBRShader"

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * _Albedo.rgb * (1.0 - _Metalness);
    float3 diffuse = diffuse_img(n) * (_Albedo.rgb / pi) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v, r);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));
  14. binaryfoundry revised this gist Mar 1, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -122,7 +122,7 @@ Shader "CustomPBRShader"
    // should match the number of images output.
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    // If not using a pre-convolved environment map which was rendered
    // at runtime use UE4 heuristic mapping to calculate level above.
    // at runtime use UE4 heuristic mapping to calculate mip level above.
    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
  15. binaryfoundry revised this gist Mar 1, 2020. 1 changed file with 15 additions and 1 deletion.
    16 changes: 15 additions & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -106,9 +106,23 @@ Shader "CustomPBRShader"
    return texCUBE(_IrradianceMap, n).rgb;
    }

    // Sample offline generated blurred environment map. MipLevels
    // https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Shaders/Private/ReflectionEnvironmentShared.ush
    // Heuristic that maps roughness to mip level
    // This is done in a way such that a certain mip level will always have the same roughness, regardless of how many mips are in the texture
    // Using more mips in the cubemap just allows sharper reflections to be supported
    //#define REFLECTION_CAPTURE_ROUGHEST_MIP 1
    //#define REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE 1.2
    //half ComputeReflectionCaptureMipFromRoughness(half Roughness, half CubemapMaxMip)
    //{
    // half LevelFrom1x1 = REFLECTION_CAPTURE_ROUGHEST_MIP - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(Roughness);
    // return CubemapMaxMip - 1 - LevelFrom1x1;
    //}

    // Sample offline generated convolved environment map. MipLevels
    // should match the number of images output.
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    // If not using a pre-convolved environment map which was rendered
    // at runtime use UE4 heuristic mapping to calculate level above.
    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
  16. binaryfoundry revised this gist Nov 25, 2019. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -99,6 +99,8 @@ Shader "CustomPBRShader"
    return f0 * AB.x + AB.y;
    }

    // Diffuse reflection map.
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.1
    float3 diffuse_img(float3 n)
    {
    return texCUBE(_IrradianceMap, n).rgb;
  17. binaryfoundry revised this gist Nov 25, 2019. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -104,6 +104,9 @@ Shader "CustomPBRShader"
    return texCUBE(_IrradianceMap, n).rgb;
    }

    // Sample offline generated blurred environment map. MipLevels
    // should match the number of images output.
    // https://google.github.io/filament/Filament.md.html#toc5.3.4.4
    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
  18. binaryfoundry revised this gist Nov 25, 2019. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -75,6 +75,8 @@ Shader "CustomPBRShader"
    return a / b;
    }

    // Maps real valued output to a suitable range for display on an
    // 8-bits per channel RGB screen.
    float3 toneMapACES(float3 color)
    {
    color = mul(ACESInputMat, color);
    @@ -84,7 +86,8 @@ Shader "CustomPBRShader"
    return color;
    }

    // Approximates the DFG lookup table generated offline.
    // Approximates the roughness/Fresnel lookup table generated offline.
    // Explained in Filament documentation.
    // https://google.github.io/filament/Filament.md.html#table_texturedfg
    float3 EnvBRDFApprox(float3 f0, float3 NoV, float roughness)
    {
  19. binaryfoundry revised this gist Nov 25, 2019. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions ShaderLabPBR.shader
    Original file line number Diff line number Diff line change
    @@ -84,6 +84,8 @@ Shader "CustomPBRShader"
    return color;
    }

    // Approximates the DFG lookup table generated offline.
    // https://google.github.io/filament/Filament.md.html#table_texturedfg
    float3 EnvBRDFApprox(float3 f0, float3 NoV, float roughness)
    {
    float4 c0 = float4(-1.0, -0.0275, -0.572, 0.022);
  20. binaryfoundry renamed this gist Nov 22, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  21. binaryfoundry revised this gist Nov 22, 2019. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,12 @@
    Shader "Unlit/DemoShader"
    Shader "CustomPBRShader"
    {
    Properties
    {
    [NoScaleOffset] _Albedo("Albedo", Color) = (1.0, 1.0, 1.0, 1.0)
    [NoScaleOffset] _Metalness("Conductivity", Range(0.0, 1.0)) = 0.0
    [NoScaleOffset] _Roughness("Roughness", Range(0.0, 1.0)) = 0.0
    [NoScaleOffset][HDR][HideInInspector] _RadianceMap("RadianceMap", CUBE) = "" {}
    [NoScaleOffset][HDR][HideInInspector] _IrradianceMap("IrradianceMap", CUBE) = "" {}
    [NoScaleOffset][HDR] _RadianceMap("RadianceMap", CUBE) = "" {}
    [NoScaleOffset][HDR] _IrradianceMap("IrradianceMap", CUBE) = "" {}
    }
    SubShader
    {
  22. binaryfoundry revised this gist Nov 22, 2019. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -96,7 +96,7 @@ Shader "Unlit/DemoShader"

    float3 diffuse_img(float3 n)
    {
    return _Albedo.rgb * texCUBE(_IrradianceMap, n).rgb;
    return texCUBE(_IrradianceMap, n).rgb;
    }

    float3 specular_img(float3 n, float3 v, float3 r)
    @@ -113,7 +113,7 @@ Shader "Unlit/DemoShader"

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (1.0 - _Metalness);
    float3 diffuse = diffuse_img(n) * _Albedo.rgb * (1.0 - _Metalness);
    float3 specular = specular_img(n, v, r);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));
  23. binaryfoundry revised this gist Nov 22, 2019. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -107,7 +107,6 @@ Shader "Unlit/DemoShader"
    fixed4 frag (v2f i) : SV_Target
    {
    float3 n = normalize(i.normal);
    float3 l = _WorldSpaceLightPos0.xyz - i.posWorld.xyz * _WorldSpaceLightPos0.w;
    float3 v = normalize(_WorldSpaceCameraPos - i.posWorld.xyz);
    float3 r = reflect(v, n);
    float NoV = dot(n, v);
  24. binaryfoundry created this gist Nov 21, 2019.
    127 changes: 127 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    Shader "Unlit/DemoShader"
    {
    Properties
    {
    [NoScaleOffset] _Albedo("Albedo", Color) = (1.0, 1.0, 1.0, 1.0)
    [NoScaleOffset] _Metalness("Conductivity", Range(0.0, 1.0)) = 0.0
    [NoScaleOffset] _Roughness("Roughness", Range(0.0, 1.0)) = 0.0
    [NoScaleOffset][HDR][HideInInspector] _RadianceMap("RadianceMap", CUBE) = "" {}
    [NoScaleOffset][HDR][HideInInspector] _IrradianceMap("IrradianceMap", CUBE) = "" {}
    }
    SubShader
    {
    Tags { "RenderType" = "Transparent" "Queue" = "Geometry" }
    LOD 100

    Pass
    {
    Blend SrcAlpha OneMinusSrcAlpha

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    #include "UnityCG.cginc"

    float4 _Albedo;
    float _Metalness;
    float _Roughness;
    samplerCUBE _RadianceMap;
    samplerCUBE _IrradianceMap;

    static float MipLevels = 8.0;
    static float Exposure = 1.5;

    struct appdata
    {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    };

    struct v2f
    {
    float4 pos : POSITION;
    float3 normal : NORMAL;
    float4 posWorld : TEXCOORD1;
    };

    v2f vert (appdata v)
    {
    v2f o;
    o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    o.normal = normalize(mul(float4(v.normal, 0.0), unity_WorldToObject).xyz);
    o.pos = UnityObjectToClipPos(v.vertex);
    return o;
    }

    static const float3x3 ACESInputMat =
    {
    {0.59719, 0.35458, 0.04823},
    {0.07600, 0.90834, 0.01566},
    {0.02840, 0.13383, 0.83777}
    };

    static const float3x3 ACESOutputMat =
    {
    { 1.60475, -0.53108, -0.07367},
    {-0.10208, 1.10813, -0.00605},
    {-0.00327, -0.07276, 1.07602}
    };

    float3 RRTAndODTFit(float3 v)
    {
    float3 a = v * (v + 0.0245786f) - 0.000090537f;
    float3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f;
    return a / b;
    }

    float3 toneMapACES(float3 color)
    {
    color = mul(ACESInputMat, color);
    color = RRTAndODTFit(color);
    color = mul(ACESOutputMat, color);
    color = saturate(color);
    return color;
    }

    float3 EnvBRDFApprox(float3 f0, float3 NoV, float roughness)
    {
    float4 c0 = float4(-1.0, -0.0275, -0.572, 0.022);
    float4 c1 = float4(1.0, 0.0425, 1.04, -0.04);
    float4 r = roughness * c0 + c1;
    float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
    float2 AB = float2(-1.04, 1.04) * a004 + r.zw;
    return f0 * AB.x + AB.y;
    }

    float3 diffuse_img(float3 n)
    {
    return _Albedo.rgb * texCUBE(_IrradianceMap, n).rgb;
    }

    float3 specular_img(float3 n, float3 v, float3 r)
    {
    return texCUBElod(_RadianceMap, float4(r, _Roughness * MipLevels)).rgb;
    }

    fixed4 frag (v2f i) : SV_Target
    {
    float3 n = normalize(i.normal);
    float3 l = _WorldSpaceLightPos0.xyz - i.posWorld.xyz * _WorldSpaceLightPos0.w;
    float3 v = normalize(_WorldSpaceCameraPos - i.posWorld.xyz);
    float3 r = reflect(v, n);
    float NoV = dot(n, v);

    float3 f0 = max(_Albedo.rgb * _Metalness, 0.04);

    float3 diffuse = diffuse_img(n) * (1.0 - _Metalness);
    float3 specular = specular_img(n, v, r);

    float3 c = lerp(diffuse, specular, EnvBRDFApprox(f0, NoV, _Roughness));

    return float4(toneMapACES(c * exposure), _Albedo.a);
    }
    ENDCG
    }
    }
    }