目前采用比较多的反射,最终效果示例:
代码已经中文注解,有2部分需扩展:反射矩阵、歪截头体矩阵。注解中有来源链接可以去理解推导过程。
可用于镜面和水面。
咱还是直接看注解过的代码
MirrorReflection.cs
using UnityEngine;
using System.Collections;
using UnityEditor;
[ExecuteInEditMode]
public class MirrorReflection : MonoBehaviour
{
//public Material m_matCopyDepth;
// 为效率,禁用像素级光
public bool m_DisablePixelLights = true;
public int m_TextureSize = 256;
// 微调,获得更准确反射
public float m_ClipPlaneOffset = 0.07f;
// 参与反射的layer
public LayerMask m_ReflectLayers = -1;
private Hashtable m_ReflectionCameras = new Hashtable(); // Camera -> Camera table
public RenderTexture m_ReflectionTexture = null;
//public RenderTexture m_ReflectionDepthTexture = null;
private int m_OldReflectionTextureSize = 0;
private static bool s_InsideRendering = false;
// 渲染摄像机
public Camera m_Camera;
// 即将渲染
public void OnWillRenderObject()
{
if (!enabled || !GetComponent<Renderer>() || !GetComponent<Renderer>().sharedMaterial || !GetComponent<Renderer>().enabled)
return;
Camera cam = Camera.current;
if (!cam)
return;
if (cam != m_Camera )
return;
// Safeguard from recursive reflections.
// 本过程不支持打断
if (s_InsideRendering)
return;
s_InsideRendering = true;
// 创建反射摄像机、渲染纹理
Camera reflectionCamera;
CreateMirrorObjects(cam, out reflectionCamera);
// find out the reflection plane: position and normal in world space
// 反射平面
Vector3 pos = transform.position;
Vector3 normal = transform.up;
// Optionally disable pixel lights for reflection
// 像素级光设为无效
int oldPixelLightCount = QualitySettings.pixelLightCount;
if (m_DisablePixelLights)
QualitySettings.pixelLightCount = 0;
// 从cam克隆出反射摄像机fov什么的
UpdateCameraModes(cam, reflectionCamera);
// Render reflection
// Reflect camera around reflection plane
// 通过offset调整过的反射面
float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset;
Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
// 使用反射屏幕得到反射矩阵
Matrix4x4 reflection = Matrix4x4.zero;
CalculateReflectionMatrix(ref ref