|
代码
1. shader:
Shader "Custom/MakeTransparent" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _TransparentColorKey ("Transparent Color Key", Color) = (0,1,0,1) _TransparencyMargin ("Transparency Margin", Float) = 0.01 } SubShader { Pass { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma vertex VertexShaderFunction #pragma fragment PixelShaderFunction #include "UnityCG.cginc" struct VertexData { float4 position : POSITION; float2 uv : TEXCOORD0; }; struct VertexToPixelData { float4 position : SV_POSITION; float2 uv : TEXCOORD0; }; VertexToPixelData VertexShaderFunction(VertexData input) { VertexToPixelData output; output.position = UnityObjectToClipPos (input.position); output.uv = input.uv; return output; } sampler2D _MainTex; float3 _TransparentColorKey; float _TransparencyMargin; float4 PixelShaderFunction(VertexToPixelData input) : SV_Target { float4 color = tex2D(_MainTex, input.uv); float deltaR = abs(color.r - _TransparentColorKey.r); float deltaG = abs(color.g - _TransparentColorKey.g); float deltaB = abs(color.b - _TransparentColorKey.b); if (deltaR < _TransparencyMargin && deltaG < _TransparencyMargin && deltaB < _TransparencyMargin) { return float4(0.0f, 0.0f, 0.0f, 0.0f); } return color; } ENDCG } }}2.C#:
using System;using System.Runtime.InteropServices;using UnityEngine;public class TransparentWindow : MonoBehaviour{ [SerializeField] private Material m_Material; 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 } void OnRenderImage(RenderTexture from, RenderTexture to) { Graphics.Blit(from, to, m_Material); }}操作:
1. 新建Material(材质球),选择shader:
2. c#脚本挂在摄像机上,摄像机的Clear Flags选择Solid Color模式,脚本上挂载刚刚新建的材质球:
3. 摄像机的Background属性要和材质球的Transparent Color Key属性一致:
4. 最重要的一点!!!我这里的Unity开发版本为2019.4.2f1版本,2019以上的版本需要取消勾选一个属性,不然是没有效果的,若是2019以下的版本则可能不需要设置,题主在2018.3.8f1上就不需要设置,如图:
2019版本若是有这个设置,则必须要关闭,设置位置:
Edit——ProjectSettings——Player——ResolutionandPresentation——UseDXGIFlipModelSwapchainforD3D11
至于是什么原因,暂时还不了解,如果有同学知道,望能指教一二
发布效果如下:
PS:我这个程序是没有鼠标穿透的,C#脚本里有鼠标穿透的代码提示,注释取消一下即可 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|