Unity Shaders and Effects

https://www.baidu.com/link?url=o85V5QLsraCjMOmzJc6081Z3bsQRw4_hjoPki5igyrvrJExygnt2Ex-_oGmH60-wm2VU53AsKInafwE2Z7NCB_&wd=&eqid=f46be4f400050577000000065d31d21e  //shader学习链接

3D纹理:

   只能脚本创建 opengl 3.0及以上才支持。

Unity Shaders and Effects_第1张图片

file:///D:/Unity5.6.6/Editor/Data/Documentation/en/Manual/SL-Material.html  //unity APL

shader 1.0    灯光调节公式: 

Ambient * Lighting Window’s Ambient Intensity setting + (Light Color * Diffuse + Light Color * Specular) + Emission

Ambient : 环境光    Specular  镜面反射    Emission: 自发光

SeparateSpecular  镜面照明不受纹理的影响。只有在使用照明时才有效果

 Lighting Window’s Ambient Intensity setting : 

Unity Shaders and Effects_第2张图片

 

进度条: 

矩阵旋转注意事项  :

使用旋转后的UV进行纹理采样。

1. 物体平移到原点,否则会绕着原点旋转,应该移动到物体中心点,再进行旋转。

2.发生旋转

3.再把物体平移到原点的位置

例如: 要做一个旋转的进度圈。

让uv坐标绕z轴进行旋转。

Unity Shaders and Effects_第3张图片绕z轴旋转得旋转矩阵。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//加到Image
Shader "Custom/Loading"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_Speed ("Speed ",float) = 2
	}
	SubShader
	{
		// No culling or depth
	//Cull Off ZWrite Off 
	
	ZTest Always
	  Blend SrcAlpha OneMinusSrcAlpha

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

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

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};
			float  _Speed ;
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}
			
			sampler2D _MainTex;	            

			fixed4 frag (v2f i) : SV_Target
			{

			    float2 tmpUV = i.uv ;

				//先把UV中心点移动到原点
				tmpUV  -= float2(0.5,0.5) ;
				//把四个中心点到顶点的距离(即<0.5f)>得改为0.5f,避免取到圆圈顶点之外得点
				if(length(tmpUV)>0.5)
				{
				    return fixed4(0,0,0,0)  ;
				}
				float2  finalUV = 0 ;
				float  angle = _Time.x*_Speed ;
				finalUV.x = tmpUV.x* cos(angle) -tmpUV.y*sin (angle)  ;
				finalUV.y =  tmpUV.x *sin(angle) + tmpUV.y *cos(angle);
				//又移回去
				finalUV += float2(0.5 ,0.5) ;
				fixed4 col = tex2D(_MainTex, finalUV);
				return col;
			}
			ENDCG
		}
	}
}

描边:

方式一:渲染两次,两个pass,一个大一个小。

方式二:找到边缘

模糊:

获取场景渲染结束的最后一张图片:  对一个像素周围的四个点求一个平均。即对一个UV

Unity Shaders and Effects_第4张图片

Alpha测试:

shader1.0 

 因为没有采样函数,所以用过Alpha测试来做

 应用:可以做图片的渐变消失

shader2.0

Unity Shaders and Effects_第5张图片

因为G-Buffer中没有像素点,所以直接显示的黑色。所以要使用Blend命令。

Unity Shaders and Effects_第6张图片

 

5. 模板测试:Stencil

 5.1 作用: 

   一般用作每个像素掩码,来保存或者丢弃像素的作用。

   0-255整数的8位掩码,

   Comp: 引用值与缓冲区当前内容进行比较的函数。

   Pass:模板测试和深度测试都通过了。默认:保持。

   Fail: 模板测试未通过该如何处理缓冲区的内容。默认:保持。

   ZFail: 模具测试通过,但是深度测试失败,该如何处理缓冲区的内容。默认:保持。

   以上操作也可以使用和正面几何图形。

   Comparison  Operation:>   >=    <  <=   ==   !=   模板测试总是通过    模板测试从不通过 

   Unity Shaders and Effects_第7张图片

   Stencil Operation: 

    Unity Shaders and Effects_第8张图片

 

 

