Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
ueczz's avatar
ueczz
Honored Guest
11 years ago

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

  • 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.
  • ueczz's avatar
    ueczz
    Honored Guest
    No worries - thanks for the reply and bug-report!
  • 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.