How to specify a material for displacement geometry shader in HdStorm

Hi guys,

I want to enable displacement shading for HdStorm on my material and I am using the following code to achieve that by directly setting up a material network map:

HdMaterialNode previewSurfaceNode;
previewSurfaceNode.identifier = UsdImagingTokens->UsdPreviewSurface;
previewSurfaceNode.path = previewSurfacePath;

HdMaterialNode primVarReaderNode;
primVarReaderNode.identifier = UsdImagingTokens->UsdPrimvarReader_float2;
primVarReaderNode.path = primVarReaderPath;
primVarReaderNode.parameters.insert({_tokens->varname, VtValue(_tokens->st)});

HdMaterialNode textureDisplacementNode;
textureDisplacementNode.identifier = UsdImagingTokens->UsdUVTexture;
textureDisplacementNode.path = textureDisplacementPath;
textureDisplacementNode.parameters.insert(
    {_tokens->file,
     VtValue(std::string("hydraPOCDisplacement.png"))});
textureDisplacementNode.parameters.insert({_tokens->sourceColorSpace, VtValue(_tokens->raw)});

rel.inputId = textureDisplacementNode.path;
rel.inputName = _tokens->r;
rel.outputId = previewSurfaceNode.path;
rel.outputName = _tokens->displacement;
network.relationships.emplace_back(rel);

rel.inputId = primVarReaderNode.path;
rel.inputName = _tokens->result;
rel.outputId = textureDisplacementNode.path;
rel.outputName = _tokens->st;
network.relationships.emplace_back(rel);

network.nodes.push_back(std::move(primVarReaderNode));
network.nodes.push_back(std::move(textureDiffuseNode));
network.nodes.push_back(std::move(textureNormalNode));
network.nodes.push_back(std::move(textureRoughnessNode));
network.nodes.push_back(std::move(textureAONode));
network.nodes.push_back(std::move(textureDisplacementNode));
network.nodes.push_back(std::move(previewSurfaceNode));
networkMap.map.insert({HdMaterialTerminalTokens->surface, network});
networkMap.map.insert({HdMaterialTerminalTokens->displacement, network});
networkMap.terminals.push_back(previewSurfacePath);

All textures are considered by the preview surface shader except the displacement and I am not sure what is missing to get the geometry shader running and correctly call the displacement shader in previewSurface.glslfx. I was debugging and reading through the code a bit and saw, that HdStMesh::_UpdateDrawItemGeometricShader actually fetches the correct shader source but I wasn’t able to identify the cause of the problem.
Maybe someone has an idea.

Cheers,
Robert

I did some more research on this and it looks like, that displacement mapping is done in the vertex shader, which just applies the offsets from the texture to each vertex. That only makes sense, if the mesh was appropriately tessellated before that. Maybe I need to setup some tessellation parameters to get a meaningful displacement mapping with HdStorm? I am rendering with the Metal Hgi if this makes any difference. I am rendering a cube with 8 vertices and I viewed the scene via Xcode metal inspection. The displacement shader is actually executed, but as I said only per vertex. I thought, that if I enable displacement mapping, it would automatically tesselate the mesh appropriately but maybe this is not the case. I think I must be still missing something.

Cheers,
Robert

There isn’t currently support in Storm for increasing the mesh tessellation rate sufficiently to resolve displacement well.
You’re correct that displacement is evaluated at triangle vertices before rasterization.
One thing you can try is to increase the tessellation rate by enabling subdivision evaluation of the mesh, e.g. env HD_ENABLE_OPENSUBDIV3_ADAPTIVE=1 usdview --complexity veryhigh pxr/usdImaging/usdImagingGL/testenv/testUsdImagingGLDisplacement/testUsdImagingGLDisplacement.usda
But as you can see with that example, even at veryhigh complexity, the tessellation rate is typically not high enough to resolve high frequency detail.
This is something we would like to improve.

1 Like

Thanks for the info!