TA-Shader-文件 转载丨Unity实时反射——AngryBots示例项目地面实时反射效果剖析
发布于
2023-9-10
586
36
TA资源类型
TA资源类型: 算法思路 
shader资源类型: shader代码 
适用引擎: unity 
资源介绍: -

您需要 登录 才可以下载或查看,没有账号?注册

x
Angry Bots是Unity安装程序自带的开源示例项目。该示例项目虽然已经发布很久了,但是其很多设计和实现仍然具有参考价值。运行该项目仔细观察,可以发现其雨天地面效果是实时反射的。这里我们先阐明实时反射的原理,然后分析其绘制流程。

构造反射相机

视图矩阵

反射相机的视图矩阵由反射矩阵变换得到,反射矩阵由反射平面确定,下面列出反射矩阵推导过程。

反射位置
20160321231659557.png
20160321231722089.png



反射方向





M1*M2即得到示例代码所示的反射矩阵。
  • static Matrix4x4 CalculateReflectionMatrix(Matrix4x4 reflectionMat, Vector4 plane)
  • {
  •     reflectionMat.m00 = (1.0F - 2.0F * plane[0] * plane[0]);
  •     reflectionMat.m01 = (-2.0F * plane[0] * plane[1]);
  •     reflectionMat.m02 = (-2.0F * plane[0] * plane[2]);
  •     reflectionMat.m03 = (-2.0F * plane[3] * plane[0]);
  •     reflectionMat.m10 = (-2.0F * plane[1] * plane[0]);
  •     reflectionMat.m11 = (1.0F - 2.0F * plane[1] * plane[1]);
  •     reflectionMat.m12 = (-2.0F * plane[1] * plane[2]);
  •     reflectionMat.m13 = (-2.0F * plane[3] * plane[1]);
  •     reflectionMat.m20 = (-2.0F * plane[2] * plane[0]);
  •     reflectionMat.m21 = (-2.0F * plane[2] * plane[1]);
  •     reflectionMat.m22 = (1.0F - 2.0F * plane[2] * plane[2]);
  •     reflectionMat.m23 = (-2.0F * plane[3] * plane[2]);
  •     reflectionMat.m30 = 0.0F;
  •     reflectionMat.m31 = 0.0F;
  •     reflectionMat.m32 = 0.0F;
  •     reflectionMat.m33 = 1.0F;
  •    return reflectionMat;


其中代码中4维数组plane存的是点法线式平面方程的参数。

投影矩阵

反射相机的投影矩阵并非常规的投影矩阵,反射面上的斜投影面才是反射相机真正的投影面,所以需要用斜投影面代替掉常规的投影面。示例代码中给出了斜投影矩阵,原理和推导过程参看本文末尾给出的参考文献链接。这里给出示意图:


绘制

流程

1.创建反射摄像机reflectionCamera,reflectionCamera默认disable,用一张RenderTexutre来保存reflectionCamera绘制的结果,用来在之后的shader里采样。

  • reflectCamera.enabled = false;
  • reflectCamera.targetTexture = CreateTextureFor(cam);
  • private RenderTexture CreateTextureFor(Camera cam)
  • {
  •     …
  •     RenderTexture rt = new RenderTexture(Mathf.FloorToInt(cam.pixelWidth * rtSizeMul), Mathf.FloorToInt(cam.pixelHeight * rtSizeMul), 24, rtFormat);
  •     rt.hideFlags = HideFlags.DontSave;
  •     return rt;


2.在LateUpdate中根据当前摄像机去构造反射摄像机变换矩阵,涉及到反射面reflectiveSurface的选取,示例中是选取合适的路面做反射面,然后手动调用绘制,绘制前设置前面剔除,绘制完置回。

  • private void RenderReflectionFor (Camera cam, Camera reflectCamera)
  • {
  •      …
  •      //构造反射平面
  •      Vector3 pos = reflectiveSurface.transform.position;
  •      pos.y = reflectiveSurface.position.y;
  •      Vector3 normal = reflectiveSurface.transform.up;
  •      float d = -Vector3.Dot(normal, pos) - clipPlaneOffset;
  •      Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
  •      //构造反射视图矩阵
  •      Matrix4x4 reflection = Matrix4x4.zero;
  •      reflection = CalculateReflectionMatrix(reflection, reflectionPlane);
  •      //得到反射摄像机位置
  •      oldpos = cam.transform.position;
  •      Vector3 newpos = reflection.MultiplyPoint (oldpos);
  •      //得到反射摄像机视图矩阵
  •      reflectCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
  •      //得到反射摄像机投影矩阵
  •      Vector4 clipPlane = CameraSpacePlane(reflectCamera, pos, normal, 1.0f);
  •      Matrix4x4 projection =  cam.projectionMatrix;
  •      projection = CalculateObliqueMatrix(projection, clipPlane);
  •      reflectCamera.projectionMatrix = projection;
  •      …
  •      GL.SetRevertBackfacing(true);
  •      reflectCamera.RenderWithShader (replacementShader, "Reflection");
  •      GL.SetRevertBackfacing(false);


Shader

反射面的材质接受反射相机绘制好的RenderTexture做为贴图对其采样。示例中的反射面——地面shader增加了uv扰动参数和噪声贴图用来达到扭曲效果,还叠加了一个水花效果,这样的话使得雨天地面反射更加真实,而不是干净得像一面镜子。

}
1  丨v2f_full vert (appdata_full v)
2  丨{
3  丨   …                                         
4  丨    // uv坐标扰动,随时间变化
5  丨    o.normalScrollUv.xyzw = v.texcoord.xyxy * _TexAtlasTiling + _Time.xxxx * _DirectionUv;
6  丨
7  丨    //经验算法?!生成UV取水花贴图                                                                     
8  丨    half3 worldSpace = mul(_Object2World, v.vertex).xyz;
9  丨    worldSpace = (-_WorldSpaceCameraPos * 0.6 + worldSpace) * 0.07;
10丨    o.fakeRefl =  worldSpace.xz;
11丨
12丨    return o;
13丨}
14丨
15丨
16丨fixed4 frag (v2f_full i) : COLOR0
17丨{      
18丨    fixed4 nrml = tex2D(_Normal, i.normalScrollUv.xy);        
19丨    nrml = (nrml - 0.5) * 0.1;            
20丨
21丨    //UV扰动,在RenderTexture采样                                                                                                                             
22丨    fixed4 rtRefl = tex2D (_ReflectionTex, (i.screen.xy / i.screen.w) + nrml.xy);                                         
23丨
24丨    //叠加上在水花贴图
25丨    rtRefl += tex2D (_FakeReflect, i.fakeRefl + nrml.xy);            
26丨
27丨    //原贴图颜色                                                      
28丨    fixed4 tex = tex2D (_MainTex, i.uv);
29丨
30丨    //SrcAlpha One混合模式叠加                           
31丨    tex  = tex + tex.a * rtRefl;                                         
32丨    return tex;
33丨}

效果

附School项目按示例方式添加雨水地面实时反射效果前后对比图:




参考链接:
http://fp.optics.arizona.edu/opt ... rror%20matrices.pdf
http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
---------------------
作者:bill2ccssddnn
来源:CSDN
原文:https://blog.csdn.net/bill2ccssddnn/article/details/50951263
版权声明:本文为博主原创文章,转载请附上博文链接!

本帖被以下画板推荐:

天将雨 夜三思

使用道具 举报 登录

回复 <
风云  发表于 2018-10-24 18:48:22  
2#
回复 收起回复
使用道具
1843918957  发表于 2018-10-24 18:55:22  
3#
回复 收起回复
使用道具
清风丨伊人醉  发表于 2018-10-24 20:08:12  
4#
不太看的懂,但是感觉很6
回复 收起回复
使用道具
fatlong  发表于 2018-10-25 09:57:14  
5#
效果增色不少。
回复 收起回复
使用道具
漫道  发表于 2018-10-25 10:15:29  
6#
回复 收起回复
使用道具
灰灰丿  发表于 2018-10-25 10:28:50  
7#
我们先定一个能达到的小目标,先赚它一亿元素币
回复 收起回复
使用道具
雪夜裸奔男  发表于 2018-10-25 11:01:14  
8#
谢谢分享
回复 收起回复
使用道具
李琛琛  发表于 2018-10-31 08:30:31  
9#

很好,正在看
回复 收起回复
使用道具
风起云涌  发表于 2018-10-31 08:49:33  
10#
总有刁民想害朕,却不知朕日日元素,早已天下无敌
回复 收起回复
使用道具
qq_..._At1  发表于 2018-11-4 19:31:40  
11#
6666666
回复 收起回复
使用道具
某只咸鱼  发表于 2018-11-4 22:08:26  
12#
围观看看看看看看看看
回复 收起回复
使用道具
某只咸鱼  发表于 2018-11-4 22:08:31  
13#
围观看看看看看看看看
回复 收起回复
使用道具
某只咸鱼  发表于 2018-11-4 22:08:34  
14#
围观看看看看看看看看
回复 收起回复
使用道具
Shiva希瓦  发表于 2018-11-4 23:16:01  
15#
不错
回复 收起回复
使用道具
冷月俊婕  发表于 2018-11-4 23:22:26  
16#
学习
回复 收起回复
使用道具
YS界王  发表于 2018-11-4 23:47:12  
17#
首发必需微元素,荣耀加身装备酷!
回复 收起回复
使用道具
李之仪  发表于 2018-11-5 09:44:53  
18#

元素那么大,我想来到处去看看!
回复 收起回复
使用道具
李琛琛  发表于 2018-11-7 08:32:45  
19#
不错,值得收藏
回复 收起回复
使用道具
yisbad  发表于 2018-11-7 08:50:15  
20#
蛮好蛮好!
回复 收起回复
使用道具
12下一页

快来发表你宝贵的意见吧!

空空山新雨后 实名

通过了实名认证的内容创造者

天将雨 夜三思

主题
966
精华
155
超神
12
扩散
1540
微金
3000
智慧
610
余额
76
在线时间
15062 小时

翡翠剑 【绝】红龙战甲 学徒法袍 赤铁剑 铁剑 元素之盾 钢剑 长剑 水晶剑 魔影剑 死亡刃 元素铜币 元素银币 元素金币 元素秘币 元素圣币 短杖 血晶杖 【绝】珍珠戒指 【绝】黄金项链 女皇之泪 长枪 双杀 巨浪 龙枪 战神 魔神战甲 元素之铠 黄金圣衣 追月 六维几何 相对时空 【绝】结界玄晶 神界之石 【绝】狂战斧 【绝】蚩尤斧 【绝】轩辕剑 圣盾-【瓦雷利亚】 秘法卷轴 裁决 神速靴 火元素 元素之钻 秘法之钻 再造药水 动感药水 智能药水 微库VIP 翠晶之钻 扩散者 钢铁矿镐 秘银矿镐 黄金矿镐 彗星钛晶矿 阿尔法晶矿 泰坦高能矿 宇宙魔方 守望者【EX】 守望者【赤炼】 守望者【天使】 【绝】守望者【死神】 希望人没事 吃鸡头盔 吉普车 吃鸡甲 振金项链 守望者【猎空】 电吉他 黑珍珠戒指 玫瑰金项链 烈-红龙战甲 【绝】千人纪念徽章 无色原始矿 绿母翠晶矿 超星赤辉矿 怀特紫星矿 粒粒皆辛苦

快速回复 返回顶部 返回列表