Unity——ShaderLab实现玻璃和镜子效果
在这一篇中会实现会介绍折射和反射,以及菲尼尔反射;并且实现镜子和玻璃效果;
这里和之前不同的地方在于取样的是一张CubeMap;
demo里的cubemap使用的一样,相机所在位置拍出来的周围环境图;
生成CubeMap的工具脚本:
public class RenderCubemapWizard : ScriptableWizard {
public Transform renderFromPosition;
public Cubemap cubemap;
void OnWizardUpdate () {
helpString = "Select transform to render from and cubemap to render into";
isValid = (renderFromPosition != null) && (cubemap != null);
}
void OnWizardCreate () {
// create temporary camera for rendering
GameObject go = new GameObject( "CubemapCamera");
go.AddComponent<Camera>();
// place it on the object
go.transform.position = renderFromPosition.position;
// render into cubemap
go.GetComponent<Camera>().RenderToCubemap(cubemap);
// destroy temporary camera
DestroyImmediate( go );
}
[MenuItem("GameObject/Render into Cubemap")]
static void RenderCubemap () {
ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
"Render cubemap", "Render!");
}
}
1.反射
用反射方向在CubeMap上取样,_ReflectAmount控制反射程度,_ReflectColor反射颜色;
v2f vert (appdata v){
//计算反射向量
o.worldReflect = reflect(-o.worldViewDir,o.worldNormal);
...
}
fixed4 frag (v2f i) : SV_Target{
//根据反射向量从cubemap纹理上取样
fixed3 reflection = texCUBE(_Cubemap,i.worldReflect).rgb * _ReflectColor.rgb;
//混合反射和漫反射
return fixed4(ambient + lerp(diffuse,reflection,_ReflectAmount)*atten, 1.0);
}

2.折射
和反射几乎相同,将反射改成折射,计算公式改成折射计算公式;
v2f vert (appdata v){
//计算反射向量
o.worldRefract = refract(-normalize(o.worldViewDir),normalize(o.worldNormal),_RefractRatio);
...
}
fixed4 frag (v2f i) : SV_Target{
//根据反射向量从cubemap纹理上取样
fixed3 refraction = texCUBE(_Cubemap,i.worldRefract).rgb * _RefractColor.rgb;
//混合反射和漫反射
return fixed4(ambient + lerp(diffuse,refraction,_RefractAmount)*atten, 1.0);
}
成像是倒的;透过茶壶可以看到对面;

3.菲尼尔
反射光的强度与视线方向和法线方向的夹角有关,夹角越大反射光越强;最高90度,也就是边缘光最强;
Schlick菲尼尔公式:Fschlick(v,n) = F0 + (1-F0)(1- dot(v,n)) ^ 5;F0控制菲尼尔强度;
fixed4 frag (v2f i) : SV_Target{
...
//Schlick Fresnel——边缘光
fixed3 reflection = texCUBE(_Cubemap,i.worldRefl).rgb;
fixed3 fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldViewDir,worldNormal), 5);
//菲尼尔系数控制反射强度
return fixed4(ambient + lerp(diffuse,reflection,saturate(fresnel)) * atten, 1.0);
}

4.玻璃效果
通过GrabPass{"_RefractionTex"} 抓取当前屏幕内容渲染到_RefractionTex贴图上
RefractionTex贴图用来取样折射纹理;_Distortion参数模拟法线扰动的程度;
GrabPass{"_RefractionTex"}
...
//GrabPass纹理
sampler2D _RefractionTex;
//纹素大小
float4 _RefractionTex_TexelSize;
fixed4 frag (v2f i) : SV_Target
{
//法线偏移扰动-模拟折射
fixed3 bump = UnpackNormal(tex2D(_BumpMap,i.uv.zw));
float2 offset = bump.xy*_Distortion*_RefractionTex_TexelSize.xy;
//折射计算-屏幕坐标偏移后透视除法取样折射纹理
i.screenPos.xy = offset + i.screenPos.xy;
fixed3 refractColor = tex2D(_RefractionTex,i.screenPos.xy/i.screenPos.w).rgb;
//矩阵计算世界法线
bump = normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump)));
//反射计算
fixed3 reflectDir = reflect(-worldViewDir,bump);
fixed4 texColor = tex2D(_MainTex,i.uv.xy);
fixed3 reflectColor = texCUBE(_Cubemap,reflectDir).rgb * texColor.rgb;
//混合反射和折射_RefractAmount
return fixed4(reflectColor*(1-_RefractAmount)+refractColor*_RefractAmount, 1.0);
}

