summaryrefslogtreecommitdiff
path: root/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader106
-rw-r--r--VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader.meta9
2 files changed, 115 insertions, 0 deletions
diff --git a/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader b/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader
new file mode 100644
index 00000000..10040df7
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader
@@ -0,0 +1,106 @@
+// Overlaps two projections, prioritizes closer pixels
+
+Shader "Hidden/ftFarSphereProjClip"
+{
+ Properties
+ {
+ }
+ SubShader
+ {
+ // No culling or depth
+ Cull Off ZWrite Off ZTest Always
+
+ Pass
+ {
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ struct v2f
+ {
+ float4 vertex : SV_POSITION;
+ float2 uv : TEXCOORD0;
+ };
+
+ v2f vert (uint id : SV_VertexID)
+ {
+ v2f o;
+ float4 pos[6];
+ pos[0] = float4(-1, -1, 0.5, 1);
+ pos[1] = float4(-1, 1, 0.5, 1);
+ pos[2] = float4(1, 1, 0.5, 1);
+
+ pos[3] = float4(1, 1, 0.5, 1);
+ pos[4] = float4(1, -1, 0.5, 1);
+ pos[5] = float4(-1, -1, 0.5, 1);
+
+ o.vertex = pos[id];
+ o.uv = o.vertex.xy * 0.5f + 0.5f;
+ o.uv.y = 1.0f - o.uv.y;
+ return o;
+ }
+
+ sampler2D _CurDepth, _ProjDepth, _CurNormal;
+ float4x4 _CurInvViewProj, _ProjViewProj;
+ float3 _CurPos, _ProjPos;
+ float _InvCubeSize;
+
+ float4 ComputeClipSpacePosition(float2 positionNDC, float deviceDepth)
+ {
+ float4 positionCS = float4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
+ positionCS.y = -positionCS.y;
+ return positionCS;
+ }
+
+ float3 ComputeViewSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invProjMatrix)
+ {
+ float4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
+ float4 hpositionVS = mul(invProjMatrix, positionCS);
+ return hpositionVS.xyz / hpositionVS.w;
+ }
+
+ float4 frag (v2f i) : SV_Target
+ {
+ float curDepth = tex2D(_CurDepth, i.uv).r; // closer is whiter
+ float3 curWPos = ComputeViewSpacePosition(i.uv, curDepth, _CurInvViewProj); // use different matrix to world
+
+ float distToCur = distance(_CurPos, curWPos);
+ float distToProj = distance(_ProjPos, curWPos);
+ if (distToCur < distToProj) discard; // keep current if it's closer
+
+ float texelOffset = _InvCubeSize;
+
+ float3 curWNormal = tex2D(_CurNormal, i.uv).xyz * 2 - 1;
+ float3 dir = normalize(curWPos - _ProjPos);
+ if (dot(-dir, curWNormal) <= 0) discard; // keep backfacing
+
+ float4 projPos = mul(_ProjViewProj, float4(curWPos, 1));
+ projPos.xyz /= projPos.w;
+ if (projPos.x < -1 || projPos.y < -1 || projPos.x > 1 || projPos.y > 1 || projPos.z < 0) discard; // keep current outside of projection
+ projPos.y = -projPos.y;
+
+ float2 projUV = projPos.xy * 0.5f + 0.5f;
+ float occlusion = 0;
+ int holeDilate = 2;
+ for(int y=-holeDilate; y<=holeDilate; y++)
+ {
+ for(int x=-holeDilate; x<=holeDilate; x++)
+ {
+ float projDepth = tex2D(_ProjDepth, projUV + float2(x,y) * texelOffset).r;
+ projDepth -= 0.0001f;
+
+ bool occluded = projDepth > projPos.z;
+ if (occluded) occlusion += 1;
+ }
+ }
+ if (occlusion > 0) discard;
+
+ // clear curDepth
+ return 0;
+ }
+ ENDCG
+ }
+ }
+}
diff --git a/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader.meta b/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader.meta
new file mode 100644
index 00000000..9a964389
--- /dev/null
+++ b/VRCSDK3Worlds/Assets/Bakery/ftFarSphereProjClip.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 931ec1b7cfa5bbd49a82f46676bdbbda
+timeCreated: 1526836856
+licenseType: Store
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant: