VR模拟枪支打靶,消灭鬼怪,换弹以及上弦等等硬核枪支操作。 使用HTCVive设备,开启SteamVR进行游玩。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.5 KiB

3 years ago
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Hidden/FogVolume"
{
SubShader
{
Tags { "Queue"="Overlay" "IgnoreProjector"="True" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Front Lighting Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma multi_compile FOG_VOLUME_INSCATTERING_ON FOG_VOLUME_INSCATTERING_OFF
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
sampler2D _MainTex;
sampler2D _CameraDepthTexture;
float4 _Color, _InscatteringColor, _BoxMin, _BoxMax;
float3 L = float3(0, 0, 1);
float _InscatteringIntensity=1, _InscateringExponent=2, _Visibility, InscatteringStartDistance = 100, InscatteringTransitionWideness = 500;
//http://www.cs.cornell.edu/courses/CS4620/2013fa/lectures/03raytracing1.pdf
//http://www.clockworkcoders.com/oglsl/rt/gpurt1.htm
//float hitbox(Ray r, vec3 m1, vec3 m2, out float tmin, out float tmax)
float hitbox (float3 startpoint, float3 direction, float3 m1, float3 m2, inout float tmin, inout float tmax)
{
float tymin, tymax, tzmin, tzmax;
float flag = 1.0;
if (direction.x > 0)
{
tmin = (m1.x - startpoint.x) / direction.x;
tmax = (m2.x - startpoint.x) / direction.x;
}
else
{
tmin = (m2.x - startpoint.x) / direction.x;
tmax = (m1.x - startpoint.x) / direction.x;
}
if (direction.y > 0)
{
tymin = (m1.y - startpoint.y) / direction.y;
tymax = (m2.y - startpoint.y) / direction.y;
}
else
{
tymin = (m2.y - startpoint.y) / direction.y;
tymax = (m1.y - startpoint.y) / direction.y;
}
if ((tmin > tymax) || (tymin > tmax)) flag = -1.0;
if (tymin > tmin) tmin = tymin;
if (tymax < tmax) tmax = tymax;
if (direction.z > 0)
{
tzmin = (m1.z - startpoint.z) / direction.z;
tzmax = (m2.z - startpoint.z) / direction.z;
}
else
{
tzmin = (m2.z - startpoint.z) / direction.z;
tzmax = (m1.z - startpoint.z) / direction.z;
}
if ((tmin > tzmax) || (tzmin > tmax)) flag = -1.0;
if (tzmin > tmin) tmin = tzmin;
if (tzmax < tmax) tmax = tzmax;
return (flag > 0);
}
struct v2f
{
float4 pos : SV_POSITION;
float3 Wpos : TEXCOORD0;
float4 ScreenUVs : TEXCOORD1;
float3 LocalPos : TEXCOORD2;
float3 ViewPos : TEXCOORD3;
float3 LocalEyePos : TEXCOORD4;
};
v2f vert (appdata_full i)
{
v2f o;
o.pos = UnityObjectToClipPos(i.vertex);
o.Wpos.xyz = mul((float4x4)unity_ObjectToWorld, float4(i.vertex.xyz, 1)).xyz;
o.ScreenUVs = ComputeScreenPos(o.pos);
o.ViewPos = mul((float4x4)UNITY_MATRIX_MV, float4(i.vertex.xyz, 1)).xyz;
o.LocalPos = i.vertex.xyz;
o.LocalEyePos = mul((float4x4)unity_WorldToObject, (float4(_WorldSpaceCameraPos, 1))).xyz;
return o;
}
float4 frag (v2f i) : COLOR
{
float3 direction = normalize(i.LocalPos - i.LocalEyePos);
float tmin, tmax;
float Volume = hitbox(i.LocalEyePos, direction, _BoxMin, _BoxMax, tmin, tmax);
// tmin must be 0 when inside the volume
int Inside[3] = {0, 0, 0}, bOutside;
Inside[0] = step(0, abs(i.LocalEyePos.x) - _BoxMax.x);
Inside[1] = step(0, abs(i.LocalEyePos.y) - _BoxMax.y);
Inside[2] = step(0, abs(i.LocalEyePos.z) - _BoxMax.z);
bOutside = min(1,(float)(Inside[0] + Inside[1] + Inside[2]));
tmin*=bOutside;
float Depth = length(DECODE_EYEDEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.ScreenUVs)).r )/normalize(i.ViewPos).z);
float MinMax[2] = {max(tmin, tmax), min(tmin, tmax)};
float thickness = min(MinMax[0], Depth) - min(MinMax[1], Depth);
float Fog = 1-exp2(-(thickness) / _Visibility) * Volume ;
//There is an artifact when AA is enabled, so I scaled the volume size a bit. That makes the edge harder, so I have to fix it here:
Fog*=Fog;
float4 Final;
#if FOG_VOLUME_INSCATTERING_ON
//Inscattering
float3 CameraWSdir = normalize(i.Wpos - _WorldSpaceCameraPos);
float Inscattering = pow(max(0, dot(L, CameraWSdir)), _InscateringExponent);
//clamp by distance:
Inscattering *= saturate( Depth/InscatteringTransitionWideness- InscatteringStartDistance);
Final = float4(_Color.rgb + _InscatteringColor * _InscatteringIntensity * Inscattering, saturate(Fog * _Color.a));
#else
Final = float4(_Color.rgb , saturate(Fog * _Color.a));
#endif
return Final;
}
ENDCG
}
}
}