Shader蛮牛视频教程

http://edu.manew.com/course/96  //学习

顶点着色器主要是处理顶点的平移,缩放等位置或者大小相关的函数。

片段着色器主要处理的是像素的颜色。

任务2 :   三大主流语言

  cg-->unity编译成--> glsl

任务3 :  图像硬件简史    

任务4 : Unity shader的组织形式 

    SubShader  -->  算法的选择 

   【fallback】 回滚,所有的shader失败时,用fallback来保障正确的显示

      

5. Fixed Function shader 固定管线功能的shader

   pass命令 : 

  color()  //()代表参数是一个固定值

   color[]  //[]代表一个参数值 

Shader "Custom/ff_1" {
	properties
	{
	    //
		_Color("Main Color",color)=(1,1,1,1)
		_Ambient("Ambient",color)=(0.3,0.3,0.3,0.3)
		_Specular("Specular",color)=(1,1,1,1)
		_Shininess("Shininess",range(0,8))=6   //range 范围,可拖动的滑动块
		_Emission("Emission",color)=(1,1,1,1)  //取的类型是color
	}
	SubShader{
				pass {
				//color(1,0,0,1)
				//	color[_Color]

				material
				{
					diffuse[_Color]     //漫反射
					ambient[_Ambient]  //ambient  环境光
					specular[_Specular]   //镜面很光滑的物体
					shininess[_Shininess]  //高光反射的区域越集中 参数是一个浮点数
					emission[_Emission]										//自发光

				}
		     	lighting on
		     	//如果使用了specular,则还需要开关
		     	separatespecular on
			}
	}
}

6.

      任务 11 :

Shader "Custom/vf" {

  SubShader{
  pass{  
      //至少有一个pass通道, 把pass通道里的代码段进行处理
      //再shaderlab中要把这个带那段代码作为cg语言编译处理,则需要生命关键字: 
      CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles

      //定制编译值类函数,定制的函数必须要编写,如果没有写pragarm,则默认使用target2.0
	  #pragma vertex vert   			//顶点着色器
      #pragma fragment frag 			//片段着色器
      typedef float4 FL4;   			//定义类型别名和c语言一样
      #define MACROFL FL4(0,0,1,1);     //宏定义

      struct v2f                        //结构体定义   
      {
      float4 pos;
      float2 uv;
      };

//      //传进来的是一个模型当中的顶点数据,输出一个变量必须是float4 4阶的类型
//      void vert(in float2 objPos:POSITION,out float4 pos:POSITION)
//      {
//      pos=float4(objPos,0,1);
//      }
//
//      //计算颜色
//      void frag(out float4 col: COLOR)
//      {
//      col=float4(1,0,0,1);
//      }

      //传进来的是一个模型当中的顶点数据,输出一个变量必须是float4 4阶的类型
      void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
      {
      pos=float4(objPos,0,1);
      col=pos;
      }

      //计算颜色,传入颜色并且输出
      void frag(inout float4 col: COLOR)
      {
      //float 
      //half  //16进制 半精度
      //fixed>fixed  基本类型 九位整数,对颜色的输出用fiexd来表示,真彩色
      //变量可以定义在任何地方,只要使用之前定义
      //int 多数情况按照float来处理的
      //sampler*

      //bool类型
       col=float4(1,0,0,1);  //向量的构造器
       bool bl=false;
       col=bl?col:fixed4(0,1,0,0);
       //float
       float2 fl2=float2(1,0);
       float3 fl3=float3(1,0,1);
       float4 fl4=float4(0,1,0,1);

       //swizzle操作 ==>从某个数据向量中取分量,也可以颠倒分量的顺序 ,也可以重复
       //取得时候xyz,rgb不能重复使用(xyz) (rgba)
       float4 f1=float4(fl2.xy,0,1); 
              f1=float4(fl2.xx,1,1); 
              f1=float4(fl2.xy,fl4.ba);

      	FL4 f2=FL4(1,1,1,1);
      	f2=MACROFL;
       //数据转换
        col=f2;  //宏定义测试

      //矩阵
      float2x2 M2x2={1,0,1,1};  //2行2列
      float2x4 M2x4={ {0,0,1,1},{0,1,0,1} };  //2行4列 1,0,1,1 // 0,1,0,1
      float2x4 M2x4_1={ fl4,{0,1,0,1} };  //2行4列 1,0,1,1 // 0,1,0,1
      //矩阵不能改变量的值
      col=M2x4_1[0];  //取第一行


      //数组,不能swizzle操作
      float arr[4]={1,0.5,0.5,1};
      col=float4(arr[0],arr[1],arr[2],arr[3] );

      //结构体的使用
      v2f o;
      o.pos=fl4;
      o.uv=fl2;
      }

      ENDCG
  }
  }
}

