Skip to main content
Up and Coming
November 4, 2014

0.4.3 Changed vignette

Hi,

My vignette no longer works, with 0.4.3. I've read a lot of info on the vignette being wrong in 0.4.3, but I'm not sure this is the same issue.
I'm using the extended mode.

This is what I want (it's what it looked like in 0.4.2):


This is what it looks like in 0.4.3:


I read out the vignette factor values that I got, and noticed some where actually below 0, which doesn't make sense to me. Isn't the vignette just there to darken the image, so it should be used to multiply the colour with - meaning it should go from 0 to ? For some reason I get values between -0.37745 and +1.
Is this the issue everyone else has been reporting? Or is this something different?

The code setting up the mesh:

for( unsigned int i = 0; i < meshData.VertexCount; i++ )
{
ovrDistortionVertex v = meshData.pVertexData[i];
manual->position( v.ScreenPosNDC.x,
v.ScreenPosNDC.y, 0 );
manual->textureCoord( v.TanEyeAnglesR.x,//*UVScaleOffset[0].x + UVScaleOffset[1].x,
v.TanEyeAnglesR.y);//*UVScaleOffset[0].y + UVScaleOffset[1].y);
manual->textureCoord( v.TanEyeAnglesG.x,//*UVScaleOffset[0].x + UVScaleOffset[1].x,
v.TanEyeAnglesG.y);//*UVScaleOffset[0].y + UVScaleOffset[1].y);
manual->textureCoord( v.TanEyeAnglesB.x,//*UVScaleOffset[0].x + UVScaleOffset[1].x,
v.TanEyeAnglesB.y);//*UVScaleOffset[0].y + UVScaleOffset[1].y);
//manual->colour( v.VignetteFactor, v.VignetteFactor, v.VignetteFactor, v.TimeWarpFactor );
manual->colour( v.VignetteFactor, v.VignetteFactor, v.VignetteFactor, v.VignetteFactor );
}
for( unsigned int i = 0; i < meshData.IndexCount; i++ )
{
manual->index( meshData.pIndexData[i] );
}


Vertex shader:

#version 130

// Values automatically defined by Ogre/OpenGL:
attribute vec4 vertex;
attribute vec2 uv0; // Red channel
attribute vec2 uv1; // Green channel
attribute vec2 uv2; // Blue channel
attribute vec4 colour; // Vertex Colour

// Load in values defined in the material:
uniform mat4 worldViewProj;
uniform vec2 eyeToSourceUVScale;
uniform vec2 eyeToSourceUVOffset;
uniform mat4 eyeRotationStart;
uniform mat4 eyeRotationEnd;

varying vec4 gl_FrontColor;

vec2 timewarpTexCoord( vec2 texCoord, mat4 rotMat )
{
vec3 transformed = (rotMat * vec4( texCoord.xy, 1, 1) ).xyz;

vec2 flattened = transformed.xy / transformed.z;

return eyeToSourceUVScale * flattened + eyeToSourceUVOffset;
}

void main(void)
{
/*float timewarpLerpFactor = 0.0;
mat4 lerpedEyeRot = eyeRotationStart * (1 - timewarpLerpFactor) + eyeRotationEnd * timewarpLerpFactor;

gl_TexCoord[0] = vec4( timewarpTexCoord( uv0, lerpedEyeRot ), 0.0, 0.0 );
gl_TexCoord[1] = vec4( timewarpTexCoord( uv1, lerpedEyeRot ), 0.0, 0.0 );
gl_TexCoord[2] = vec4( timewarpTexCoord( uv2, lerpedEyeRot ), 0.0, 0.0 );*/

gl_TexCoord[0] = vec4( eyeToSourceUVScale * uv0 + eyeToSourceUVOffset, 0.0, 0.0 );
gl_TexCoord[1] = vec4( eyeToSourceUVScale * uv1 + eyeToSourceUVOffset, 0.0, 0.0 );
gl_TexCoord[2] = vec4( eyeToSourceUVScale * uv2 + eyeToSourceUVOffset, 0.0, 0.0 );

gl_Position = worldViewProj * vertex;

gl_FrontColor = colour;
}



Fragment shader:


uniform sampler2D diffuseMap;

void main(void)
{
float red = texture2D(diffuseMap, gl_TexCoord[0].xy).r;
float green = texture2D(diffuseMap, gl_TexCoord[1].xy).g;
float blue = texture2D(diffuseMap, gl_TexCoord[2].xy).b;

gl_FragColor = vec4( red, green, blue, 1.0 )*gl_Color;

//gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy);//vec4( red, green, blue, 1.0 );
//gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
}


This is all running in OGRE 1.9.0.

Edit: When setting

vignette = std::max( v.VignetteFactor, (float)0.0 );

then I get the expected result (with a larger vignette). The question remains, though - why negative values?

    3 replies

    Inspiring
    January 14, 2015
    OK, I have sent the engineering team a link to this thread in a bug report.

    There were some similar issues with the vignette that have been recently fixed (not released yet) and it's possible this is fixed as well. I will try to get an update either way. Sorry for the long delay on this.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    ueczzAuthor
    Up and Coming
    January 15, 2015
    No worries - thanks for the reply and bug-report!
    Participant
    January 15, 2015
    Vignette values now do go negative at vertices - this intentional, and it's so that when the value is interpolated, it hits zero at the exact correct place on the screen, even if there isn't a mesh vertex there. Previously, it would only go to zero at a vertex, and sometimes that vertex would be outside the visible area, and you'd see "too far" (potentially to the other eye, causing "bleeding"). Using negative values fixes this problem, but I apologize for not documenting this change well enough.

    To try to illustrate with awesome ASCII art:

    vertex vertex
    -0.5 1.0
    +-------------------+
    ^actual edge of texture, vignette=0.0


    I suspect the problem is the negative value is being converted to an unsigned byte, so -0.37 is getting turned into a byte value of +160, which is interpreted by the GPU as +0.62, but only at the very edges, and that's causing the oddness. It all depends what this line of the code is actually compiled to under the hood:

    manual->colour( v.VignetteFactor, v.VignetteFactor, v.VignetteFactor, v.VignetteFactor );


    There's two possible fixes.

    The quick one is to clamp the VignetteFactor to zero before conversion so it never goes negative. This will work, but it might show the structure of the distortion mesh, and because the zero-crossing isn't in the exact correct place they may still get some tiny "bleeding" (the solution for this is to move the rendertargets apart more, so there's a padding of black pixels, but it's still a bit of a hack).

    A better solution is to change the format used for the vertex so that instead of unsigned bytes, it uses something that can handle signed numbers. Signed bytes would work, though hardware support is spotty. A better alternative is float16. Since there's only two channels of data (Vignette and TimewarpLerp), 2*float16 will fit in the same space as 4*unorm8.
    Tom Forsyth - OculusVR coder