Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save unitycoder/79ec47502be9b8c3af6ec237bbdad44d to your computer and use it in GitHub Desktop.

Select an option

Save unitycoder/79ec47502be9b8c3af6ec237bbdad44d to your computer and use it in GitHub Desktop.

Revisions

  1. @bgolus bgolus created this gist Dec 11, 2019.
    116 changes: 116 additions & 0 deletions HatchBlend6_DistanceAndFOVCorrected.shader
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,116 @@
    // A modification of Kyle Halladay's Pencil Sketch Effect shader
    // http://kylehalladay.com/blog/tutorial/2017/02/21/Pencil-Sketch-Effect.html

    // Blends between two scales of hatching based on distance and camera fov to
    // keep a perceptually constant hatching scale (assuming consistent mesh UVs).

    Shader "Unlit/SingleObjectHatch_DistanceAndFOVCorrected"
    {
    Properties
    {
    _MainTex ("Texture", 2D) = "white" {}
    _Hatch0("Hatch 0", 2D) = "white" {}
    [NoScaleOffset] _Hatch1("Hatch 1", 2D) = "white" {}
    }
    SubShader
    {
    Tags { "RenderType"="Opaque" }
    LOD 100

    Pass
    {
    Tags{ "LightMode" = "ForwardBase" }

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"

    struct appdata
    {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float3 norm : NORMAL;
    };

    struct v2f
    {
    float4 pos : SV_POSITION;
    float2 uv : TEXCOORD0;
    float3 nrm : TEXCOORD1;
    float3 cameraRelativeWorldPos : TEXCOORD2;
    };

    sampler2D _MainTex;
    float4 _MainTex_ST;

    sampler2D _Hatch0;
    sampler2D _Hatch1;
    float4 _Hatch0_ST;

    float4 _LightColor0;

    v2f vert (appdata v)
    {
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    o.nrm = mul(float4(v.norm, 0.0), unity_WorldToObject).xyz;
    o.cameraRelativeWorldPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1)).xyz - _WorldSpaceCameraPos.xyz;
    return o;
    }

    fixed3 Hatching(float2 _uv, half _intensity)
    {
    half3 hatch0 = tex2D(_Hatch0, _uv).rgb;
    half3 hatch1 = tex2D(_Hatch1, _uv).rgb;

    half3 overbright = max(0, _intensity - 1.0);

    half3 weightsA = saturate((_intensity * 6.0) + half3(-0, -1, -2));
    half3 weightsB = saturate((_intensity * 6.0) + half3(-3, -4, -5));

    weightsA.xy -= weightsA.yz;
    weightsA.z -= weightsB.x;
    weightsB.xy -= weightsB.zy;

    hatch0 = hatch0 * weightsA;
    hatch1 = hatch1 * weightsB;

    half3 hatching = overbright + hatch0.r +
    hatch0.g + hatch0.b +
    hatch1.r + hatch1.g +
    hatch1.b;

    return hatching;

    }


    fixed4 frag (v2f i) : SV_Target
    {
    fixed4 color = tex2D(_MainTex, TRANSFORM_TEX(i.uv, _MainTex));
    fixed3 diffuse = color.rgb * _LightColor0.rgb * dot(_WorldSpaceLightPos0, normalize(i.nrm));

    fixed intensity = dot(diffuse, fixed3(0.2326, 0.7152, 0.0722));

    float dist = length(i.cameraRelativeWorldPos) * unity_CameraInvProjection[0][0];

    float x = log2(dist);
    float2 _x = floor((x + float2(0.0, 1.0)) * 0.5) * 2.0 - float2(0.0, 1.0);
    float2 scale = pow(2.0, _x);
    float blend = abs(frac(x * 0.5) * 2.0 - 1.0);

    float2 hatchinguv = TRANSFORM_TEX(i.uv, _Hatch0);

    fixed3 h1 = Hatching(hatchinguv / scale.x, intensity);
    fixed3 h2 = Hatching(hatchinguv / scale.y, intensity);

    color.rgb = lerp(h1, h2, blend);

    return color;
    }
    ENDCG
    }
    }
    }