12.Cg语言入门5流程控制

    //switch在Cg中支持不好,模型中x的最小值-0.5,最大值 0.5,单位立方体
    //循环控制语

     //while的循环次数和显卡有关

Shader "Custom/vf11" {

	SubShader {

	pass
	{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
 	    //传进来的是一个模型当中的顶点数据,输出一个变量必须是float4 4阶的类型
	void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
	{
		pos=float4(objPos,0,1);
		//Cg条件控制语句
		if(pos.x<0&&pos.y<0) //红色
		{
		col=float4(1,0,0,1);
		}
		else if(pos.x<0)
		{
		col=float4(0,1,0,1);

		}else if(pos.y>0)
		{
		col=float4(1,1,0,1);
		}
		else
		{
	     col=float4(0,0,1,1);
		}
	 }

	//计算颜色,传入颜色并且输出
	void frag(inout float4 col: COLOR)
	{
		//switch在Cg中支持不好,模型中x的最小值-0.5,最大值 0.5,单位立方体
		//循环控制语句
		int i=0;
		while(i<10)
		{
		i++;
		}
		if(i==10)
		{
		col=float4(0,0,0,1);
		}
		i=0;

		do
		{
		i++;
		}while(i<10);

		if(i==10)
		{
		col=float4(1,1,1,1);
		}

		for(i=0;i<1023;i++){}
		if(i==1023)//显卡
		{
		col=float4(0.5,0.5,0,1);
		}
    }
		ENDCG
	}
}
	FallBack "Diffuse"
}

13.Cg语言入门,Cg函数_1

    代码的复用,函数的申明,函数参数都是值拷贝方式传递 ,或者使用out参数

Shader "Custom/vf2" {

		Subshader{
			pass{
			CGPROGRAM

            #pragma exclude_renderers d3d11 xbox360 gles
			#pragma vertex vert
			#pragma fragment frag
			#include "Assets\sbin\sbin.cginc"

//			void Func(out float4 c);
//			float FunArr(float arr[2]);
			void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
			{
			pos=float4(objPos,0,1);
			col=pos;
			}
			void frag(inout float4 col:COLOR)
			{
			 //Func(col);
			  float arr[]={0.5,0.5};
			  col.x=FunArr(arr) ;

			}

  //********************************************************************************
//			//CG总是数据类型都是值拷贝,如果想有效,则使用out参数
//			void Func(out float4 c)
//			{
//			c=float4(0,1,0,1);
//			}
//			//数组的传递
//			float FunArr(float arr[2])
//			{
//			  //初始化
//			  float num=0;
//			  for(int cow=0;cow<arr.Length;cow++)
//			  {
//			  num+=arr[cow];
//			  }
//			  return num;
//			}
//**********************************************************************************
			//代码的复用   .cginc//高亮   


			ENDCG
			}
		}
	}

     14.Cg语言入门,Cg函数_2

       cg标准函数库    https://wenku.baidu.com/view/3a9db318fad6195f312ba675.html

      

       数学函数  

      几何函数,距离判断,反射折射

      纹理函数  

      导出函数

 14.3D数学基础 1,坐标系

模型坐标系------各种矩阵变换-------->世界坐标系------视口变换--->摄像机坐标系----投影变换--》屏幕投影坐标系

(1).模型坐标系

  (2)3D中的世界坐标系

  (3)摄像机坐标系

(4)屏幕坐标系

         做投影算法,3D模型透视投影

16. 3D数学基础:向量

  4d向量,又叫齐次向量,主要是用在矩阵运算

  (1)加法:对应分量分别相加

(2)减法 :对应分量分别相减

   

(3)和标量相乘,和分量分别相乘

(4)模长x平方+y平方,再开平方

(5)点积

Dot(v1,v2)=v1*v2=对应分量相乘再相加=一个变量值

可以计算两个向量的夹角

1--》0度

0.5--》60度

0--》90度         <90,则>0  =90,则=0     >90,则<0

计算1: 两个向量分量对应相乘再相加

(6)叉积

