转载丨Unity实时反射——AngryBots示例项目地面实时反射效果剖析...
Shader材质球TA图形学渲染引擎技术综合
显示全部 7
609 36
实名

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

发布于 2023-9-10 00:30:59

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

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
版权声明:本文为博主原创文章,转载请附上博文链接!

本帖被以下画板推荐:

天将雨 夜三思
使用道具 <
ゞ囙艏往倳ゞ  发表于 2020-8-28 09:39:42  
37#
定一个能达到的小目标,先赚它一亿元素币
回复 收起回复
使用道具
过去、是回忆  发表于 2020-7-1 19:54:44  
36#

不太看的懂,但是感觉很6
回复 收起回复
使用道具
MasterZjy  发表于 2019-3-25 15:26:07  
35#
大佬大佬
回复 收起回复
使用道具
peet07  发表于 2019-1-20 20:26:04  
34#
感谢分享~~
回复 收起回复
使用道具
ulysses  发表于 2019-1-18 11:21:37  
33#
反射很强 支持一下
回复 收起回复
使用道具
qq_男爵_N7Z  发表于 2019-1-15 09:51:39  
32#
不错
回复 收起回复
使用道具
qq_男爵_N7Z  发表于 2019-1-13 13:57:16  
31#
不错
回复 收起回复
使用道具
wwwgogdfcorgcn  发表于 2018-12-29 09:56:24  
30#
回复 收起回复
使用道具
kavi5000  发表于 2018-11-19 17:08:13  
29#
回复 收起回复
使用道具
LJHhahaha  发表于 2018-11-19 16:30:44  
28#
太好看了,攒钱买
回复 收起回复
使用道具
qq_叫我小明_LUo  发表于 2018-11-16 23:37:35  
27#
66666666666666
回复 收起回复
使用道具
pxh02412  发表于 2018-11-16 06:32:46  
26#
每天一早上元素,挖矿撩妹两不误!
回复 收起回复
使用道具
peet07  发表于 2018-11-11 21:25:40  
25#

资源甚好,发帖艰辛,且阅且珍惜
回复 收起回复
使用道具
xcy5566  发表于 2018-11-11 11:01:53  
24#
资源哪里好,肯定元素找
回复 收起回复
使用道具
白银  发表于 2018-11-7 10:01:51  
23#
666666666666666666
回复 收起回复
使用道具
smokee  发表于 2018-11-7 09:56:48  
22#
资源甚好,发帖艰辛,且阅且珍惜!
回复 收起回复
使用道具
behindjj  发表于 2018-11-7 09:06:44  
21#
十分感谢楼主分享!!!!
回复 收起回复
使用道具
yisbad  发表于 2018-11-7 08:50:15  
20#
蛮好蛮好!
回复 收起回复
使用道具
李琛琛  发表于 2018-11-7 08:32:45  
19#
不错,值得收藏
回复 收起回复
使用道具
12下一页
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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