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
- The mesh is rendered with an offset
- 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,