几何意义: 得到垂直向量

17   . 数学基础  矩阵

矩阵的维度和记法

矩阵的转置 :T表示转置

矩阵和标量的乘法 :每个元素分别相乘

矩阵和矩阵的乘法 : 

规律:(1). 用第一个矩阵得第一行得每个分量和第二行得每一列的每个分量(然后再第二行),再相加

           (2).交换位置,再转置,乘积是原来没有交换位置和转置的值

           (3).   3行2列矩阵和3行3列矩阵不能相乘,要把3行2列矩阵做一下转置,转成2行3列的矩阵,再相乘

eg: 3*3矩阵乘以3*1列向量,则值是列向量

      (4)单位矩阵,主对角线都是1,单位矩阵乘另一个矩阵,还是原来的矩阵。

18.   3D数学,矩阵和行列式

      .矩阵和变换       2D旋转矩阵     3D旋转矩阵  c#顶点变换demo

      (1) 2D旋转矩阵     

19. 矩阵的逆

     2D缩放矩阵

k是缩放因子,N 是向量

3D旋转矩阵,绕坐标轴旋转

参考: https://blog.csdn.net/haiying2016/article/details/77685459,描述的旋转后每个点对应的关系

3D缩放矩阵,绕任一个轴n进行缩放

缩放矩阵: 

物体变换的组合: 

P物体的每个顶点的位置   M变换矩阵

20. 矩阵和变换

向量扩展为3维的

 

透视投影: 

21. 矩阵变换三维渲染—1

22. 矩阵变换三维渲染__2

23. 矩阵变换三维渲染__3

24. 矩阵变换三维渲染__4

   方阵: 行数和列数相等,只有方阵的行列式有定义

2阶矩阵行列式: 主对角线是正,反对角线是负值

3阶方阵

3阶矩阵行列式: 主对角线和反对角线

代数余子式来计算n*n阶的行列式

n*n的行列式: 选随便一行中随便取四个数再*概该数的余子式

余子式是:取除掉这个数的行和列,剩下的数组成的矩阵就是这个数的余子式

系数的符号: (-1)i+j次方,i+j是行和列的系数,来判断是取正值还是取负数

完了后再按照3阶矩阵的余子式乘法

25.  矩阵变换三维渲染__5

   矩阵的逆 逆的定义 计算 正交矩阵和它的逆

  单位矩阵。它是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1。除此以外全都为0。

  行列式为0,则是奇异矩阵 ,没有逆矩阵 ,逆矩阵行列式不为0

  标准伴随矩阵:http://edu.manew.com/course/96/task/1442/show

   标准伴随矩阵过程: 先求原矩阵每个数的代数余子式,再转置

    

矩阵求逆: 伴随矩阵 / 该矩阵的行列式

  

逆矩阵*原矩阵=单位矩阵(单位矩阵:主对角线=1,其他都是0)

矩阵的逆: 用于撤销对图像的变换,投影变换是撤销不了的

正常计算矩阵的逆: 原矩阵的代数余子式矩阵-->转置--》伴随矩阵--》除以行列式,如果是正交矩阵,则不用

26. 矩阵变换三维渲染__6,矩阵的逆矩阵

27. 顶点数据的输入与输出 1

//vert顶点程序所有的输出必须要带一个语义,一个语义只能有一个输出(没有赋值不算输出,默认无效).

//frag程序使用POSITIO语义的变量,有且只有一个,顶点和片段 语义相同则就是同一个变量,和变量名无关

28. 顶点数据的输出和输出2,使用结构体对顶点的输出左包装

29. 更好的数据组织方式struct

30.  Vertex Shader - Uniform 与 properties属性

31: Vertex Shader - 几何变换 —MVP矩阵变换 1

32 :Vertex Shader - 几何变换 —MVP矩阵变换 2

33: Vertex Shader - 几何变换 —顶点颜色变换 1

     模型:x,y最小值是-0.5,最大值是   0.5

34: Vertex Shader - 几何变换 —顶点颜色变换 2

35:Vertex Shader - 几何变换 —顶点位移

