3

I'm trying to implement the code from this tutorial, but in much greater proportions (radius = 100000 units).

I don't know if the size matters but on my earth render the clouds have a strange render. As the tutorial does, I'm using two spheres and three textures (earth map, bump map, clouds).

Here the result (that's worse if the clouds are closer): Earth

More the clouds are closer of the planet surface, more this glitch is visible. If the clouds are sufficiently far (but that's not realistic) the problem disappears completely.

What can I do?

LJᛃ
  • 7,655
  • 2
  • 24
  • 35
Morgan Touverey Quilling
  • 4,181
  • 4
  • 29
  • 41

2 Answers2

5

Use logarithmic depth buffer instead of the linear one. This is a very simple change, just enable logarithmicDepthBuffer when you create your THREE.WebGLRenderer like so:

var renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true});

Here's an example you can have a look at: http://threejs.org/examples/#webgl_camera_logarithmicdepthbuffer

Using polygonOffset as suggested by LJ_1102 is a possibility, but it shouldn't be necessary.

travnik
  • 690
  • 7
  • 18
  • Thanks a lot, it works. You can also see my comment on LJ_1102's answer. About your answer, I suppose that logarithmic depth buffer is less optimized? I can't see differences for now in render duration but I will need to add a lot more elements to my scene in the future. – Morgan Touverey Quilling Nov 05 '14 at 10:41
  • 1
    @MorganTouvereyQuilling Log buffer has an overhead in fragment shader which adds, well - a logarithm function. As far as all the other things are concerned which need to happen for fragment's color and position to be computed - this is a tiny drop i the see. In other words: performance overhead is very small. Also, this overhead is static - no matter how many objects you have in the scene depth test is essentially done once per rendered pixel. Source https://github.com/mrdoob/three.js/blob/1769fbfc6c994b51a54c15a5c096855fd3cb8a1a/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl – travnik Nov 05 '14 at 10:53
  • Help, finally your solution causes an issue on the render of my particles. I'm using ShaderParticleEngine as my particle engine and now the particles are rendered behind all other elemnts, see that: http://i.imgur.com/cPYvE7U.png (ship reactor's particles displayed... behind the Earth, and also behind the reactor - the emitter origin is **inside** the reactor) – Morgan Touverey Quilling Nov 05 '14 at 13:28
  • That's a separate question my friend! :) A little magic goes a long way in this case, pass additional parameter to your `SPE.Group` in constructor like so `new SPE.Group({depthTest:false})` this should cause particles to be rendered regardless. See bug report https://github.com/squarefeet/ShaderParticleEngine/issues/56 – travnik Nov 05 '14 at 14:46
  • Sorry for the delay! It doesn't change anything. These arguments were present in the particle editor export and I copy/pasted the given code. I have "depthWrite: false" and "depthTest: false" – Morgan Touverey Quilling Nov 14 '14 at 13:30
  • Very simple and efficient, thanks. I used LJ's option 2 for a while and it also worked, but I wanted to set the near clipping plane as close to 0 as possible for zooming purposes, and your solution allows that. Upvoted both your answers and the question, since it was something I had to deal with as well. – Yin Cognyto Jun 17 '22 at 14:09
2

What you're experiencing is z-fighting due to insufficient depth buffer resolution.

You basically have three options to counteract this:

  1. Write / use a multi-texture shader that renders all three textures on one sphere.

  2. Increase the distance between the sphere faces. / Decrease the distance between your near and far clipping planes.

  3. Use polygonOffset and the POLYGON_OFFSET_FILL renderstate to offset depth values written by your outer sphere. Read more about polygonOffset here.

LJᛃ
  • 7,655
  • 2
  • 24
  • 35
  • Thanks! Finally I used the travnik solution, it works perfecly. But I have some questions. You're speaking about insufficient depth buffer resolution. Are you saying that, in one sense, I'm using too big values for spheres radii? I don't think because I found the z-fighting origin: I'm using 64 segments (width and height) to draw the sphere. If I increase the number of segments to, eg., 512, the problem disappears almost completely. It lets me think that z-fighting occurs because the faces of the two spheres are fighting because they're flat. Only the vertices are at the "good height". – Morgan Touverey Quilling Nov 05 '14 at 10:38
  • 1
    Btw: I wanted to accept your answer AND the travnik's answer but I see that's not possible. I gave you an upvote but I'm sorry I can't do more 'cause your answer is more complete and offers more investigation possibilities. – Morgan Touverey Quilling Nov 05 '14 at 10:45
  • The problem lies not in the fact your spheres are too large, but that the distance between their faces is "too small" in relation to the size of the spheres. The default depth buffer is non linear and has decreasing resolution towards the far clipping plane. Your assumption is correct, as you increase segment count of the sphere your getting a better approximation to the ideal sphere and by that get less error in the interpolation of depth values across the faces. – LJᛃ Nov 05 '14 at 15:04