示例#1
0
    private void UpdateCameraMatrix()
    {
        Vector3 dir = mirrorCamera.transform.position - transform.position;
        var     up  = Vector3.Cross(-dir, mirrorCamera.transform.right);

        mirrorCamera.transform.rotation = Quaternion.LookRotation(-dir, up);

        Vector4 clipplane = CameraHelper.CameraSpacePlane(mirrorCamera, transform.position, transform.forward, 0.01f);

        Matrix4x4 clipP = mirrorCamera.projectionMatrix;

        CameraHelper.CalculateObliqueMatrix(ref clipP, clipplane);

        mirrorCamera.projectionMatrix = clipP;
    }
示例#2
0
    void RenderReflectionAndRefraction()
    {
        Camera renderCamera = Camera.mainCamera;

        Matrix4x4 originalWorldToCam = renderCamera.worldToCameraMatrix;

        int cullingMask = ~(1 << 4) & renderLayers.value;

        ;

        //Reflection pass
        Matrix4x4 reflection = Matrix4x4.zero;

        //TODO: Use local plane here, not global!

        float d = -transform.position.y;

        offscreenCam.backgroundColor = RenderSettings.fogColor;

        CameraHelper.CalculateReflectionMatrix(ref reflection, new Vector4(0f, 1f, 0f, d));

        offscreenCam.transform.position  = reflection.MultiplyPoint(renderCamera.transform.position);
        offscreenCam.transform.rotation  = renderCamera.transform.rotation;
        offscreenCam.worldToCameraMatrix = originalWorldToCam * reflection;

        offscreenCam.cullingMask   = cullingMask;
        offscreenCam.targetTexture = reflectionTexture;

        //Need to reverse face culling for reflection pass, since the camera
        //is now flipped upside/down.
        GL.SetRevertBackfacing(true);

        Vector4 cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, new Vector3(0.0f, transform.position.y, 0.0f), Vector3.up, 1.0f);

        Matrix4x4 projection        = renderCamera.projectionMatrix;
        Matrix4x4 obliqueProjection = projection;

        offscreenCam.fieldOfView = renderCamera.fieldOfView;
        offscreenCam.aspect      = renderCamera.aspect;

        CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane);

        //Do the actual render, with the near plane set as the clipping plane. See the
        //pro water source for details.
        offscreenCam.projectionMatrix = obliqueProjection;

        if (!renderReflection)
        {
            offscreenCam.cullingMask = 0;
        }

        offscreenCam.Render();


        GL.SetRevertBackfacing(false);

        //Refractionpass
        //TODO: If we want to use this as a refraction seen from under the seaplane,
        //      the cameraclear should be skybox.

        offscreenCam.cullingMask   = cullingMask;
        offscreenCam.targetTexture = refractionTexture;
        obliqueProjection          = projection;

        offscreenCam.transform.position  = renderCamera.transform.position;
        offscreenCam.transform.rotation  = renderCamera.transform.rotation;
        offscreenCam.worldToCameraMatrix = originalWorldToCam;


        cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, Vector3.zero, Vector3.up, -1.0f);
        CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane);
        offscreenCam.projectionMatrix = obliqueProjection;

        //if (!renderRefraction)
        //offscreenCam.cullingMask = 0;

        offscreenCam.Render();

        offscreenCam.projectionMatrix = projection;


        offscreenCam.targetTexture = null;
    }