Shader "Custom/vf35" {

properties
{
_R("R",range(0,5))=1
_OX("OX",range(-5,5))=0
}
	SubShader 
	{
		pass
		{

		    //file:///D:/unity5.3.4/Editor/Data/Documentation/en/Manual/SL-UnityShaderVariables.html
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
			    #include "unitycg.cginc"

			    float4x4 mvp;
			    float4x4 rm;
			    float4x4 sm;
			    float _R;
			    float _OX;

			    typedef struct v2f
				{
					//定义时把语义就指明
					float4 pos:POSITION;
					fixed4 col:COLOR;
				}V2f;


				//语义对应即可
				//如果需要改变颜色时,可以使用屏幕坐标,来集中处理
				//模型顶点位移的变化,在mvp之前处理变化
				//基于物理的网格特性shader中没有的,shader只是改变的顶点的位置信息来显示
				V2f vert(appdata_base v)  //函数的返回语义
				{
				    float4 wpos=mul(_Object2World,v.vertex);

					float2 xy=wpos.xz;  //取得是3维度的xz,范围

					float d=_R-length(xy-float2(_OX,0)); //计算模长  /计算向量的模长sqrt( (xy.x-0)*(xy.x-0)+(xy.y-0)*(xy.y-0) ); //减圆心分量是0 
					d=d<0?0:d;
					float height=1;
					float4 uppos=float4(v.vertex.x,height*d,v.vertex.z,v.vertex.w);
					V2f o;
					o.pos=mul(UNITY_MATRIX_MVP,uppos);  //矩阵乘法 得到得m*顶点
					o.col=fixed4(uppos.y,uppos.y,uppos.y,1);

					return o; 
				}

				//frag程序使用POSITIO语义的变量,有且只有一个,顶点和片段 语义相同则就是同一个变量
				fixed4 frag(V2f IN):COLOR
				{
			      return IN.col;
				}


				ENDCG
		}
  }
}

36: Vertex Shader - 几何变换 —扭曲

Shader "Custom/vf36" {

	SubShader 
	{
		pass
		{

		    //file:///D:/unity5.3.4/Editor/Data/Documentation/en/Manual/SL-UnityShaderVariables.html
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
			    #include "unitycg.cginc"

			    float4x4 mvp;
			    float4x4 rm;
			    float4x4 sm;
			    float _R;
			    float _OX;

			    typedef struct v2f
				{
					//定义时把语义就指明
					float4 pos:POSITION;
					fixed4 col:COLOR;
				}V2f;


				//语义对应即可
				//如果需要改变颜色时,可以使用屏幕坐标,来集中处理
				//模型顶点位移的变化,在mvp之前处理变化
				//基于物理的网格特性shader中没有的,shader只是改变的顶点的位置信息来显示
				V2f vert(appdata_base v)  //函数的返回语义
				{

					//弯曲变换
//				    float angle=length(v.vertex)*_SinTime.w;  ////计算模长  /计算向量的模长sqrt( (xy.x-0)*(xy.x-0)+(xy.y-0)*(xy.y-0) ); //减圆心分量是0 
				    //把顶点绕y轴旋转
//				    float4x4 m=
//				    {
//				    float4(cos(angle),0,sin(angle),0),
//				    float4(0,1,0,0),
//				    float4(-sin(angle),0,cos(angle),0),
//				    float4(0,0,0,1)
//				    };



					//扭曲变换
                    float angle=v.vertex.z+_Time.w; 
				    float4x4 m=
				    {
				    float4(sin(angle)/8+0.5,0,0,0),
				    float4(0,1,0,0),
				    float4(0,0,1,0),
				    float4(0,0,0,1)
				    };

				   //用投射到屏幕后的来影响矩阵m
				    v.vertex=mul(m,v.vertex);
					V2f o;
					o.pos=mul(UNITY_MATRIX_MVP,v.vertex);  //矩阵乘法 得到得m*顶点
					o.col=fixed4(0,1,1,1);
			
					return o; 
				}

				//frag程序使用POSITIO语义的变量,有且只有一个,顶点和片段 语义相同则就是同一个变量
				fixed4 frag(V2f IN):COLOR
				{
			      return IN.col;
				}


				ENDCG
		}
  }
}

37: Vertex Shader - 几何变换 —波

     

   38:图形学入门 - 法向量与光照http://edu.manew.com/course/96/task/1550/show

     (1) 光的向量的方向是相反的,一定是从模型的顶点指向光

    (2)光的计算:需要两个向量,一个是法向量,一个是从顶点指向光源的向量

(3)两个向量规范化后,点积越小,光线越弱,判断法向量和视向量(camera)>90度,背对着,不可以显示

   点积: 

叉积:左手,四指从u指向v,大拇指的方向就是法向的方向,u*v得到向上的法向量,乘法顺序

