/// <summary> /// Blend other texture as overlay. /// </summary> /// <param name="source">The texture background. </param> /// <param name="overlay">The texture overlay. </param> /// <param name="overlayPosition">The position that overlay texture will be blended in background texture. </param> /// <param name="depth">Number of bits in depth buffer (0, 16 or 24). Note that only 24 bit depth has stencil buffer.</param> /// <param name="canvasRenderTextureFormat">The texture format of canvas render texture. </param> /// <returns>The texture that has blended background texture and overlay texture.</returns> /// <exception cref="ArgumentNullException"><c>overlay</c> is <c>null</c>. </exception> public static Texture2D BlendTextureOverlay( this Texture2D source, Texture2D overlay, Vector2Int overlayPosition, int depth = 0, RenderTextureFormat canvasRenderTextureFormat = RenderTextureFormat.ARGB32) { if (!overlay) { throw new ArgumentNullException(nameof(overlay)); } if (SystemInfo.supportsComputeShaders) { var renderTexture = new RenderTexture(source.width, source.height, depth, canvasRenderTextureFormat) { enableRandomWrite = true }; renderTexture.Create(); var shader = Resources.Load <ComputeShader>("Shaders/BlendTextureOverlay"); var kernel = shader.FindKernel("blendTextureOverlay"); shader.SetTexture(kernel, "source", source); shader.SetTexture(kernel, "overlay", overlay); shader.SetInts("overlayDimensions", overlay.width, overlay.height); shader.SetInts("overlayPosition", overlayPosition.x, overlayPosition.y); shader.SetTexture(kernel, "canvas", renderTexture); shader.Dispatch(kernel, source.width, source.height, 1); var output = renderTexture.ToTexture(new Rect(0, 0, renderTexture.width, renderTexture.height)); Object.Destroy(renderTexture); return(output); } else { Debug.LogWarning($"The platform {Application.platform} do not support compute shader, so blend texture will use CPU to process!"); var output = new Texture2D(source.width, source.height, TextureFormat.RGBA32, false) { wrapMode = TextureWrapMode.Clamp }; for (var x = 0; x < source.width; x++) { for (var y = 0; y < source.height; y++) { var color1 = source.GetPixel(x, y); var color2 = Color.clear; var position = new Vector2Int(x - overlayPosition.x, y - overlayPosition.y); if (0 <= position.x && position.x <= overlay.width && 0 <= position.y && position.y <= overlay.height) { color2 = overlay.GetPixel(position.x, position.y); } output.SetPixel(x, y, color1 + color2); } } output.Apply(); return(output); } }