How to force render a vtkActor

Hello VTK community,
vtkActors that are not visible (outside camera range) seems to not getting rendered. I becomes an issue when I try to change the actor’s position using the shader (gl_Position). The actor disappears when its bounding box is outside the camera’s range. Although acoording to the new position set by the shader, it should be inside the camera’s range.
So, how to force render the actor or mark it as inside the camera’s range?

Here’s a video of the issue:

1 Like

If changing clipping planes does not solve the problem, and normalization is out of question then it is very likely that this is a bug. Or vtk is using a different internal variable and not glPosition. Any other ideas VTK team?

1 Like

Here is an example in which this problem occurs:

from vtkmodules.vtkFiltersSources import vtkSphereSource
import vtkmodules.vtkInteractionStyle
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkRenderWindow,
    vtkRenderWindowInteractor,
    vtkRenderer
)
from vtkmodules.vtkRenderingOpenGL2 import vtkOpenGLPolyDataMapper, vtkShader


vertex_impl = \
    f"""
    // Translation matrix
    mat4 tr = mat4(
        vec4(1.0, 0.0, 0.0, 0.0),
        vec4(0.0, 1.0, 0.0, 0.0),
        vec4(0.0, 0.0, 1.0, 0.0),
        vec4(10.0, 0.0, 0.0, 1.0)
    );
    
   vertexVCVSOutput = tr * MCVCMatrix * vertexMC;
   gl_Position = MCDCMatrix * tr * vertexMC;
    """


def shader_to_actor(actor, shader_type, impl_code="", decl_code="",
                    block="//VTK::ValuePass"):
    shader_typ = {"vertex": vtkShader.Vertex, 'fragment': vtkShader.Fragment}
    block_dec = block + "::Dec" + "\n" + decl_code
    block_impl = block + "::Impl" + "\n" + decl_code

    sp = actor.GetShaderProperty()
    sp.AddShaderReplacement(shader_typ[shader_type], block_dec, True,
                            decl_code, False)
    sp.AddShaderReplacement(shader_typ[shader_type], block_impl, True,
                            impl_code, False)


def sphere_actor(pos=(100, 0, 0), color=(1, 0, 1)):
    sphereSource = vtkSphereSource()
    sphereSource.SetCenter(*pos)
    sphereSource.SetRadius(1.0)
    sphereSource.SetPhiResolution(100)
    sphereSource.SetThetaResolution(100)

    mapper = vtkOpenGLPolyDataMapper()
    mapper.SetInputConnection(sphereSource.GetOutputPort())

    sph_actor = vtkActor()
    sph_actor.SetMapper(mapper)
    sph_actor.GetProperty().SetColor(*color)
    return sph_actor


if __name__ == '__main__':
    renderer = vtkRenderer()
    camera = renderer.GetActiveCamera()
    renderWindow = vtkRenderWindow()
    renderWindow.SetWindowName("Sphere")
    renderWindow.AddRenderer(renderer)
    renderWindowInteractor = vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)

    sphere_actor_native = sphere_actor(pos=(0, 0, 0), color=(0, 0, 1))
    sphere_actor_shader = sphere_actor(pos=(0, 0, 0), color=(0, 1, 0))

    shader_to_actor(sphere_actor_shader, "vertex", impl_code=vertex_impl)

    renderer.AddActor(sphere_actor_native)
    renderer.AddActor(sphere_actor_shader)

    renderWindowInteractor.EndRotateEvent()
    renderWindowInteractor.Start()

So, both of the spheres are at the origin. But the green one is translated using vertex shader, As you can see, When the origin is out of the camera’s scope, the sphere dissappears.