裸睡的鱼 发表于 2012-12-30 21:45

Unity3D中如何实现反射教程


一.

float d = -Vector3.Dot (normal, pos) - m_ClipPlaneOffset; //原点到平面的距离

//可通过m_ClipPlaneOffset调整物体与反射物体之间的缝隙。

Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d); //定义反射平面



备注:线性代数之平面
平面方程:Ax + By + Cz + w = 0;

这个方程的意义,可以看成两个向量的点击 N(A,B,C) V(x,y,z), N.dot(V) = -w; 向量N是一个常量向量,向量V代表一类向量。N可以看成平面的单位法向量,V可以看成平面上的点和原点的连线向量。则此时的w就有了特殊含义:原点到平面的距离。

如下图, N.dot(V) = A*x + B*y + C*z = |N| * |V| * cos(angle) = |V| * cos(angle) = distance;

角度angle为平面法线和向量V的夹角。

所以平面方程可以表示为法向量和距离的二元组。

plane = <Normal, distance>






更多延伸link

二.

   Matrix4x4 reflection = Matrix4x4.zero;
   CalculateReflectionMatrix (ref reflection, reflectionPlane); //通过反射平面生成反射矩阵
   Vector3 oldpos = cam.transform.position;
   Vector3 newpos = reflection.MultiplyPoint( oldpos ); //通过反射矩阵变换观察相机位置得到反射相机位置
   reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; //通过反射矩阵变换观察相机世界矩阵生成反射相机世界矩阵

三.

   Vector4 clipPlane = CameraSpacePlane( reflectionCamera, pos, normal, 1.0f );//生成反射相机裁剪平面
   Matrix4x4 projection = cam.projectionMatrix;
   CalculateObliqueMatrix (ref projection, clipPlane); //通过观察相机投影矩阵与裁剪平面生成非对称投影矩阵给反射相机
   reflectionCamera.projectionMatrix = projection;

四.

   GL.SetRevertBackfacing (true); //开启背面显示
   reflectionCamera.transform.position = newpos;
   Vector3 euler = cam.transform.eulerAngles;
   reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z);
   reflectionCamera.Render(); //渲染反射相机的内容到rtt
   reflectionCamera.transform.position = oldpos;
   GL.SetRevertBackfacing (false); //关闭背面显示



shader中通过ComputeScreenPos()直接生成投影坐标,在用tex2Dproj()采样即可。

云上太阳 发表于 2016-12-19 11:11


感谢楼主的无私分享!

artist66 发表于 2017-2-12 13:45

好帖就是要顶

沉默 发表于 2017-2-12 13:05

真心顶

想淰伱の亽~ 发表于 2017-2-12 13:41

难得一见的好帖

Mr._chen。 发表于 2017-2-12 13:04

很好哦

Mr._chen。 发表于 2017-2-12 13:15

LZ真是人才

WZ╄→其实属于 发表于 2017-3-2 20:39

很不错

chenlu632 发表于 2017-3-2 21:06

难得一见的好帖

U侠 发表于 2017-3-2 21:25

说的非常好
页: [1]
查看完整版本: Unity3D中如何实现反射教程