ShaderLab学习笔记

来源:互联网 发布:mac谷歌翻墙教程 编辑:程序博客网 时间:2024/06/05 17:11

笔记:

18.mesh Filter 存储一个Mesh(网格,模型的网络,即模型的所有三角面信息)

19.mesh Render 用来渲染模型外观 (贴图+shader)
20.游戏程序(shader命令)->图形接口(OpenGL,DirectX)->显卡驱动->显卡渲染
21.GLSL OpenGL HLSL DirectX
CG语言 Nvidia 在两个平台都可以使用
Unity中ShaderLab(对CG封装)
22.Shader分类:1)表面着色器 Surface 2)顶点片元着色器 Vertex/Fragment Shader 3)固定函数着色器(弃用)
23.shader中的属性:Color,Vector,Int,Float,Range,2D,Cube,3D
   对应shader代码中数据结构:float4,float3,float2,float,half,fixed,sampler2D,sampler3D
   float 32 half 16 fixed 11
24.shader中的语义
   从应用程序传递到顶点函数的语义包括:POSITION 顶点坐标(模型空间下)
                                       NORMAL 法线(模型空间下)
                                       TANGENT 切线(模型空间下)
                                       TEXCOORD 0-n 纹理坐标
                                       COLOR 顶点颜色
   从顶点函数传递给片元函数的时候可以使用的语义
                                       SV_POSITION 剪裁空间中的顶点坐标(一般是系统直接使用)
                                       COLOR0 可以传递一组值
                                       TEXCOORD 0-7 传递纹理坐标
   片元函数传递给系统
   SV_Target 颜色值,显示到屏幕上的颜色
25.标准光照模型
   标准光照模型中,我们把进入摄像机的光分为四个部分
   自发光:
   高光反射:specular=直射光*pow(cosθ,高光参数x) θ是反射光和摄像机方向的夹角 x值越大光圈越小
   漫反射:diffuse =直射光颜色*max(0,cosθ(光和法线的夹角))
   环境光:abmbient
26.Tags{"LightMode"="ForwardBase"}
只有定义了正确的LightMode才能得到一些Unity的内置光照变量
#include "Lighting.cginc"
包含Unity的内置的文件,擦恶意使用Unity内置的一些变量


27.normalize()用来把一个向量单位化
   max()用来取得最大值
   dot 用来取得两个向量的点积
   _WorldSpaceLightPos() 取得平行光的位置
   _LightColor()取得平行光的颜色
   UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
   _World2Object 这个矩阵用来把一个方向向量从世界空间转换到模型空间
   UNITY_LIGHTMODEL_AMBITENT 用来获取环境光
   reflect(a,b) a为入射光,b为法向量,得到的是反射光
   
29.兰伯特光照模型
   Diffuse=直射光颜色*max(0,cosθ) cosθ即光和法线的夹角 cosθ=光方向*法线方向
   半兰伯特光照模型
   Diffuse=直射光颜色*max(cosθ*0.5+0.5)
   半兰伯特光照模型可以让背光面不是完全的黑暗,效果较好


30.Blinn光照模型
   Specular=直射光*pow(max(cosθ,0),高光参数)
   Blinn-Phong 光照模型
   Specular=直射光*pow(max(cosβ,0),高光参数) β是视野方向与反射光方向夹角的一半


31.UnityCG.cginc 中一些常用函数
   摄像机方向(视角方向)
   float3 WorldSpaceViewDir(float4 v) 根据模型空间中的顶点坐标得到(世界空间)从这个点到摄像机的观察方向
   float3 UnityWorldSpaceViewDir(float4 v) 世界空间中的顶点坐标==>世界空间从这个点到摄像机的观察方向
   float3 ObjSpaceViewDir(float4 v) 模型空间中的顶点坐标==>模型空间从这个点到摄像机的观察方向
   光源方向
   float3 WorldSpaceLightDir(float4 v) 模型空间中的顶点坐标==>世界空间中从这个点到光源的方向
   float3 UnityWorldSpaceLightDir(float4 v) 世界空间中的顶点坐标==>世界空间中从这个点到光源的方向
   float3 ObjSpaceLightDir(float4 v) 模型空间中的顶点坐标==>模型空间从这个点到光源的方向
   方向转换
   float3 UnityObjectToWorldNormal(float3 norm) 法线方向 模型空间==>世界空间
   float3 UnityObjectToWorldDir(float3 dir) 方向 模型空间==>世界空间
   float4 UnityWorldToObjectDir(float3 dir) 方向 世界空间==>模型空间
   
