Last active
November 12, 2024 11:08
-
-
Save unitycoder/85f0ddf57829e6faee9cf66b3adea04d to your computer and use it in GitHub Desktop.
Shader World Position From Depth (Frag or Surf shader)
This file contains hidden or 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
Shader "Custom/SurfaceDepthTexture" { | |
Properties { | |
_Color ("Color", Color) = (1,1,1,1) | |
_MainTex ("Albedo (RGB)", 2D) = "white" {} | |
_Glossiness ("Smoothness", Range(0,1)) = 0.5 | |
_Metallic ("Metallic", Range(0,1)) = 0.0 | |
_InvFade ("Soft Factor", Range(0.01,3.0)) = 1.0 | |
} | |
SubShader { | |
Tags { "Queue"="Transparent" "RenderType"="Transparent" } | |
LOD 200 | |
CGPROGRAM | |
// Physically based Standard lighting model, and enable shadows on all light types | |
#pragma surface surf Standard vertex:vert alpha:fade nolightmap | |
// Use shader model 3.0 target, to get nicer looking lighting | |
#pragma target 3.0 | |
sampler2D _MainTex; | |
struct Input { | |
float2 uv_MainTex; | |
float4 screenPos; | |
float eyeDepth; | |
}; | |
half _Glossiness; | |
half _Metallic; | |
fixed4 _Color; | |
sampler2D_float _CameraDepthTexture; | |
float4 _CameraDepthTexture_TexelSize; | |
float _InvFade; | |
void vert (inout appdata_full v, out Input o) | |
{ | |
UNITY_INITIALIZE_OUTPUT(Input, o); | |
COMPUTE_EYEDEPTH(o.eyeDepth); | |
} | |
void surf (Input IN, inout SurfaceOutputStandard o) { | |
// Albedo comes from a texture tinted by color | |
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; | |
o.Albedo = c.rgb; | |
// Metallic and smoothness come from slider variables | |
o.Metallic = _Metallic; | |
o.Smoothness = _Glossiness; | |
float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos)); | |
float sceneZ = LinearEyeDepth(rawZ); | |
float partZ = IN.eyeDepth; | |
float fade = 1.0; | |
if ( rawZ > 0.0 ) // Make sure the depth texture exists | |
fade = saturate(_InvFade * (sceneZ - partZ)); | |
o.Alpha = c.a * fade; | |
} | |
ENDCG | |
} | |
} |
This file contains hidden or 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
// https://forum.unity.com/threads/color-intersect-shader.986198/#post-6408075 | |
Shader "Unlit/WorldPosFromDepth" | |
{ | |
Properties | |
{ | |
} | |
SubShader | |
{ | |
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" } | |
LOD 100 | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
}; | |
struct v2f | |
{ | |
float4 pos : SV_POSITION; | |
float4 projPos : TEXCOORD0; | |
float3 camRelativeWorldPos : TEXCOORD1; | |
}; | |
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); | |
v2f vert (appdata v) | |
{ | |
v2f o; | |
o.pos = UnityObjectToClipPos(v.vertex); | |
o.projPos = ComputeScreenPos(o.pos); | |
o.camRelativeWorldPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)).xyz - _WorldSpaceCameraPos; | |
return o; | |
} | |
bool depthIsNotSky(float depth) | |
{ | |
#if defined(UNITY_REVERSED_Z) | |
return (depth > 0.0); | |
#else | |
return (depth < 1.0); | |
#endif | |
} | |
half4 frag (v2f i) : SV_Target | |
{ | |
float2 screenUV = i.projPos.xy / i.projPos.w; | |
// sample depth texture | |
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenUV); | |
// get linear depth from the depth | |
float sceneZ = LinearEyeDepth(depth); | |
// calculate the view plane vector | |
// note: Something like normalize(i.camRelativeWorldPos.xyz) is what you'll see other | |
// examples do, but that is wrong! You need a vector that at a 1 unit view depth, not | |
// a1 unit magnitude. | |
float3 viewPlane = i.camRelativeWorldPos.xyz / dot(i.camRelativeWorldPos.xyz, unity_WorldToCamera._m20_m21_m22); | |
// calculate the world position | |
// multiply the view plane by the linear depth to get the camera relative world space position | |
// add the world space camera position to get the world space position from the depth texture | |
float3 worldPos = viewPlane * sceneZ + _WorldSpaceCameraPos; | |
half4 col = 0; | |
// draw grid where it's not the sky | |
if (depthIsNotSky(depth)) | |
col.rgb = saturate(2.0 - abs(frac(worldPos) * 2.0 - 1.0) * 100.0); | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://forum.unity.com/threads/how-to-get-world-coordinates-of-pixel-in-fragment-shader.1156646/