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; } }
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(); }
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(); } }
private ACommandBuffer GetBeforeOpaqueCB() { if (cbBeforeOpaque == null) { cbBeforeOpaque = new ACommandBuffer("Shadow Volume Before Opaque CB", CameraEvent.BeforeForwardOpaque); } return(cbBeforeOpaque); }
private ACommandBuffer GetAfterAlphaCB() { if (cbAfterAlpha == null) { cbAfterAlpha = new ACommandBuffer("Shadow Volume After Alpha CB", CameraEvent.AfterForwardAlpha); } return(cbAfterAlpha); }
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); } } }