Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undesirable shadows with Haskell OpenGL

I have drawn the Barth sextic with Haskell OpenGL and there's a problem. I have also drawn it in R (with packages rgl and misc3d) and there's no problem. The two algorithms (in Haskell and R) are very similar. The Barth sextic is an implicit surface, and in Haskell I compute a triangulation of this surface with a marching cubes algorithm that I got by translating the one of misc3d to Haskell and C. I use the vertex normals, each defined by the gradient of the implicit equation.

Here is the problem:

enter image description here

I don't want these black shadows. When I look at the back of the sextic, by a 180° rotation, there's no such shadow:

enter image description here

The full code is available in this Github repo. Here are the parts of the code relevant to the colors:

fuchsia :: Color4 GLfloat
fuchsia = Color4 1.00 0.00 1.00 1
discord :: Color4 GLfloat
discord = Color4 0.21 0.22 0.25 1

  renderPrimitive Triangles $ mapM_ drawTriangle triangles
  swapBuffers
  where
    drawTriangle ((v1,v2,v3), (n1,n2,n3)) = do
      materialDiffuse FrontAndBack $= fuchsia
      normal n1
      vertex v1
      normal n2
      vertex v2
      normal n3
      vertex v3

  clearColor $= discord
  materialAmbient FrontAndBack $= black
  materialDiffuse FrontAndBack $= white
  materialEmission FrontAndBack $= black
  lighting $= Enabled
  lightModelTwoSide $= Enabled
  light (Light 0) $= Enabled
  position (Light 0) $= Vertex4 0 0 (-1000) 1
  ambient (Light 0) $= white
  diffuse (Light 0) $= white
  specular (Light 0) $= white

I have tried to change the colors in this last piece of code, but no way to get rid of these shadows. Am I doing something bad with the colors? I am sure the normals are correct because this works in R. However the shadows appear where the surface is not smooth, so I'm wondering whether the issue is caused by the normals.

The R rendering:

gfycat

Edit

I have managed to get rid of these shadows:

enter image description here

I don't really know how, I've done so many attempts... But anyway, now the problem is that the back of the sextic is too lighty:

enter image description here

like image 806
Stéphane Laurent Avatar asked Nov 16 '18 08:11

Stéphane Laurent


Video Answer


1 Answers

Now the rendering is nice :-)

enter image description here

I don't know what caused the problem because I have done numerous changes... Here are the relevant parts of the code:

resize :: Double -> Size -> IO ()
resize zoom s@(Size w h) = do
  viewport $= (Position 0 0, s)
  matrixMode $= Projection
  loadIdentity
  perspective 45.0 (w'/h') 1.0 100.0
  lookAt (Vertex3 0 0 (-6+zoom)) (Vertex3 0 0 0) (Vector3 0 1 0)
  matrixMode $= Modelview 0
  where
    w' = realToFrac w
    h' = realToFrac h

main :: IO ()
main = do
  _ <- getArgsAndInitialize
  _ <- createWindow "Barth Sextic"
  windowSize $= Size 500 500
  initialDisplayMode $= [RGBMode, DoubleBuffered, WithDepthBuffer]
  clearColor $= discord
  clientState ColorArray $= Disabled -- this is a default option, I think
  materialAmbient Front $= black
  materialDiffuse Front $= white
  materialEmission Front $= Color4 0 0 0 0
  materialSpecular Front $= white
  materialShininess Front $= 50
  lighting $= Enabled
  light (Light 0) $= Enabled
  position (Light 0) $= Vertex4 500 500 (-1000) 1
  diffuse (Light 0) $= white
  specular (Light 0) $= white
  lightModelAmbient $= Color4 0.35 0.35 0.35 1
  depthMask $= Enabled -- this is default option
  depthFunc $= Just Lequal
  shadeModel $= Smooth
  fog $= Disabled -- this is default option, I think
  polygonMode $= (Fill, Fill) -- this is default option
  polygonSmooth $= Enabled
  cullFace $= Just Front
  rescaleNormal $= Enabled
  ......

I have also changed the order of the vertices of each triangle:

drawTriangle ((v1,v2,v3), (n1,n2,n3)) = do
  materialDiffuse Front $= fuchsia
  normal n1
  vertex v1
  normal n3
  vertex v3
  normal n2
  vertex v2

This answer is a bit premature. I will investigate more later, and I'll edit to write my findings.

EDIT

Well, I have done further investigations and sadly, my conclusion is that I have no explanation: I have reverted all my changes, and no way to reproduce the issue !!

Now I use this shorter code:

display :: ...... -> displayCallback
  ......
  renderPrimitive Triangles $
    mapM_ drawTriangle triangles
  swapBuffers
  where
    drawTriangle ((v1,v2,v3), (n1,n2,n3)) = do
      materialDiffuse Front $= fuchsia
      normal n1
      vertex v1
      normal n2
      vertex v2
      normal n3
      vertex v3

resize :: Double -> Size -> IO ()
resize zoom s@(Size w h) = do
  viewport $= (Position 0 0, s)
  matrixMode $= Projection
  loadIdentity
  perspective 45.0 (w'/h') 1.0 100.0
  lookAt (Vertex3 0 0 (-6+zoom)) (Vertex3 0 0 0) (Vector3 0 1 0)
  matrixMode $= Modelview 0
  where
    w' = realToFrac w
    h' = realToFrac h

The two MatrixMode are important.

main :: IO ()
main = do
  _ <- getArgsAndInitialize
  _ <- createWindow "Barth Sextic"
  windowSize $= Size 500 500
  initialDisplayMode $= [RGBMode, DoubleBuffered, WithDepthBuffer]
  clearColor $= discord
  materialAmbient Front $= black
  materialDiffuse Front $= white
  materialEmission Front $= black
  lighting $= Enabled
  light (Light 0) $= Enabled
  position (Light 0) $= Vertex4 500 500 (-1000) 1
  ambient (Light 0) $= white
  diffuse (Light 0) $= white
  specular (Light 0) $= white
  depthFunc $= Just Less
  shadeModel $= Smooth
  cullFace $= Just Back
  ......

polygonSmooth and rescaleNormal were useless. I have also changed the position of the light but this is not the point which caused the issue. The cullFace is not necessary but it is good because there's no visible back face.

like image 69
Stéphane Laurent Avatar answered Oct 10 '22 12:10

Stéphane Laurent