SteamVR(HTC Vive) Unity插件深度分析(八)
8. Resources
主要包含一些自定义的shader,目前对于Unity Shader的写法还不懂,各shader的作用暂时就不分析了
8.1. SteamVR_AlphaOut.shader
Shader "Custom/SteamVR_AlphaOut"{
Properties{ _MainTex ("Base (RGB)", 2D) = "white" {} }
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2fvert(appdata_base v) {
v2fo;
o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
o.tex= v.texcoord;
returno;
}
floatluminance(float3 color)
{
return0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
}
float4frag(v2f i) : COLOR {
float4color = tex2D(_MainTex, i.tex);
floata = saturate(color.a + luminance(color.rgb));
returnfloat4(a, a, a, a);
}
ENDCG
SubShader{
Pass{
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
}
}
8.2. SteamVR_Blit.shader
Shader "Custom/SteamVR_Blit" {
Properties{ _MainTex ("Base (RGB)", 2D) = "white" {} }
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2fvert(appdata_base v) {
v2fo;
o.pos= v.vertex;
o.tex= v.texcoord;
returno;
}
float4frag(v2f i) : COLOR {
returntex2D(_MainTex, i.tex);
}
float4frag_linear(v2f i) : COLOR {
returnpow(tex2D(_MainTex, i.tex), 1.0 / 2.2);
}
ENDCG
SubShader{
Pass{
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
Pass{
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag_linear
ENDCG
}
}
}
8.3. SteamVR_BlitFlip.shader
Shader "Custom/SteamVR_BlitFlip"{
Properties{ _MainTex ("Base (RGB)", 2D) = "white" {} }
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2fvert(appdata_base v) {
v2fo;
o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
o.tex.x= v.texcoord.x;
o.tex.y= 1 - v.texcoord.y;
returno;
}
float4frag(v2f i) : COLOR {
returntex2D(_MainTex, i.tex);
}
ENDCG
SubShader{
Pass{
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
}
}
8.4. SteamVR_ClearAll.shader
Shader "Custom/SteamVR_ClearAll"{
Properties{ _MainTex ("Base (RGB)", 2D) = "white" {} }
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2fvert(appdata_base v) {
v2fo;
o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
o.tex= v.texcoord;
returno;
}
float4frag(v2f i) : COLOR {
returnfloat4(0, 0, 0, 0);
}
ENDCG
SubShader{
Tags{"Queue" = "Background" }
Pass{
ZTestAlways Cull Off ZWrite On
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
}
}
8.5. SteamVR_ColorOut.shader
Shader "Custom/SteamVR_ColorOut"{
Properties{ _MainTex ("Base (RGB)", 2D) = "white" {} }
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2fvert(appdata_base v) {
v2fo;
o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
o.tex= v.texcoord;
returno;
}
floatluminance(float3 color)
{
return0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
}
float4frag(v2f i) : COLOR {
float4color = tex2D(_MainTex, i.tex);
returnfloat4(color.rgb, 1);
}
ENDCG
SubShader{
Pass{
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
}
}
8.6. SteamVR_Fade.shader
Shader "Custom/SteamVR_Fade" {
SubShader { Pass {
BlendSrcAlpha OneMinusSrcAlpha
ZTestAlways Cull Off ZWrite Off Fog { Mode Off }
BindChannels{ Bind "vertex", vertex Bind "color", color }
} } }
8.7. SteamVR_HiddenArea.shader
Shader"Custom/SteamVR_HiddenArea" {
CGINCLUDE
#include"UnityCG.cginc"
float4vert(appdata_base v) : SV_POSITION { return v.vertex; }
float4frag(float4 v : SV_POSITION) : COLOR { return float4(0,0,0,0); }
ENDCG
SubShader{
Tags{ "Queue" = "Background" }
Pass{
ZTestAlways Cull Off ZWrite On
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
}
}
8.8. SteamVR_Overlay.shader
Shader "Custom/SteamVR_Overlay" {
Properties{ _MainTex ("Base (RGB)", 2D) = "white" {} }
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2fvert(appdata_base v) {
v2fo;
o.pos= v.vertex;
o.tex= v.texcoord;
returno;
}
float4frag(v2f i) : COLOR {
returntex2D(_MainTex, i.tex);
}
float4frag_linear(v2f i) : COLOR {
returnpow(tex2D(_MainTex, i.tex), 2.2);
}
ENDCG
SubShader{
Pass{
BlendSrcAlpha OneMinusSrcAlpha
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
Pass{
BlendSrcAlpha OneMinusSrcAlpha
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag_linear
ENDCG
}
}
}
8.9. SteamVR_SphericalProjection.shader
Shader"Custom/SteamVR_SphericalProjection" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_N("N (normal of plane)", Vector) = (0,0,0,0)
_Phi0("Phi0", Float) = 0
_Phi1("Phi1", Float) = 1
_Theta0("Theta0", Float) = 0
_Theta1("Theta1", Float) = 1
_UAxis("uAxis", Vector) = (0,0,0,0)
_VAxis("vAxis", Vector) = (0,0,0,0)
_UOrigin("uOrigin", Vector) = (0,0,0,0)
_VOrigin("vOrigin", Vector) = (0,0,0,0)
_UScale("uScale", Float) = 1
_VScale("vScale", Float) = 1
}
CGINCLUDE
#include"UnityCG.cginc"
sampler2D_MainTex;
float4_N;
float_Phi0, _Phi1, _Theta0, _Theta1;
float4_UAxis, _VAxis;
float4_UOrigin, _VOrigin;
float_UScale, _VScale;
structv2f {
float4pos : SV_POSITION;
float2tex : TEXCOORD0;
};
v2f vert(appdata_basev) {
v2fo;
o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
o.tex= float2(
lerp(_Phi0,_Phi1, v.texcoord.x),
lerp(_Theta0,_Theta1, v.texcoord.y));
returno;
}
float3cartesian(float phi, float theta)
{
floatsinTheta = sin(theta);
returnfloat3(
sinTheta* sin(phi),
cos(theta),
sinTheta* cos(phi));
}
float4frag(v2f i) : COLOR {
float3V = cartesian(i.tex.x, i.tex.y);
float3P = V / dot(V, _N.xyz); // intersection point on plane
float2uv = float2(
dot(P- _UOrigin.xyz, _UAxis.xyz) * _UScale,
dot(P- _VOrigin.xyz, _VAxis.xyz) * _VScale);
returntex2D(_MainTex, uv);
}
ENDCG
SubShader{
Pass{
ZTestAlways Cull Off ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragmavertex vert
#pragmafragment frag
ENDCG
}
}
}
8.10. SteamVR_ExternalCamera.prefab
这是专门为外部相机(用于拍摄玩家真实世界和游戏虚拟世界混合视频的)而做的预制体。
可以看到,它主要由一个带SteamVR_ControllerManager脚本的父对象和一个带SteamVR_ExternalCamera及SteamVR_TrackedObject脚本的子对象组成。除了核心的SteamVR_ExternalCamera以外,另外两个脚本都是与跟踪设备有关的。原因是在制作这种视频的时候需要在外部摄像机上绑一个手柄以实现外部相机的定位。
这里有这种视频的一个示例:https://www.youtube.com/watch?v=w9dQkiI8raY
这里有如何拍摄这种视频的详细步骤:https://www.htcvive.com/cn/forum/chat.php?mod=viewthread&tid=1170
这里有关拍摄这种视频的技术讨论:https://steamcommunity.com/app/358720/discussions/0/405694031549662100/
9. Scenes
这下面有一个example.unity,是一个立方体矩阵,纹理用的是Steam Workshop网站首页的截图。如图:
有密集恐惧症的人慎看,而且向下看有悬崖的感觉
主要由4大部分组成,[Status]预制体和[SteamVR]预制体前面说过了,seaOfCubes就是那个立方体矩阵,总共是21x21的,每个submesh是3x21的。Main Camera为相机骨骼(CameraRig预制体),不过下面的Tracked Devices另外添加的。