- Home /
Unity 5 fragment shader that writes custom depth into the depth texture
Hello there. So im trying to write custom depth for the object with my shader (i want to turn a quad, into a circle), but it doesnt seem to do absolutely anything. Heres my current shader:
Shader "Custom/My Metaball" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Cutoff("CUTOFF", Range(0,1)) = 0.1
}
SubShader {
Pass{
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float _Cutoff;
struct v2f
{
float4 position : POSITION;
float2 uv : TEXCOORD0;
};
struct fragOut
{
half4 color : COLOR;
float depth : DEPTH;
};
v2f vert(appdata_base v)
{
v2f o;
o.position = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
return o;
}
fragOut frag(v2f i) : COLOR {
fragOut o;
fixed4 col = tex2D(_MainTex, i.uv);
o.color = col;
o.depth = 0;
return o;
}
ENDCG
}
}
//Fallback "Diffuse"
}
Im setting the depth to 0 just for test purposes.
If i uncomment the fallback, then it does standard depth writing, but with commented fallback - no depth output. Am i doing something wrong? Is it not possible at all? Ive seen some folk do this on forums.
Does removing COLOR
from the return semantics of the fragment shader help?
I wrote a shader a while back to make a shadow map. The fragment shader didn't output DEPTH
since i wanted to use the h/w. I created the render target with RenderTargetFormat.Depth
and used a secondary camera to render the scene into it. I did try writing to the depth buffer (my render target didn't have a color buffer since the format was set as above) in the fragment shader. All i needed to do was add DEPTH
semantics and output a float.
You must be doing most of this, correct?
Um, no. I want it to write directly into _CameraDepthTexture. So that i dont have a need to redo like 4 shaders of $$anonymous$$e that rely on depth from it. And especially SSAO, cause i have no idea how it works.
Ok, so you have this script attached to your quad game objects?
Answer by atomicjoe · Aug 04, 2016 at 04:35 PM
For anyone still struggling with this: The above shader DOES WORK, but it's writing directly to the DEPTH BUFFER used to check polygons depth against each other. It does NOT write to the user accessible DEPTH TEXTURE wich is generated by Unity when you set a camera to generate a depth or normal+depth TEXTURE. (using Camera.depthTextureMode) The depth TEXTURE is different than the actual depth buffer used internally to check polygons against when rendering. The DEPTH TEXTURE is generated by Unity manually with an extra pass in forward mode (rendering everything in the scene once again using Replacement Shaders) and in deferred render Unity will just direct you to the internal GBuffer2 were normals and depth are always rendered. This means you will have to modify the internal deferred shader that generates depth and normals in deferred mode or you will have to modify the internal depth and normals replacement shader for it to work in forward mode. It's quite complicated, but just keep in mind the DEPTH BUFFER you are writing to inside your shader IS NOT THE SAME as the Depth Texture Unity generates for you when you use Camera.depthTextureMode. This is for compatibility reasons, since some build targets can't read info from the native depth buffers, only write in it. (android, iOS...) Unity generates the Depth Texture manually as a way for the user to read the depth of the image even when the build target can't do it natively. Also, keep in mind the shaders that write directly to the depth buffer like the one posted above are VERY SLOW to render even on modern Desktop hardware. You should avoid this: it will cut your frame rate by half.
Hm very interesting, thanks for the insights! Do you by any chance know the rendertype I need to use to be called by the replacement shader? I have a special cutout shader that is turning a texture towards the camera, and therefore has a different $$anonymous$$VP matrix as the normal cutout has. Therefore just using ' Fallback "Legacy Shaders/Transparent/Cutout/Diffuse" ' leaves me with a wrong depth buffer.
Or is there any sample code out there? I took a look at the unity shaders, but I only found the Light$$anonymous$$ode tag that was new for me.
@Johannski You will have to download the replacement shader source code from the BUILTIN SHADERS pack and modify it yourself to suit your needs. It's the only way to manage non standard behaviours for depth textures. You will have to expand the shader with a new rendertype with your custom name and write the custom vertex shader there. It's not that dificult if you just copy paste and then modify other rendertypes to make your custom one. The shader to modify is "Internal-DepthNormalsTexture.shader" and you can find it in "DefaultResourcesExtra". Copy paste the shader source into your assets folder and it should automagically replace the internal one when compiled. JUST BE SURE TO SAVE IT WITH THE EXACT SA$$anonymous$$E FILENA$$anonymous$$E AND SHADER NA$$anonymous$$$$anonymous$$ The last builtin shaders can be downloaded here: http://netstorage.unity3d.com/unity/38b4efef76f0/builtin_shaders-5.5.0f3.zip
Thanks for the answer. I took a look at the hidden shader you pointed me at and actually found out why my shader was not using the depth buffer. you need to include all properties defined there in any other cutout shader if they should use the depth buffer. In my case I just changed the properties to
_$$anonymous$$ainTex("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff("Alpha cutoff", Range(0,1)) = 0.5
// Not used, but important for fallback to render the correct depth buffer
[HideInInspector] _Color("$$anonymous$$ain Color", Color) = (1,1,1,1)
and it magically worked ;)
Thanks a lot!
Is it possible to get the shader ? I have added these properties and still have the same problem