叉积运算:

uV->叉积 法向量-->再和光向量点击

见图:

    

         //因为我们是在xy平面上,所以判断z轴
        var crossResult = Vector3.Cross(Vector3.up,p2-p1).z;
        //Vector3.Cross(trans1.up, trans2.position - trans1.position).z; //transform的写法
        Debug.Log("crossResult:" + crossResult);

39:基础实例 - C# 光照渲染 1//??

40:基础实例- C# 光照渲染 2

        float dot;
        bool cullBack;
        /// <summary>
        /// 计算三角形光照
        /// </summary>
        public void CalculateNormal(MatriX4x4 _Object2World,Vector4 _light)
        {
            //一: 物体到世界
            this.Transform(_Object2World); 
            //二:法线向量叉乘
            Vector4 U = this.b - this.a;
            Vector4 V = this.c - this.a;
            Vector4 normal= U.Cross(V);  //法向量用U叉乘V
            //三: 法线向量规范化后求点积,求点积的向量必须是规范化后的
            dot = normal.Normalized.Dot(_light.Normalized);
            dot = Math.Max(0, dot);

            //背面光照剔除,法向量和视向量点积后,如果<0,则是背面,剔除
            Vector4 E = new Vector4(0,0,-1,0);
            cullBack = normal.Normalized.Dot(E) <0? true : false;
            }

   41:基础实例- C# 光照渲染 3

   42:基础实例- C# 光照渲染 4

  绘制cube,该面看的到,是顺时针绘制,看不到反时针

 43:图形学入门 - 实现漫反射 Diffuse shader 1

   tags{"LightMode"="ForwardBase"}  //加这个标签就可以支持顶点光照

UNITY_LIGHTMODEL_AMBIENT环境光,必须要加,不然计算光照没有意义

     #include "lighting.cginc"

    点击的计算 法和光 向量必须是同一个坐标系中

44: 图形学入门 - 实现漫反射 Diffuse shader 2

  

			V2f vert(appdata_base v)  //函数的返回语义
				{
					V2f o;
					o.pos=mul(UNITY_MATRIX_MVP,v.vertex);  //矩阵乘法 得到得m*顶点
					o.col=fixed4(0,0,1,1);

					//v.normal=mul(_Object2World,v.normal);

					float3 N= normalize(v.normal);
					float3 L=normalize(_WorldSpaceLightPos0);

					N=mul(float4(N,0),_World2Object);  //交换参数传递顺序是转置矩阵  模型进行非等比例缩放后,用物体到模型的矩阵的逆矩阵的转置矩阵
					N= normalize(N);

			        //N=mul(_Object2World,float4(N,0).xyz);
					//L=mul(_World2Object,float4(L,0).xyz);  //把光向量转到模型坐标系

					float ndot1=saturate(dot(N,L) );//saturate 限定取得的值是0-1
					o.col=_LightColor0*ndot1;  //_LightColor0 光照射后的颜色

					return o; 
				}

     45:图形学入门 - 反射向量与Cg reflect函数

    46:图形学入门 – 实现phong 光照

    R=Reflect(I,N)  //l是入射光 N是法线向量,是否是高亮
 

