简单的认识一下-Shader
**
一.
**Shader的三种语言
1 余弦值和角度成(0-180度)负相关
点积值和角度成(0-180度)负相关
2.三种着色器区别
1.Fixed function Shader: 固定管线着色器:比较老的一种着色器,针对高级shader在老显卡上兼容性不很友好的时候 使用固定管线
2.Vertex and Fragment Shader :顶点片段着色器:相对来说比较难的着色器,可以实现复杂的视觉效果
3.Surface Shader: 表面着色器:unity推荐使用的着色器,底层是顶点片段着色器,unity在基础上进行封装,使用起来比较简单,
并且官方处理以一些光照效果。
3.着色器书写格式
Shader “着色器名称”//给当前着色器命名
{
Properties
{
//颜色 贴图 颜色区域
} //属性定义
SubShader{
} //子着色器1
SubShader{} //子着色器2
...
FallBack "备用着色器名称"
}
4.子着色器和FallBack的关系
程序在执行到第一个子着色器的时候,
如果第一个子着色器兼容当前显卡,那么执行第一个子着色器内部代码。
后面的子着色器不再执行。
如果第一个子着色器不兼容,检查第二个,依次类推。。。直到有一个子着色器可以使用。
如果都不兼容 执行FallBack
5.固定管线属性定义
Properties
{
名称 (“显示名称”, Vector) = (.34, .85, .92, 1) // 四维向量值
名称 (“显示名称”, Float) = 0.1// 浮点属性
名称(“显示名称”, Range (0.02,0.15)) = 0.07 // 范围
名称 (“显示名称”, Color) = (.34, .85, .92, 1) // 颜色
名称 (“显示名称”, 2D) = “” {} // 2D纹理
名称 ("显示名称 ", Rect) = “”{}//矩形纹理
}
6.表面着色器属性
float:float2 float3 float4
half:浮点型
int:整型
fixed:定点型
bool:
Sampler2D:纹理类型
string:
7.模型上颜色的叠加用的是乘法,环境光的叠加用加法
8.边缘高光(描边)
视角和物体的视角向量,观察位置点的法线向量
视角向量 和 法线向量的夹角 越接近0 越接近中心 越接近90度 越靠近边缘
余弦值
视角向量 和 法线向量的余弦值 越接近1,夹角越接近0 余弦值越接近0 夹角越接近90
余弦值和 夹角成负相关 余弦值越小的话 越接近边缘
点积
视角向量 和 法线向量的点积 点积值接近1的话 越接近1,夹角越接近0 点积值越接近0 夹角越接近90
余弦值和 夹角成负相关 点积值越小的话 越接近边缘
9.高光Pong光照模型
原理:
计算光的反射向量 和 视角向量的夹角, 光照强度和点积值 是 正相关
夹角越小(余弦值越大,点积值越大,越接近1),当前像素点的光越强
夹角越大(余弦值越小,点积值越小,越接近0),当前像素点的光越弱
10.顶点片段着色器语义
提前约定好的字符(关键字),程序检测到当前字符(关键字) 会把指定数据填充到 变量中
--------------学习之后的认知
shader学习笔记
自定义光照模型
漫反射:法线与光源方向的 点乘
高光:视线(归一化)与光源方向(归一化)的 相加 再与法线的 点乘
**
二.脚本示范
**
1.Fixed function Shader:
Shader "VR180701Zk/FixedFunctionShader001"
{
//属性
Properties
{
//定义一个名称为Main Color属性
_Color("MainColor", Color) =(0.5,0.8,0.3,1)
_SpecularColor("高光颜色",Color)= (1,0.5,0.5,1)
_EmissionColor("自发光颜色",Color)= (1,0.5,0.5,1)
_Shininess("光泽度",Range(0.01,1))=0.5
_MainTex("主纹理",2D) = "" {}
}
SubShader//子着色器
{
pass//通道
{
// SetTexture[_MainTex]{}
// Color(0.6,0.5,0.4)
Material
{
//漫反射
//Diffuse(0.6,0.5,0.4)
//DIFFUSE(0.6,0.5,0.4)
diffuse(0.5,0.8,0.3)
// DIFFUSE[_Color]
// //环境光
Ambient(0.5,0.8,0.3)
// Ambient[_Color]
// //自发光
// Emission[_EmissionColor]
// //高光颜色
// SPECULAR[_SpecularColor]
// //光泽度
// Shininess[_Shininess]
}
//开启光照
Lighting On
//开启高光
SeparateSpecular On
}
}
}
2.Vertex and Fragment Shader
Shader "VR180701Zk/FragmentSpecularShader001"
{
Properties
{
}
SubShader
{
//设置前向渲染
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
Pass
{
CGPROGRAM
//顶点函数 vert为顶点操作方法的主入口
#pragma vertex vert
//片段函数 frag为片段操作方法的主方法
#pragma fragment frag
//引入命名空间 对应的库函数 相当于C#中的using lua中的require
#include "UnityCG.cginc"
#include "Lighting.cginc"
//appdata 结构体 类似于surface中的Input结构体
struct appdata
{
float4 vertex : POSITION;//需要光照点 到 顶点的向量
float3 normal: NORMAL;
};
//2:to vert--->fragment
//传输的数据
struct v2f
{
//必须有的
float4 vertex : SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldLightDir:TEXCOORD1;
float3 worldViewDir:TEXCOORD2;
//fixed3 color:Color;
};
//顶点函数 计算一些数据 比如可以计算光照
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);//必不可少 把模型空间下的顶点坐标通过矩阵转换 转到裁剪空间 才能被显示出来
//传入一个 模型空间下的顶点位置 返回世界空间下的 光照到当前顶点的向量
o.worldLightDir =normalize(WorldSpaceLightDir(v.vertex));//1.v.vertex模型空间坐标变成世界坐标 2.v.vertex编程世界坐标-光源位置的世界坐标
//转换 法线模型空间---->世界空间的转化
o.worldNormal = mul(unity_ObjectToWorld, v.normal) ;//法线从模型空间转化到的世界空间
o.worldViewDir = normalize(WorldSpaceViewDir(v.vertex));;//视角 到 模型顶点的向量
//o.color= diffuse+ambient;
return o;
}
//片段函数 处理片段中的数据 颜色
//SV_Target 会把返回的颜色暂存颜色缓冲区,颜色缓冲区的颜色为模型显示的最后颜色
fixed4 frag (v2f i) : SV_Target
{
//计算h向量
fixed3 h = normalize(i.worldViewDir+i.worldLightDir);
//高光的系数
float nh = saturate(dot(i.worldNormal,h));
float speNh = pow(nh,48);
//高光颜色
fixed3 specular = _LightColor0.rgb*speNh;
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
//diff漫反射系数
float diff =saturate(dot(i.worldNormal,i.worldLightDir));
//每个点的漫反射颜色值
fixed3 diffuse = _LightColor0.rgb*diff;
fixed3 color = diffuse+ambient+specular;
return fixed4(color,1);
}
ENDCG
}
}
}
3.Surface Shader:
1.Lambert光照模式
Shader "VR180701Zk/SurfaceShader001"
{
Properties
{
_MainColor("主颜色",Color) = (1,1,1,1)
_MainTex("主纹理",2D) = ""{}
_NormalTex("法线纹理",2D) = ""{}
_RimColor("边缘高管",Color) = (1,1,1,1)
_RimPower("边缘高光可调节强度",Range(0.1,9.0))=3.0
}
//--------------------------------【子着色器】----------------------------------
SubShader
{
//-----------子着色器标签----------
Tags { "RenderType" = "Opaque" } //标签:渲染非透明物体
//-------------------开始CG着色器编程语言段-----------------
CGPROGRAM //表面着色器的代码段必须放在CGPROGRAM ENDCG中
//【1】光照模式声明:使用兰伯特光照模式
//shader入口 surf入口函数 Lambert光照模式
#pragma surface surf Lambert
//【2】输入结构 可以通过Input输入结构 把模型的一些数据传送shader语言中
//C# 声明struct new
//input就这一个改变结构体会改变输入
struct Input
{
//四元素的颜色值(RGBA)
float4 color : COLOR;
float2 uv_MainTex;
float2 uv_NormalTex;
float3 viewDir;
};
float4 _MainColor;
float4 _RimColor;
float _RimPower;
sampler2D _MainTex;//主纹理
sampler2D _NormalTex;//法线纹理
//【3】表面着色函数的编写
//IN 是输入的模型的数据 inout (C#中out) SurfaceOutput系统内置的结构体
void surf (Input IN, inout SurfaceOutput o)
{
//反射率
// o.Albedo = float3(0.5,0.8,0.3);//(0.5,0.8,0.3)分别对应于RGB分量
//o.Albedo = _MainColor.rgb;//(0.5,0.8,0.3)分别对应于RGB分量
//而o.Albedo = 0.6;等效于写o.Albedo = float3(0.6,0.6,0.6);
//贴图
o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb*_MainColor.rgb;
//法线
o.Normal = UnpackNormal(tex2D(_NormalTex,IN.uv_NormalTex));
//自发光 边缘高光(描边)
float rim = 1-saturate(dot(normalize(IN.viewDir),o.Normal));
o.Emission = _RimColor*pow(rim,_RimPower);
}
//-------------------结束CG着色器编程语言段------------------
ENDCG
}
//“备胎”为普通漫反射
Fallback "Diffuse"
}
2.自定义光照模式
Shader "VR180701Zk/SurfaceShaderSpecular" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
//声明使用CustomSpecular光照模式
#pragma surface surf CustomSpecular
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
fixed4 _Color;
void surf (Input IN, inout SurfaceOutput o) {
// Albedo comes from a texture tinted by color
//fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = _Color.rgb;
}
half4 LightingCustomSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
half3 h = normalize(viewDir+lightDir);
half diff =max(0,dot(s.Normal,lightDir));//漫反射系数 s.Normal模型点的法线
//高光的系数
float nh = saturate(dot(s.Normal,h));
float speNh = pow(nh,48);
half4 c;
c.rgb =s.Albedo *_LightColor0.rgb*diff + _LightColor0.rgb*speNh;//_LightColor0 内置变量 存储当前的光照颜色和强度
return c;
}
ENDCG
}
FallBack "Diffuse"
}
上一篇: 抖音火山版(原火山小视频)无水印视频获取
下一篇: 数组名和&数组名的地址