S老师 Shader 学习
Mesh Filter : 存储一个Mesh(网格,模型的网格,就是模型的由哪些三角面组成,组成一个什么样子的模型,三角面的一些顶点信息) Mesh Renderer:用来渲染一个模型的外观,就是样子, 按照 mesh给它皮肤,给它颜色 通过Material(材质)控制模型渲染的样子 Material 贴图(可以没有,可以是一个单纯的颜色) 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 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) 把方向 模型空间=》世界空间 float3 UnityWorldToObjectDir(float3 dir) 把方向 世界空间=》模型空间 什么是OpenGL、DirectX shader可以认为是一种渲染命令 ,由opengl 或者dx进行解析,来控制渲染丰富多彩的图形 OpenGL 使用GLSL 编写shader DirectX 使用HSSL 编写shader 英伟达 CG 编写shader(跨平台) Unity Shader的分类 使用的是ShaderLab编写Unity中的Shader 1,表面着色器 Surface Shader 2,顶点/片元着色器 Vertex/Fragment Shader 3,固定函数着色器 Fixed Function Shader Unityshader中属性的类型有哪些 _Color("Color",Color)=(1,1,1,1) _Vector("Vector",Vector)=(1,2,3,4) _Int("Int",Int)= 34234 _Float("Float",Float) = 4.5 _Range("Range",Range(1,11))=6 _2D("Texture",2D) = "red"{} _Cube("Cube",Cube) = "white"{} _3D("Texure",3D) = "black"{} 从应用程序传递到顶点函数的语义有哪些a2v POSITION 顶点坐标(模型空间下的) NORMAL 法线( 模型空间下) TANGENT 切线(模型空间) TEXCOORD0 ~n 纹理坐标 COLOR 顶点颜色 从顶点函数传递给片元函数的时候可以使用的语义 SV_POSITION 剪裁空间中的顶点坐标(一般是系统直接使用) COLOR0 可以传递一组值 4个 COLOR1 可以传递一组值 4个 TEXCOORD0~7 传递纹理坐标 片元函数传递给系统 SV_Target 颜色值,显示到屏幕上的颜色 什么是光照模型 光照模型就是一个公式,使用这个公式来计算在某个点的光照效果 标准光照模型 在标准光照模型里面,我们把进入摄像机的光分为下面四个部分 自发光 高光反射 Blinn光照模型 Specular=直射光 * pow( max(cosθ,0),10) θ:是反射光方向和视野方向的夹角 Blinn-Phong光照模型 Specular=直射光 * pow( max(cosθ,0),10) θ:是法线和x的夹角 x 是平行光和视野方向的平分线 漫反射 Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) ) cosθ = 光方向· 法线方向 环境光 Tags{ "LightMode"="ForwardBase" } 只有定义了正确的LightMode才能得到一些Unity的内置光照变量 #include "Lighting.cginc" 包含unity的内置的文件,才可以使用unity内置的一些变量 normalize() 用来把一个向量,单位化(原来方向保持不变,长度变为1) max() 用来取得函数中最大的一个 dot 用来取得两个向量的点积 _WorldSpaceLightPos0 取得平行光的位置 _LightColor0取得平行光的颜色 UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间 _World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间 UNITY_LIGHTMODEL_AMBIENT用来获取环境光 半兰伯特光照模型 Diffuse = 直射光颜色 *( cosθ *0.5 +0.5 ) 兰伯特光照模型 Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) ) cosθ = 光方向· 法线方向 shader中的各种空间坐标 http://blog.csdn.net/lyh916/article/details/50906272 什么是切线空间 http://blog.csdn.net/bonchoix/article/details/8619624 pixel = (normal+1)/2 normal = pixel*2 - 1
Shader "Siki/01 myshader"{//这里指定shader的名字,不要求跟文件名保持一致 Properties{ //属性 _Color("Color",Color)=(1,1,1,1) //float4 _Vector("Vector",Vector)=(1,2,3,4) //float4 _Int("Int",Int)= 34234 //float _Float("Float",Float) = 4.5 //float _Range("Range",Range(1,11))=6 //float _2D("Texture",2D) = "red"{} //sampler2D _Cube("Cube",Cube) = "white"{} //samplerCube _3D("Texure",3D) = "black"{} //sampler3D } //SubShader可以写很多个 显卡运行效果的时候,从第一个SubShader开始,如果第一个SubShader里面的效果都可以实现,那么就使用第一个SubShader,如果显卡这个SubShader里面某些效果它实现不了,它会自动去运行下一个SubShader SubShader{ //至少有一个Pass Pass{ //在这里编写shader代码 HLSLPROGRAM CGPROGRAM //使用CG语言编写shader代码 float4 _Color; //float half fixed //fixed4 float3 t1;// half3 fixed3 float2 t;//half2 fixed2 float t2; float4 _Vector; float _Int; float _Float; float _Range; sampler2D _2D; samplerCube _Cube; sampler3D _3D; //float 32位来存储 //half 16 -6万 ~ +6万 //fixed 11 -2 到 +2 ENDCG } } Fallback "VertexLit" }
Shader "Siki/02 secondshader can run"{ SubShader{ Pass{ CGPROGRAM //顶点函数 这里只是声明了,顶点函数的函数名 //基本作用是 完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境转换到视野相机屏幕上) #pragma vertex vert //片元函数 这里只是声明了,片元函数的函数名 //基本作用 返回模型对应的屏幕上的每一个像素的颜色值 #pragma fragment frag float4 vert(float4 v : POSITION) :SV_POSITION {//通过语义告诉系统,我这个参数是干嘛的, 比如POSITION是告诉系统我需要顶点坐标 //SV_POSITION这个语义用来解释说明返回值, 意思是返回值是剪裁空间下的顶点坐标 //float4 pos = mul(UNITY_MATRIX_MVP,v); //return pos; return mul(UNITY_MATRIX_MVP,v); } fixed4 frag() :SV_Target { return fixed4(0.5,0.5,1,1); } ENDCG } } Fallback "VertexLit" }
Shader "Siki/03 Use struct"{ SubShader{ Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag //application to vertex struct a2v { float4 vertex:POSITION;//告诉unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL;//告诉unity吧模型空间下的法线方向填充给normal float4 texcoord : TEXCOORD0;//告诉unity把第一套纹理坐标填充给texcoord }; struct v2f { float4 position:SV_POSITION; float3 temp:COLOR0;//这个语义可以由用户自己定义,一般都存储颜色 }; v2f vert(a2v v) { v2f f; f.position = mul(UNITY_MATRIX_MVP,v.vertex); f.temp = v.normal; return f; } fixed4 frag(v2f f) :SV_Target{ return fixed4(f.temp,1); } ENDCG } } Fallback "VertexLit" }
Shader "Siki/04-Diffuse Vertex"{ Properties{ _Diffuse("Diffuse Color",Color) = (1,1,1,1) } SubShader{ Pass{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; //application to vertex 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 fixed4(f.color,1); } ENDCG } } Fallback "Diffuse" }
Shader "Siki/05-Diffuse Fragment"{ Properties{ _Diffuse("Diffuse Color",Color) = (1,1,1,1) } SubShader{ Pass{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; //application to vertex 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 fixed4(tempColor,1); } ENDCG } } Fallback "Diffuse" }
Shader "Siki/06-Diffuse Fragment HalfLambert"{ Properties{ _Diffuse("Diffuse Color",Color) = (1,1,1,1) } SubShader{ Pass{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; //application to vertex 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);//对于每个顶点来说 光的位置就是光的方向 ,因为光是平行光 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 "Diffuse" }
Shader "Siki/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{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; fixed4 _Specular; half _Gloss; //application to vertex 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; //取得漫反射的颜色 fixed3 reflectDir = normalize(reflect(-lightDir, normalDir)); fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(v.vertex, _World2Object).xyz); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(dot(reflectDir, viewDir), 0), _Gloss); f.color = diffuse + ambient + specular; return f; } fixed4 frag(v2f f) :SV_Target{ return fixed4(f.color,1); } ENDCG } } Fallback "Diffuse" }
Shader "Siki/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{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; fixed4 _Specular; half _Gloss; //application to vertex struct a2v { float4 vertex:POSITION;//告诉unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL; }; struct v2f { float4 position:SV_POSITION; 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; fixed3 normalDir = normalize(f.worldNormal); 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.rgb * pow(max(dot(reflectDir, viewDir), 0), _Gloss); fixed3 tempColor = diffuse + ambient + specular; return fixed4(tempColor,1); } ENDCG } } Fallback "Diffuse" }
Shader "Siki/09-Specular Fragment BlinnPhong"{ 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{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" //取得第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; fixed4 _Specular; half _Gloss; //application to vertex struct a2v { float4 vertex:POSITION;//告诉unity把模型空间下的顶点坐标填充给vertex float3 normal:NORMAL; }; struct v2f { float4 position:SV_POSITION; float3 worldNormal : TEXCOORD0; float4 worldVertex :TEXCOORD1; }; v2f vert(a2v v) { v2f f; f.position = mul(UNITY_MATRIX_MVP,v.vertex); //f.worldNormal = mul(v.normal, (float3x3) _World2Object); f.worldNormal = UnityObjectToWorldNormal(v.normal); f.worldVertex = mul(v.vertex, _World2Object); return f; } fixed4 frag(v2f f) :SV_Target{ fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; fixed3 normalDir = normalize(f.worldNormal); //fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//对于每个顶点来说 光的位置就是光的方向 ,因为光是平行光 fixed3 lightDir = normalize( WorldSpaceLightDir(f.worldVertex).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 viewDir = normalize(UnityWorldSpaceViewDir(f.worldVertex)); fixed3 halfDir = normalize(viewDir + lightDir); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(dot(normalDir, halfDir), 0), _Gloss); fixed3 tempColor = diffuse + ambient + specular; return fixed4(tempColor,1); } ENDCG } } Fallback "Diffuse" }
Shader "Siki/10-Diffuse Specular"{ Properties{ _Diffuse("Diffuse Color",Color) = (1,1,1,1) _Specular("Specular Color",Color) = (1,1,1,1) _Gloss("Gloss",Range(10,200)) = 20 } SubShader{ Pass{ Tags{"LightMode" = "ForwardBase"} CGPROGRAM #include "Lighting.cginc" #pragma vertex vert #pragma fragment frag fixed4 _Diffuse; fixed4 _Specular; half _Gloss; struct a2v{ float4 vertex:POSITION; float3 normal:NORMAL; }; struct v2f { float4 svPos:SV_POSITION; float3 worldNormal:TEXCOORD0; float4 worldVertex:TEXCOORD1; }; v2f vert(a2v v) { v2f f; f.svPos = mul(UNITY_MATRIX_MVP, v.vertex); f.worldNormal = UnityObjectToWorldNormal(v.normal); f.worldVertex = mul(v.vertex, _World2Object); return f; } fixed4 frag(v2f f) :SV_Target{ fixed3 normalDir = normalize(f.worldNormal); fixed3 lightDir = normalize(WorldSpaceLightDir(f.worldVertex)); fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(dot(normalDir, lightDir), 0); fixed3 viewDir = normalize(UnityWorldSpaceViewDir(f.worldVertex)); fixed3 halfDir = normalize(lightDir + viewDir); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(dot(normalDir, halfDir), 0), _Gloss); fixed3 tempColor = diffuse + specular + UNITY_LIGHTMODEL_AMBIENT.rgb; return fixed4(tempColor, 1); } ENDCG } } Fallback "Specular" }
Shader "Siki/11-Texture"{ Properties{ //_Diffuse("Diffuse Color",Color) = (1,1,1,1) _Color("Color",Color)=(1,1,1,1) _MainTex("Main Tex",2D) = "white"{} _Specular("Specular Color",Color) = (1,1,1,1) _Gloss("Gloss",Range(10,200)) = 20 } SubShader{ Pass{ Tags{"LightMode" = "ForwardBase"} CGPROGRAM #include "Lighting.cginc" #pragma vertex vert #pragma fragment frag //fixed4 _Diffuse; fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Specular; half _Gloss; struct a2v{ float4 vertex:POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; }; struct v2f { float4 svPos:SV_POSITION; float3 worldNormal:TEXCOORD0; float4 worldVertex:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f f; f.svPos = mul(UNITY_MATRIX_MVP, v.vertex); f.worldNormal = UnityObjectToWorldNormal(v.normal); f.worldVertex = mul(v.vertex, _World2Object); f.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; return f; } fixed4 frag(v2f f) :SV_Target{ fixed3 normalDir = normalize(f.worldNormal); fixed3 lightDir = normalize(WorldSpaceLightDir(f.worldVertex)); fixed3 texColor = tex2D(_MainTex, f.uv.xy)*_Color.rgb; fixed3 diffuse = _LightColor0.rgb * texColor * max(dot(normalDir, lightDir), 0); fixed3 viewDir = normalize(UnityWorldSpaceViewDir(f.worldVertex)); fixed3 halfDir = normalize(lightDir + viewDir); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(dot(normalDir, halfDir), 0), _Gloss); fixed3 tempColor = diffuse + specular + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor; return fixed4(tempColor, 1); } ENDCG } } Fallback "Specular" }
Shader "Siki/12-Rock"{ Properties{ //_Diffuse("Diffuse Color",Color) = (1,1,1,1) _Color("Color",Color)=(1,1,1,1) _MainTex("Main Tex",2D) = "white"{} } SubShader{ Pass{ Tags{"LightMode" = "ForwardBase"} CGPROGRAM #include "Lighting.cginc" #pragma vertex vert #pragma fragment frag //fixed4 _Diffuse; fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; struct a2v{ float4 vertex:POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; }; struct v2f { float4 svPos:SV_POSITION; float3 worldNormal:TEXCOORD0; float4 worldVertex:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f f; f.svPos = mul(UNITY_MATRIX_MVP, v.vertex); f.worldNormal = UnityObjectToWorldNormal(v.normal); f.worldVertex = mul(v.vertex, _World2Object); f.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; return f; } fixed4 frag(v2f f) :SV_Target{ fixed3 normalDir = normalize(f.worldNormal); fixed3 lightDir = normalize(WorldSpaceLightDir(f.worldVertex)); fixed3 texColor = tex2D(_MainTex, f.uv.xy)*_Color.rgb; fixed3 diffuse = _LightColor0.rgb * texColor * max(dot(normalDir, lightDir), 0); fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor; return fixed4(tempColor, 1); } ENDCG } } Fallback "Specular" }
Shader "Siki/13-Rock Normal Map"{ Properties{ //_Diffuse("Diffuse Color",Color) = (1,1,1,1) _Color("Color",Color) = (1,1,1,1) _MainTex("Main Tex",2D) = "white"{} _NormalMap("Normal Map",2D) = "bump"{} _BumpScale("Bump Scale",Float)=1 } SubShader{ Pass{ Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #include "Lighting.cginc" #pragma vertex vert #pragma fragment frag //fixed4 _Diffuse; fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _NormalMap; float4 _NormalMap_ST; float _BumpScale; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; float4 tangent:TANGENT;//tangent.w是用来确定切线空间中坐标轴的方向的 float4 texcoord:TEXCOORD0; }; struct v2f { float4 svPos:SV_POSITION; //float3 worldNormal:TEXCOORD0; //float4 worldVertex:TEXCOORD1; float3 lightDir : TEXCOORD0; float4 uv:TEXCOORD1; }; v2f vert(a2v v) { v2f f; f.svPos = mul(UNITY_MATRIX_MVP, v.vertex); // f.worldNormal = UnityObjectToWorldNormal(v.normal); // f.worldVertex = mul(v.vertex, _World2Object); f.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw; TANGENT_SPACE_ROTATION;//调用这个后之后,会得到一个矩阵 rotation 这个矩阵用来把模型空间下的方向转换成切线空间下 //ObjSpaceLightDir(v.vertex)//得到模型空间下的平行光方向 f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)); return f; } fixed4 frag(v2f f) :SV_Target{ //fixed3 normalDir = normalize(f.worldNormal); fixed4 normalColor = tex2D(_NormalMap,f.uv.zw); // // fixed3 tangentNormal = normalize( normalColor.xyz * 2 - 1 ) ; //切线空间下的法线 fixed3 tangentNormal = UnpackNormal(normalColor); tangentNormal.xy = tangentNormal.xy*_BumpScale; tangentNormal = normalize(tangentNormal); fixed3 lightDir = normalize(f.lightDir); fixed3 texColor = tex2D(_MainTex, f.uv.xy)*_Color.rgb; fixed3 diffuse = _LightColor0.rgb * texColor * max(dot(tangentNormal, lightDir), 0); fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor; return fixed4(tempColor, 1); } ENDCG } } Fallback "Specular" }
Shader "Siki/14-Rock Alpha"{ Properties{ //_Diffuse("Diffuse Color",Color) = (1,1,1,1) _Color("Color",Color) = (1,1,1,1) _MainTex("Main Tex",2D) = "white"{} _NormalMap("Normal Map",2D) = "bump"{} _BumpScale("Bump Scale",Float)=1 _AlphaScale("Alpha Scale",Float)=1 } SubShader{ Tags{ "Queue"="Transparent" "IngnoreProjector"="True" "RenderType"="Transparent" } Pass{ Tags{ "LightMode" = "ForwardBase" } ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #include "Lighting.cginc" #pragma vertex vert #pragma fragment frag //fixed4 _Diffuse; fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _NormalMap; float4 _NormalMap_ST; float _BumpScale; float _AlphaScale; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; float4 tangent:TANGENT;//tangent.w是用来确定切线空间中坐标轴的方向的 float4 texcoord:TEXCOORD0; }; struct v2f { float4 svPos:SV_POSITION; //float3 worldNormal:TEXCOORD0; //float4 worldVertex:TEXCOORD1; float3 lightDir : TEXCOORD0; float4 uv:TEXCOORD1; }; v2f vert(a2v v) { v2f f; f.svPos = mul(UNITY_MATRIX_MVP, v.vertex); // f.worldNormal = UnityObjectToWorldNormal(v.normal); // f.worldVertex = mul(v.vertex, _World2Object); f.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw; TANGENT_SPACE_ROTATION;//调用这个后之后,会得到一个矩阵 rotation 这个矩阵用来把模型空间下的方向转换成切线空间下 //ObjSpaceLightDir(v.vertex)//得到模型空间下的平行光方向 f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)); return f; } fixed4 frag(v2f f) :SV_Target{ //fixed3 normalDir = normalize(f.worldNormal); fixed4 normalColor = tex2D(_NormalMap,f.uv.zw); // // fixed3 tangentNormal = normalize( normalColor.xyz * 2 - 1 ) ; //切线空间下的法线 fixed3 tangentNormal = UnpackNormal(normalColor); tangentNormal.xy = tangentNormal.xy*_BumpScale; tangentNormal = normalize(tangentNormal); fixed3 lightDir = normalize(f.lightDir); fixed4 texColor = tex2D(_MainTex, f.uv.xy)*_Color; fixed3 diffuse = _LightColor0.rgb * texColor.rgb * max(dot(tangentNormal, lightDir), 0); fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor; return fixed4(tempColor,_AlphaScale*texColor.a ); } ENDCG } } Fallback "Specular" }