Custom shader programs in VR

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


very
Gnoblar
Posts: 1
Joined: Wed Mar 11, 2026 3:08 pm

Custom shader programs in VR

Post by very »

Hello,

I'm investigating an issue with non-HLMS materials not rendering as expected in VR in our application. In short, from what I can tell there is no "automatic" support for custom shader programs, and I would like to know if and how I could make them VR compatible.

In particular, I have a simple material used to project a mirror texture onto a mesh that is constructed like this:

Code: Select all

static Ogre::MaterialPtr createMirrorMaterial()
{
  auto material = Ogre::MaterialManager::getSingleton().create("MirrorMaterial", "General");
  auto pass = material->getTechnique(0)->getPass(0);
  auto tus = pass->createTextureUnitState();

  pass->setVertexProgram("Mirror_vp");
  pass->setFragmentProgram("Mirror_fp");

  Ogre::HlmsSamplerblock sampler;

  sampler.mU = Ogre::TAM_CLAMP;
  sampler.mV = Ogre::TAM_CLAMP;

  tus->setSamplerblock(sampler);

  return material;
}

and then assign with Ogre::SubItem::setMaterial.

Mirror_{vp, fp}.glsl look like

Code: Select all

#version 420

in vec4 vertex;
in vec3 normal;
in vec2 uv0;

uniform mat4 viewProjMat;
uniform mat4 modelMat;
uniform mat4 mirrorProjMat;

out gl_PerVertex
{ 
  vec4 gl_Position;
};

out block 
{
  vec4 uv;
} outPs ;
   
void main () {
vec4 pos = viewProjMat * modelMat * vertex; outPs.uv = mirrorProjMat * modelMat * vertex; gl_Position = pos; } #version 420 uniform sampler2D mirrorTex; uniform float shade; uniform vec4 fogParams; uniform vec4 fogColor; in block { vec4 uv ; } inPs ; out vec3 fragColor; void main () { fragColor = shade*textureProj(mirrorTex, inPs.uv).xyz; float fogDistance = length( (1.0 - gl_FragCoord.z) / gl_FragCoord.w ); float fogFactor = 1.0 - clamp((fogParams.z - fogDistance) / (fogParams.z - fogParams.y),0.0,1.0); fragColor.xyz = mix(fragColor.xyz, fogColor.xyz, fogFactor ); }

The two problems that occur are

  1. The mesh is rendered with an offset
  2. The mesh is only rendered in one eye

Mirror_vp uses param_named_auto viewProjMat viewproj_matrix, which as I understand does not take Ogre::Camera::setVrData into account, so I'm not surprised that the mesh is rendered with an offset. For this to work it seems like there would have to be a similar auto parameter but for the two VR view matrices instead that could be used to render the VR scene.

The second issue has been more difficult to understand, and I would very much appreciate input on it. My pure guess is that it may have something to do with how Ogre sets glViewport/glScissors for each eye, and that I may have to reset and then restore them before and after the mirror mesh is rendered, but I'm not sure on how to do that.

How should non-HLMS materials like these be handled for VR?

Thank you,