Unity 在postprocess之后截透明图片

也算是一种方法吧,可以截后处理之后的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);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值