Нежелательные тени с Haskell OpenGL - PullRequest
0 голосов
/ 16 ноября 2018

Я нарисовал секс-барт с Haskell OpenGL, и есть проблема. Я также нарисовал это в R (с пакетами rgl и misc3d), и нет никаких проблем. Два алгоритма (в Haskell и R) очень похожи. Секстика Барта неявное поверхность, а в Haskell я вычислить триангуляцию этой поверхности с помощью алгоритма походные кубов, которые я получил, переводя один из misc3d до Haskell и C. Я использую нормали вершин, каждая из которых определяется градиентом неявного уравнения.

Вот проблема:

enter image description here

Мне не нужны эти черные тени. Когда я смотрю на заднюю часть секстика с поворотом на 180 °, такой тени нет:

enter image description here

Полный код доступен в этом репозитории Github . Вот части кода, относящиеся к цветам:

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

Я пытался изменить цвета в этом последнем фрагменте кода, но не смог избавиться от этих теней. Я делаю что-то плохое с цветами? Я уверен, что нормали правильно, потому что это работает в R. Однако тень появляется там, где поверхность не гладкая, так что мне интересна, будет ли проблема вызвана нормалями.

The R визуализации:

gfycat

Редактировать

Мне удалось избавиться от этих теней:

enter image description here

Я не знаю, как, я сделал так много попыток ... Но в любом случае, сейчас проблема в том, что задняя части секстики слишком Лайти:

enter image description here

1 Ответ

0 голосов
/ 17 ноября 2018

Теперь рендеринг хорош: -)

enter image description here

Я не знаю, что вызвало проблему, потому что я сделал множество изменений ...Вот соответствующие части кода:

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
  ......

Я также изменил порядок вершин каждого треугольника:

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

Этот ответ являетсянемного преждевременноЯ буду расследовать позже, и я отредактирую, чтобы написать свои выводы.

РЕДАКТИРОВАТЬ

Что ж, я провел дальнейшие исследования, и, к сожалению, я пришел к выводу, что у меня нет никаких объяснений: у меня естьотменил все мои изменения и не смог воспроизвести проблему !!

Теперь я использую этот более короткий код:

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

Два MatrixMode важны.

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 и rescaleNormal были бесполезны.Я также изменил положение света, но это не та причина, которая вызвала проблему.cullFace не является необходимым, но это хорошо, потому что нет видимой задней поверхности.

...