Shader "Custom/vf46" {

		   properties
		   {
		   _SpecularColor("SpecularColor",color)=(1,1,1,1)
		   _Shininess("Shininess",range(1,64))  = 8//衰减
		   }
	SubShader 
	{
	    //file:///D:/unity5.3.4/Editor/Data/Documentation/en/Manual/SL-UnityShaderVariables.html
		pass
		{

		    //此处申明,什么通道,用什么函数
		    tags{"LightMode"="ForwardBase"}  //加这个标签就可以支持顶点光照  
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
			    #include "unitycg.cginc"
			     #include "lighting.cginc"

			    float4 _SpecularColor;
			    float _Shininess;
			    typedef struct v2f
				{
					float4 pos:POSITION;
					fixed4 col:COLOR;
				}V2f;

				V2f vert(appdata_base v)  //函数的返回语义
				{
					V2f o;
					o.pos=mul(UNITY_MATRIX_MVP,v.vertex);  //矩阵乘法 得到得m*顶点
					o.col=fixed4(0,0,1,1);

					float3 N= normalize(v.normal);
					//获取世界空间中的光的位置信息,并且归一化
					float3 L=normalize(_WorldSpaceLightPos0);


					//模型进行非等比例缩放后,用物体到模型的矩阵的逆矩阵(m->w或者w->m)的转置矩阵
					N=mul(float4(N,0),_World2Object).xyz;  //交换参数的传递顺序是转置矩阵  
					N= normalize(N);

					float ndot1=saturate(dot(N,L) );//saturate 限定取得的值是0-1
					o.col=_LightColor0*ndot1;  //_LightColor0 光照射后的颜色

					//wpos是世界空间中光的位置向量
					//float3 wpos=mul(_Object2World,v.vertex).xyz;
					//wpos -WorldSpaceLightPos0; 取反顶点到光源的方向

					//照射点到光源的向量,慢反射光
					float3 I=-WorldSpaceLightDir(v.vertex);   
					float3 R=reflect(I,N);   
					float3 V=WorldSpaceViewDir(v.vertex);  //谁相机视向量
					R=normalize(R);
					V=normalize(V);
					//镜面反射,光线是否全部进入到摄像机中
					float specularScale=pow( saturate(dot(R,V)),_Shininess);//pow(,n) n次方,模拟衰减的幅度
					o.col.rgb+=_SpecularColor*specularScale;


					return o; 
				}

				fixed4 frag(V2f IN):COLOR
				{
			      return IN.col+UNITY_LIGHTMODEL_AMBIENT; //UNITY_LIGHTMODEL_AMBIENT环境光,必须要加,不然计算光照没有意义
				}		
				ENDCG
		}
  }
}

47 . 图形学入门 - 半角向量与BlinnPhong——反射向量的原理

下图说明: 如果是单位向量,则Cos(N,L)=Dot(N,L)==>R  世界坐标

//光叠加使用->Phong模型

//BlinnPhong模型 没有使用点积

以下向量都是规范化向量

x,r都是单位向量的长度是1

BlinnPhong

入射光向量L和视向量求半角向量,半角向量和N法线求点积,先规范化后

48:Fragment shader - 片段级光照 1

顶点:基于顶点的,顶点的位置,缩放

片段:是基于像素的,颜色

漫反射:需要环境光

在顶点程序中处理光照和法线是不行的,因为每个顶点程序是把每个顶点并行来处理,在片段中一个三角面会使用同一个顶点的数据和法向量,在片段中基于原始的数据(顶点和法向量)来处理

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

49: Fragment shader - 片段级光照 2

50:Fragment shader - 片段级光照 3

 阴影投射器: 创建的球体,如果使用5.0之后的标准着色器,则点光源必须是Soft Shadows,接收阴影

自己创建的shadow没有接收阴影,需要回滚到unity中检查看是否使用阴影投射器fallback "Diffuse" 

51:Fragment shader - 片段颜色混合

 (1)让自己的shader材质接收阴影

blend: 一个生成的颜色乘以原计数

52: Fragment shader - 边缘泛光shader 1

   (1)设置shader的透明:

    //需求:边缘地方很亮,不是边缘的很暗,
    //摄像机看到这个物体,最边缘的顶点法线和摄像机视角夹角是90度,越暗,用点积来达到这种类似于边缘查找的效果

      tags{"queue"="transparent"}  //设置透明,渲染的顺序设置为transparent(透明)

      blend srcalpha oneminussrcalpha  //1-srcalpha(当前屏幕物体的阿尔法)
      float bright=1.0-saturate( dot(N,V) );     //越暗则越亮:  点积的结果越大,越暗 法向量和视向量>90度,则越暗

      zwrite off  //写入深度的关闭,则透明物体之间没有遮挡

53: Fragment shader - 边缘泛光shader 2

54:Fragment shader - 片段级模型动态变色 1

55:Fragment shader - 片段级模型动态变色 2 

       if else 使用过多会导致机器硬件可能编译出错,是汇编语言

      lerp(a,b,c)//用a*(1-c)+b*c

必须知道模型本地坐标最大最小数据是多少

     

