public ClipMaterialPool(Material material) { this.small = new Material(material); this.medium = new Material(material); this.large = new Material(material); this.huge = new Material(material); this.massive = new Material(material); this.small.EnableKeyword("BATCH_SIZE_SMALL"); this.medium.EnableKeyword("BATCH_SIZE_MEDIUM"); this.large.EnableKeyword("BATCH_SIZE_LARGE"); this.huge.EnableKeyword("BATCH_SIZE_HUGE"); this.massive.EnableKeyword("BATCH_SIZE_MASSIVE"); this.smallBlock = new ClipPropertyBlock(small, RenderContext.k_ObjectCount_Small); this.mediumBlock = new ClipPropertyBlock(medium, RenderContext.k_ObjectCount_Medium); this.largeBlock = new ClipPropertyBlock(large, RenderContext.k_ObjectCount_Large); this.hugeBlock = new ClipPropertyBlock(huge, RenderContext.k_ObjectCount_Huge); this.massiveBlock = new ClipPropertyBlock(massive, RenderContext.k_ObjectCount_Massive); }
// depth buffer means our regions are locked per channel // 2 options: 1. each channel is its own set of draw calls, this is easy but maybe not as fast. do this as a first pass // 2. try to re-use regions for different channels, almost certainly leads to less throughput but faster since we don't need extra draw calls // probably means we have sub-sorting regions, ie large packers would have sub-packers // would definitely want to sort by size in that case and first try to pack larger regions into themselves // would likely update rect packer to be channel aware, when trying to place next item instead of moving over try colliding a different channel instead public void Clip(Camera camera, CommandBuffer commandBuffer) { // breaks on refresh if we don't do this :( this.clearMaterial.SetColor(s_Color, Color.white); this.clearCountMaterial.SetColor(s_Color, new Color(0, 0, 0, 0)); requireRegionCounting = false; for (int i = 0; i < batchesToRender.size; i++) { batchesToRender[i].pooledMesh.Release(); StructList <Matrix4x4> .Release(ref batchesToRender.array[i].transforms); StructList <Vector4> .Release(ref batchesToRender.array[i].objectData); StructList <Vector4> .Release(ref batchesToRender.array[i].colorData); } batchesToRender.Clear(); Gather(); Vector3 cameraOrigin = camera.transform.position; cameraOrigin.x -= 0.5f * Screen.width; cameraOrigin.y += (0.5f * Screen.height); cameraOrigin.z += 2; Matrix4x4 origin = Matrix4x4.TRS(cameraOrigin, Quaternion.identity, Vector3.one); LightList <ClipData> texturedClippers = LightList <ClipData> .Get(); regionMesh?.Release(); regionMesh = GetRegionMesh(out requireRegionCounting); clipTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 24, RenderTextureFormat.Default); // todo -- use lower resolution #if DEBUG commandBuffer.BeginSample("UIFora Clip Draw"); #endif commandBuffer.SetRenderTarget(clipTexture); // probably don't need this actually, can bake it into clear. keep for debugging commandBuffer.ClearRenderTarget(true, true, Color.black); commandBuffer.DrawMesh(regionMesh.mesh, origin, clearMaterial, 0, 0); // todo -- handle multiple shapes from one path ClipBatch batch = new ClipBatch(); batch.transforms = StructList <Matrix4x4> .Get(); batch.colorData = StructList <Vector4> .Get(); batch.objectData = StructList <Vector4> .Get(); for (int i = 0; i < clippers.size; i++) { ClipData clipData = clippers[i]; Path2D clipPath = clipData.clipPath; if (clipPath == null) { // todo if transform is not identity we need to generate a rotated or skewed rect for the clip shape continue; } clipPath.UpdateGeometry(); // should early out if no update required if (AnyShapeUsesTextures(clipPath)) { // todo -- handle textures // todo -- handle text continue; } batch = DrawShapesInPath(batch, clipPath, clipData, clipData); for (int j = 0; j < clipData.dependents.size; j++) { batch = DrawShapesInPath(batch, clipPath, clipData, clipData.dependents[j]); } } FinalizeBatch(batch, false); for (int i = 0; i < batchesToRender.size; i++) { ref ClipBatch clipBatch = ref batchesToRender.array[i]; ClipPropertyBlock propertyBlock = clipMaterialPool.GetPropertyBlock(clipBatch.transforms.size); propertyBlock.SetData(clipBatch); commandBuffer.DrawMesh(clipBatch.pooledMesh.mesh, origin, clipDrawMaterial, 0, 0, propertyBlock.matBlock); }