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 (4-1)(4-2)静态立方体贴图的创建与使用
開始学习第4章 - 着色器的反射 看完了1.2节,来记录一下.反射主要是利用了 Cubemap 立方体贴图. 认识Cubemap 立方体贴图.就如同名字所说.在一个立方体上有6张图.就这样觉得吧. 假 ...
- Unity Shaders and Effects Cookbook (3-5) 金属软高光
书上这一节看得我头昏脑胀,数学渣表示自理不能-- 并且也不了解这个效果的实际意义. 先记录下来,后面真正看懂了再来补充具体理论. 通过一张纹理贴图,定义高光的形状,利用到的纹理贴图有三种 这里并非把纹 ...
- 【Unity Shaders】《Unity Shaders and Effects Cookbook》总结篇
我的唠叨 不知不觉,从发表第一篇关于<Unity Shaders and Effects Cookbook>已经快十个月了.一开始的初衷就是学习笔记,毕竟将来回过头去看的时候,再看英文难免 ...
- Unity Shaders and Effets Cookbook
Unity Shaders and Effects Cookbook 最近在读 <Unity Shaders and Effects Cookbook> 中文名称:<Unity 着色 ...
- Unity Shader and Effects Cookbook问题记录
1.p61的specular计算,涉及到的一个参数“_SpecColor”是在Unity的官方cginc文件(UnityLightingCommon.cginc)中,是直接赋颜色给这个参数,反应到你模 ...
- 【Unity Shaders】Using Textures for Effects —— 实现Photoshop的色阶效果
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 【Unity Shaders】Using Textures for Effects——打包和混合textures
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 【Unity Shaders】Using Textures for Effects——让sprite sheets动起来
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 【Unity Shaders】Using Textures for Effects——通过修改UV坐标来滚动textures
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
随机推荐
- SQL 与或运算
如果一个字段需要同时包含多个信息点, 最佳的方法是进行位运算,如:1,2,4,8,16 根据与运算进行判断,如一个字段为7,判断2是否存在, 7&2 = 2为ture时,表示存在,反之亦然, ...
- 爬取本blog的所有标题和链接
#coding=utf-8 from bs4 import BeautifulSoup import urllib.request for i in range(1,54): url = " ...
- Welcome-to-Swift-23访问控制(Access Control)
访问控制可以限定你在源文件或模块中访问代码的级别,也就是说可以控制哪些代码你可以访问,哪些代码你不能访问.这个特性可以让我们隐藏功能实现的一些细节,并且可以明确的指定我们提供给其他人的接口中哪些部分是 ...
- Spring Boot 必须先说说 Spring 框架!
现在 Spring Boot 非常火,各种技术文章,各种付费教程,多如牛毛,可能还有些不知道 Spring Boot 的,那它到底是什么呢?有什么用?今天给大家详细介绍一下. Spring Boot ...
- 关闭webkit浏览器的自动完成,修正,大写
关闭input自动完成<input name="q" type="text" autocomplete="off"/>关闭整个表 ...
- NOIP2017赛前模拟1:总结
题目: 1.造盒子 题目描述 企鹅豆豆收到了面积为 K 的一块橡皮泥.但是他没有合适的盒子来装下这个橡皮泥.所以他打算造一个盒子. 制造台是有方形网格的平台,每个小正方形边长为 1 .现在豆豆有两类木 ...
- P2622 关灯问题II (状态压缩,最短路)
题目链接 Solution 这道题算是很经典的状压问题了,好题. 考虑到 \(n\) 的范围仅为 \(10\) , 那么也就是说所有状态压起来也只有 \(1024\) 种情况. 然后我们发现 \(m\ ...
- scrapy之spiders
官方文档:https://docs.scrapy.org/en/latest/topics/spiders.html# 一句话总结:spider是定义爬取的动作(是否跟进新的链接)及分析网页结构(提取 ...
- 介绍一款移动端滚动加载的插件---dropload
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- es6总结(十二)--generator