ShaderLab: Stencil     file:///D:/unity2018insatll/Editor/Data/Documentation/en/Manual/SL-Stencil.html 

符合条件的通过写入到G-Buffer中,不符合的丢弃。

G-Buffer中包含: RGBA    深度信息   模板信息

公式:输入的值和G-Buffer中的模板值做比较。

Unity Shaders and Effects_第9张图片

Unity Shaders and Effects_第10张图片

应用: 墙穿透效果:

     Stencil {
                Ref 2   //设置模板值等于2 
                Comp always  //使模具测试始终通过。
                Pass replace
            }

<1. 设置前边物体,并且关闭深度缓存,防止前边物体挡住back物体。

<2. 设置中间物体,如果不等于2,则显示出来。否则丢弃掉像素。即被前边物体遮挡的区域就透明掉了。

<3. 设置后边物体, 如果和2相等时,则显示出来。

 

深度测试:

深度: 物体位置到相机水平线的投影。

深度缓存:新的像素和深度缓存中的深度做对比,如果小于深度缓存中的深度,则替换RGBA像素,且替换深度缓存中的深度值。

深度测试: ZWrite  : 将要渲染的物体的Z值和G-buffer中的深度缓存值进行对比。

Unity Shaders and Effects_第11张图片

深度相同时,可以通过调整Offset来微调。强迫一个多边形在另一个上绘制,尽管它们实际上处于相同的位置.

Unity Shaders and Effects_第12张图片Unity Shaders and Effects_第13张图片

 

Blend: 

 

 

 

 

 

 

 

 

 

 

https://www.baidu.com/link?url=o85V5QLsraCjMOmzJc6081Z3bsQRw4_hjoPki5igyrvrJExygnt2Ex-_oGmH60-wm2VU53AsKInafwE2Z7NCB_&wd=&eqid=f46be4f400050577000000065d31d21e

Texture Type

选择适合的类型,Unity会为Unity Shader传递正确的纹理,并对一些纹理进行优化。

Defualt(默认纹理)

Unity Shaders and Effects_第14张图片

 

Normal map(法线纹理)

Unity Shaders and Effects_第15张图片

 

使用了法线纹理类型,Unity会根据不同平台对纹理进行压缩,如DXT5nm格式,通过UnpackNormal函数进行采样,见下面UnityCG.cginc中源码。这种压缩只用两个通道(原来三个),减少法线纹理占用的内存空间。

inline fixed3 UnpackNormalDXT5nm (fixed4 packednormal)
{
    fixed3 normal;
    normal.xy = packednormal.wy * 2 - 1;
    normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
    return normal;
}
inline fixed3 UnpackNormal(fixed4 packednormal)
{
#if defined(UNITY_NO_DXT5nm)
    return packednormal.xyz * 2 - 1;
#else
    return UnpackNormalDXT5nm(packednormal);
#endif
}

 

Create from Grayscale

Unity Shaders and Effects_第16张图片

 

用于高度图生成法线纹理。这样就可以和切线空间下的法线纹理同等对待了。

- Bumpiness:控制凹凸程度

- Filtering:决定凹凸程度计算方式

- Smooth:生成平滑的法线纹理

- Sharp:使用Sobel滤波(一种边缘检测使用的滤波器)生成法线纹理

 

WrapMode

决定纹理坐标超过[0, 1]范围后将会被如何平铺(Tiling)。

Unity Shaders and Effects_第17张图片

 

  • Repeat:如果纹理坐标超过1(同理小于0)时,整数部分会被舍弃,如值为2.23采样值等于0.23。
  • Clamp:如果纹理坐标超过1(同理小于0)时,会截取到1(或0)。

 

