Unity Shaders and Effects Cookbook (3-4) 使用高光贴图
在学习完上一节之后。已经了解了在Unity 中怎样实现一个高光 Shader ,可是会有一个问题。就是效果看起来不切实际,如以下的问题
我用一张图片贴到了Cube上面。然后用了一个高光材质,得到了下图的效果。
事实上这个效果还算能够,可是认真看就会发现。这个结果是不符合自然现象的。
这个箱子是木头的,然后有铁皮 作为封条。
首先不符合常理的是为什么这个木头箱子会反光!
可能木头箱子打蜡了。然后就反光。可是为什么打蜡的木头 和 铁皮 看起来是一样的。光滑度是一样的吗?
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
这样一种效果是非常难解释的通的。
那么怎样模拟真实的情况。也就是该反光的地方才反光。不该反光的地方不反光?
回忆一下高光的原理。高光是依据反射光与 视线的角度来求出高光的强度值的。对于上面的箱子,木材 和 铁片是在同一个平面上的,所以求出的高光强度值是同样的。
也就是说。依照上一节的做法是不能将 铁片 和 木材的高光强度值区分开来的。
那么我们要想一个办法。
首先想到的是,把铁片 和 木材分开来。木材作为单独的一张贴图,铁片作为另外一张贴图,里面是空白的。
灯光仅仅作用于铁片这一张贴图。我们计算出来的 高光强度 Specular * 铁片贴图的RGB。由于铁片中间是黑色的,所以铁片的中间这一块的 RGB 都是 0 。所以实际上仅仅有外側铁片的地方,才真正受到了光照的影响!然后再和 木材的贴图的颜色相加。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
由此引入这一节的知识 -- 高光贴图。
如上面所说,须要两个贴图,木材这一个贴图仅仅接受漫反射光照。而铁片这一个高光贴图 接收高光。
在 Shader 中定义相应的变量
Properties
{_MainTex ("Base (RGB)", 2D) = "white" {}_SpecularColor("Specular Color",Color)=(1,1,1,1)_SpecularTexture("Specular Texture",2D)="white" {}_SpecularPower("Specular Power",Range(0.1,100))=1
}
我们在 Suf 函数中,对两个纹理取样。然后存储到 SurfaceOutput 结构体中传入到 光照模型函数。
然后会遇到一个问题,SurfaceOutput 结构体,是Unity 定义的一个结构体,其定义存在与 Lighting.cginc 文件里
struct SurfaceOutput {fixed3 Albedo;fixed3 Normal;fixed3 Emission;half Specular;fixed Gloss;fixed Alpha;
};
查看法线。里面并没实用于存储高光贴图颜色信息的变量!
所以这次我们要自己定义一个 SurfaceOutput 结构体,加入一个 SpecularColor 变量。
struct CustomSurfaceOutput
{fixed3 Albedo;fixed3 Normal;fixed3 Emission;half Specular;fixed3 SpecularColor;fixed Gloss;fixed Alpha;
};
然后把 surf 和 光照模型函数中的 SurfaceOutput 都改动为自己定义的 CustomSurfaceOutput
void surf (Input IN, inout CustomSurfaceOutput o)
{half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = c.rgb;o.Alpha = c.a;
}inline fixed4 LightingCustomPhong(CustomSurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten)
{fixed4 c;c.rgb=s.Albedo;c.a=s.Alpha;return c;
}
注意。这个时候我们还没有指定光照模型函数为 CustomPhong,所以Unity 会抛出一堆莫名其妙的错,这是由于 surf 中传给 Lambert 光照模型的是 CustomSurfaceOutput,而不是默认的 SurfaceOutput 了。
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
指定光照模型为 CustomPhong
CGPROGRAM
#pragma surface surf CustomPhong
由于要在 Surf 函数中处理 木头 这个 漫反射贴图 和 铁皮 这个高光贴图,原来的 Input 结构体中是仅仅有 漫反射贴图的 UV信息的,所以改动 Input结构体加入高光贴图的 UV信息
struct Input
{float2 uv_MainTex;float2 uv_SpecularTexture;
};
改动 surf 函数,依据 Input 中的UV信息,提取当前 UV坐标的颜色信息(纹素)
void surf (Input IN, inout CustomSurfaceOutput o)
{//不接受高光的,漫反射贴图,比如木头half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = c.rgb;o.Alpha = c.a;//接收高光的,高光贴图,比如铁皮half4 specularC=tex2D(_SpecularTexture,IN.uv_SpecularTexture);o.SpecularColor=specularC.rgb;//用r值作为系数,假设当前UV坐标是位于铁片里面黑色的那一块。那么rgb都是0。这样里面黑色的那一块事实上是无效的。o.Specular = specularC.r;
}
改动光照函数
inline fixed4 LightingCustomPhong(CustomSurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten)
{//首先计算漫反射;float diffuse=max(0,dot(s.Normal,lightDir));//计算漫反射颜色;float3 diffuseColor=_LightColor0*s.Albedo * diffuse;//计算反射光方向向量float3 halfReflectVector=normalize(lightDir + viewDir);//计算反射光强度;假设当前位置是铁片黑色的那一块,那么Specular是0,这里就没有高光了。float specular = pow( max(0,dot(s.Normal,halfReflectVector)) , _SpecularPower) * s.Specular;//计算高光颜色 高光贴图採样颜色 * 反射光强度 * 编辑器中指定的高光颜色 * 光照颜色;float3 specularColor =_LightColor0.rgb* s.SpecularColor * specular * _SpecularColor.rgb *(atten*5);fixed4 c;c.rgb=diffuseColor + specularColor;c.a=s.Alpha;return c;
}
终于完毕得到结果
演示样例project下载:
http://pan.baidu.com/s/1dFyiyDb
Unity Shaders and Effects Cookbook (3-4) 使用高光贴图相关推荐
- Unity Shaders and Effects Cookbook (3-6) 创建各向异性高光类型(Anisotropic) 模拟金属拉丝效果
这一次学习各向异性高光类型,名字真拗口,Anisotropic 这个英文单词也很拗口. 各向异性是模拟物体表面 沟槽方向性的高光反射类型,他会修改或延伸垂直方向上的高光. 比如模拟金属拉丝的效果,就可 ...
- Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画
上一节中说了,在 Surface Shader 中,添加顶点函数,我们可以在 顶点函数中获取到 顶点数据,比如顶点颜色.顶点坐标等. 这一节学习获取顶点坐标,并且修改顶点坐标,来实现顶点动画. 简单介 ...
- Unity Shaders and Effects Cookbook (2-7)实现 Photoshop 色阶效果
看完了这一书上的代码,然后在网上查找 Photoshop 色阶的一些解释,大致理解为:调整色阶就是调整亮度,也就是调整纹理 R.G.B 通道的数值大小. 下面是 Photoshop 中的直方图转自ht ...
- Unity Shaders and Effects Cookbook (4-5)Cubemap与菲涅尔反射
菲涅尔是人名,他发现,当我们站在水中,直直的往下看水面,是看不到反射的太阳光的.而当我们往远处看时,就能看到很强的反光,也就是成语波光粼粼所体现的.这一现象就被命名为 菲涅尔反射. 刚看这一节的时候觉 ...
- Unity Shaders and Effects
https://www.baidu.com/link?url=o85V5QLsraCjMOmzJc6081Z3bsQRw4_hjoPki5igyrvrJExygnt2Ex-_oGmH60-wm2VU5 ...
- 【《Unity 2018 Shaders and Effects Cookbook》翻译提炼】(九)Physically - Based Rendering
制作过程中最重要的方面时效率,实时着色很昂贵,而Lambertian或BlinnPhong等技术是计算成本和现实之间的折中. 拥有更 强大的GPU允许我们逐步写更强大的光照模型和渲染引擎,目的是模 ...
- 22.01.23 《Unity 2018 Shaders and Effects Cookbook》笔记Chapter7
7.Fragment Shaders and Grab Passes vertex and fragment shader 对光照如何影响物体表面不感兴趣,不受物理限制,对非真实感的效果很好 使用#p ...
- 【《Unity 2018 Shaders and Effects Cookbook》翻译提炼】(三)法线贴图和透明材质
1.法线贴图 3D模型的每个三角形都有一个面向方向,这是它指向的方向.它通常用放置在三角形中心的箭头表示,并且与表面正交.面对方向在光线反射到表面上的方式中起着重要作用.如果两个相邻的三角形朝着不同的 ...
- 【《Unity 2018 Shaders and Effects Cookbook》翻译提炼】(八)BlinnPhong模型和 Anisotropic 高光(可用于金属性,头发)
这篇文章最好与前一篇连着看,自己可做比较. 1.BlinnPhong 模型 Blinn是计算和估计镜面反射的另一种更有效的方法.这是通过从 视图方向和光方向获得半矢量来完成饿.JimBlinn将它带入 ...
最新文章
- ORA-24247: network access denied by access control list (ACL)
- HDU 1115 Lifting the Stone(求多边形重心)
- 电商企业怎样用好大数据
- mac地址漂移flapping的前因后果
- 批量修改TS Profile、盘符计算器小工具
- c和JAVA的安全编码_C、C++ 和 Java安全编码实践提示与技巧
- 解决:fatal: not a git repository (or any of the parent directories): .git的问题
- linux串口 demo 解析原创 代码没有完全测试
- 两波形相位差的计算值_波形相位频率可调DDS信号发生器(设计分享)
- php null空值(转)
- 怎么让计算机文件格式显示,已知文件类型的扩展名如何设置显示与隐藏?
- cad墙线打断lisp_[求助]很多相交线快速打断 - AutoLISP/Visual LISP 编程技术 - CAD论坛 - 明经CAD社区 - Powered by Discuz!...
- (一)移动端前端开发-移动端基础
- vue中使用vue-awesome-swiper的方法(实现一屏展示多个图片,点击左右滚动一张)
- 程序中中文乱码问题的总结
- 互联网思维——社会化思维
- jzoj5498 【清华集训2017模拟12.10】大佬的难题 巧妙容斥
- php_curl.dll下载,php_curl.dll,下载,简介,描述,修复,等相关问题一站搞定_DLL之家
- 两行代码隐藏进程在top中的显示
- jsencrypt.js加密java后端解密
热门文章
- mendeley 笔记_免费文献管理器 Mendeley,其实比你想象的好用!
- 2008年卫星地图_黄河入海口1984年-2016年,34年卫星地图变化
- python语法与java语法的区别_Python语言与java语法的异同之处
- java面向对象笔试_Java面向对象笔试题.doc
- 理解JavaScript的宏微任务
- ASP.NET的ADO(ActiveX Data Objects)
- java poi修改word2007_java poi 替换word2007中的指定文本
- python识别复杂验证码2020_Python识别验证码!学会这步,百分之60的网站你基本都能识别了!...
- 南京江宁软通动力怎么样_南京有什么美食?有哪些必游景点?
- html是非结构数据吗,Python处理非结构数据