32.纹理贴图及法线映射
   tex2D(贴图,纹理坐标) 返回像素点的颜色
   贴图偏移量及缩放
   贴图名+_ST中xy存储着偏移,zw存储着缩放
   法线映射用一张贴图上的rgb值存储该点坐标的法线向量,使用法线映射可以在不用修改模型情况下产生立体感
   切线空间贴图为蓝色;模型空间贴图包含各种颜色
   由于法线向量取值为-1到+1,rgb存储0到1 所以使用算法 pixel=(normal+1)/2
   使用预设的宏TANGENT_SPACE_ROTATION会在rotation(内置的字段)生成矩阵,使用该矩阵可以把模型空间中光

的方向转换到切线空间中


代码及注释:

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Custom/myShader6" {    Properties{  _Color("Color",COLOR)=(1,1,1,1)  _Specular("Specular",Range(8,200))=8  _MainTex("Texture",2D)="white"{}  _NormalMap("NormalTex",2D)="bump"{}  _BumpScale("BumpScale",Float)=1}SubShader {Pass{    Tags{"LightMode"="ForwardBase"}CGPROGRAM#include "Lighting.cginc"#pragma vertex vert#pragma fragment frag        //向顶点函数传递变量的结构体,包括://POSITION 顶点坐标(模型空间下)        //NORMAL 法线(模型空间下)        //TANGENT 切线(模型空间下)        //TEXCOORD 0-n 纹理坐标        //COLOR 顶点颜色sampler2D _MainTex;sampler2D _NormalMap;float4 _NormalMap_ST;float4 _MainTex_ST;float4 _Color;int _Specular;float _BumpScale;        struct a2v{  float4 vertex:POSITION;  float3 normal:NORMAL;  float4 tangent:TANGENT;  //tangent.w用来确定切线空间中坐标轴的方向  float4 texcoord:TEXCOORD;};//顶点函数向片元函数传递的结构体,包括://SV_POSITION 剪裁空间中的顶点坐标(一般是系统直接使用)        //COLOR0 可以传递一组值        //TEXCOORD 0-7 传递纹理坐标struct v2f{  float4 position:SV_POSITION;  fixed3 worldNormalDir:COLOR0;  fixed3 lightDir:TEXCOORD1;  fixed4 vertex:COLOR1;  fixed4 uv:TEXCOORD;};        v2f vert (a2v v){  v2f f;  f.position=UnityObjectToClipPos(v.vertex);                 //顶点坐标转剪裁空间  f.worldNormalDir=mul(v.normal,(float3x3)unity_WorldToObject);    //法线向量从模型空间转到世界空间  f.vertex=v.vertex;  f.uv.xy=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;       //xy来存储主贴图的纹理坐标  f.uv.zw=v.texcoord.xy*_NormalMap_ST+_NormalMap_ST.zw;      //zw来存储法线贴图的纹理坐标  TANGENT_SPACE_ROTATION;                                    //获得用于转换切线空间的矩阵  f.lightDir=mul(rotation,ObjSpaceLightDir(v.vertex));       //获得切线空间中光的方向  return f;};fixed4 frag(v2f f):SV_TARGET {  fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb;               //环境光  fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);  fixed3 normalDir = normalize(f.worldNormalDir);              fixed3 reflectDir=normalize(reflect(-lightDir,normalDir));  fixed3 viewDir=normalize( _WorldSpaceCameraPos.xyz-mul(f.vertex,unity_WorldToObject).xyz);  fixed3 halfDir=normalize(reflectDir+viewDir);  fixed3 specular=_LightColor0.rgb*pow(max( dot(reflectDir,halfDir),0),_Specular);  //Blinn-Phong高光反射  fixed3 normalColor =UnpackNormal(tex2D(_NormalMap,f.uv.zw));//先取得rgb值然后转化为法线向量  normalColor.xy=normalColor.xy*_BumpScale;                  //添加凹凸属性  fixed3 tangentNormal=normalize(normalColor);               //归一化  fixed3 texColor=tex2D(_MainTex,f.uv.xy)*_Color;            //主贴图像素点颜色  fixed3 diffuse=_LightColor0.rgb*(dot(tangentNormal,f.lightDir)*0.5+0.5)*texColor; //漫反射光合成  float3 tempColor=diffuse+specular+ambient*texColor;        //对环境光处理  return fixed4(tempColor,1);}ENDCG} }FallBack "VertexLit"}

吐槽一下VS对Shader的支持,排个版都排不好,花了几天时间大概学习了一下shader的基础,暂时也不准备深入了,毕竟不当技美,就到这里吧。