Unity Toon Shading with Texture

reference the toon shading in  the wiki

https://en.wikibooks.org/wiki/Cg_Programming/Unity/Toon_Shading

and add
_MainTex(“Base (RGB) Trans (A)”, 2D) = “white” {}

pass the uv : TEXCOORD0 from vertexInput to vertexOutput

 

take the texel form the uv

fixed4 col = tex2D(_MainTex, input.uv) * input.color;

 

Download: ToonShadeingWithTex.shader

the shader code as below:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

Shader "Cg shader for toon shading with texture test" {
	Properties{
		_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
	_Color("Diffuse Color", Color) = (1,1,1,1)
		_UnlitColor("Unlit Diffuse Color", Color) = (0.5,0.5,0.5,1)
		_DiffuseThreshold("Threshold for Diffuse Colors", Range(0,1)) = 0.1
		_OutlineColor("Outline Color", Color) = (0,0,0,1)
		_LitOutlineThickness("Lit Outline Thickness", Range(0,1)) = 0.1
		_UnlitOutlineThickness("Unlit Outline Thickness", Range(0,1)) = 0.4
		_SpecColor("Specular Color", Color) = (1,1,1,1)
		_Shininess("Shininess", Float) = 10
	}
		SubShader{
		Pass{
		Tags{ "LightMode" = "ForwardBase" }
		// pass for ambient light and first light source

		CGPROGRAM

#pragma vertex vert  
#pragma fragment frag 

#include "UnityCG.cginc"
		uniform float4 _LightColor0;
	// color of light source (from "Lighting.cginc")

	sampler2D _MainTex;

	// User-specified properties
	uniform float4 _Color;
	uniform float4 _UnlitColor;
	uniform float _DiffuseThreshold;
	uniform float4 _OutlineColor;
	uniform float _LitOutlineThickness;
	uniform float _UnlitOutlineThickness;
	uniform float4 _SpecColor;
	uniform float _Shininess;

	struct vertexInput {
		fixed4 color : COLOR;
		float4 vertex : POSITION;
		float3 normal : NORMAL;
		float2 uv: TEXCOORD0;
	};
	struct vertexOutput {
		fixed4 color : COLOR;
		float4 pos : SV_POSITION;
		float2 uv: TEXCOORD0;
		float4 posWorld : TEXCOORD1;
		float3 normalDir : TEXCOORD2;
	};

	vertexOutput vert(vertexInput input)
	{
		vertexOutput output;

		float4x4 modelMatrix = _Object2World;
		float4x4 modelMatrixInverse = _World2Object;

		output.posWorld = mul(modelMatrix, input.vertex);
		output.normalDir = normalize(mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
		output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
		output.color = input.color;
		output.uv = input.uv;
		return output;
	}

	float4 frag(vertexOutput input) : COLOR
	{
		float3 normalDirection = normalize(input.normalDir);

		float3 viewDirection = normalize(_WorldSpaceCameraPos - input.posWorld.xyz);
		float3 lightDirection;
		float attenuation;

		if (0.0 == _WorldSpaceLightPos0.w) // directional light?
		{
			attenuation = 1.0; // no attenuation
			lightDirection = normalize(_WorldSpaceLightPos0.xyz);
		}
		else // point or spot light
		{
			float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
			float distance = length(vertexToLightSource);
			attenuation = 1.0 / distance; // linear attenuation 
			lightDirection = normalize(vertexToLightSource);
		}

		// default: unlit 
		float3 fragmentColor = _UnlitColor.rgb;

		// low priority: diffuse illumination
		if (attenuation * max(0.0, dot(normalDirection, lightDirection)) >= _DiffuseThreshold)
		{
			fragmentColor = _LightColor0.rgb * _Color.rgb;
		}

		// higher priority: outline
		if (dot(viewDirection, normalDirection)
			< lerp(_UnlitOutlineThickness, _LitOutlineThickness, max(0.0, dot(normalDirection, lightDirection))))
		{
			fragmentColor = _LightColor0.rgb * _OutlineColor.rgb;
		}

		// highest priority: highlights
		if (dot(normalDirection, lightDirection) > 0.0
			// light source on the right side?
			&& attenuation *  pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess) > 0.5)
			// more than half highlight intensity? 
		{
			fragmentColor = _SpecColor.a * _LightColor0.rgb * _SpecColor.rgb + (1.0 - _SpecColor.a) * fragmentColor;
		}
		// final texture
		fixed4 col = tex2D(_MainTex, input.uv) * input.color;
		return col * float4(fragmentColor, 1.0);
	}
		ENDCG
	}

		Pass{
		Tags{ "LightMode" = "ForwardAdd" }
		// pass for additional light sources
		Blend SrcAlpha OneMinusSrcAlpha
		// blend specular highlights over framebuffer

		CGPROGRAM

#pragma vertex vert  
#pragma fragment frag 

#include "UnityCG.cginc"
		uniform float4 _LightColor0;
	// color of light source (from "Lighting.cginc")

	sampler2D _MainTex;

	// User-specified properties
	uniform float4 _Color;
	uniform float4 _UnlitColor;
	uniform float _DiffuseThreshold;
	uniform float4 _OutlineColor;
	uniform float _LitOutlineThickness;
	uniform float _UnlitOutlineThickness;
	uniform float4 _SpecColor;
	uniform float _Shininess;

	struct vertexInput {
		fixed4 color : COLOR;
		float4 vertex : POSITION;
		float3 normal : NORMAL;
		float2 uv: TEXCOORD0;
	};
	struct vertexOutput {
		fixed4 color : COLOR;
		float4 pos : SV_POSITION;
		float2 uv: TEXCOORD0;
		float4 posWorld : TEXCOORD1;
		float3 normalDir : TEXCOORD2;
	};

	vertexOutput vert(vertexInput input)
	{
		vertexOutput output;

		float4x4 modelMatrix = _Object2World;
		float4x4 modelMatrixInverse = _World2Object;

		output.posWorld = mul(modelMatrix, input.vertex);
		output.normalDir = normalize(mul(float4(input.normal, 0.0), modelMatrixInverse).rgb);
		output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
		output.color = input.color;
		output.uv = input.uv;
		return output;
	}

	float4 frag(vertexOutput input) : COLOR
	{
		float3 normalDirection = normalize(input.normalDir);

		float3 viewDirection = normalize(_WorldSpaceCameraPos - input.posWorld.rgb);
		float3 lightDirection;
		float attenuation;

		if (0.0 == _WorldSpaceLightPos0.w) // directional light?
		{
			attenuation = 1.0; // no attenuation
			lightDirection = normalize(_WorldSpaceLightPos0.xyz);
		}
		else // point or spot light
		{
			float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
			float distance = length(vertexToLightSource);
			attenuation = 1.0 / distance; // linear attenuation 
			lightDirection = normalize(vertexToLightSource);
		}

		float4 fragmentColor = float4(0.0, 0.0, 0.0, 0.0);
		if (dot(normalDirection, lightDirection) > 0.0
			// light source on the right side?
			&& attenuation *  pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess) > 0.5)
			// more than half highlight intensity? 
		{
			fragmentColor = float4(_LightColor0.rgb, 1.0) * _SpecColor;
		}
		// final texture
		fixed4 col = tex2D(_MainTex, input.uv) * input.color;
		return col * fragmentColor;
	}
		ENDCG
	}
	}
		Fallback "Specular"
}

Comments

comments