Unity透明软件背景,显示桌面背景方案

更新:URP支持透明,版本2023.1.11(URP15),时间:2023.10.20*

Unity采用内置渲染管线,版本2020.3.0
参考网上资料:链接

Unity新版需要关闭选项:Edit——ProjectSettings——Player——ResolutionandPresentation——UseDXGIFlipModelSwapchainforD3D11
这个参考上面链接

没有按照上面链接的方式对颜色进行比较,部分场景会有非常多的锯齿,而是直接清空背景颜色

重要的事说三遍:
说下思路:先清除颜色,再渲染需要的!先清除颜色,再渲染需要的!先清除颜色,再渲染需要的!

第一种:不采用UI
在OnRenderImage方法上添加属性ImageEffectOpaque,这样会渲染完不透明物体后立刻执行,所以在自定义UnlitShader的片元阶段直接返回float4(0.0,0.0,0.0,0.0),即清除所有颜色,把我们需要显示的材质改为不透明顺序之后材质,如透明材质,这样就可以了。
第二种:采用UI
在自定义的Shader的片元阶段直接返回float4(0.0,0.0,0.0,0.0),即清除所有颜色,用UI显示我们的图片或视频就可以了,因为UI的渲染靠后。

透明后,窗口置顶,鼠标穿透等功能可参考网上资料

URP实现:版本2023.1.11(URP15)

总体思路和内置管线一样,但是需要URP14以后的版本才行(大牛可以自己添加功能,请忽略)
URP14新增了Full Screen Pass Renderer Feature功能,和内置管线的OnRenderImage类似的功能(URP版本不能使用OnRenderImage)

1.新建一个ShaderGraph,再由此ShaderGraph创建一个材质:
1.1.设置里Material类型改为Fullscreen
1.2.片元着色器透明度设置为0,颜色为黑色
测试后也可以设置其他颜色(导致整体带某种颜色,也是透明的)
透明的也可以不是0,大于0小于1背景半透明效果
在这里插入图片描述

2.添加Full Screen Pass Renderer Feature功能:
2.1.项目使用哪个渲染器对哪个渲染器设置,可以都设置上了,不同渲染器对应不同质量的设置,在ProjectSetting下的Quality
2.2.如下图添加Full Screen Pass Renderer Feature,把上一步创建的ShaderGraph新建一个材质放进来即可
2.3.把InjectionPoint改为Before Rendering Transparents(在渲染透明对象前)
在这里插入图片描述
3.把相机的后处理和HDR功能关闭,也可以在URP渲染管线设置里关闭(最彻底)
如果没有关闭渲染管线的设置,一个相机关闭的设置,一个相机没有关闭设置,则只用关闭设置的相机渲染部分是透明的,也可能是你想要的效果

几个设置关闭的地方:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4.最后把这个脚本挂在任意物体上,上面链接里的脚本,去掉了OnRenderImage
最重要的代码是:DwmExtendFrameIntoClientArea(_hwnd, ref margins);
没有它无法透明

using System;
using System.Runtime.InteropServices;
using UnityEngine;

public class TransparentWindow : MonoBehaviour
{   
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }

    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();

    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

    [DllImport("Dwmapi.dll")]
    private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);

    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    private static extern int SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy,
        int uFlags);

    [DllImport("user32.dll")]
    static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

    [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
    static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);

    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    const int GWL_STYLE = -16;
    const int GWL_EXSTYLE = -20;
    const uint WS_POPUP = 0x80000000;
    const uint WS_VISIBLE = 0x10000000;

    const uint WS_EX_TOPMOST = 0x00000008;
    const uint WS_EX_LAYERED = 0x00080000;
    const uint WS_EX_TRANSPARENT = 0x00000020;

    const int SWP_FRAMECHANGED = 0x0020;
    const int SWP_SHOWWINDOW = 0x0040;
    const int LWA_ALPHA = 2;

    private IntPtr HWND_TOPMOST = new IntPtr(-1);

    private IntPtr _hwnd;

    void Start()
    {
#if !UNITY_EDITOR
        MARGINS margins = new MARGINS() { cxLeftWidth = -1 };
        _hwnd = GetActiveWindow();
        int fWidth = Screen.width;
        int fHeight = Screen.height;
        SetWindowLong(_hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
        //SetWindowLong(_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT);//若想鼠标穿透,则将这个注释恢复即可
        DwmExtendFrameIntoClientArea(_hwnd, ref margins);
        SetWindowPos(_hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, SWP_FRAMECHANGED | SWP_SHOWWINDOW); 
        ShowWindowAsync(_hwnd, 3); //Forces window to show in case of unresponsive app    // SW_SHOWMAXIMIZED(3)
#endif
    }
}

5.把想要显示的物体的材质设置为透明,比如下图的方块和圆球,UI可以直接添加,因为UI的渲染顺序更靠后

效果如下:颜色设置的是红色,设置为黑色就完全透明,左边相机禁用了后处理和HDR(左边透明),右边没有禁用
在这里插入图片描述
Github上有一个透明软件背景的项目:添加链接描述

更新:又发现一种方式,官方给的例子,代码的方式:官方链接

这种是自己定义全屏渲染功能,上一种是官方提供了直接用,原理是一样的。在shader里把返回颜色和透明度改成需要的即可

不同的地方是要修改插入点,改为:BeforeRenderingTransparents

public ColorBlitPass(Material material)
{
    m_Material = material;
    renderPassEvent = RenderPassEvent.BeforeRenderingTransparents;
}
  • 33
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值