Shader "Custom/vf54" {


   properties
   {
   _MainColor("MainColor",color)=(1,1,1,1)
   _SecondColor("SecondColor",color)=(1,1,1,1)
   _Center("Center",range(-0.7,0.7))=0.2
   _R("R",range(-0.5,0.5))=0
   }
	SubShader
	{
		pass
		{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "unitycg.cginc"


		float4 _MainColor;
		float4 _SecondColor;
		float _Center;
		float _R;

		//顶点输出数据的结构体
		struct v2f
		{
		 float4 pos:POSITION;
		 float y:TEXCOORD0;//COLOR语义的变量会强制转正值
		};

		v2f vert(appdata_base v)
		{
		   v2f o;
		   o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
		   o.y=v.vertex.y;
		   return o;
		}
		fixed4 frag(v2f IN):COLOR
		{
	      float d=IN.y-_Center; //润和的中心点 //0.3  0.2 0
	      float s=abs(d); 
	      d=d/s;//正或负 -1<-->1
	      float f=s/_R; //接近润和点的润和比率
	      f=saturate(f); //限定在0-1,如>1,全部润和
	      d=d*f; 
	      d=d/2+0.5;
	      return lerp(_MainColor,_SecondColor,d);

		}

		ENDCG
		}
	}

}

56: Fragment shader - 片段级模型动态变色 3

       (1)求一个模型滋生坐标的最大最小值

        Vector3[] vec1=    mf1.mesh.vertices;
        float max= vec1.Max (v=>v.x);
        float min=    vec1.Min (v=>v.x);
        Debug.Log (max+"   "+min);

      (2)

           表面shader是一个框架,编译时会自动带上语义,里面封装了完整的光的处理

          让Surface Shader使用顶点着色器,插入编译指令  

         appdata_base //中只包含少了的顶点数据  appdata_full包含所有的的顶点数据

        Albedo时影响材质的亮度

57: Fragment shader - 2D纹理采样 1

     _MainTex的数据类型是sampler2D

     DX11之前,2D纹理采样只能写在片段着色器中

设置:

WrapMode:图片导入模式设置为Repeat时,可以重复,则当U值是负值的时候,则会把图片拼接到左边

FilterMode(图像过滤模式):没有过滤时不会有颜色的重合计算,Biliner双线性过滤模式,Triliner三线性过滤模式,

U*512  获取的这个值得不到一个整数的时候,第一种就近采样,第二种Biliner,会找周围四个点(权重),得到这个颜色,

Triliner三线性过滤模式

采样:  fixed4 col=tex2D(_MainTex,IN.uv);//采样函数

58:Fragment shader - 2D纹理采样 2

     Tiling : x,y 表示再x和y放方向上平铺的数量

     _MainTex_ST.xy+_MainTex_ST.zw  //.xy 平铺   zw偏移

59:Fragment shader - 2D纹理采样 3

    

60.  Fragment shader – UV动画 1

61:Fragment shader – UV动画 2_uv本身的改变

62:Fragment shader – UV动画 3

旋转时时,正视摄像机,则清晰,反之模糊

63: Fragment shader –纹理混合动画 1

   创建动态背景,不使用粒子

  cg种二维向量加float,则对每一位分量都加float

   shader种过多使用sin和cos会使性能变慢,过多使用半透明回事性能变慢

64:Fragment shader –纹理混合动画 2 _两张纹理混合 _//alf半透明混合(增加性能)  多pass通道混合

66:纹理程序

66:Fragment shader – 程序纹理水波仿真1

67: Fragment shader – 程序纹理水波仿真2

   1. 范围压缩: -1<--->1  0<---->1  ==》 0ffest_u/2*0.5f         0<--->1  -1<---->1  ==》 0ffest_u*2-1;

   2.数组之间不要拷贝,使用交换引用的的方式  

              float[,] temp = waveA;
              waveA = wavaB;
              waveB = temp;

68.69

70: Fragment shader - Alpha 与 blend 运算  //对半透明物体额绘制

     Zwrite off   //不要进行深度写入,前提是深度测试ztest通过   使用透明或者不透明

 71: Fragment shader 7 - 实现半透明着色 1   的制作,把zwirte关闭 

    效果: 角色: 一半处于透明。遮挡后处于高亮显示

72: Fragment shader 7 - 实现半透明着色 2  深度纹理采样

73:Fragment shader - 纹理法线与凹凸贴图 1

       (1)凹凸映射  对法线进行编程 法线存在纹理中,再用纹理和光进行交互

74:Fragment shader - 纹理法线与凹凸贴图 2——从灰度到法线纹理,相邻灰度差

      取出灰度值,构成高度差,图片要写入时用rgb32,使用压缩后再写入

75: Fragment shader - 纹理法线与凹凸贴图 3

猜你喜欢

转载自blog.csdn.net/qq_35433081/article/details/83011520
今日推荐