示例#3
0
    void RenderReflectionAndRefraction()
    {
        //return;
        //camera.ResetWorldToCameraMatrix();

        offscreenCam.enabled = true;
        int oldPixelLightCount = QualitySettings.pixelLightCount;

        QualitySettings.pixelLightCount = 0;


        Camera renderCamera = mycam;

        Matrix4x4 originalWorldToCam = renderCamera.worldToCameraMatrix;

        int cullingMask = renderCamera.cullingMask & ~(1 << LayerMask.NameToLayer("Water"));

        //Reflection pass
        Matrix4x4 reflection = Matrix4x4.zero;

        //TODO: Use local plane here, not global!
        CameraHelper.CalculateReflectionMatrix(ref reflection, new Vector4(0.0f, 1.0f, 0.0f, 0.0f));

        offscreenCam.transform.position = reflection.MultiplyPoint(renderCamera.transform.position);
        offscreenCam.transform.rotation = renderCamera.transform.rotation;
        offscreenCam.transform.Rotate(0, 180, 0);
        offscreenCam.worldToCameraMatrix = originalWorldToCam * reflection;

        offscreenCam.cullingMask   = cullingMask;
        offscreenCam.targetTexture = reflectionTexture;
        offscreenCam.clearFlags    = renderCamera.clearFlags;

        //Need to reverse face culling for reflection pass, since the camera
        //is now flipped upside/down.
        GL.SetRevertBackfacing(false);

        Vector4 cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, Vector3.zero, Vector3.up, 1.0f);

        Matrix4x4 projection        = renderCamera.projectionMatrix;
        Matrix4x4 obliqueProjection = projection;

        CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane);

        //Do the actual render, with the near plane set as the clipping plane. See the
        //pro water source for details.
        offscreenCam.projectionMatrix = obliqueProjection;
        offscreenCam.Render();


        GL.SetRevertBackfacing(false);

        //Refractionpass
        bool  fog        = RenderSettings.fog;
        Color fogColor   = RenderSettings.fogColor;
        float fogDensity = RenderSettings.fogDensity;

        RenderSettings.fog        = true;
        RenderSettings.fogColor   = Color.grey;
        RenderSettings.fogDensity = waterDirtyness / 10;

        //TODO: If we want to use this as a refraction seen from under the seaplane,
        //      the cameraclear should be skybox.
        offscreenCam.clearFlags      = CameraClearFlags.Color;
        offscreenCam.backgroundColor = Color.grey;

        offscreenCam.targetTexture = refractionTexture;
        obliqueProjection          = projection;

        offscreenCam.transform.position  = renderCamera.transform.position;
        offscreenCam.transform.rotation  = renderCamera.transform.rotation;
        offscreenCam.worldToCameraMatrix = originalWorldToCam;

        cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, Vector3.zero, Vector3.up, -1.0f);
        CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane);
        offscreenCam.projectionMatrix = obliqueProjection;

        offscreenCam.Render();

        RenderSettings.fog        = fog;
        RenderSettings.fogColor   = fogColor;
        RenderSettings.fogDensity = fogDensity;

        offscreenCam.projectionMatrix = projection;


        offscreenCam.targetTexture = null;

        QualitySettings.pixelLightCount = oldPixelLightCount;

        //	camera.ResetWorldToCameraMatrix();

        //GL.SetRevertBackfacing (true);
    }
