How to connect Shaders to Actor2D?

I am trying to create something like this but using Actor2D.
utah_shaders

Reference: Varying Color — FURY 0.8.0.post102.dev0+g2832e935 documentation

For this, I was trying to connect Shaders to Actor2D but it is not working as expected.

I am using this below code but it neither throws any error nor adds the shaders to the Actor2D.


#!/usr/bin/env python

# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
from vtkmodules.vtkRenderingOpenGL2 import vtkShader
from vtkmodules.vtkCommonCore import vtkPoints
from vtkmodules.vtkCommonDataModel import vtkPolyData, vtkPolygon, vtkCellArray
from vtkmodules.vtkRenderingCore import (
    vtkActor2D,
    vtkPolyDataMapper2D,
    vtkRenderWindow,
    vtkRenderWindowInteractor,
    vtkRenderer
)


size = (200, 200)
points = vtkPoints()
points.InsertNextPoint(0, 0, 0)
points.InsertNextPoint(size[0], 0, 0)
points.InsertNextPoint(size[0], size[1], 0)
points.InsertNextPoint(0, size[1], 0)

# Create the polygon
polygon = vtkPolygon()
polygon.GetPointIds().SetNumberOfIds(4)  # make a quad
polygon.GetPointIds().SetId(0, 0)
polygon.GetPointIds().SetId(1, 1)
polygon.GetPointIds().SetId(2, 2)
polygon.GetPointIds().SetId(3, 3)

# Add the polygon to a list of polygons
polygons = vtkCellArray()
polygons.InsertNextCell(polygon)

# Create a PolyData
polygonPolyData = vtkPolyData()
polygonPolyData.SetPoints(points)
polygonPolyData.SetPolys(polygons)

# Create a mapper and actor
mapper = vtkPolyDataMapper2D()
mapper.SetInputData(polygonPolyData)

actor = vtkActor2D()
actor.SetMapper(mapper)
actor.SetPosition(400, 250)


sp = actor.GetShaderProperty()
sp.AddShaderReplacement(vtkShader.Vertex, '''//VTK::ValuePass::Dec''', True, '''
    //VTK::ValuePass::Dec
    out vec4 myVertexVC;
    ''', False)
sp.AddShaderReplacement(vtkShader.Vertex, '''//VTK::ValuePass::Impl''', True, '''
    //VTK::ValuePass::Impl
    myVertexVC = vertexMC;
    ''', False)
sp.AddShaderReplacement(vtkShader.Fragment, '''//VTK::ValuePass::Dec''', True, '''
    //VTK::ValuePass::Dec
    uniform float time;
    varying vec4 myVertexVC;
    ''', False)
sp.AddShaderReplacement(vtkShader.Fragment, '''//VTK::ValuePass::Impl''',
                        True, '''//VTK::ValuePass::Impl''', False)
sp.AddShaderReplacement(
    vtkShader.Fragment, '''//VTK::Light::Dec''', True, '''//VTK::Light::Dec''', False)
sp.AddShaderReplacement(vtkShader.Fragment, '''//VTK::Light::Impl''', True, '''
    //VTK::Light::Impl
    vec2 iResolution = vec2(1024,720);
    vec2 uv = myVertexVC.xy/iResolution;
    vec3 col = 0.5 + 0.5 * cos((time/30) + uv.xyx + vec3(0, 2, 4));
    fragOutput0 = vec4(col, fragOutput0.a);
    ''', False)


# Create a renderer, render window, and interactor
renderer = vtkRenderer()
renderWindow = vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindowInteractor = vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)

# Add the actor to the scene
renderer.AddActor(actor)
renderWindow.SetSize(1024, 720)

renderWindow.SetWindowName('Actor2D')

# Render and interact
renderWindow.Render()
# w2if = vtkWindowToImageFilter()
# w2if.SetInput(renderWindow)
# w2if.Update()
#
# writer = vtkPNGWriter()
# writer.SetFileName('TestActor2D.png')
# writer.SetInputConnection(w2if.GetOutputPort())
# writer.Write()
renderWindowInteractor.Start()


Output:

Can anybody explain how I could integrate shaders with Actor2D??

system platform: Windows 10
python version: 3.9.13
vtk version: 9.1.0

Okay I can confirm afaik that in VTK there is no example showing how to connect shaders to Actor2D. I can also confirm that what you do (although the shaders are not exact) should give you at least a debugging output showing that the shader is not correct. The silence i.e. no error message is unexpected. However, when we look at the VTK documentation it seems that Actor2D should be accessible from GLSL shaders like a standard Actor.
Can the VTK developers kindly provide here a minimalistic example? For example, showing how to simply change the color of Actor2D with a fragment shader? Or scale the size of Actor2D with a vertex shader?

1 Like

Unfortunately, vtkActor2D and vtkPolyDataMapper2D do not use vtkShaderProperty as of yet.

Thank you for the clarification Sankhesh.

Thank You @sankhesh.