Page 1 of 1

Texture flickering/Z-fighting with Engine 3D

Posted: Mon May 17, 2021 10:19 pm
by Programie
Hi,

I experience major texture flickering (also called Z-fighting) when the camera is about 150000 world units away from two entities.

The first entity is located behind the second entity but the texture of the first entity flickers through the second entity.

Example code:

Code: Select all

EnableExplicit

Enumeration
  #Window
  #Camera
  #Texture1
  #Texture2
  #Material1
  #Material2
  #Cube1
  #Cube2
EndEnumeration

#CameraSpeed = 1000

Define KeyX
Define KeyY

InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

Add3DArchive("Textures", #PB_3DArchive_FileSystem)

If OpenWindow(#Window, 0, 0, 1920, 1080, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window))
EndIf

CreateCamera(#Camera, 0, 0, 100, 100)
CameraRange(#Camera, 0, 1000000)

CreateMaterial(#Material1, LoadTexture(#Texture1, "a.jpg"))
CreateMaterial(#Material2, LoadTexture(#Texture2, "b.jpg"))

CreateCube(#Cube1, 10000)
CreateEntity(#Material1, MeshID(#Cube1), MaterialID(#Material1), 0, 0, 0)

CreateCube(#Cube2, 10000)
CreateEntity(#Material2, MeshID(#Cube2), MaterialID(#Material2), 0, 0, 20000)

Repeat
  ExamineMouse()
  ExamineKeyboard()
  
  If KeyboardPushed(#PB_Key_A)
    KeyX = -#CameraSpeed
  ElseIf KeyboardPushed(#PB_Key_D)
    KeyX = #CameraSpeed
  Else
    KeyX = 0
  EndIf
  If KeyboardPushed(#PB_Key_W)
    KeyY = -#CameraSpeed
  ElseIf KeyboardPushed(#PB_Key_S)
    KeyY = #CameraSpeed
  Else
    KeyY = 0
  EndIf
  
  RotateCamera(#Camera, -MouseDeltaY() * 0.05, -MouseDeltaX() * 0.05, 0, #PB_Relative)
  MoveCamera(#Camera, KeyX, 0, KeyY)
  
  WindowEvent()
  RenderWorld()
  
  If StartDrawing(ScreenOutput())
    DrawText(10, 10, Str(CameraX(#Camera)) + " x " + Str(CameraY(#Camera)) + " x " + Str(CameraZ(#Camera)))
    StopDrawing()
  EndIf
  
  FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape)
a.jpg and b.jpg in the Textures folder are just single colored images (red and blue).

I can reproduce the issue on both, Windows and Linux, with the latest PureBasic version 5.73. On Windows, I've tested it with DirectX and OpenGL.

Screenshots: https://imgur.com/a/nAX1ufP

Re: Texture flickering/Z-fighting with Engine 3D

Posted: Mon May 17, 2021 11:18 pm
by pf shadoko
for z-fithing problems what counts is the far/near ratio of camera range
try with
CameraRange(#Camera, 1, 1000000)

Re: Texture flickering/Z-fighting with Engine 3D

Posted: Tue May 18, 2021 8:48 am
by infratec
To make it easier for testers:

Code: Select all

CreateTexture(#Texture1, 100, 100)
If StartDrawing(TextureOutput(#Texture1))
  Box(0, 0, 100, 100, #Red)
  StopDrawing()
EndIf

CreateTexture(#Texture2, 100, 100)
If StartDrawing(TextureOutput(#Texture2))
  Box(0, 0, 100, 100, #Blue)
  StopDrawing()
EndIf

CreateMaterial(#Material1, TextureID(#Texture1))
CreateMaterial(#Material2, TextureID(#Texture2))
And the fix drom pf shadoko works for me (opengl as subsystem)

Re: Texture flickering/Z-fighting with Engine 3D

Posted: Tue May 18, 2021 8:58 am
by RSBasic
Confirmed.
There is also a Z-order problem with entities.
If the camera is a bit far away, the 2nd entity is in the foreground, although the 2nd entity is behind the 1st entity.

Re: Texture flickering/Z-fighting with Engine 3D

Posted: Tue May 18, 2021 10:03 am
by Programie
pf shadoko wrote: Mon May 17, 2021 11:18 pm for z-fithing problems what counts is the far/near ratio of camera range
try with
CameraRange(#Camera, 1, 1000000)
Thanks for the hint.

Setting the Near parameter to 1 instead of 0 increases the distance where the issue starts. In my case, with Near = 0 the issue starts at around Z = 150000 while with Near = 1 the issue starts at around Z = 450000.

Increasing Near to 10 allows me to correctly see the objects even from a huge distance (about 1000000 world units away). But in that case, small entities won't be rendered if the camera is just < 10 world units away from the entity.

Re: Texture flickering/Z-fighting with Engine 3D

Posted: Tue May 18, 2021 10:50 am
by STARGĂ…TE
The values for the camera range can't be 0, because reciprocal values were used in the z-buffer.
Z-fighting is a normal behavior of any 3D engine and it is no bug!

If the z-buffer uses a normal depth of e.g. 16 bits, you have a resolution of roghly 5 order of magnitudes, meaning the Z-fighting occures when far is more than 5 order of magnitudes larger than near and the distance between faces are smaller than such resolution.

https://en.wikipedia.org/wiki/Z-fighting