public void SetData(ClipBatch data) { Array.Copy(data.transforms.array, 0, transformData, 0, data.transforms.size); Array.Copy(data.objectData.array, 0, objectData, 0, data.objectData.size); Array.Copy(data.colorData.array, 0, colorData, 0, data.colorData.size); matBlock.SetMatrixArray(s_TransformDataKey, transformData); matBlock.SetVectorArray(s_ColorDataKey, colorData); matBlock.SetVectorArray(s_ObjectDataKey, objectData); if (data.texture != null) { material.SetTexture(s_MainTextureKey, data.texture); } }
// 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); }