예제 #1
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);
    }
예제 #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
    // 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;
    }