Forked from bgolus/HatchBlend6_DistanceAndFOVCorrected.shader
Created
October 20, 2023 12:29
-
-
Save unitycoder/79ec47502be9b8c3af6ec237bbdad44d to your computer and use it in GitHub Desktop.
A modification of Kyle Halladay's Pencil Sketch Effect shader from his blog post here: http://kylehalladay.com/blog/tutorial/2017/02/21/Pencil-Sketch-Effect.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment