예제 #1
0
    private void OnDestroy()
    {
        if (drawingMtrl != null)
        {
            DestroyImmediate(drawingMtrl);
            drawingMtrl = null;
        }

        if (mainCam != null)
        {
            DestroySceneViewCameras();
            mainCam.targetTexture = null;
            mainCam = null;
        }

        DestroyScreenMesh();
        ReleaseRenderTextureCompositeResources();
        ReleaseImageEffects();

        if (cbAfterAlpha != null)
        {
            cbAfterAlpha.Destroy();
            cbAfterAlpha = null;
        }

        if (cbBeforeOpaque != null)
        {
            cbBeforeOpaque.Destroy();
            cbBeforeOpaque = null;
        }
    }
예제 #2
0
    private void Start()
    {
        InitMaterialUniformNames();

        cbAfterAlpha   = new ACommandBuffer("Shadow Volume After Alpha CB", CameraEvent.AfterForwardAlpha);
        cbBeforeOpaque = new ACommandBuffer("Shadow Volume Before Opaque CB", CameraEvent.BeforeForwardOpaque);

        drawingMtrl      = new Material(Shader.Find("Hidden/ShadowVolume/Drawing"));
        drawingMtrl.name = "Shadow Volume Drawing Material";

        shadowVolumeRT          = Shader.PropertyToID("_ShadowVolumeRT");
        shadowVolumeFadeRT      = Shader.PropertyToID("_ShadowVolumeFadeRT");
        shadowVolumeColorRT     = Shader.PropertyToID("_ShadowVolumeColorRT");
        shadowDistanceUniformId = Shader.PropertyToID("_ShadowVolumeDistance");

        mainCam = GetComponent <Camera>();

        sceneViewFirstTime = IsSceneViewCamera();

        InitSceneViewRT();

        CreateScreenMesh();

        UpdateCommandBuffers();

        SetupSceneViewCameras();
    }
예제 #3
0
    private void UpdateCommandBuffers()
    {
        ACommandBuffer cbBeforeOpaque = GetBeforeOpaqueCB();

        CollectImageEffects();

        cbBeforeOpaque.AddToCamera(mainCam);

        mainCam.allowMSAA = isRenderTextureComposite ? false : anti_aliasing;
        mainCam.allowHDR  = false; // HDR is not supported

        cbBeforeOpaque.CB.Clear();
        if (isRenderTextureComposite)
        {
            cbBeforeOpaque.CB.SetRenderTarget(GetMainCamRT());
            cbBeforeOpaque.CB.ClearRenderTarget(true, true, new Color(0, 0, 0, 0), 1.0f);
            if (IsSceneViewCamera())
            {
                cbBeforeOpaque.CB.Blit(sceneViewRT, GetMainCamRT());
            }
        }

        UpdateCommandBuffer_AfterAlpha(null);

        if (!isRenderTextureComposite)
        {
            ReleaseRenderTextureCompositeResources();
        }
    }
예제 #4
0
 private ACommandBuffer GetBeforeOpaqueCB()
 {
     if (cbBeforeOpaque == null)
     {
         cbBeforeOpaque = new ACommandBuffer("Shadow Volume Before Opaque CB", CameraEvent.BeforeForwardOpaque);
     }
     return(cbBeforeOpaque);
 }
예제 #5
0
 private ACommandBuffer GetAfterAlphaCB()
 {
     if (cbAfterAlpha == null)
     {
         cbAfterAlpha = new ACommandBuffer("Shadow Volume After Alpha CB", CameraEvent.AfterForwardAlpha);
     }
     return(cbAfterAlpha);
 }
예제 #6
0
    private void UpdateCommandBuffer_AfterAlpha(ShadowVolumeObject[] svos)
    {
        ACommandBuffer cbAfterAlpha = GetAfterAlphaCB();

        cbAfterAlpha.AddToCamera(mainCam);

        cbAfterAlpha.CB.Clear();
        if (isRenderTextureComposite)
        {
            RenderTexture mainCamRT = GetMainCamRT();
            cbAfterAlpha.CB.GetTemporaryRT(shadowVolumeRT, mainCamRT.width, mainCamRT.height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
            cbAfterAlpha.CB.SetRenderTarget(shadowVolumeRT, mainCamRT);
            cbAfterAlpha.CB.ClearRenderTarget(false, true, Color.white);

            if (IsShadowDistanceFadeEnabled())
            {
                cbAfterAlpha.CB.GetTemporaryRT(shadowVolumeFadeRT, mainCamRT.width, mainCamRT.height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
                cbAfterAlpha.CB.SetRenderTarget(shadowVolumeFadeRT, mainCamRT);
                cbAfterAlpha.CB.ClearRenderTarget(false, true, Color.white);
            }
        }

        ReleaseSVOs();

        int pass_two_side_stencil = IsShadowDistanceFadeEnabled() ? 10 : 4;
        int pass_back_face        = IsShadowDistanceFadeEnabled() ? 7 : 0;
        int pass_front_face       = IsShadowDistanceFadeEnabled() ? 8 : 1;
        int pass_zero_stencil     = 3;
        int pass_draw_shadow      = isRenderTextureComposite ? (IsShadowDistanceFadeEnabled() ? 9 : 6) : 2;
        int pass_composite_shadow = 5;

        ShadowVolumeCombined[] combinedObjs = static_combinedSVOs == null || !Application.isPlaying ? FindObjectsOfType <ShadowVolumeCombined>() : static_combinedSVOs;
        static_combinedSVOs = combinedObjs;
        if (combinedObjs != null && combinedObjs.Length > 0)
        {
            cbAfterAlpha.CB.DrawMesh(screenMesh, Matrix4x4.identity, drawingMtrl, 0, pass_zero_stencil);
            foreach (var combinedObj in combinedObjs)
            {
                MeshFilter mf = combinedObj.GetComponent <MeshFilter>();
                if (mf != null && mf.sharedMesh != null)
                {
                    if (isTwoSideStencil)
                    {
                        cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, Matrix4x4.identity, drawingMtrl, 0, pass_two_side_stencil);
                    }
                    else
                    {
                        cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, Matrix4x4.identity, drawingMtrl, 0, pass_back_face);
                        cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, Matrix4x4.identity, drawingMtrl, 0, pass_front_face);
                    }
                }
            }
            if (IsShadowDistanceFadeEnabled())
            {
                cbAfterAlpha.CB.SetRenderTarget(shadowVolumeRT, mainCamRT);
            }
            cbAfterAlpha.CB.DrawMesh(screenMesh, Matrix4x4.identity, drawingMtrl, 0, pass_draw_shadow);
        }
        else
        {
            cbAfterAlpha.CB.DrawMesh(screenMesh, Matrix4x4.identity, drawingMtrl, 0, pass_zero_stencil);
            ShadowVolumeObject[] svObjs = svos == null || !Application.isPlaying ? FindObjectsOfType <ShadowVolumeObject>() : svos;
            static_svos = svObjs;
            UpdateBounds();
            if (svObjs != null)
            {
                Vector3 camWPos                 = mainCam.transform.position;
                Vector3 camWForward             = mainCam.transform.forward;
                bool    isShadowDistanceEnabled = IsShadowDistanceEnabled();

                foreach (var svObj in svObjs)
                {
                    if (IsShadowVolulmeObjectVisible(svObj, isShadowDistanceEnabled, ref camWPos, ref camWForward))
                    {
                        MeshFilter mf = svObj.meshFilter;
                        if (mf != null && mf.sharedMesh != null)
                        {
                            Matrix4x4 l2w          = svObj.l2w;
                            bool      twoSubMeshes = mf.sharedMesh.subMeshCount == 2;
                            if (isTwoSideStencil)
                            {
                                cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, l2w, drawingMtrl, 0, pass_two_side_stencil);
                                if (twoSubMeshes)
                                {
                                    cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, l2w, drawingMtrl, 1, pass_two_side_stencil);
                                }
                            }
                            else
                            {
                                cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, l2w, drawingMtrl, 0, pass_back_face);
                                if (twoSubMeshes)
                                {
                                    cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, l2w, drawingMtrl, 1, pass_back_face);
                                }
                                cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, l2w, drawingMtrl, 0, pass_front_face);
                                if (twoSubMeshes)
                                {
                                    cbAfterAlpha.CB.DrawMesh(mf.sharedMesh, l2w, drawingMtrl, 1, pass_front_face);
                                }
                            }
                        }
                    }
                }
            }
            if (IsShadowDistanceFadeEnabled())
            {
                cbAfterAlpha.CB.SetRenderTarget(shadowVolumeRT, mainCamRT);
            }
            cbAfterAlpha.CB.DrawMesh(screenMesh, Matrix4x4.identity, drawingMtrl, 0, pass_draw_shadow);
        }

        if (isRenderTextureComposite)
        {
            cbAfterAlpha.CB.SetGlobalTexture(shadowVolumeColorRT, GetMainCamRT());
            cbAfterAlpha.CB.Blit(null, GetCompositeRT(), drawingMtrl, pass_composite_shadow);
            cbAfterAlpha.CB.ReleaseTemporaryRT(shadowVolumeRT);

            if (IsShadowDistanceFadeEnabled())
            {
                cbAfterAlpha.CB.ReleaseTemporaryRT(shadowVolumeFadeRT);
            }
        }
    }