打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【使用Unity制作无窗口应用】

  既然说到窗口,大家可能有所察觉了,今天的教程只针对Windows平台。我们可以结合摄像机的OnRenderImage事件和一些Windows底层API调用来实现该效果。

  首先呢,需要创建一个自定义Shader,奉上代码:

[AppleScript] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
Shader "Custom/ChromakeyTransparent" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TransparentColourKey ("Transparent Colour Key", Color) = (0,0,0,1)
_TransparencyTolerance ("Transparency Tolerance", Float) = 0.01
}
SubShader {
Pass {
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct a2v
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(a2v input)
{
v2f output;
output.pos = mul (UNITY_MATRIX_MVP, input.pos);
output.uv = input.uv;
return output;
}
sampler2D _MainTex;
float3 _TransparentColourKey;
float _TransparencyTolerance;
float4 frag(v2f input) : SV_Target
{
// What is the colour that *would* be rendered here?
float4 colour = tex2D(_MainTex, input.uv);
// Calculate the different in each component from the chosen transparency colour
float deltaR = abs(colour.r - _TransparentColourKey.r);
float deltaG = abs(colour.g - _TransparentColourKey.g);
float deltaB = abs(colour.b - _TransparentColourKey.b);
// If colour is within tolerance, write a transparent pixel
if (deltaR < _TransparencyTolerance && deltaG < _TransparencyTolerance && deltaB < _TransparencyTolerance)
{
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
// Otherwise, return the regular colour
return colour;
}
ENDCG
}
}
}



  代码比较简单易懂,就是输入一张纹理,一个关键颜色值以及相应的阈值,用于将指定的范围变透明(也就是大家所熟知的“抠图”)。

  接下来新建一个材质并使用上面的Shader,选定你想要替换的关键颜色值(必要时也可改变阈值)。注意这里不用手动指定纹理,我们会将摄像机的输出应用到该纹理,也就是下一步要做的事情。

  然后新建如下脚本绑定到主摄像机:

[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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;
}
// Define function signatures to import from Windows APIs
[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);
// Definitions of window styles
const int GWL_STYLE = -16;
const uint WS_POPUP = 0x80000000;
const uint WS_VISIBLE = 0x10000000;
void Start()
{
#if !UNITY_EDITOR
var margins = new MARGINS() { cxLeftWidth = -1 };
// Get a handle to the window
var hwnd = GetActiveWindow();
// Set properties of the window
// See: [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx[/url]
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
// Extend the window into the client area
See: [url]https://msdn.microsoft.com/en-us/library/windows/desktop/aa969512%28v=vs.85%29.aspx[/url]
DwmExtendFrameIntoClientArea(hwnd, ref margins);
#endif
}
// Pass the output of the camera to the custom material
// for chroma replacement
void OnRenderImage(RenderTexture from, RenderTexture to)
{
Graphics.Blit(from, to, m_Material);
}
}



  上面的代码用到了InterOpServices命名空间,以便调用一些Windows底层API从而改变Unity应用在运行时的窗口属性。然后使用OnRenderImage事件将摄像机的输出应用到RenderTexture。将使用了上面自定义Shader的材质赋给脚本种的m_Material字段,这样我们就可以开始抠图了。

  然后,重点来了:将摄像机的背景颜色改为与透明材质中_TransparentColourKey属性一样。



  你可以随便设置该颜色,但两边必须一致。

  最后就是生成和运行啦。因为用到了RenderTexture,所以如果使用Unity4.x必须为Pro版,而unity5.x任意版本均可。

  下图是Unity示例项目Stealth中的Ethan在桌面上走动。

  



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
猫都能学会的Unity3D Shader入门指南(一)
Unity Shader基础(2)
【浅墨Unity3D Shader编程】之十 深入理解Unity5中的Standard Shader...
【新提醒】【【Unity Shaders】学习笔记
UnityShader快速上手指南(一)
Visual Studio 2015 正式发布,已开放下载
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服