Last active
March 31, 2018 15:39
-
-
Save netri/8f48994252f3437d9a22c9ae82cb9cb2 to your computer and use it in GitHub Desktop.
Neitri/World Space Position
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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