When I draw a road as is (stencil:off, depth:on,less), the results are like this - Road with depth;

Then I tried adding stencil a test for the road:

// Write to Stencil, Color & Depth buffers
Gl.Clear((uint)(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit));

// Write 1, when image drawing (road)
Gl.StencilFunc(StencilFunction.Always, 1, 0xff);
// write all bits of "reference" param;
// stencil fail; stencil pass, depth fail; stencil pass, depth pass
Gl.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Replace); 

road.Draw();  //draw road
// now, road in stencil buffer is 1, others - zeros;

//all not one - fail stencil, and do not drawing
Gl.StencilFunc(StencilFunction.Notequal, 1, 0xff);
// no more write to stencil buff
Gl.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);

// draw terrain

and got this: road visible behind mountain

after 3 days of random tests, I managed to hide the road behind the mountain, but there are still glitches (blue-green fill - "stencil pass, depth fail" in GlStencilOP()") glitches3 Here are 2 calls for drawing the terrain and 2 calls for drawing the road, with the one additional step for clearing of the depth. I think this is not correct way.

I found What are the correct steps for the renderer, to do normal roads drawing on terrain mesh?, but no solution, also, other than modifying the mesh.


1 Answer 1


As @DMGregory said, for solution use glPolygonOffset - Renderer code:

Gl.PolygonOffset(1f, 100f);

frag shader code:

#version 330
out vec4 fragColor;

uniform mat4 uView;
uniform mat4 uProjection;
uniform mat4 uModel;
in vec3 v_position;

void main()
    vec4 v_clip_coord = uProjection * uView * uModel * vec4(v_position, 1.0);
    float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
    gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;

    fragColor = vec4(1.0, 1.0, 1.0, 1.0);

vert shader code:

#version 330
layout (location = 0) in vec3 vPosition;

uniform mat4 uView;
uniform mat4 uProjection; 
out vec3 v_position;
void main()
    v_position = vPosition;
    gl_Position = uProjection * uView * vec4(vPosition, 1.0);

Additional detailed description about glPolygonOffset.

  • \$\begingroup\$ Why do you use glPolygonOffset() AND gl_FragDepth? \$\endgroup\$
    – Tara
    Commented Apr 28 at 18:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .