发布时间:2023-01-20 10:00
1. Mesh Filter
存储一个Mesh(网格,模型的网格,就是模型由哪些三角面组成,组成一个什么样子的模型,三角面的一些顶点信息)
2. Mesh Renderer
根据Mesh的顶点信息,渲染一个模型的外观,就是样子,按照Mesh给它皮肤,给它颜色,通过Material(材质)控制模型渲染的样子
3. Material
渲染的样子,包括贴图和Shader,贴图可以没有,可以是一个单纯的颜色
4. Shader
书籍
unity shader 入门精要(乐乐程序猿)
unity 3d shaderlab开发实战详解(第二版)
unity 5.x shaders and effects cookbook(中文版 unity着色器和屏幕特效开发秘籍)
CG语言教程官网
http://http.developer.nvidia.com/CgTutorial/cg_tutorial_frontmatter.html
一些网站
www.shadertoy.com
http://blog.csdn.net/poem_qianmo?viewmode=contents
数学函数在线演示
http://zh.numberempire.com/graphingcalculator.php
光照模型就是一个公式,使用这个公式来计算在某个点的光照效果
标准光照模型
在标准光照模型里面,我们把进入摄像机的光分为下面四个部分
1. 自发光(emissive)
这个部分用于描述当给定一个方向时,一个表面本身会向该方向发射多少辐射量。需要注意的是,如果没有使用全局光照(global illumination)技术,这些自发光的表面并不会真的照亮周围的物体,而是它本身看起来更亮了而已。
2. 高光反射(specular)
这个部分用于描述当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。(高光是指光源照射到物体反射到人的眼镜里时,物体上最亮的那个点就是高光)
3. 漫反射(diffuse)
这个部分用于描述当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。(漫反射是投射在粗糙表面上的光向各个方向反射的现象)
4. 环境光(ambient)
它用于描述其他所有的间接光照
Diffuse = 直射光颜色 * max(0, cosθ)
注:θ为光和法线的夹角
cosθ怎么算
当矢量a与b的模都为1的时候,a与b的点乘结果即为cosθ,所以如果我们可以通过光的单位矢量与法线的单位矢量求得cosθ
定义LightMode
只有定义了正确的LightMode才能得到一些Unity的内置光照变量
Pass
{
Tags{ "LightMode" = "ForwardBase"}
}
包含Unity内置文件
包含unity的内置的Lighting.cginc文件,才可以使用unity内置的变量
shader #include "Lighting.cginc"
逐顶点光照(加入环境光的影响)
Shader "Shader Learning Siki/Lighting/Diffuse PerVertex"
{
Properties
{
_Diffuse("Diffuse Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Pass
{
Tags{ "LightMode" = "ForwardBase"}
CGPROGRAM
//用于取得第一个直射光的颜色 _LightColor0
//用于取得第一个直射光的位置 _WorldSpaceLightPos0
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
struct a2v
{
float4 vertex : POSITION; //告诉Unity把模型空间下的顶点坐标填充给vertex
float3 normal : NORMAL;
};
struct v2f
{
float4 position : SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(a2v v)
{
v2f f;
f.position = mul(UNITY_MATRIX_MVP, v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; //获取环境光
fixed3 normalDir = normalize( mul(v.normal, (float3x3)_World2Object));
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //对于每个顶点来说 光源的位置就是光源的方向,因为光是平行光
fixed3 diffuse = _LightColor0.rgb * max(dot( normalDir, lightDir), 0) * _Diffuse.rgb; //取得漫反射的颜色
f.color = diffuse + ambient; //漫反射光部分和环境光两种光叠加,得到最终的光照结果
return f;
}
fixed4 frag(v2f f) : SV_Target
{
return fixed(f.color, 1.0);
}
ENDCG
}
}
Fallback "Diffuse"
}
逐像素光照可以得到更加平滑的光照效果
逐像素漫反射计算只需要将 在逐顶点漫反射计算中的部分计算挪到片元着色器中计算即可。
Shader "Shader Learning Siki/Lighting/Diffuse PerFragment"
{
Properties
{
_Diffuse("Diffuse Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Pass
{
Tags{ "LightMode" = "ForwardBase"}
CGPROGRAM
//用于取得第一个直射光的颜色 _LightColor0
//用于取得第一个直射光的位置 _WorldSpaceLightPos0
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
struct a2v
{
float4 vertex : POSITION; //告诉Unity把模型空间下的顶点坐标填充给vertex
float3 normal : NORMAL;
};
struct v2f
{
float4 position : SV_POSITION;
fixed3 worldNormalDir : COLOR0;
};
v2f vert(a2v v)
{
v2f f;
f.position = mul(UNITY_MATRIX_MVP, v.vertex);
f.worldNormalDir = mul(v.normal, (float3x3)_World2Object);
return f;
}
fixed4 frag(v2f f) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; //获取环境光
fixed3 normalDir = normalize(f.worldNormalDir);
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //对于每个顶点来说 光源的位置就是光源的方向,因为光是平行光
fixed3 diffuse = _LightColor0.rgb * max(dot( normalDir, lightDir), 0) * _Diffuse.rgb; //取得漫反射的颜色
fixed3 tempColor = diffuse + ambient; //漫反射光部分和环境光两种光叠加,得到最终的光照结果
return fixed(tempColor , 1.0);
}
ENDCG
}
}
}