Shader笔记(创建shader)

  • 上一个笔记补充:Pass{[Name and tags][RenderSetup][TextureSetup]}

TextureSetup主要针对的是顶点着色器。

  • Shader要求:

最终输出一张半透明面片;面片颜色可调;正反面均可显示。

Shader "Custom/Simple"
{
	Properties
	{
		_Color("Base Color",Color)=(1,1,1,1)//颜色控制
		_MainTex("Base(RGB)",2D)="white"{}//输入一张半透明的贴图
	}
	SubShader
	{
	    tags{"Queue"="Transparent""RenderType"="Transparent""IgnoreProjector"="True"}//透明物体渲染顺序、渲染模式、忽略投影

		Blend SrcAlpha OneMinusSrcAlpha   //渲染状态 混合模式 SrcAlpha+OneMinusSrcAlpha=1  SrcAlpha混合因子
	    Pass
		{
		    Name "Simple"
			Cull off//正反面都显示

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

			sampler2D  _MainTex;
			float4 _Color;

			struct v2f//从顶点到片段过度的结构体
			{
			    float4 pos:POSITION;
				float4 uv:TEXCOORD0;
			};//结构体后面要有分号 

			v2f vert(appdata_base v)//获取的是物体坐标系
			{
				v2f o;
				o.pos=UnityObjectToClipPos(v.vertex);//模型坐标系、观察坐标系、投影坐标系变换矩阵相乘=MVP?最后得到的结果是投影坐标系
				o.uv=v.texcoord;
				return o;
			}

			half4 frag(v2f i):COLOR
			{
			    half4 c=tex2D(_MainTex,i.uv.xy)*_Color;//纹理影射
			    return c;
			}


			ENDCG
		}
	}
}

  • 效果:

Shader笔记(创建shader)_第1张图片

  • normal 值在1到-1之间 只有xyz三个值

normal数据转为颜色数据时的操作:


  • 效果:

Shader笔记(创建shader)_第2张图片

  • 如果使贴图*法线颜色

Shader笔记(创建shader)_第3张图片

Shader笔记(创建shader)_第4张图片

frac();  取小数位

saturate(x)   如果x小于0,返回0 ,如果大于1,返回1,否则,返回x。

any() 当前值是否非0   是的话 返回true。

  • 功能扩充:

使得上例中的透明面片可以旋转,可以控制旋转速度。

Shader "Custom/Simple"
{
	Properties
	{
		_Color("Base Color",Color)=(1,1,1,1)//颜色控制
		_MainTex("Base(RGB)",2D)="white"{}//输入一张半透明的贴图
		_RSpeed("RotateSpeed",Range(1,100))=30//设置旋转速度
	}
	SubShader
	{
	    tags{"Queue"="Transparent""RenderType"="Transparent""IgnoreProjector"="True"}//透明物体渲染顺序、渲染模式、忽略投影

		Blend SrcAlpha OneMinusSrcAlpha   //渲染状态 混合模式 SrcAlpha+OneMinusSrcAlpha=1  SrcAlpha混合因子
	    Pass
		{
		    Name "Simple"
			Cull off//正反面都显示

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

			sampler2D  _MainTex;
			float4 _Color;
			float _RSpeed;

			struct v2f//从顶点到片段过度的结构体
			{
			    float4 pos:POSITION;
				float4 uv:TEXCOORD0;
			};//结构体后面要有分号 

			v2f vert(appdata_base v)//获取的是物体坐标系
			{
				v2f o;
				o.pos=UnityObjectToClipPos(v.vertex);//模型坐标系、观察坐标系、投影坐标系变换矩阵相乘=MVP?最后得到的结果是投影坐标系
				o.uv=v.texcoord;
				return o;
			}

			half4 frag(v2f i):COLOR
			{
			    float2 uv=i.uv.xy-float2(0.5,0.5);
				float2 rotate=float2(cos(_RSpeed*_Time.x),sin(_RSpeed*_Time.x));
				uv=float2(uv.x*rotate.x-uv.y*rotate.y,uv.x*rotate.y+uv.y*rotate.x);
				uv+=float2(0.5,0.5);

			    half4 c=tex2D(_MainTex,uv)*_Color;//纹理影射
			    return c;
			}


			ENDCG
		}
	}
}

  • uv坐标的范围是0到1,相当于把3D图形展开成2D面片。坐标系中,左上角0,0 右下角1,1
  • 2D向量的旋转原理 :将UV进行坐标变换

Shader笔记(创建shader)_第5张图片


  • 纹理寻址模式(解释为什么旋转时候边缘会有一些多余图片像素):

Shader笔记(创建shader)_第6张图片

Shader笔记(创建shader)_第7张图片

Shader笔记(创建shader)_第8张图片

Shader笔记(创建shader)_第9张图片

  • 在贴图的设置里  Wrap Mode  分为 Repeat 和Clamp(如果贴图边界透明,则uv坐标系外都设置为透明)

                                 Filter Mode  过滤模式    

                                                       point(最近点)   Bilinear(插值产生新像素图)  Trilinear(三维线性插值)

  • 贴图和画面的像素并不是一对一的关系

贴图缩小:贴图像素密度高,画面像素密度低,需要将多个贴图像素映射到同一个画面像素。如:

Shader笔记(创建shader)_第10张图片

反过来是贴图放大:贴图像素密度低,画面像素密度高,需要将一个贴图像素映射到多个画面像素。

可能造成的问题:

Shader笔记(创建shader)_第11张图片

  • 解决方法:贴图采样   确定当有多个贴图像素可选时,采取什么样的方式选择像素进行贴图

主要两种方法:1.最靠近的像素:Nearest-Point Sampling

                                2.线性插值:Linear Sampling(BiLinear Samling 二维线性采样)  会将最靠近的4个贴图像素进行线性插值,                                                       计算一个新的像素图作为结果。(可以解决贴图放大的问题,但缩小问题依然存在)

 解决贴图缩小时的采样锯齿问题,要使用新贴图结构:mip-map   根据分辨率(距离远近)来调用不同大小

Shader笔记(创建shader)_第12张图片 

(就是需要近处清晰的就调用大图,远处不需要那么清晰的,就调用小图)

  • Mip-map的采样方式:

Shader笔记(创建shader)_第13张图片

Shader笔记(创建shader)_第14张图片

  • 3维线性采样(消耗性能最大 效果最好):

Shader笔记(创建shader)_第15张图片

  • Aniso Level  各向异性等级 可以调整显示细节。
  • _Time:  x,y,z,w代表不同的时间变量


你可能感兴趣的:(unity,shader)