[SOLVED]View space to projection space to texture coords?

Hi, I’m checking I have everything down before I get to deep into screen space reflections but I cannot get UV coords from view space position.

I’m using the function nehon wrote in the SSAO filter to get position from depth and texCoord. (This is all a post filter frag shader)

vec3 getPosition(vec2 uv)
{
  //Reconstruction from depth
  float depthv = texture2D(m_DepthTexture,uv).r;
  float depth =  (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));

  //one frustum corner method
  float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, uv.x);
  float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, uv.y);

  return depth* vec3(x, y, m_FrustumCorner.z);
}

My understanding is that this is in view space (camera or eye space or whatever you like :slight_smile: )

I then multiply this by ‘g_ProjectionMatrix’ which I listed as a world parameter in the j3md file. So this takes it from
View space to Clip/Projection space.

Once it’s in projection space, since that’s [-1, 1] (is this wrong?) I multiply by 0.5, then add 0.5 to give the results between [0,1] to use as UV coords. Using this to get the output from the texture

texture2D(m_Texture, coords)

I know I’m misunderstanding something because my results are pretty messy.

Here is the full segment:

vec3 startPos = getPosition(texCoord);//get position using depth
vec4 screenSpaceStartPos = g_ProjectionMatrix * vec4(startPos,1.0);//view to projection space
screenSpaceStartPos.xy /= screenSpaceStartPos.w;

vec2 coords = (vec2(screenSpaceStartPos.x, screenSpaceStartPos.y) * 0.5) + 0.5;//0-1

//gl_FragColor = texture2D(m_Background,texCoord);//works as expected, normal way of doing it
gl_FragColor = texture2D(m_Background,coords);//broken

This is the bit I am confusing I think:

screenSpaceStartPos.xy /= screenSpaceStartPos.w;

I’m not sure if I need to factor in my screen width and height or if this is already done by the projection matrix, or if the [-1,1] is even correct. Could anyone tell me what I am getting wrong?

Ok I found some good reading, and came up with the following which has confused me even more:

vec3 getPosition(vec2 uv)
{
  //Reconstruction from depth
  float depthv = texture2D(m_DepthTexture,uv).r;
  float depth =  (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv* (m_FrustumNearFar.y-m_FrustumNearFar.x));

  //one frustum corner method
  float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, uv.x);
  float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, uv.y);

  return depth* vec3(x, y, m_FrustumCorner.z);
}

void main() 
{	
	vec3 viewSpacePos = getPosition(texCoord);
	vec4 clipSpacePosition = g_ProjectionMatrix * vec4(viewSpacePos,1.0);
	vec3 ndcSpacePos = clipSpacePosition.xyz / clipSpacePosition.w;//normalized device coords
	vec2 windowSpacePos = (ndcSpacePos.xy + 1.0) / 2.0;

	gl_FragColor = texture2D(m_Background, windowSpacePos);
	//gl_FragColor = texture2D(m_Background, texCoord);
}

That is essentially my entire shader. Going from view to clip to normalized device coordinates and then to window space.
(m_Background is the scenes texture)

The two lines at the bottom, one uses the texCoord as provided to the shader, resulting in:

So as expected, but using the coordinates I calculated:

Why can the character be seen, or at least half of it? If the coordinates are wrong I would have thought it’d be totally unrecognizable, and yet the colors are messed up :confused:

1 Like

correct

correct

are you sure m_FrustumNearFar and FrustumCorner are properly set?

protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) 
{
        screenWidth = w;
        screenHeight = h;

(Gap for formatting)

    frustumNearFar = new Vector2f();

    float farY = (vp.getCamera().getFrustumTop() / vp.getCamera().getFrustumNear()) * vp.getCamera().getFrustumFar();
    float farX = farY * ((float) screenWidth / (float) screenHeight);
    frustumCorner = new Vector3f(farX, farY, vp.getCamera().getFrustumFar());
    frustumNearFar.x = vp.getCamera().getFrustumNear();
    frustumNearFar.y = vp.getCamera().getFrustumFar();

(Gap for formatting)

  material.setVector3("FrustumCorner", frustumCorner);
  material.setVector2("FrustumNearFar", frustumNearFar);

It’s a copy pasted from SSAOFilter.java, also printed them to console after setting them just to be double-sure

screen width: 1200
screen height: 900
frustumNearFar.x: 0.1
frustumNearFar.y: 1000.0
frustumCorner: (579.7499, 434.81238, 1000.0)

Also earlier I set the gl_FragColor to each of viewSpacePosition.x and viewSpacePosition.y to check the position was ok I figured it looks right:

edit: for completeness I checked Z aswell, used smoothstep(0,100, viewSpacePos.z) to get visible values, looks as expected

Progress! So I tried to calculated the ProjectionMatrix myself and pass it to the shader. Needless to say I messed something up but I got this:

https://i6.imgpile.com/i/vQ4yR.png

I guess it’s always something obvious/simple, I must have messed up setting up my material definition.

In my j3md after MaterialParameters I have the following:

Technique {
        VertexShader GLSL100:   Common/MatDefs/Post/Post.vert
        FragmentShader GLSL100: Shaders/Effects/ApplySSAO.frag

        WorldParameters {
                    WorldViewProjectionMatrix
			ProjectionMatrix
        }
    }

Then in my .frag I have

uniform mat4 g_ProjectionMatrix;

at the top. Is this all that is required to access this matrix?

If not I will continue trying to send it myself, though with less er, zoom :stuck_out_tongue:

Well, solved. I ended up sending

vp.getCamera().getProjectionMatrix()

into the shader as a uniform and it works as expected.

Only possible causes I can think of: I am on 3.0 perhaps a bug, or I cocked up something with the j3md. Anyway solved.

Ha! that was an important information.
In 3.0 you couldn’t use g_<camera_stuff> in post processes. Well you could but they were not the informations from the scene camera, so basically useless. In 3.1 it changed…