渐变纹理应该选择Clamp(下右图)。因为Repeat(下左图)可能产生如下错误,大于1的值如1.01会采样为0.01,为黑色。

Unity Shaders and Effects_第18张图片

 

FilterMode

决定纹理拉伸时采样哪种滤波模式。

 

Point、Bilinear、Trilinear  最邻近插值法、双线性插值以及双三线性插值对比如下,效果依次提升,性能消耗同样增大。

图像插值就是当图像进行放大/缩小时,图像原有的像素数量不足以满足需求,例如从3X3的像素矩阵往4X4的像素矩阵变换的时候,就会出现像素值不知该如何填充的问题,而图像插值算法就是为了解决这个问题。

Unity Shaders and Effects_第19张图片

 

  • Point:最邻近滤波,缩放是采样像素数目只有一个。当纹理的大小与贴图的三维图形的大小差不多时,这种方法非常有效和快捷。如果大小不同,纹理就需要进行放大或缩小,这样,结果就会变得矮胖、变形或模糊。
  • Bilinear:使用线性滤波,找到四个近邻像素,然后进行线性插值混合得到,图像模糊了。

    双线性过滤以pixel对应的纹理坐标为中心,采该纹理坐标周围4个texel的像素,再取平均,以平均值作为采样值。

    双线性过滤像素之间的过渡更加平滑,但是它只作用于一个MipMap Level,它选取texel和pixel之间大小最接近的那一层MipMap进行采样。当和pixel大小匹配的texel大小在两层Mipmap level之间时,双线性过滤在有些情况效果就不太好。于是就有了三线性过滤。

  • Trilinear:几乎和Bilinear一样,只是如果开启多级渐远纹理技术,那就会在多级渐远纹理之间进行混合。

    三线性过滤以双线性过滤为基础。会对pixel大小与texel大小最接近的两层Mipmap level分别进行双线性过滤,然后再对两层得到的结果进生线性插值。

    三线性过滤在一般情况下效果非常理想了。但是到目前为止,我们均是假设是texture投射到屏幕空间是各向同性的。但是当各向异性的情况时,效果仍然不理想,于是产生了Anisotropic Filtering(各向异性过滤)。

多级渐远纹理(mipmapping)

面板中Advanced->Generate Mip Maps默认开启。原理是提前用滤波处理得到更小的图形,每一层都是上一层图像降采样得到,以此类推,形成一个图像金字塔。在物体远离摄像机时,直接使用较小的纹理。缺点是通常会多占用33%的内存空间。

 

 

 

https://blog.csdn.net/candycat1992/article/details/17097907   【Unity Shaders】概述及Diffuse Shading介绍】

https://blog.csdn.net/candycat1992/article/details/39994049   初探Surface Shader背后的机制

第一章 漫反射

1.5 自定义漫反射

Unity Shaders and Effects_第20张图片

Unity Shaders and Effects_第21张图片

如果 你想在着色器代码里通过变量名来获得它的属性值,则必须创建与之对应的另一个变量。
 #pragma surface   告诉编辑器使用哪个光照模型计算。

三种格式的光照模型函数:命名 Lighting+任何名字

● half4 LightingName (SurfaceOutput s, half3 lightDir, half atten){} 该函数用于不需要视角方向的前向着色。

● half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten){} 该函数用于需要视角方向的前向着色。

● half4 LightingName_PrePass (SurfaceOutput s, half4 light){} 该函数用于需要使用延迟着色的项目

1.6 创建 Half Lambert 光照模型

Half Lambert  : 用于在低光照区域照亮 物体的技术。它基本上提高了材质和物体表面周围的漫反射光照。用来防止某个物体的背光面 丢失形状并且显得太过平面化。没有物理原理,只是为了视觉增强。

左:半兰伯特模型  右:普通漫反射