5.镜子
tex2Dproj(_ReflectionTex,UNITY_PROJ_COORD(i.refl));
UNITY_PROJ_COORD:given a 4-component vector, return a texture coordinate suitable for projected texture reads. On most platforms this returns the given value directly.
传入Vector4,返回一张用来投影取样的纹理,大部分平台直接返回给定值;
镜子直接传入屏幕顶点坐标获得投影纹理,再通过投影取样获得颜色,和最终结果混合;
但是上面效果和局限性都比较大,所以找了个大佬写的镜子效果;
使用相机和RenderTexture,底层原理差不多,效果要好了很多;

Unity——ShaderLab实现玻璃和镜子效果的更多相关文章
- Unity镜子效果的实现(无需镜子Shader)
Unity镜子效果制作教程 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...
- Unity ShaderLab学习总结
http://www.jianshu.com/p/7b9498e58659 Unity ShaderLab学习总结 Why Bothers? 为什么已经有ShaderForge这种可视化Shader编 ...
- ShaderLab实现Vignette过场动画效果
实现Vignette过场动画效果 postprocessing中有渐晕效果(Vignette),镜头可以由边缘往中间慢慢变黑: 但是我打包WebGL的时候提示我postprocessing,GPU不支 ...
- 使用Unity创造动态的2D水体效果
者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染器,触发器以及粒子的混合体来创造这一水体效果,最终得到可运用于你下款游戏的水纹和 ...
- Unity的NGUI插件篇——入场效果
Unity的NGUI插件篇--入场效果 入场效果 入场效果须要借助于NGUI提供的TweenPosition类来完毕.为了说明此类的用法.本节将使会解说两个演示样例.本文选自 大学霸 <NGU ...
- Unity Shaderlab: Object Outlines 转
转 https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/ Unity Shader ...
- unity之自制玻璃啤酒瓶shader
客户的要求如下 步骤: 1.进行玻璃瓶效果分析 效果如下:高光,类次表面散射(里层通透而外层较为暗淡),外层白色勾勒轮廓. 高光:unity内部提供光滑度参数,越光滑则高光效果越明显,啤酒瓶材质是属于 ...
- 【转】如何使用Unity创造动态的2D水体效果
原文:http://gamerboom.com/archives/83080 作者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染 ...
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
随机推荐
- go recover让崩溃的程序继续执行
package main import ( "fmt" "log" ) func de() { //recover() //可以打印panic的错误信息 //f ...
- Linux学习 - 文本编辑器Vim
一.Vim工作模式 二.命令 插入 a 光标后插入 A 光标所在行尾插入 i 光标前插入 I 光标所在行首插入 o 光标下插入新行 O 光标上插入新行 删除 x 删除光标处字符 nx 删除光标处后 ...
- Linux 性能优化笔记:应用监控
指标监控 跟系统监控一样,在构建应用程序的监控系统之前,首先也需要确定,到底需要监控哪些指标.特别是要清楚,有哪些指标可以用来快速确认应用程序的性能问题. 对系统资源的监控,USE 法简单有效,却不代 ...
- 商城项目的购物车模块的实现------通过session实现
1.新建购物车的实体类Cart public class Cart implements java.io.Serializable{ private Shangpin shangpin;//存放商品实 ...
- myfs 操作系统课内实验 文件管理系统 Ext2
To 学弟学妹们: 写这个随笔原意是记录一下这个很有趣的实验 ,记录一下写的时候的细节和思路. 要是光是抄这个代码,反而使得这个实验失去了意义. 加油,这个实验收获真的很大. 任务描述: 用一个空白文 ...
- 优化器统计跟踪(SYS.EXP_HEAD$ SYS.EXP_OBJ$ SYS.EXP_STAT$不)导致表空间 SYSAUX不断增长
资料来自support文档 ID 2354960.1 环境: aws rds 19c(亚马逊云oracle 数据库) 背景: 在一次查看数据库表段的占用空间大小的时候,无意间发现其中EXP_开头的表占 ...
- springboot项目WEB-INF 目录 jsp页面报404
我是跟着<深入浅出 Spring Boot 2.x>这本书学习的,在"初识Spring MVC"章节中,搭建项目,然后访问jsp页面时报错:Path with &quo ...
- java 多线程:线程安全问题,示例DateFormat多线程执行冲突解决方案ThreadLocal、方法内变量
SimpleDateFormat多线程中执行报错 java.lang.NumberFormatException: For input string: "" import ja ...
- 可以通过外键的.id直接传值
可以通过外键的.id直接传值 如<input type="text" name="user.department.id" value="1&qu ...
- IDEA报错 Error:(24, 35) java: 常量字符串过长
修改设置