示例#4
0
    public void CalculateCameraMatrix(BoxCollider Box, Camera cam, bool bleft = true)
    {
        Vector3 dir = stereoCameraHead.transform.position - Box.transform.position;

        //dl -> dr -> ur -> rl  clockwise
        points = Box.GetMinProjectBox(ref dir);// new Vector3[] {dl, dr, ur, ul };

        Debug.DrawLine(cam.transform.position - dir, cam.transform.position, Color.yellow);

        Vector3 vecLeft, vecRight;

        Vector3 cameraUp = Vector3.up;


        float aspect = 0;

        for (int i = 0; i < 4; i++)
        {
            int iLeft  = (i - 1 + 4) % 4;
            int iRight = (i + 1) % 4;

            vecLeft  = points[iLeft] - points[i];
            vecRight = points[iRight] - points[i];

            float angle = Vector3.Angle(vecLeft, vecRight);
            if (angle < 90)
            {
                continue;
            }

            float lenLeft  = vecLeft.magnitude;
            float lenRight = vecRight.magnitude;
            if (lenLeft > lenRight)
            {
                Vector3 vec = Vector3.Project(vecRight, vecLeft);

                points[i] = points[i] + vec;

                points[(i + 2) % 4] -= vec;

                cameraUp = points[iRight] - points[i];
                vec      = points[iLeft] - points[i];

                aspect = vec.magnitude / cameraUp.magnitude;
            }
            else
            {
                Vector3 vec = Vector3.Project(vecLeft, vecRight);

                points[i] = points[i] + vec;

                points[(i + 2) % 4] -= vec;

                cameraUp = points[iLeft] - points[i];
                vec      = points[iRight] - points[i];

                aspect = vec.magnitude / cameraUp.magnitude;
            }

            break;
        }

        cam.transform.rotation = Quaternion.LookRotation(-dir, cameraUp);
        //cam.transform.LookAt(-dir, cameraUp);
        //Vector3 vecDLtoDR = dl - dr;
        //Vector3 vecURtoDR = ur - dr;
        //float lenDLtoDR = vecDLtoDR.magnitude;
        //float lenURtoDR = vecURtoDR.magnitude;
        //if (lenDLtoDR > lenURtoDR)
        //{
        //    //base edge vecDLtoDR

        float fov = Mathf.Atan2(cameraUp.magnitude / 2, dir.magnitude) * 180 / Mathf.PI;

        cam.fieldOfView = fov * 2;

        cam.aspect = aspect;
        Matrix4x4 P = Matrix4x4.Perspective(fov * 2, aspect, 0.1f, 1000);

        Vector4 clipplane = CameraHelper.CameraSpacePlane(cam, Box.transform.position, -Box.transform.forward, 0.01f);

        Matrix4x4 clipP = P;

        CameraHelper.CalculateObliqueMatrix(ref clipP, clipplane);
        ///Matrix4x4 mat = Camera.main.projectionMatrix;
        cam.projectionMatrix = clipP;
        // = Camera.main.CalculateObliqueMatrix(clipplane);

        //calculate the mirror camera's vp
        //var mirrorVPMat = mat * Camera.main.worldToCameraMatrix;
        //var mirrorVPMat = mat.transpose;// * Camera.main.worldToCameraMatrix;
        Matrix4x4 V = cam.worldToCameraMatrix;

        P = GL.GetGPUProjectionMatrix(P, true);
        Matrix4x4 VP = P * V;

        if (bleft)
        {
            Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix01", new Vector4(VP.m00, VP.m01, VP.m02, VP.m03));
            Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix02", new Vector4(VP.m10, VP.m11, VP.m12, VP.m13));
            Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix03", new Vector4(VP.m20, VP.m21, VP.m22, VP.m23));
            Box.GetComponentInChildren <Renderer>().material.SetVector("_matrix04", new Vector4(VP.m30, VP.m31, VP.m32, VP.m33));
        }
        else
        {
            Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix01", new Vector4(VP.m00, VP.m01, VP.m02, VP.m03));
            Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix02", new Vector4(VP.m10, VP.m11, VP.m12, VP.m13));
            Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix03", new Vector4(VP.m20, VP.m21, VP.m22, VP.m23));
            Box.GetComponentInChildren <Renderer>().material.SetVector("_rmatrix04", new Vector4(VP.m30, VP.m31, VP.m32, VP.m33));
        }

        Box.GetComponentInChildren <Renderer>().material.SetFloat("_depth", dir.magnitude - 0.1f);
    }
示例#5
0
    // This is called when it's known that the object will be rendered by some

    // camera. We render reflections and do other updates here.

    // Because the script executes in edit mode, reflections for the scene view

    // camera will just work!

    public void OnWillRenderObject()
    {
        var rend = GetComponent <Renderer>();

        if (!enabled || !rend || !rend.sharedMaterial || !rend.enabled)
        {
            return;
        }

        Camera cam = Camera.current;

        if (!cam)
        {
            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;

        UpdateCameraModes(cam, reflectionCamera);

        // Render reflection

        // Reflect camera around reflection plane

        float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset;

        Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);



        Matrix4x4 reflection = Matrix4x4.zero;

        CameraHelper.CalculateReflectionMatrix(ref reflection, reflectionPlane);

        Vector3 oldpos = cam.transform.position;

        Vector3 newpos = reflection.MultiplyPoint(oldpos);

        reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;



        // Setup oblique projection matrix so that near plane is our reflection

        // plane. This way we clip everything below/above it for free.

        Vector4 clipPlane = CameraHelper.CameraSpacePlane(reflectionCamera, pos, normal, 1.0f);

        //Matrix4x4 projection = cam.projectionMatrix;
        //Matrix4x4 projection = cam.CalculateObliqueMatrix(clipPlane);
        Matrix4x4 clipP = reflectionCamera.projectionMatrix;

        CameraHelper.CalculateObliqueMatrix(ref clipP, clipPlane);

        reflectionCamera.projectionMatrix = clipP;

        reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer

        reflectionCamera.targetTexture = m_ReflectionTexture;

        GL.SetRevertBackfacing(true);

        reflectionCamera.transform.position = newpos;

        Vector3 euler = cam.transform.eulerAngles;

        reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z);

        reflectionCamera.Render();

        //reflectionCamera.transform.position = oldpos;

        GL.SetRevertBackfacing(false);

        Material[] materials = rend.sharedMaterials;

        foreach (Material mat in materials)
        {
            if (mat.HasProperty("_ReflectionTex"))
            {
                mat.SetTexture("_ReflectionTex", m_ReflectionTexture);
            }
        }


        // Restore pixel light count

        s_InsideRendering = false;
    }