ShaderLab学习笔记

这篇ShaderLab学习笔记主要探讨了Unity中mesh Filter如何存储模型的Mesh信息,并详细阐述了如何将方向转换到切线空间的过程,通过代码注释进行了深入解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

笔记:

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的基础,暂时也不准备深入了,毕竟不当技美,就到这里吧。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值