   Zbuffer - how to set?
  Hi! Is it possible to write to Zbuffer in HLSL?Like, I have some model Zbuffer value in my application, lets say, "10". End I have camera near end far clip planes(from 40 to 300)... Based on that, it is possible to calculate value in shader, which will represent this "10" and write it back to final output somehow?   
  See my topic here, you might find it useful.   ;  Thank you very much, that will definitely help me.   ;  Hmm... I can't find a way to determine output depth value I should use. I will explain my situation properly.I use FRB Engine, where everything is flat sprites. Among those flat sprites, I put my 3D Model (orthogonal camera mode).Now, because sprites are flat, and model is not, my model starts to stick out from different sprites.(Like, if sprite has Z value == 10, it will sort out properly will sprite with Z value == 11, because they are flat, but if I use model with Z value == 11, then it is not working, because model has other parts with Z value > 11 and < 11)So... Lets say, I set model "Z" value to 11, and pass it to my shader. I need model to be outputted like it is FLAT, so its Z value would be 11 when it is out for every pixel. What is the most efficient way to do it? Ok, I can sample its depth buffer. And pass this "11" value. But, is shader I have buffer in 0.0f to 1.0f range. Firstly, how can I convert this "11" to acceptable float?   Should I use something like:float averagedepth = 11 / (NearClipPlane - FraclipPlane)? But as I know, depth buffer is not linear?Maybe some other approach is needed?   ;  Is this Z value the value of viewSpacePosition.z (simply the distance from the near clip plane of the camera to the object)?If that is the case, I believe you can use the formula presented here: http://en.wikipedia.org/wiki/Z-buffering#Mathematics;  If you know what order you want thing rendered, it might be easier to just sort your sprites and 3D model by depth and then render them back to front with z-culling disabled.Otherwise you can output depth from your pixel shader. You said you're using an orthographic projection, in which case depth will be linear (you can use that equation you described). It's only when you use a perspective projection that things get...funky.   ;Quote:Original post by MJPIf you know what order you want thing rendered, it might be easier to just sort your sprites and 3D model by depth and then render them back to front with z-culling disabled.Otherwise you can output depth from your pixel shader. You said you're using an orthographic projection, in which case depth will be linear (you can use that equation you described). It's only when you use a perspective projection that things get...funky.Thank you all for the replies!So far, I succeeded only in writing some values to depth buffer only. But...If I sort sprites with model, I still have the same problem: Model is not Flat. I need to output it as "Flat" image, where it has depth buffer with pixels with exactly the same value.But, if I do this now... I get some part of the model, which should be behind, on top of it! That is because when I set depth directly, it messes up. So, basically, I need to:1: Process model normally, with Z-Buffer enabled.2: At the end, take the final image, and assign every pixel the same Z value.Will this work? Currently, if I assign Z value to every pixel, I get model messed up (like it was not processed normally). Maybe it has somethign to do with my code... I'll out full FX source for reference.//////////////////////////////////////////////////////////////////////ANIMATION LIBRARY DEFINITION///////////////////////////////////////////////////////////////////////////////////    float4x4 MatrixPalette[56];//////////////////////////////////////////////////////////////////////WORLDS DEFINITION///////////////////////////////////////////////////////////////////////////////////    float4x4 World;//////////////////////////////////////////////////////////////////////Engine Shared Values///////////////////////////////////////////////////////////////////////////////////shared float4x4 View : VIEW;shared float4x4 Projection : PROJECTION;shared float2 PixelSize;shared float4x4 InvViewProj;shared float NearClipPlane;shared float FarClipPlane;shared float3 CameraPosition;//////////////////////////////////////////////////////////////////////Texture///////////////////////////////////////////////////////////////////////////////////    float ZValue;    texture BasicTexture;    texture DepthTexture;    // Stores sampler state info for the texture    sampler TextureSampler:register(s0) = sampler_state    {  Texture = (BasicTexture);   MinFilter = linear;   MagFilter = linear;   MipFilter = linear;   AddressU = Clamp;   AddressV = Clamp;    };sampler DepthSampler : register(s1) = sampler_state{    Texture = (DepthTexture);    MinFilter = Linear;    MagFilter = Linear;    MipFilter = Linear;    AddressU = Wrap;    AddressV = Wrap;};//////////////////////////////////////////////////////////////////////Structs//////////////////////////////////////////////////////////////////////////////////////////////////////////////float2 samples[12]={-0.326212, -0.405805,-0.840144, -0.073580,-0.695914,  0.457137,-0.203345,  0.620716, 0.962340, -0.194983, 0.473434, -0.480026, 0.519456,  0.767022, 0.185461, -0.893124, 0.507431,  0.064425, 0.896420,  0.412458,-0.321940, -0.932615,-0.791559, -0.597705};//Output for the outline vertex shaderstruct VS_OUTPUT2{float4 Position: POSITION0;float4 Normal: TEXCOORD1;};// This is passed into our vertex shader from Xna    struct VS_INPUT    {   // This is the position of the vertex in the model filefloat4 position : POSITION;   // The vertex normalfloat3 normal : NORMAL;// This is the texture coordinate for the vertex in the model filefloat2 texcoord : TEXCOORD0;  float3 tangent    : TANGENT;// These are the indices (4 of them) that index the bones that affect// this vertex.  The indices refer to the MatrixPalette.half4 indices : BLENDINDICES0;// These are the weights (4 of them) that determine how much each bone// affects this vertex.float4 weights : BLENDWEIGHT0;    };// This is passed out from our vertex shader once we have processed the input    struct VS_OUTPUT    {   // The final position of the vertex in world spacefloat4 position : POSITION;// The texture coordinate associated with the vertexfloat2 texcoord : TEXCOORD0;   float4 color : COLOR;    };  // This is the output from our skinning method    struct SKIN_OUTPUT    {   float4 position;   float4 normal;   float4 tangent;    };//////////////////////////////////////////////////////////////////////XNA Skin Shader////////////////////////////////////////////////////////////////////////////////////////////////////////// // This method takes in a vertex and applies the bone transforms to it.    SKIN_OUTPUT Skin4( const VS_INPUT input)    {   SKIN_OUTPUT output = (SKIN_OUTPUT)0;   // Since the weights need to add up to one, store 1.0 - (sum of the weights)   float lastWeight = 1.0;   float weight = 0;   // Apply the transforms for the first 3 weights   for (int i = 0; i < 3; ++i)   {  weight = input.weights;  lastWeight -= weight;  output.position+= mul( input.position, MatrixPalette[input.indices]) * weight;  output.normal  += mul( input.normal, MatrixPalette[input.indices]) * weight;  output.tangent  += mul( input.tangent , MatrixPalette[input.indices]) * weight;   }   // Apply the transform for the last weight   output.position+= mul( input.position, MatrixPalette[input.indices[3]])*lastWeight;   output.normal  += mul( input.normal, MatrixPalette[input.indices[3]])*lastWeight;   output.tangent  += mul( input.tangent, MatrixPalette[input.indices[3]])*lastWeight;   return output;    };//////////////////////////////////////////////////////////////////////Pixel Shader////////////////////////////////////////////////////////////////////////////////////////////////////////////This is the ouline pixel shader. It just outputs unlit black.void Blur_PS(float2 texCoord : TEXCOORD0,float depth1 : DEPTH0,out float depth : DEPTH,out float4 Color: COLOR0){Color = tex2D(TextureSampler, texCoord);   depth = tex2D(DepthSampler, texCoord).z;for (int i = 0; i < 12; i++){   Color += tex2D(TextureSampler, texCoord + 20 * samples);   //depth = ZValue / (FarClipPlane - NearClipPlane) + depth / 1000;}}//This is the ouline pixel shader. It just outputs unlit black.void Black(float2 texCoord : TEXCOORD0, float depth1 : DEPTH0,out float depth : DEPTH,out float4 Color: COLOR0){depth = tex2D(DepthSampler, texCoord).z;//depth = ZValue / (FarClipPlane - NearClipPlane) + depth / 1000;Color.r = 0.0f;Color.g = 0.0f;Color.b = 0.0f;Color.a = 1.0f;}//////////////////////////////////////////////////////////////////////Vertex Shader////////////////////////////////////////////////////////////////////////////////////////////////////////////"peaks" the surface (scales it out on it's normal) VS_OUTPUT2 Outline(VS_INPUT Input){//Here's the important value. It determins the thickness of the outline.//The value is completely dependent on the size of the model.//My model is very tiny so my outine is very tiny.//You may need to increase this or better yet, caluclat it based on the distance//between your camera and your model.float offset = 0.15;float4x4 WorldViewProjection = mul(mul(World, View), Projection);SKIN_OUTPUT skin = Skin4(Input);VS_OUTPUT2 Output;Output.Normal= mul(skin.normal, World);Output.Position= mul(skin.position, WorldViewProjection)+(mul(offset, mul(skin.normal, WorldViewProjection)));return Output;}//////////////////////////////////////////////////////////////////////Techniques//////////////////////////////////////////////////////////////////////////////////////////////////////////  void TransformVertex2 (in VS_INPUT input, out VS_OUTPUT output)    {   // Calculate the skinned position   SKIN_OUTPUT skin = Skin4(input);   // This is the final position of the vertex, and where it will be drawn on the screen   float4x4 WorldViewProjection = mul(World,mul(View,Projection));   output.position = mul(skin.position, WorldViewProjection);   // This is not used by is included to demonstrate how to get the normal in world space   float4 transformedNormal = mul(skin.normal, WorldViewProjection);   output.texcoord = input.texcoord;   output.color = 1;    }// Pixel Shadervoid ps_default2(VS_OUTPUT input,float depth1 : DEPTH0,out float depth : DEPTH,out float4 Color: COLOR0){Color = tex2D(TextureSampler, input.texcoord);depth = tex2D(DepthSampler, input.texcoord).z;//depth = ZValue / (FarClipPlane - NearClipPlane) + depth / 1000;}void blur1VS(in VS_INPUT input,uniform float exten,out float4 outPosition : POSITION0,out float2 outTexcoord : TEXCOORD0){SKIN_OUTPUT skin = Skin4(input);skin.position.xyz += skin.normal/(exten-3);outTexcoord = input.texcoord;float4x4 WorldViewProjection = mul(World,mul(View,Projection));outPosition = mul(skin.position, WorldViewProjection);}void blur1PS (uniform float alpha,in float4 inTexcoord : TEXCOORD0,float depth1 : DEPTH0,out float4 outColor : COLOR0, out float depth: DEPTH){depth = tex2D(DepthSampler, inTexcoord);//depth = ZValue / (FarClipPlane - NearClipPlane) + depth / 1000;outColor = tex2D(TextureSampler , inTexcoord.xy);outColor.a=alpha;outColor.r=0;outColor.g=0;outColor.b=0;}   technique TransformTechnique    {    pass P00    {VertexShader = compile vs_3_0 TransformVertex2 ();PixelShader  = compile ps_3_0 ps_default2();  }//Render the outline surface inverted to create fake edge detectionpass P01{VertexShader = compile vs_3_0 Outline();PixelShader  = compile ps_3_0 Black();CullMode = CW;}pass p1 {ZENABLE = TRUE;zwriteenable=true;AlphaBlendEnable = true;VertexShader = compile vs_3_0 blur1VS(10);PixelShader = compile ps_3_0 blur1PS(1);}pass p2 {zwriteenable=true;ZENABLE = TRUE;AlphaBlendEnable = true;VertexShader = compile vs_3_0 blur1VS(8);PixelShader = compile ps_3_0 blur1PS(1);}pass p3 {zwriteenable=true;ZENABLE = TRUE;AlphaBlendEnable = true;VertexShader = compile vs_3_0 blur1VS(7);PixelShader = compile ps_3_0 blur1PS(1);}pass p4 {zwriteenable=true;ZENABLE = TRUE;AlphaBlendEnable = true;VertexShader = compile vs_3_0 blur1VS(9);PixelShader = compile ps_3_0 blur1PS(1);}pass p5 {zwriteenable=true;ZENABLE = TRUE;AlphaBlendEnable = true;VertexShader = compile vs_3_0 blur1VS(12);PixelShader = compile ps_3_0 blur1PS(1);}    };Quote:Original post by RyuMasterIf I sort sprites with model, I still have the same problem: Model is not Flat. I need to output it as "Flat" image, where it has depth buffer with pixels with exactly the same value.If you're not using z-buffering then everything essentially is "flat", since the appearance of sprites and models is controlled completely by the order in which you draw them.  So if you draw some sprites and then draw a model, the model will *always* be drawn above the other sprites regardless of the depth of individual portions of the model.