Half Lambert 技术实现的原理:

    把漫反射光照值的范围分成两半,然后加上0.5。基本 意思就是如果光照值是1,对半开后就是 0.5,然后再加 0.5 回去,将会再得到 1。如果你对 0 进行操作,那么你会得到 0.5,因此我们将 0 ~ 1 之间的所有值重新映射到区间 0.5 ~ 1。 

Unity Shaders and Effects_第22张图片

1.7 创建渐变纹理来控制漫反射着色

—使用渐变纹理(ramp texture)来控 制漫反射光照的颜色。这允许你突出表面的颜色,来模拟更多的反射光照或者其他高级的 灯光设置.想要突出艺术画面,不需要真实物理模拟时使用。

tex2D 函数有两个参数,第一个参数是我们使用的纹理,第二个参数包含的是映射纹理的 UV 坐标。 ,tex2D 函数会去搜索(0,0)UV坐标处的纹理像素。

1.8 使用 2D 渐变纹理创建假的 BRDF

由光照函数BRDF【双向反射分布函数】提供的视角方向,观察方向指的是我们看向物体自身的方向。它是一个标注了方向的向量,这意味着我们可以将它和法线以及光照方向结合起来使用。这种视点向量可以为我们提供一种更先进 的纹理索引技术。 

【双向反射分布函数】可以简单理解为入射光在不透明物体表面同时反射到观察方向 (观察者眼睛方向)和出射光两个方向。

Unity Shaders and Effects_第23张图片

当使用观察方向参数时,我们可以创建一个简单的衰减渲染效果。你可以使用这个参 数来制作任何不同类型的效果:一个透明的泡泡、边缘高光效果、盾牌效果,甚至可以制 作卡通边缘线效果。

 

使用纹理贴图制作特效

Unity Shaders and Effects_第24张图片

PC上都是按照最高精度float来计算,而在移动平台。fixed在比较旧的移动平台用,大多数都是把half和fixed当成同精度来处理。

注意: shader中的语法错误,定位行是40行,其错误可能在39行引起的下一行错误。

 

插值:

lerp(a,b,f)=(1-f )* a + b * f  ;

f的取值范围是【0-1】。当f=1时,直接放回b, 当f=0时返回a , f=0.5时,返回(a+b)平均数。

返回的这个数是一个定值,应用时需要把上一次插值的结果作为下一次插值的a.

//transform.position = Vector3.Lerp(transform.position, end, 0.5f);
//Debug.Log(transform.position + "   " + start + "      " + end);

 

2.4 压缩和混合纹理贴图

  原理是:利用插值从一个纹理图片插值到另一个纹理插值,使用第三张贴图的r来作为影响参数。

2.5  法线贴图

   用途: 它是用来在不增加额外多边形的情况下 添加更多的细节。该技术的一个常见用途是通过一个高多边形模型或高度图形成法线贴图, 这样就显著地提高了低多边形模型的表现效果以及细节。 

UnpackNormals() 函数(法线解压函数)来使用法线贴图

2.6  创建程序纹理贴图
   概念:需要动态创建纹理或者在运行时修改它们的像素 值,这种情况通常被称为程序性的纹理效果。

   创建流程: 需要在一个二维空间中创建一组像素然后将其应用到一个新的纹理上。再将创建 的新纹理传入到着色器中,使它们可以在着色器中进行计算。

   应用:使用动态创建纹理贴图的 方式可以制造一种玩家和游戏环境之间的互动效果。也可以用它来制作一些贴花的效果, 或者创建一些可以在着色器函数中使用的程序化形状等。

2.7 Photoshop 色阶效果

色阶是表示图像亮度强弱的指数标准。

Unity Shaders and Effects_第25张图片Unity Shaders and Effects_第26张图片

Unity Shaders and Effects_第27张图片Unity Shaders and Effects_第28张图片

实现原理:


