关于UnityShader的入门学习
Posted 魔卡先生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于UnityShader的入门学习 相关的知识,希望对你有一定的参考价值。
1.逐顶点的漫反射Shader
Shader "Mocha/04 Diffuse Vertex"{//逐顶点的漫反射 Properties{ _Diffuse("Diffuse Color",Color)=(1,1,1,1) } SubShader{ Pass{ //只有定义了正确的LightMode才能得到一些Unity的内置光照变量 Tags{"LightMode"="ForwardBase"} CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色_LightColor0 Unity内置 取得第一个直射光的位置 _WorldSpaceLightPos0 fixed3 _Diffuse; //顶点函数 这里只是声明了顶点函数的函数名 //基本作用 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境到相机视野屏幕上) #pragma vertex vert //片元函数 这里只是声明了片元函数的函数名 //基本作用 返回模型对应的屏幕上的每一个像素的颜色值 #pragma fragment frag //使用结构体存储 //a2v 即 application to vertex struct a2v{ float4 vertex:POSITION;//告诉Unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL;//告诉Unity把模型空间下的法线方向填充给normal }; //使用结构体存储 struct v2f{ float4 position:SV_POSITION;//告诉Unity存储剪裁空间下的顶点坐标 fixed3 color:COLOR;//存储颜色语义 }; v2f vert(a2v v){ v2f f; f.position=mul(UNITY_MATRIX_MVP,v.vertex); //将模型空间坐标转换到剪裁空间坐标 fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb; //获取到Unity环境光 fixed3 normalDir=normalize(mul(v.normal,(float3x3)_World2Object));//将模型空间转换到世界空间,再将向量量化 //_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 fixed4(f.color,1); } ENDCG } } Fallback "VertexLit" }
2.逐像素(片元)的漫反射Shader
Shader "Mocha/06 Diffuse Fragment HalfLambert"{//逐像素(片元)的半兰伯特光照 Properties{ _Diffuse("Diffuse Color",Color)=(1,1,1,1) } SubShader{ Pass{ //只有定义了正确的LightMode才能得到一些Unity的内置光照变量 Tags{"LightMode"="ForwardBase"} CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色_LightColor0 Unity内置 取得第一个直射光的位置 _WorldSpaceLightPos0 fixed3 _Diffuse; //顶点函数 这里只是声明了顶点函数的函数名 //基本作用 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境到相机视野屏幕上) #pragma vertex vert //片元函数 这里只是声明了片元函数的函数名 //基本作用 返回模型对应的屏幕上的每一个像素的颜色值 #pragma fragment frag //使用结构体存储 //a2v 即 application to vertex struct a2v{ float4 vertex:POSITION;//告诉Unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL;//告诉Unity把模型空间下的法线方向填充给normal }; //使用结构体存储 struct v2f{ float4 position:SV_POSITION;//告诉Unity存储剪裁空间下的顶点坐标 fixed3 wordNormalDir:COLOR;//存储颜色语义 }; v2f vert(a2v v){ v2f f; f.position=mul(UNITY_MATRIX_MVP,v.vertex); //将模型空间坐标转换到剪裁空间坐标 f.wordNormalDir=mul(v.normal,(float3x3)_World2Object); return f; } fixed4 frag(v2f f) : SV_Target{ fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb; //获取到Unity环境光 fixed3 normalDir=normalize(f.wordNormalDir);//将模型空间转换到世界空间,再将向量量化 //_World2Object 在左侧世界空间转模型空间,在右侧模型空间转世界空间 fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//对于每个顶点来说光的位置就是光的方向,因为光是平行光 float halfLambert=dot(normalDir,lightDir)*0.5+0.5; //半兰伯特光照算法 fixed3 diffuse=_LightColor0.rgb*halfLambert*_Diffuse.rgb;//取得漫反射的颜色 fixed3 tempColor=diffuse + ambient; return fixed4(tempColor,1); } ENDCG } } Fallback "VertexLit" }
3.逐顶点的高光反射Shader
Shader "Mocha/07 Specular Vertex"{//逐顶点的高光反射 Properties{ _Diffuse("Diffuse Color",Color)=(1,1,1,1) //材质颜色 _Specular("Specular Color",Color)=(1,1,1,1)//高光颜色 _Gloss("Gloss",Range(8,200))=10 //高光参数 } SubShader{ Pass{ //只有定义了正确的LightMode才能得到一些Unity的内置光照变量 Tags{"LightMode"="ForwardBase"} CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色_LightColor0 Unity内置 取得第一个直射光的位置 _WorldSpaceLightPos0 fixed3 _Diffuse; fixed4 _Specular; half _Gloss; //顶点函数 这里只是声明了顶点函数的函数名 //基本作用 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境到相机视野屏幕上) #pragma vertex vert //片元函数 这里只是声明了片元函数的函数名 //基本作用 返回模型对应的屏幕上的每一个像素的颜色值 #pragma fragment frag //使用结构体存储 //a2v 即 application to vertex struct a2v{ float4 vertex:POSITION;//告诉Unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL;//告诉Unity把模型空间下的法线方向填充给normal }; //使用结构体存储 struct v2f{ float4 position:SV_POSITION;//告诉Unity存储剪裁空间下的顶点坐标 fixed3 color:COLOR;//存储颜色语义 }; v2f vert(a2v v){ v2f f; f.position=mul(UNITY_MATRIX_MVP,v.vertex); //将模型空间坐标转换到剪裁空间坐标 fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb; //获取到Unity环境光 fixed3 normalDir=normalize(mul(v.normal,(float3x3)_World2Object));//将模型空间转换到世界空间,再将向量量化 //_World2Object 在左侧世界空间转模型空间,在右侧模型空间转世界空间 fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//对于每个顶点来说光的位置就是光的方向,因为光是平行光 fixed3 diffuse=_LightColor0.rgb*max(dot(normalDir,lightDir),0)*_Diffuse.rgb;//取得漫反射的颜色 fixed3 reflectDir=normalize(reflect(-lightDir,normalDir));//获取到发射光的单位向量 fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-mul(v.vertex,_World2Object).xyz);//获取到相机视角方向单位向量 fixed3 specular=_LightColor0.rgb*_Specular*pow(max(dot(reflectDir,viewDir),0),_Gloss);//计算的到高光颜色(其中_Gloss为高光参数 根据效果需要更改数值 一般取大于10的数值) f.color=diffuse + ambient+specular; return f; } fixed4 frag(v2f f) : SV_Target{ return fixed4(f.color,1); } ENDCG } } Fallback "VertexLit" }
4.逐像素(片元)的高光反射Shader
Shader "Mocha/08 Specular Fragment"{//逐像素(片元)的高光反射 Properties{ _Diffuse("Diffuse Color",Color)=(1,1,1,1) //材质颜色 _Specular("Specular Color",Color)=(1,1,1,1)//高光颜色 _Gloss("Gloss",Range(8,200))=10 //高光参数 } SubShader{ Pass{ //只有定义了正确的LightMode才能得到一些Unity的内置光照变量 Tags{"LightMode"="ForwardBase"} CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色_LightColor0 Unity内置 取得第一个直射光的位置 _WorldSpaceLightPos0 fixed3 _Diffuse; fixed4 _Specular; half _Gloss; //顶点函数 这里只是声明了顶点函数的函数名 //基本作用 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境到相机视野屏幕上) #pragma vertex vert //片元函数 这里只是声明了片元函数的函数名 //基本作用 返回模型对应的屏幕上的每一个像素的颜色值 #pragma fragment frag //使用结构体存储 //a2v 即 application to vertex struct a2v{ float4 vertex:POSITION;//告诉Unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL;//告诉Unity把模型空间下的法线方向填充给normal }; //使用结构体存储 struct v2f{ float4 position:SV_POSITION;//告诉Unity存储剪裁空间下的顶点坐标 float3 worldNormal:TEXCOORD0;//纹理语义存储 float3 worldVertex:TEXCOORD1;//纹理语义存储 }; v2f vert(a2v v){ v2f f; f.position=mul(UNITY_MATRIX_MVP,v.vertex); //将模型空间坐标转换到剪裁空间坐标 f.worldNormal=mul(v.normal,(float3x3)_World2Object); f.worldVertex=mul(v.vertex,_World2Object).xyz; return f; } fixed4 frag(v2f f) : SV_Target{ fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb; //获取到Unity环境光 fixed3 normalDir=normalize(f.worldNormal);//将模型空间转换到世界空间,再将向量量化 //_World2Object 在左侧世界空间转模型空间,在右侧模型空间转世界空间 fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);//对于每个顶点来说光的位置就是光的方向,因为光是平行光 fixed3 diffuse=_LightColor0.rgb*max(dot(normalDir,lightDir),0)*_Diffuse.rgb;//取得漫反射的颜色 fixed3 reflectDir=normalize(reflect(-lightDir,normalDir));//获取到发射光的单位向量 fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-f.worldVertex);//获取到相机视角方向单位向量 fixed3 specular=_LightColor0.rgb*_Specular*pow(max(dot(reflectDir,viewDir),0),_Gloss);//计算的到高光颜色(其中_Gloss为高光参数 根据效果需要更改数值 一般取大于10的数值) fixed3 tempColor=diffuse + ambient+specular; return fixed4(tempColor,1); } ENDCG } } Fallback "VertexLit" }
以上是关于关于UnityShader的入门学习 的主要内容,如果未能解决你的问题,请参考以下文章
Unity Shader入门精要学习笔记 - 第11章 让画面动起来
UnityShader入门精要-3.5 UnityShader的形式
UnityShader入门精要-3.3 UnityShader的结构