Home>

principle

Use 6 sketch textures for rendering,During the rendering stage,Calculate the lighting per vertex in the vertex shading stage,Determine the mixing weight of 6 textures according to the lighting result,And pass it to the fragment shader.Mix the sampling results of 6 textures according to these weights in the fragment shader

shader implementation

shader "hatching"
{
 properties {
 _color ("color tint", color)=(1, 1, 1, 1) //color
 _tilefactor ("tile factor", float)=1 //Tile factor of texture,The larger the value, the denser the sketch line
 _outline ("outline", range (0, 1))=0.1
 _hatch0 ("hatch 0", 2d)="white" {}
 _hatch1 ("hatch 1", 2d)="white" {}
 _hatch2 ("hatch 2", 2d)="white" {}
 _hatch3 ("hatch 3", 2d)="white" {}
 _hatch4 ("hatch 4", 2d)="white" {}
 _hatch5 ("hatch 5", 2d)="white" {} //The corresponding 6 sketch textures
 }
 subshader {
 tags {"rendertype"="opaque" "queue"="geometry"}
 pass {
 tags {"lightmode"="forwardbase"}
 cgprogram
 #pragma vertex vert
 #pragma fragment frag
 #pragma multi_compile_fwdbase
 #include "unitycg.cginc"
 #include "lighting.cginc"
 #include "autolight.cginc"
 #include "unityshadervariables.cginc"
 fixed4 _color;
 float _tilefactor;
 sampler2d _hatch0;
 sampler2d _hatch1;
 sampler2d _hatch2;
 sampler2d _hatch3;
 sampler2d _hatch4;
 sampler2d _hatch5;
 struct a2v {
 float4 vertex:position;
 float4 tangent:tangent;
 float3 normal:normal;
 float2 texcoord:texcoord0;
 };
 struct v2f {
 float4 pos:sv_position;
 float2 uv:texcoord0;
 fixed3 hatchweights0:texcoord1;//
 fixed3 hatchweights1:texcoord2;//6 mixed weights,There are two fixed3 variables
 float3 worldpos:texcoord3;
 shadow_coords (4)
 };
 v2f vert (a2v v) {
 v2f o;
 o.pos=unityobjecttoclippos (v.vertex);
 o.uv=v.texcoord.xy * _tilefactor;
 fixed3 worldlightdir=normalize (worldspacelightdir (v.vertex));
 fixed3 worldnormal=unityobjecttoworldnormal (v.normal);
 fixed diff=max (0, dot (worldlightdir, worldnormal));//The diffuse reflection coefficient
 o.hatchweights0=fixed3 (0, 0, 0);
 o.hatchweights1=fixed3 (0, 0, 0);
 float hatchfactor=diff * 7.0;//Zoom diff to [0,7] range
 //Pure white
 if (hatchfactor>6.0)
 {
 } else if (hatchfactor>5.0) {
  o.hatchweights0.x=hatchfactor-5.0;
 } else if (hatchfactor>4.0) {
  o.hatchweights0.x=hatchfactor-4.0;
  o.hatchweights0.y=1.0-o.hatchweights0.x;
 } else if (hatchfactor>3.0) {
  o.hatchweights0.y=hatchfactor-3.0;
  o.hatchweights0.z=1.0-o.hatchweights0.y;
 } else if (hatchfactor>2.0) {
  o.hatchweights0.z=hatchfactor-2.0;
  o.hatchweights1.x=1.0-o.hatchweights0.z;
 } else if (hatchfactor>1.0) {
  o.hatchweights1.x=hatchfactor-1.0;
  o.hatchweights1.y=1.0-o.hatchweights1.x;
 } else {
  o.hatchweights1.y=hatchfactor;
  o.hatchweights1.z=1.0-o.hatchweights1.y;
 }
 o.worldpos=mul (unity_objecttoworld, v.vertex) .xyz;
 transfer_shadow (o);
 return o;
 }
 fixed4 frag (v2f i):sv_target
 {//Sample according to the corresponding weight
 fixed4 hatchtex0=tex2d (_hatch0, i.uv) * i.hatchweights0.x;
 fixed4 hatchtex1=tex2d (_hatch1, i.uv) * i.hatchweights0.y;
 fixed4 hatchtex2=tex2d (_hatch2, i.uv) * i.hatchweights0.z;
 fixed4 hatchtex3=tex2d (_hatch3, i.uv) * i.hatchweights1.x;
 fixed4 hatchtex4=tex2d (_hatch4, i.uv) * i.hatchweights1.y;
 fixed4 hatchtex5=tex2d (_hatch5, i.uv) * i.hatchweights1.z;
 fixed4 whitecolor=fixed4 (1, 1, 1, 1) * (1-i.hatchweights0.x-i.hatchweights0.y-i.hatchweights0.z-
  i.hatchweights1.x-i.hatchweights1.y-i.hatchweights1.z);
 fixed4 hatchcolor=hatchtex0 + hatchtex1 + hatchtex2 + hatchtex3 + hatchtex4 + hatchtex5 + whitecolor;
 unity_light_attenuation (atten, i, i.worldpos);
 return fixed4 (hatchcolor.rgb * _color.rgb * atten, 1.0);
 }
 endcg
 }
 }
 fallback "diffuse"
}

The effect is as follows:

  • Previous Unity Shader achieves graphics drawing (blue sky, white clouds and sea)
  • Next Python implements entering multiple numbers in one line (separated by spaces)