Shader "Custom/ColorStage" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_inBlack("Input Black",Range(0,255)) = 0
		_inGamma("Input Gamma",Range(0,2)) = 1.61
		_inWhite("Input White",Range(0,255)) = 255
		_outWhite("Out White",Range(0,255)) = 255
		_outBlack("Out Black",Range(0,255)) = 0

	}
		SubShader{
			Tags { "RenderType" = "Opaque" }
			LOD 200

			CGPROGRAM
#pragma surface surf Lambert

		float _inBlack;
		float _inGamma;
		float _inWhite;
		float _outWhite;
		float _outBlack;

		float outRPixel;  //存储红色通道

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

		float GetPixelLevel(float pixelColor)
		{
			float pixelResult;
			// 因为tex2D() 函数所提供的颜色值范围是从0 到 1,所以我们需要将其重新映射至 0.0 到 255.0 的范围内
			pixelResult = (pixelColor * 255.0);
			//. 然后减去我们的输入值_inBlack,这样当我们将输入色阶的黑色滑块朝着255.0 滑动 时可以使所有像素变得更暗。
			pixelResult = max(0, pixelResult - _inBlack);
			//然后,当我们将输入色阶的白色滑块朝着0.0 滑动时,可以将所有像素变得更亮,并 对得到的结果求 _inGamma 次方
			pixelResult = saturate(pow(pixelResult / (_inWhite - _inBlack), _inGamma));
			// 最后,我们将新的像素值与_outWhite 减去_outBlack 的差相乘,然后将新的像素值 重新映射到 0.0 ~ 1.0 的范围内:
			//我们使用_outWhite 和 _outBlack 再次修改像素值,这样你就可以对最小像素值 以及最大像素值有一个最终的全局控制了。
			pixelResult = (pixelResult * (_outWhite - _outBlack) + _outBlack) / 255.0;
			return pixelResult;
		}

		void surf (Input IN, inout SurfaceOutput o)
		{
			half4 c = tex2D(_MainTex, IN.uv_MainTex);

			float outRPixel = GetPixelLevel(c.r);
			float outGPixel = GetPixelLevel(c.g);
			float outBPixel = GetPixelLevel(c.b);

			o.Albedo = float3(outRPixel, outGPixel, outBPixel);
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

第 3 章 利用镜面反射让游戏闪耀起来

UnityCG.cginc 文件有Lambert 和 BlinnPhong 两种光照模型可以使用。

 #pragma surface surf BlinnPhong 编译着色器 的时候,你就会告诉着色器使用UnityCG.cginc 文件中的BlinnPhong 光照函数。

#pragma surface surf Lambert.... 实现前边已经说过了。

3.3 创建Phong高光模型:

高光着色器:

Unity Shaders and Effects_第29张图片

告诉编辑器我们创建一个自定义的视点相关性着色器。注意和申明的语句一致。

Unity Shaders and Effects_第30张图片

 

 

 

第6章   透明度

6.2 使用Alpha参数创建透明效果

  修改表面着色器的#pragma语句的参数:

  用来告诉unity允许一个透明表面渲染到屏幕上,可以为内置的值赋值。 o.Alpha = c.b * _MyTransVal;

   Unity Shaders and Effects_第31张图片

修改表面着色器的输出输出参数:标准的输入输出参数改为普通的输入输出

Unity Shaders and Effects_第32张图片

6.3 透明度裁剪着色器

使用一个值来简单的控制某些特定的像素不渲染到屏幕上,因此可以实现一个完全透明和不透明混合的着色器。网易观点:裁剪普遍情况下比半透耗。

Unity Shaders and Effects_第33张图片

Shader "91YGame/TransparentCutoff" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        //申明_Cutoff变量;
        _Cutoff("Cutoff Value",Range(0.01,1))=0.5
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        //告诉着色器 我们需要的是一个裁剪类型的着色器;
        CGPROGRAM
        #pragma surface surf Lambert alphatest:_Cutoff

        sampler2D _MainTex;
        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.r;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

Unity Shaders and Effects_第34张图片Unity Shaders and Effects_第35张图片

透明度混合Blend:

    将片段着色器中计算出来的颜色称之为 “源颜色”,帧缓存中对应的像素已经存在的颜色叫做“目标颜色”。混合操作就是将源颜色与目标颜色以一些选项进行结合。

通用公式 float4 result = SrcFactor * fragment_output + DstFactor * pixel_color;

        Blend SrcAlpha OneMinusSrcAlpha        //alpha blending
        Blend One OneMinusSrcAlpha             //premultiplied alpha blending
        Blend One One                          //additive
        Blend SrcAlpha One                     //additive blending
        Blend OneMinusDstColor One             //soft additive
        Blend DstColor    Zero                 //multiplicative
        Blend DstColor SrcColor                //2x multiplicative
        Blend Zero SrcAlpha                    //multiplicative blending for attenuation by the fragment's alpha

(r,g,b) * a = (r*a , g*a , b*a)
(r,g,b) * (x,y,z) = (r*x , g*y , b*z)
(r,g,b) + (x,y,z) = (r+x , g+y , b+z)
(r,g,b) - (x,y,z)  = (r-x , g-y , b-z)

混合操作的基本语法: Blend SrcFactor DstFactor

Unity Shaders and Effects_第36张图片

例如:

 

Unity Shaders and Effects_第37张图片

根据通用公式:下图

Blend SrcAlpha One  

//源颜色(输出颜色) * 源透明值+目标因子(One) * 目标颜色(帧缓存中的颜色,一般是背景颜色)   

《==》 (1,0,0)*1+(1,1,1)(0,0,0)=(0.5,0.5,0.5)  

Unity Shaders and Effects_第38张图片

《shader入门精要》

Blend SrcFactor DstFactor:  稍微解释一下,这行指令意思就是将本 Shader 计算出的颜色值(源颜色值,即蓝色) * 源Alpha值(0.6) + 目标颜色值(可以理解为背景色) * (1-0.6),从而让蓝色方块展示出了40%的透明度。

 

 

6.4  通过渲染队列进行深度排序

https://blog.csdn.net/puppet_master/article/details/73478905   //学习链接

深度排序: 物体被渲染的先后顺序。利用层级方法来渲染你的物体,也就是利用Unity提供的内置标签。

渲染顺序: 其实前后无所谓的,因为即使是先渲染人模,再渲染栅栏,遮挡部分深度测试成功也会替代人模的部分,这样会造成OverDraw,所以Unity对于不透明物体一般采用从前向后的顺序,把遮挡的部分不用替代了。

Unity Shaders and Effects_第39张图片

初始:

Unity Shaders and Effects_第40张图片  

给前边加上shader,设置成先渲染

Shader "Custom/Depth" { 
    Properties { 
        _MainTex ("Base (RGB)", 2D) = "white" {} 
    } 
    SubShader { 
        Tags { "Queue"="Geometry-20" } //设置渲染顺序,Geometry为2000,-20表示在所有几何体后面显示
        ZWrite Off                     //告诉Unity我们想自己控制该对象的渲染顺序,而不写到深度缓冲中,我们想要重写对象的深度排序,并且我们将会为它指定一个新的渲染队列
        LOD 200  
        CGPROGRAM 
        #pragma surface surf Lambert  
        sampler2D _MainTex;  
        struct Input { 
            float2 uv_MainTex; 
        };  
        void surf (Input IN, inout SurfaceOutput o) { 
            half4 c = tex2D (_MainTex, IN.uv_MainTex); 
            o.Albedo = c.rgb; 
            o.Alpha = c.a; 
        } 
        ENDCG 
    }  
    FallBack "Diffuse" 
}

Unity Shaders and Effects_第41张图片

Pass通道:

之前的shader中都只有一个Pass,也就是单通道渲染,这样的话如果要对同一个RenderTexture在不同的时刻进行不同的渲染效果输出就需要不停的更换shader。

所有需要Pass,根据需求设定通过哪个Pass来进行渲染,从而实现在不同的时候对使用同一个shader对同一个对象进行不同的效果处理。

Unity Shaders and Effects_第42张图片

物体边缘:

Unity Shaders and Effects_第43张图片Unity Shaders and Effects_第44张图片

光向量和法向量求点积,得到的是光线的强度,即光线入眼的多少

摄像机看到这个物体,物体的顶点法线和摄像机视角夹角是90度,越暗,用点积来达到这种类似于边缘查找的效果。

点积的结果越大,越暗, 即法向量和视向量>90度,则越暗。1减去结果作为系数乘以一个边缘光颜色就达到了边缘光的效果。

缺陷:边缘光效果只是在当前模型本身的光照计算时调整了边缘位置的颜色值,并没有达到真正的“描边”

Unity Shaders and Effects_第45张图片

描边 : 边缘泛光shader 2

描边效果:https://blog.csdn.net/puppet_master/article/details/54000951

一般都是在正常模型的渲染状态下,在模型外面扩展出一个描边的效果。既然要让模型的形状有所改变(向外拓一点),那么肯定就和vertex shader有关系了。而我们的描边效果,肯定就是要让模型更“胖”一点,能够把我们原来的大小包裹住;微观一点来看,一个面,如果我们让它向外拓展,而我们指的外,也就是这个面的法线所指向的方向,那么就让这个面朝着法线的方向平移一点;再微观一点来看,对于顶点来说,也就是我们的vertex shader真正要写的内容了,我们正常计算顶点的时候,传入的vertex会经过MVP变换,最终传递给fragment shader,那么我们就可以在这一步让顶点沿着法线的方向稍微平移一些。我们在描边后,描边这一次渲染的边缘其实是没有办法和我们正常的模型进行区分的,为了解决这个问题,就需要用两个Pass来渲染,第一个Pass渲染描边的效果,进行外拓,而第二个Pass进行原本效果的渲染,这样,后面显示的就是稍微“胖”一点的模型,然后正常的模型贴在上面,把中间的部分挡住,边缘挡不住就露出了描边的部分了。
 

第7章  顶点魔法

1. 顶点信息基本应用------提取存储的顶点信息

Unity Shaders and Effects_第46张图片

 

2. 顶点信息进阶应用,顶点信息的应用

.Unity Shaders and Effects_第47张图片

Unity Shaders and Effects_第48张图片

 

第8章   移动平台上着色器的优化

https://www.cnblogs.com/jaffhan/p/7358383.html

8.2 轻型着色器

1.用最少的数据达到相同的效果   

 <1 .计算精度优化。

 float(32bits)half(16bits)fixed(11bits)

  • 对于世界空间位置和纹理坐标,使用float精度。 
  • 对于其他一切(矢量,HDR颜色、UV、颜色值等),首先使用half精度,必要时增加精度。 +-60000
  • 对于纹理数据的非常简单的操作,使用fixed精度。光照、颜色  +-2

  应该使用哪种数据精度取决于平台和GPU::

  • 所有现代桌面级GPU总是以完全float精度进行计算,float/half/fixed在底层是完全相同的。因此在Unity编辑器中(即使切换为移动平台),难以确定半/固定精度是否足够,因此请始终在目标设备上测试着色器以获得准确的结果
  • 移动GPU具有实际half精度支持。通常更快,并且使用更少的功率来进行计算。
  • Fixed精度通常仅对较旧的移动GPU有效。fixed内部处理成和half精度完全一样。 

<2 .把没用到的输入变量删掉

<3. 通过设置灯光的渲染模式  自动选择  逐像素渲染物体  逐顶点渲染物体

Unity Shaders and Effects_第49张图片

 

你可能感兴趣的:(shader)