I want to display an actor and a widget with some transparency.
It seems VTK8 was in alpha blending but VTK9 uses additive blending. Shading seems broken too.
How to do to have same rendering as in VTK 8?
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereRepresentation.h>
#include <vtkSphereSource.h>
#include <vtkSphereWidget2.h>
int main(int, char*[])
{
// Create a sphere/mapper/actor
auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(2.0);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
actor->GetProperty()->SetOpacity(0.5);
// Create a renderer/render window/interactor
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(0, 0, 0);
auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
auto renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// Create widget
auto sphereWidget = vtkSmartPointer<vtkSphereWidget2>::New();
sphereWidget->SetInteractor(renderWindow->GetInteractor());
auto sphereRep = vtkSmartPointer<vtkSphereRepresentation>::New();
sphereWidget->SetRepresentation(sphereRep);
sphereRep->SetRadius(1);
sphereRep->UseBoundsOff();
sphereRep->HandleTextOff();
sphereRep->RadialLineOff();
sphereRep->GetSphereProperty()->SetOpacity(0.99);
sphereRep->GetSphereProperty()->SetColor(0.0, 1.0, 0.0);
sphereRep->SetRepresentationToSurface();
sphereWidget->On();
// Start the rendering loop
renderWindow->Render();
renderer->ResetCamera();
renderWindowInteractor->Start();
return 0;
}
I tried adding a normal vtkActor, vtkPolyDataMapper and vtkSphereSource. I compared the properties, identical, but the sphere from the widget appears wrongly (like the author has shown). Removing the SetOpacity(0.99) makes it appear correct, but I guess you know that. It seems like the OIT is broken.
Effectively, having 2 vtkSphereSource with vtkPolyDataMapper and vtkActor with transparency appears correctly. But obviously I need to have a vtkAbstractWidget (with transparency, obviously too…).
In reality, I don’t use vtkSphereWidget2 and vtkWidgetRepresentation, but my own widget and representation, inherit from vtkAbstractWidget and vtkSphereRepresentation. Is there a way to workaround this issue?
Good question and I would like to see the answer. In a canoe right now. Sunday, when I get back I will check iwhy my widgets with transparency work together with other transparent objects. I have not tried two transparent widgets. I dont inherit from vtkSphereRepresentation
FTR, the issue happens on both VTK 9.2.6 and 9.3.1 which makes me think it’s the switch to VTK 9 which is the culprit. @Jens_Munk_Hansen If you have any idea or need any kind of additional investigation from us, let us know as I am too interested in finding a solution (and hopefully a bug fix) to this issue.
I cannot reproduce similarly behavior here with their latest master. My sphere has opacity 0.5 and the handle, which is part of my widget has opacity 0.99 and is inside.
The widget I have made using the very old approach where it is not separated into a widget and a representation. There is no secret in the old “vtkImplicitPlaneWidget”. If you want I can upload the code.
We will try again with the latest commit of VTK. I would also be interested to see the source code of your example combining widgets and actors to see if we are doing something wrong.
Took the exact code, but replaced the widget with my own widget (made using the old design, no representation). Here things look correct. I can reproduce the above behavior for the code Laure provided.
#include <vtkActor.h>
#include <vtkImplicitRectangleWidget.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereRepresentation.h>
#include <vtkSphereSource.h>
#include <vtkSphereWidget2.h>
int main(int, char*[])
{
// Create a sphere/mapper/actor
auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(2.0);
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
actor->GetProperty()->SetOpacity(0.5);
// Create a renderer/render window/interactor
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(0, 0, 0);
auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
auto renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkNew<vtkImplicitRectangleWidget> widget;
widget->SetInteractor(renderWindow->GetInteractor());
widget->GetHandleProperty()->SetOpacity(0.99);
renderWindow->SetMultiSamples(0); // Disable multi-sampling (for clarity)
renderWindow->SetAlphaBitPlanes(1); // Ensure alpha channel if blending is used
// Start the rendering loop
renderWindow->Render();
renderer->ResetCamera();
renderWindowInteractor->Initialize();
widget->On();
renderWindowInteractor->Start();
return 0;
}