也算是一种方法吧,可以截后处理之后的alpha截图
https://forum.unity.com/threads/post-processing-truns-off-cameras-solid-color-alpha.473636/
设置相机为solid color
alpha设为0
新建自定义后处理
AlphaCapture.cs
using System;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
[Serializable]
[PostProcess(typeof(AlphaCaptureRenderer), PostProcessEvent.AfterStack, "Custom/AlphaCapture")]
public sealed class AlphaCapture : PostProcessEffectSettings
{
[Range(0f, 1f), Tooltip("AlphaCapture effect intensity.")]
public FloatParameter blend = new FloatParameter { value = 0.5f };
}
public sealed class AlphaCaptureRenderer : PostProcessEffectRenderer<AlphaCapture>
{
private RenderTexture m_Rt;
public static bool SaveRenderTextureToPNG(Texture2D spng, string contents, string pngName)
{
string r = contents + "/" + pngName + ".png";
Debug.Log($"save {r}");
Texture2D png = new Texture2D(spng.width, spng.height, TextureFormat.ARGB32, false);
png.ReadPixels(new Rect(0, 0, spng.width, spng.height), 0, 0);
byte[] bytes = spng.EncodeToPNG();
if (!Directory.Exists(contents))
Directory.CreateDirectory(contents);
FileStream file = File.Open(r, FileMode.Create);
BinaryWriter writer = new BinaryWriter(file);
writer.Write(bytes);
file.Close();
Texture2D.DestroyImmediate(png);
png = null;
return true;
}
private void CaptureToDesktop()
{
Texture2D texture2D = GetTex2D();
SaveRenderTextureToPNG(
texture2D,
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
DateTime.Now.ToString("yyyyMMddHHmmssffff_" + "_"));
}
private Texture2D GetTex2D()
{
int width = m_Rt.width;
int height = m_Rt.height;
Texture2D texture2D = new Texture2D(width, height, TextureFormat.RGBA32, false);
RenderTexture.active = m_Rt;
texture2D.ReadPixels(new Rect(0, 0, width, height), 0, 0);
texture2D.Apply();
return texture2D;
}
public override void Render(PostProcessRenderContext context)
{
var sheet = context.propertySheets.Get(Shader.Find("Hidden/Custom/AlphaCapture"));
sheet.properties.SetFloat("_Blend", settings.blend);
context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
m_Rt = context.GetScreenSpaceTemporaryRT();
context.command.Blit(context.destination, m_Rt);
// 截图
if (Input.GetKey(KeyCode.Space))
{
CaptureToDesktop();
Debug.Log("截图");
}
RenderTexture.ReleaseTemporary(m_Rt);
}
}
新建shader
Shader "Hidden/Custom/AlphaCapture"
{
HLSLINCLUDE
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float _Blend;
float4 Frag(VaryingsDefault i) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
// float luminance = dot(color.rgb, float3(0.2126729, 0.7151522, 0.0721750));
// color.rgb = lerp(color.rgb, luminance.xxx, _Blend.xxx);
return color;
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
ENDHLSL
}
}
}
增加一个相机截图
参考Unity官方的例子,增加一个延迟渲染的相机,然后再插入到AfterEverything后面
这样
// 延迟渲染
var displayGO = new GameObject();
displayGO.name = "CameraHostGO-" + displayGO.GetInstanceID();
//displayGO.transform.parent = session.recorderGameObject.transform;
var camera = displayGO.AddComponent<Camera>();
camera.clearFlags = CameraClearFlags.Nothing;
camera.cullingMask = 0;
camera.renderingPath = RenderingPath.DeferredShading;
camera.targetDisplay = 0;
camera.rect = new Rect(0, 0, 1, 1);
camera.depth = float.MaxValue;
m_Camera = camera;
m_quad = CreateFullscreenQuad();
// 渲染一个面片,然后用顶点着色器写到屏幕上
CaptureRT = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32)
{
wrapMode = TextureWrapMode.Repeat
};
CaptureRT.Create();
shader = Shader.Find("Hidden/Recorder/Inputs/CBRenderTexture/CopyFB");
captureMaterial = new Material(shader);
//captureMaterial.EnableKeyword("OFFSCREEN");
captureMaterial.EnableKeyword("TRANSPARENCY_ON");
var tid = Shader.PropertyToID("_TmpFrameBuffer");
m_CbCopyFB = new CommandBuffer { name = "Capture Screen ##############" };
m_CbCopyFB.GetTemporaryRT(tid, -1, -1, 0, FilterMode.Bilinear);
m_CbCopyFB.Blit(BuiltinRenderTextureType.CurrentActive, tid);
m_CbCopyFB.SetRenderTarget(CaptureRT);
m_CbCopyFB.DrawMesh(m_quad, Matrix4x4.identity, captureMaterial, 0, 0);
m_CbCopyFB.ReleaseTemporaryRT(tid);
m_Camera.AddCommandBuffer(CameraEvent.AfterEverything, m_CbCopyFB);