您需要 登录 才可以下载或查看,没有账号?注册
x
4.凹凸纹理载入
让我们慢慢添加特性,使得到的Surface Shader的效果与功能越来越强大。接着来看看Surface Shader的凹凸纹理如何实现:
[cpp] view plain copy
- Shader "浅墨Shader编程/Volume6/27.凹凸纹理载入"
- {
- //--------------------------------【属性】----------------------------------------
- Properties
- {
- _MainTex ("【主纹理】Texture", 2D) = "white" {}
- _BumpMap ("【凹凸纹理】Bumpmap", 2D) = "bump" {}
- }
- //--------------------------------【子着色器】----------------------------------
- SubShader
- {
- //-----------子着色器标签----------
- Tags { "RenderType" = "Opaque" }
- //-------------------开始CG着色器编程语言段-----------------
- CGPROGRAM
- //【1】光照模式声明:使用兰伯特光照模式
- #pragma surface surf Lambert
- //【2】输入结构
- struct Input
- {
- //主纹理的uv值
- float2 uv_MainTex;
- //凹凸纹理的uv值
- float2 uv_BumpMap;
- };
- //变量声明
- sampler2D _MainTex;//主纹理
- sampler2D _BumpMap;//凹凸纹理
- //【3】表面着色函数的编写
- void surf (Input IN, inout SurfaceOutput o)
- {
- //从主纹理获取rgb颜色值
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- //从凹凸纹理获取法线值
- o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
- }
- //-------------------结束CG着色器编程语言段------------------
- ENDCG
- }
- //“备胎”为普通漫反射
- Fallback "Diffuse"
- }
我们将此Shader编译后赋给材质,得到如下效果:
场景中的实测效果图为:
5.纹理载入+颜色可调
接着看一看纹理如何通过一个finalcolor关键字自定义函数,来达到调色的目的:
[cpp] view plain copy
- Shader "浅墨Shader编程/Volume6/28.纹理+颜色修改"
- {
- //--------------------------------【属性】----------------------------------------
- Properties
- {
- _MainTex ("【主纹理】Texture", 2D) = "white" {}
- _ColorTint ("【色泽】Tint", Color) = (0.6, 0.3, 0.6, 0.3)
- }
- //--------------------------------【子着色器】----------------------------------
- SubShader
- {
- //-----------子着色器标签----------
- Tags { "RenderType" = "Opaque" }
- //-------------------开始CG着色器编程语言段-----------------
- CGPROGRAM
- //【1】光照模式声明:使用兰伯特光照模式+自定义颜色函数
- #pragma surface surf Lambert finalcolor:setcolor
- //【2】输入结构
- struct Input
- {
- //纹理的uv值
- float2 uv_MainTex;
- };
- //变量声明
- fixed4 _ColorTint;
- sampler2D _MainTex;
- //【3】自定义颜色函数setcolor的编写
- void setcolor (Input IN, SurfaceOutput o, inout fixed4 color)
- {
- //将自选的颜色值乘给color
- color *= _ColorTint;
- }
- //【4】表面着色函数的编写
- void surf (Input IN, inout SurfaceOutput o)
- {
- //从主纹理获取rgb颜色值
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- }
- //-------------------结束CG着色器编程语言段------------------
- ENDCG
- }
- //“备胎”为普通漫反射
- Fallback "Diffuse"
- }
我们将此Shader编译后赋给材质,得到如下效果:
调些颜色玩一玩:
场景中的实测效果图为:
6. 凹凸纹理+边缘光照
在之前凹凸纹理的基础上让我们加上喜闻乐见的边缘光照:
[cpp] view plain copy
- Shader "浅墨Shader编程/Volume6/29.凹凸纹理+边缘光照"
- {
- //--------------------------------【属性】----------------------------------------
- Properties
- {
- _MainTex ("【主纹理】Texture", 2D) = "white" {}
- _BumpMap ("【凹凸纹理】Bumpmap", 2D) = "bump" {}
- _RimColor ("【边缘颜色】Rim Color", Color) = (0.26,0.19,0.16,0.0)
- _RimPower ("【边缘颜色强度】Rim Power", Range(0.5,8.0)) = 3.0
- }
- //--------------------------------【子着色器】----------------------------------
- SubShader
- {
- //-----------子着色器标签----------
- Tags { "RenderType" = "Opaque" }
- //-------------------开始CG着色器编程语言段-----------------
- CGPROGRAM
- //【1】光照模式声明:使用兰伯特光照模式+自定义颜色函数
- #pragma surface surf Lambert
- //【2】输入结构
- struct Input
- {
- //主纹理的uv值
- float2 uv_MainTex;
- //凹凸纹理的uv值
- float2 uv_BumpMap;
- //当前坐标的视角方向
- float3 viewDir;
- };
- //变量声明
- sampler2D _MainTex;//主纹理
- sampler2D _BumpMap;//凹凸纹理
- float4 _RimColor;//边缘颜色
- float _RimPower;//边缘颜色强度
- //【3】表面着色函数的编写
- void surf (Input IN, inout SurfaceOutput o)
- {
- //从主纹理获取rgb颜色值
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- //从凹凸纹理获取法线值
- o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
- //从_RimColor参数获取自发光颜色
- half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
- o.Emission = _RimColor.rgb * pow (rim, _RimPower);
- }
- //-------------------结束CG着色器编程语言段------------------
- ENDCG
- }
- //“备胎”为普通漫反射
- Fallback "Diffuse"
- }
其中的viewDir 意为WorldSpace View Direction,也就是当前坐标的视角方向:
关于surf中的两句新加的代码在这里也讲一下。
上面已经提到过,Normalize函数,用于获取到的viewDir坐标转成一个单位向量且方向不变,外面再与点的法线做点积。最外层再用 saturate算出一[0,1]之间的最靠近的值。这样算出一个rim边界。原理可以这样解释:
这里o.Normal就是单位向量。外加Normalize了viewDir。因此求得的点积就是夹角的cos值。因为cos值越大,夹角越小,所以,这时取反来。这样,夹角越大,所反射上的颜色就越多。于是就得到的两边发光的效果。哈哈这样明了吧。
这里再介绍一下这个half。CG里还有类似的float和fixed。half是一种低精度的float,但有时也会被选择成与float一样的精度。先就说这么多吧,后面还会遇到的,到时候再讲。
我们将此Shader编译后赋给材质,得到如下效果,除了凹凸纹理的选择之外,还有边缘发光颜色和强度可供自由定制:
依然是调一些颜色玩一玩:
场景中的实测截图为:
7.凹凸纹理+颜色可调
接下来我们看看凹凸纹理+颜色可调的Shader怎么写:
[cpp] view plain copy
- Shader "浅墨Shader编程/Volume6/30.凹凸纹理+颜色可调+边缘光照"
- {
- //--------------------------------【属性】----------------------------------------
- Properties
- {
- _MainTex ("【主纹理】Texture", 2D) = "white" {}
- _BumpMap ("【凹凸纹理】Bumpmap", 2D) = "bump" {}
- _ColorTint ("【色泽】Tint", Color) = (0.6, 0.3, 0.6, 0.3)
- _RimColor ("【边缘颜色】Rim Color", Color) = (0.26,0.19,0.16,0.0)
- _RimPower ("【边缘颜色强度】Rim Power", Range(0.5,8.0)) = 3.0
- }
- //--------------------------------【子着色器】----------------------------------
- SubShader
- {
- //-----------子着色器标签----------
- Tags { "RenderType" = "Opaque" }
- //-------------------开始CG着色器编程语言段-----------------
- CGPROGRAM
- //【1】光照模式声明:使用兰伯特光照模式+自定义颜色函数
- #pragma surface surf Lambert finalcolor:setcolor
- //【2】输入结构
- struct Input
- {
- //主纹理的uv值
- float2 uv_MainTex;
- //凹凸纹理的uv值
- float2 uv_BumpMap;
- //当前坐标的视角方向
- float3 viewDir;
- };
- //变量声明
- sampler2D _MainTex;
- sampler2D _BumpMap;
- fixed4 _ColorTint;
- float4 _RimColor;
- float _RimPower;
- //【3】自定义颜色函数setcolor的编写
- void setcolor (Input IN, SurfaceOutput o, inout fixed4 color)
- {
- color *= _ColorTint;
- }
- //【4】表面着色函数的编写
- void surf (Input IN, inout SurfaceOutput o)
- {
- //从主纹理获取rgb颜色值
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- //从凹凸纹理获取法线值
- o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
- //从_RimColor参数获取自发光颜色
- half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
- o.Emission = _RimColor.rgb * pow (rim, _RimPower);
- }
- //-------------------结束CG着色器编程语言段------------------
- ENDCG
- }
- //“备胎”为普通漫反射
- Fallback "Diffuse"
- }
我们将此Shader编译后赋给材质,得到如下非常赞的效果。除了载入纹理,还有色泽,边缘颜色和强度可供调节:
依然是调些效果玩一玩:
而在场景中的实测效果为:
8.细节纹理
接着我们来看一个在屏幕上显示纹理细节的Shader:
[cpp] view plain copy
- Shader "浅墨Shader编程/Volume6/31.细节纹理"
- {
- //--------------------------------【属性】----------------------------------------
- Properties
- {
- _MainTex ("【主纹理】Texture", 2D) = "white" {}
- _Detail ("【细节纹理】Detail", 2D) = "gray" {}
- }
- //--------------------------------【子着色器】----------------------------------
- SubShader
- {
- //-----------子着色器标签----------
- Tags { "RenderType" = "Opaque" }
- //-------------------开始CG着色器编程语言段-----------------
- CGPROGRAM
- //【1】光照模式声明:使用兰伯特光照模式
- #pragma surface surf Lambert
- //【2】输入结构
- struct Input
- {
- //主纹理的uv值
- float2 uv_MainTex;
- //细节纹理的uv值
- float2 uv_Detail;
- };
- //变量声明
- sampler2D _MainTex;
- sampler2D _Detail;
- //【3】表面着色函数的编写
- void surf (Input IN, inout SurfaceOutput o)
- {
- //先从主纹理获取rgb颜色值
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- //设置细节纹理
- o.Albedo *= tex2D (_Detail, IN.uv_Detail).rgb * 2;
- }
- //-------------------结束CG着色器编程语言段------------------
- ENDCG
- }
- //“备胎”为普通漫反射
- Fallback "Diffuse"
- }
我们将此Shader编译后赋给材质,不加细节纹理如下:
加纹理细节的效果图如下:
而在场景中的实测效果为:
9.凹凸纹理+颜色可调+边缘光照+细节纹理
结合上面的8个Shader,我们可以完成本期文章这个结合了凹凸纹理+颜色可调+边缘光照+细节纹理的稍微复杂一点的Surface Shader:
[cpp] view plain copy
- Shader "浅墨Shader编程/Volume6/32.凹凸纹理+颜色可调+边缘光照+细节纹理"
- {
- Properties
- {
- _MainTex ("【主纹理】Texture", 2D) = "white" {}
- _BumpMap ("【凹凸纹理】Bumpmap", 2D) = "bump" {}
- _Detail ("【细节纹理】Detail", 2D) = "gray" {}
- _ColorTint ("【色泽】Tint", Color) = (0.6, 0.3, 0.6, 0.3)
- _RimColor ("【边缘颜色】Rim Color", Color) = (0.26,0.19,0.16,0.0)
- _RimPower ("【边缘颜色强度】Rim Power", Range(0.5,8.0)) = 3.0
- }
- //--------------------------------【子着色器】----------------------------------
- SubShader
- {
- //-----------子着色器标签----------
- Tags { "RenderType" = "Opaque" }
- //-------------------开始CG着色器编程语言段-----------------
- CGPROGRAM
- //【1】光照模式声明:使用兰伯特光照模式+自定义颜色函数
- #pragma surface surf Lambert finalcolor:setcolor
- //【2】输入结构
- struct Input
- {
- //主纹理的uv值
- float2 uv_MainTex;
- //凹凸纹理的uv值
- float2 uv_BumpMap;
- //细节纹理的uv值
- float2 uv_Detail;
- //当前坐标的视角方向
- float3 viewDir;
- };
- //变量声明
- sampler2D _MainTex;
- sampler2D _BumpMap;
- sampler2D _Detail;
- fixed4 _ColorTint;
- float4 _RimColor;
- float _RimPower;
- //【3】自定义颜色函数setcolor的编写
- void setcolor (Input IN, SurfaceOutput o, inout fixed4 color)
- {
- color *= _ColorTint;
- }
- //【4】表面着色函数的编写
- void surf (Input IN, inout SurfaceOutput o)
- {
- //先从主纹理获取rgb颜色值
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- //设置细节纹理
- o.Albedo *= tex2D (_Detail, IN.uv_Detail).rgb * 2;
- //从凹凸纹理获取法线值
- o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
- //从_RimColor参数获取自发光颜色
- half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
- o.Emission = _RimColor.rgb * pow (rim, _RimPower);
- }
- //-------------------结束CG着色器编程语言段------------------
- ENDCG
- }
- //“备胎”为普通漫反射
- Fallback "Diffuse"
- }
我们将此Shader编译后赋给材质,得到如下效果:
依然是调一些效果玩一玩:
而在场景中的实测效果为:
|