Enabling self-occlusion shadows wrt. Image-based skybox lighting

I want to illuminate a triangle mesh (from an .stl file) using only imagebased skybox lighting. When rendering an object, it appears that no shadows are cast from self occlusion. Eg. lighting a cylinder from a 45 degree angle wrt. the symmetry axis leads to a rendering where the inside of the cylinder have the same amount of illumination where realistically the light should only be able to light a part of the inside while the rest is in shadow.

Is it possible to enable casting of shadows?

Perhaps I should add that I have not computed normals or tangents for the imported .stl mesh. Is this neccesary?

Below is a codesnippet showing the setup of the vtkRenderer:

renderer->RemoveAllLights();
renderer->SetTwoSidedLighting(false);
renderer->SetLightFollowCamera(false);
renderer->SetAutomaticLightCreation(false);
renderer->UseImageBasedLightingOn();
renderer->SetEnvironmentTexture(cubemap);
renderer->SetBackground(colors->GetColor3d(“BkgColor”).GetData());
renderer->AddActor(actor);

auto skyboxActor = vtkSmartPointer::New();
skyboxActor->SetTexture(skybox);
renderer->AddActor(skyboxActor);

I think that if you want to render proper shadows you’ll need to add the proper passes into your rendering pipeline, vtkSSAOPass will add in ambient occlusion to a scene and I’ve used it fine but I’m not sure if it’ll work with external lights or with color. There’s also vtkShadowMapPass that supports colored lighting however I don’t know how advanced it is.

I’ve included a function to add in SSAO, it might be useful. You should have a look at the other passes VTK can utilise.

def add_SSAO(ren):

    bounds = np.asarray(ren.ComputeVisiblePropBounds())

    b_r = np.linalg.norm([bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]])

    occlusion_radius = b_r * 0.1 # tune to your preference
    occlusion_bias = 0.04 # not actually sure what this does

    passes = vtk.vtkRenderPassCollection()
    passes.AddItem(vtk.vtkRenderStepsPass())

    seq = vtk.vtkSequencePass()
    seq.SetPasses(passes)

    ssao = vtk.vtkSSAOPass()
    ssao.SetRadius(occlusion_radius)
    ssao.SetDelegatePass(seq)
    ssao.SetBias(occlusion_bias)
    ssao.SetBlur(True)
    ssao.SetKernelSize(256) # if this is too low the AO is inaccurate

    fxaaP = vtk.vtkOpenGLFXAAPass() # Anti-Aliasing isn't included in the default
    fxaaP.SetDelegatePass(ssao)

    ren.SetPass(fxaaP)

    ren.SetUseDepthPeeling(True)
    ren.SetOcclusionRatio(0.1)
    ren.SetMaximumNumberOfPeels(100)

    return ren

I think you are correct that I need the correct render passes. I have implemented the vtkShadowMapPass and I get self occluding shadows from vtkLights, however there is no occlusion from the environment lighting.

Environment lighting is not used in the vtkShadowMapPass.
If you have a static scene, the best result can be achieved using baked lighting textures (you need to use an external software for this) and use it in VTK (with the ORM texture)