Light disappears when camera view direction is parallel to plane

I have a textured plane with ambient, diffuse, specular and specular power set. There are no lights in the scene.
When I move the camera such that the view is in line with the plane, or away from it, then the plane goes black.

Animatie

It has nothing to do with the texture. In the reproduction below the same occurs with a plain white plane.

Running vtk 9.0.3 but same behavior in RC of 9.1

Reproduce:


import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonTransforms import vtkTransform
from vtkmodules.vtkFiltersCore import vtkTriangleFilter
from vtkmodules.vtkFiltersGeneral import vtkTransformPolyDataFilter
from vtkmodules.vtkFiltersSources import vtkPlaneSource
from vtkmodules.vtkIOImage import vtkImageReader2Factory
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkPolyDataMapper,
    vtkRenderWindow,
    vtkRenderWindowInteractor,
    vtkRenderer,
    vtkTexture,
    vtkLight, vtkCamera,
)


from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackballCamera


colors = vtkNamedColors()

# Create a plane source and actor. The vtkPlanesSource generates
# texture coordinates.
#
plane = vtkPlaneSource()
planeMapper = vtkPolyDataMapper()
planeMapper.SetInputConnection(plane.GetOutputPort())

planeActor = vtkActor()
planeActor.SetMapper(planeMapper)

pr = planeActor.GetProperty()
pr.LightingOn()
pars = [0.8, 0.1, 0.0,  0]
pr.SetAmbient(0.8)
pr.SetDiffuse(0.1)
pr.SetSpecular(0)
pr.SetSpecularPower(0)    # default = 1.0 <------ this triggers the behaviour

# Create the RenderWindow, Renderer and Interactor.
renderer = vtkRenderer()
renWin = vtkRenderWindow()
renWin.AddRenderer(renderer)
iren = vtkRenderWindowInteractor()

style = vtkInteractorStyleTrackballCamera()
iren.SetInteractorStyle(style)

iren.SetRenderWindow(renWin)

# Add the actors to the renderer, set the background and size.
renderer.AddActor(planeActor)
renWin.SetSize(640, 480)
renWin.SetWindowName('TexturePlane')

renderer.SetBackground(colors.GetColor3d('DarkSlateGray'))
renderer.ResetCamera()
renderer.ResetCameraClippingRange()

camera = renderer.GetActiveCamera()
camera.SetPosition(1,2,0.4)
camera.SetFocalPoint(0,0,0.4)
camera.SetViewUp(0,0,1)

renWin.Render()
iren.Start()

I suspect this is just an issue in that we should prohibit 0 as a specular power. (we need to sanitize our input and prevent a setting of zero). The specular power gets passed into a pow function in glsl, basically specular = pow(planeNormal dot cameraViewDirection, specularPower) and the pow(x,y) function documentation includes

The result is undefined if $x < 0$ or if $x = 0$ and $y \leq 0$. 

In your example y is 0 so if x is <= 0 (which happens when the plane is pointing backwards) we will get undefined results which I suspect is what is happening here. You still see the plane when it is pointing backwards due to perspective. (the camera is perspective, the light is parallel)

Hi @ken-martin , I can confirm that setting the specular power to a very small value (1e-8) instead of 0 solves the issue.

Where should we check, SetSpecularPower()? If so then I can try to make a PR for this.

I will feed flag this in the vedo library for python as well as there specular power is set to 0 by some of the default functions.