zoukankan      html  css  js  c++  java
  • Shader食谱 Chapter3--Toonshader卡通效果

    Shader食谱 Chapter3--Toonshader卡通效果

    Shader食谱 Chapter3--Toonshader卡通效果

    OverView

    toon shader是游戏中比较常用的效果之一,尤其在二次元游戏中为了模拟角色在动画中手绘的效果。它是一种非真实的渲染技术,可以让3D角色显得平软很多。Toon效果实现过程主要是将大片光照接近的区域归到接近的步长,比如光照00.2全都为0,0.20.4全都视为0.2...这里主要通过两种方式来实现该效果。第一种使用坡度图映射光照,第二种使用算法来将光照分成不同步长
    standardshader与toonshader比较:
    standardshadertoonshader

    方法一:使用坡度图RampMap

    我们知道纹理的UV范围在0-1,我们如果将某一方向上颜色按一定的步长分隔,然后将初始的光照强度作为另一方向的 参数信息,由此则会获得按特定步长分隔的光照强度。

    RampMap

    RampMap

    Shader "ShaderCookbook/Toon" {
    	Properties {
    		_Color ("Color", Color) = (1,1,1,1)
    		_MainTex("Main Texture",2D)="white"{}
    		_RampTex("Ramp",2D)="white"{}	
    		
    	}
    	SubShader {
    		Tags { "RenderType"="Opaque" }
    		LOD 200
    		
    		CGPROGRAM
    		
    		#pragma surface surf Toon
    		#pragma target 3.0
    
            sampler2D _MainTex;
    	    sampler2D _RampTex;	
            fixed4 _Color;
    
    		struct Input {
    			float2 uv_MainTex;
    		};
    
    		fixed4 LightingToon(SurfaceOutput s,fixed2 lightDir,fixed atten){
                half NdotL=dot(s.Normal,lightDir);
    			//uv范围0~1,这里通过fixed2(NdotL,0.5)从rampmap上取样,固定V的值为0.5,通过NdotL的值
    			//来在坡度图上取样,由此获得如cartoon中色彩分明的效果
    			//如果色彩在V轴上是固定的,那么V取0~1内的值结果都一致
    			NdotL=tex2D(_RampTex,fixed2(NdotL,0.5));
    			fixed4 c;
    			c.rgb=s.Albedo*_LightColor0*NdotL*atten;
    			c.a=s.Alpha;
    			return c;
    		}
            
    
    		void surf (Input IN, inout SurfaceOutput o) {
    			fixed4 c=tex2D(_MainTex,IN.uv_MainTex)*_Color;
    			o.Albedo=c.rgb;
    			o.Alpha=c.a;
    		}
    		ENDCG
    	}
    	FallBack "Diffuse"
    }
    
    

    方法二:使用算法来分隔光照强度

    本文中一开始的比较图中的Toonshader就是使用该方式CelShadingLevels为5时表现的效果,很明显看到角色上的光照显示出一层一层的样子,CelShadingLevels越高,这种分层效果就越细致。
    //使用floor方法将按_CelshadingLevels等份得到的值向下取整,依然保[0-1]范围内的cel值
    half cel = floor(NdotL * _CelShadingLevels) / (_CelShadingLevels -0.10);
    下面是模拟取CelShadingLevels分别为3,5时候得到cel的值

    enter description here

    GetCel

    Shader "ShaderCookbook/Toon2" {
    	Properties {
    		_Color ("Color", Color) = (1,1,1,1)
    		_MainTex("Main Texture",2D)="white"{}
    		_CelShadingLevels("_CelShading Levels",Range(0,10))=1
    		
    	}
    	SubShader {
    		Tags { "RenderType"="Opaque" }
    		LOD 200
    		
    		CGPROGRAM
    		
    		#pragma surface surf CustomLambert
    		#pragma target 3.0
    
            sampler2D _MainTex;
            fixed4 _Color;
    		int _CelShadingLevels;
    
    		struct Input {
    			float2 uv_MainTex;
    		};
    
    		half4 LightingCustomLambert (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
            half NdotL = dot (s.Normal, lightDir);
    		
    		//使用floor方法将按_CelshadingLevels等份得到的值向下取整,依然保[0-1]范围内的cel值
            half cel = floor(NdotL * _CelShadingLevels) / (_CelShadingLevels -0.10); //Snap
            half4 c;
            c.rgb = s.Albedo * _LightColor0.rgb * cel * atten;
            c.a = s.Alpha;
            return c;
    }
            
    
    		void surf (Input IN, inout SurfaceOutput o) {
    			fixed4 c=tex2D(_MainTex,IN.uv_MainTex)*_Color;
    			o.Albedo=c.rgb;
    			o.Alpha=c.a;
    		}
    		ENDCG
    	}
    	FallBack "Diffuse"
    }
    
    
  • 相关阅读:
    QTableWidget的使用和美工总结
    pyqt下QTableWidget使用方法小结(转)
    改变QTableWidget 行高(转)
    Qt中 文件对话框QFileDialog 的使用
    Qt:拖拽图片到QLabel上并显示(转)
    Qt获取组合键(转)
    Qt图片显示效率的比较(转)
    QComboBox用法小列(转)
    TinyXML:一个优秀的C++ XML解析器(转)
    JZOJ 3099. Vigenère密码 NOIP2012
  • 原文地址:https://www.cnblogs.com/Firepad-magic/p/8904481.html
Copyright © 2011-2022 走看看