Skip to content

Instantly share code, notes, and snippets.

@netri
Last active March 31, 2018 15:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save netri/8f48994252f3437d9a22c9ae82cb9cb2 to your computer and use it in GitHub Desktop.
Save netri/8f48994252f3437d9a22c9ae82cb9cb2 to your computer and use it in GitHub Desktop.
Neitri/World Space Position
// taken & edited from https://gamedev.stackexchange.com/a/132845/41980
Shader "Neitri/World Space Position"
{
Properties
{
}
SubShader
{
Tags {
"Queue"="Overlay-10"
"RenderType"="Opaque"
}
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldDirection : TEXCOORD0;
float4 screenPosition : TEXCOORD1;
};
sampler2D _CameraDepthTexture;
v2f vert (appdata v)
{
v2f o;
// Subtract camera position from vertex position in world
// to get a ray pointing from the camera to this vertex.
o.worldDirection = mul(unity_ObjectToWorld, v.vertex).xyz - _WorldSpaceCameraPos;
// Typical boilerplate.
o.vertex = UnityObjectToClipPos(v.vertex);
// Save the clip space position so we can use it later.
// (There are more efficient ways to do this in SM 3.0+,
// but here I'm aiming for the simplest version I can.
// Optimized versions welcome in additional answers!)
o.screenPosition = o.vertex;
// Done.
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// Compute projective scaling factor...
float perspectiveDivide = 1.0f / i.screenPosition.w;
// Scale our view ray to unit depth.
float3 direction = i.worldDirection * perspectiveDivide;
// Calculate our UV within the screen (for reading depth buffer)
float2 screenUV = (i.screenPosition.xy * perspectiveDivide) * 0.5f + 0.5f;
// No idea
screenUV.y = 1 - screenUV.y;
// VR stereo support
screenUV = UnityStereoTransformScreenSpaceTex(screenUV);
// Read depth, linearizing into worldspace units.
float depth = LinearEyeDepth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, screenUV)));
// Advance by depth along our view ray from the camera position.
// This is the worldspace coordinate of the corresponding fragment
// we retrieved from the depth buffer.
float3 worldspace = direction * depth + _WorldSpaceCameraPos;
// Draw a worldspace tartan pattern over the scene to demonstrate.
return float4(frac(worldspace), 1.0f);
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment