Hi recently tried to modify a script * Mirror Reflection *
And this would take the tranform to a new location and movement of the camera matrix.
But in my tests, stopped working!
However, unity does not mark it as error, but the script is a mess(not working).
Can you tell me where the bad spot? ;)
you can use mirror reflection shader
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class PortalMirror : MonoBehaviour
{
// Fields
public float m_ClipPlaneOffset = 0.01f;
public bool m_DisablePixelLights = true;
private int m_OldReflectionTextureSize;
private Hashtable m_ReflectionCameras = new Hashtable();
private RenderTexture m_ReflectionTexture;
public LayerMask m_ReflectLayers = -1;
public int m_TextureSize = 1024;
private static bool s_InsideRendering = false;
public Transform PortalTansfom;
// Methods
private static void CalculateObliqueMatrix(ref Matrix4x4 projection, Vector4 clipPlane)
{
Vector4 vector = projection.inverse * new Vector4(
sgn(clipPlane.x),
sgn(clipPlane.y),
1f,
1f
);
Vector4 vector2 = clipPlane * (2f / Vector4.Dot(clipPlane, vector));
////////////////
projection [2]= vector2.x - projection[3];
projection [6]= vector2.y - projection[7];
projection [10]= vector2.z - projection[11];
projection [14]= vector2.w - projection[15];
}
private static void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane)
{
reflectionMat.m00 = (1f -2f * plane[0] * plane[0]);
reflectionMat.m01 = ( -2f * plane[0] * plane[1]);
reflectionMat.m02 = ( -2f * plane[0] * plane[2]);
reflectionMat.m03 = ( -2f * plane[3] * plane[0]);
reflectionMat.m10 = ( -2f * plane[1] * plane[0]);
reflectionMat.m11 = (1f -2f * plane[1] * plane[1]);
reflectionMat.m12 = ( -2f * plane[1] * plane[2]);
reflectionMat.m13 = ( -2f * plane[3] * plane[1]);
reflectionMat.m20 = ( -2f * plane[2] * plane[0]);
reflectionMat.m21 = ( -2f * plane[2] * plane[1]);
reflectionMat.m22 = (1f -2f * plane[2] * plane[2]);
reflectionMat.m23 = ( -2f * plane[3] * plane[2]);
reflectionMat.m30 = 0f;
reflectionMat.m31 = 0f;
reflectionMat.m32 = 0f;
reflectionMat.m33 = 1f;
}
private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
{
Vector3 vector = pos + normal * m_ClipPlaneOffset;
Matrix4x4 matrixx = cam.worldToCameraMatrix;
Vector3 vector2 = matrixx.MultiplyPoint(vector);
Vector3 vector3 = matrixx.MultiplyVector(normal).normalized * sideSign;
return new Vector4(vector3.x, vector3.y, vector3.z, -Vector3.Dot(vector2, vector3));
}
private void CreateMirrorObjects(Camera currentCamera, out Camera reflectionCamera)
{
reflectionCamera = null;
if (!m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize)
{
if (m_ReflectionTexture)
{
Object.DestroyImmediate(m_ReflectionTexture);
}
m_ReflectionTexture = new RenderTexture(m_TextureSize, m_TextureSize, 16);
m_ReflectionTexture.name = "__Portal" + GetInstanceID();
m_ReflectionTexture.isPowerOfTwo = true;
m_ReflectionTexture.hideFlags = HideFlags.DontSave;
m_OldReflectionTextureSize = m_TextureSize;
}
reflectionCamera = m_ReflectionCameras[currentCamera] as Camera;
if (!reflectionCamera)
{
GameObject objArray1 = new GameObject("Portal Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox) );
GameObject obj2 = new GameObject(string.Concat(objArray1), typeof(Camera), typeof(Skybox) );
reflectionCamera = obj2.camera;
reflectionCamera.enabled = false;
reflectionCamera.transform.position = transform.position;
reflectionCamera.transform.rotation = transform.rotation;
reflectionCamera.gameObject.AddComponent("FlareLayer");
obj2.hideFlags = HideFlags.HideAndDontSave;
m_ReflectionCameras[currentCamera] = reflectionCamera;
}
}
private void OnDisable()
{
if (m_ReflectionTexture)
{
DestroyImmediate(m_ReflectionTexture);
m_ReflectionTexture = null;
}
IDictionaryEnumerator enumerator = m_ReflectionCameras.GetEnumerator();
{
while (enumerator.MoveNext())
{
foreach( DictionaryEntry entry in m_ReflectionCameras )
DestroyImmediate(((Camera) entry.Value).gameObject);
m_ReflectionCameras.Clear();
}
}
m_ReflectionCameras.Clear();
}
public void OnWillRenderObject()
{
if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled )
{
Camera currentCamera = Camera.current;
if (!currentCamera )
{
Camera camera2;
if( s_InsideRendering )
return;
s_InsideRendering = true;
CreateMirrorObjects(currentCamera, out camera2);
Vector3 vector = transform.up;
Vector3 vector2 = transform.right;
int num = QualitySettings.pixelLightCount;
if (m_DisablePixelLights)
{
QualitySettings.pixelLightCount = 0;
}
UpdateCameraModes(currentCamera, camera2);
Vector4 plane = new Vector4(vector.x, vector.y, vector.z, -m_ClipPlaneOffset);
Vector4 vector4 = new Vector4(vector2.x, vector2.y, vector2.z, 0f);
Matrix4x4 reflectionMat = Matrix4x4.zero;
Matrix4x4 matrixx2 = Matrix4x4.zero;
Matrix4x4 matrixx3 = Matrix4x4.zero;
Quaternion quaternion = transform.rotation * Quaternion.Inverse(PortalTansfom.transform.rotation);
CalculateReflectionMatrix(ref reflectionMat, plane);
CalculateReflectionMatrix(ref matrixx2, vector4);
matrixx3 = Matrix4x4.TRS(transform.position, Quaternion.identity, new Vector3(1f, 1f, 1f)) * (reflectionMat * matrixx2);
matrixx3 *= Matrix4x4.TRS(new Vector3(0f, 0f, 0f), quaternion, new Vector3(1f, 1f, 1f));
matrixx3 *= Matrix4x4.TRS(-PortalTansfom.transform.position, Quaternion.identity, new Vector3(1f, 1f, 1f));
camera2.worldToCameraMatrix = currentCamera.worldToCameraMatrix * matrixx3;
Vector4 clipPlane = CameraSpacePlane(camera2, PortalTansfom.transform.position, PortalTansfom.transform.up, 1f);
Matrix4x4 projection = currentCamera.projectionMatrix;
CalculateObliqueMatrix(ref projection, clipPlane);
camera2.projectionMatrix = projection;
camera2.cullingMask = -17 & m_ReflectLayers.value;
camera2.targetTexture = m_ReflectionTexture;
camera2.Render();
Material[] materialArray = renderer.sharedMaterials;
foreach (Material material in materialArray)
{
if (material.HasProperty("_ReflectionTex"))
{
material.SetTexture("_ReflectionTex", m_ReflectionTexture);
}
}
Matrix4x4 matrixx5 = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));
Vector3 vector6 = transform.lossyScale;
Matrix4x4 matrixx6 = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(1f / vector6.x, 1f / vector6.y, 1f / vector6.z));
matrixx6 = ((matrixx5 * currentCamera.projectionMatrix) * currentCamera.worldToCameraMatrix) * matrixx6;
foreach (Material material2 in materialArray)
{
material2.SetMatrix("_ProjMatrix", matrixx6);
}
if (m_DisablePixelLights)
{
QualitySettings.pixelLightCount = num;
}
s_InsideRendering = false;
}
}
}
private static float sgn(float a)
{
if (a > 0f)
{
return 1f;
}
if (a < 0f)
{
return -1f;
}
return 0f;
}
private void UpdateCameraModes(Camera src, Camera dest)
{
if (dest == null)
{
dest.backgroundColor = src.backgroundColor;
dest.clearFlags = src.clearFlags;
if (src.clearFlags == CameraClearFlags.Skybox)
{
Skybox component = src.GetComponent(typeof(Skybox)) as Skybox;
Skybox skybox2 = dest.GetComponent(typeof(Skybox)) as Skybox;
if ((component == null) || (component.material == null))
{
skybox2.enabled = false;
}
else
{
skybox2.enabled = true;
skybox2.material = component.material;
}
}
dest.farClipPlane = src.farClipPlane;
dest.nearClipPlane = src.nearClipPlane;
dest.orthographic = src.orthographic;
dest.fieldOfView = src.fieldOfView;
dest.aspect = src.aspect;
dest.orthographicSize = src.orthographicSize;
}
}
}
↧