0

Here is my question, i will list them to make it clear:

  1. I am writing a program drawing squares in 2D using instancing.
  2. My camera direction is (0,0,-1), camera up is (0,1,0), camera position is (0,0,3), and the camera position changes when i press some keys.
  3. What I want is that, when I zoom in (the camera moves closer to the square), the square's size(in the screen) won't change. So in my shader:
#version 330 core
layout(location = 0) in vec2 squareVertices;
layout(location = 1) in vec4 xysc; 
out vec4 particlecolor;
uniform mat4 VP; 

void main()
{
    float particleSize = xysc.z;
    float color = xysc.w;
    
    gl_Position = VP* vec4(xysc.x, xysc.y, 2.0, 1.0) + vec4(squareVertices.x*particleSize,squareVertices.y*particleSize,0,0);
    particlecolor = vec4(1.0f * color , 1.0f * (1-color), 0.0f, 0.5f);
}

Please notice that, inorder to keep the squares' size unchanged, what I do is:

1. transform the center of the square first
VP * vec4(xysc.x, xysc.y, 2.0, 1.0) 

2. then compute one of the four corners (x,y,z,1) of the square 
+ vec4(squareVertices.x*particleSize,squareVertices.y*particleSize,0,0);

instead of:

   gl_Position = VP* (vec4(xysc.x, xysc.y, 2.0, 1.0) + vec4(squareVertices.x*particleSize,squareVertices.y*particleSize,0,0));

However when I move the camera closer to z=0 plane. The squares' size grows unexpectedly. Where is the problem? I can provide a demo code if necessary.

YNX
  • 511
  • 6
  • 17

1 Answers1

1

Sounds like you use a perspective projection, and the formula you use in steps 1 and 2 won't work because VP * vec4 will in the general case result in a vec4(x,y,z,w) with the w value != 1, and adding a vec4(a,b,0,0) to that will just get you vec3( (x+a)/w, (y+b)/w, z) after the perspective divide, while you seem to want vec3(x/w + a, y/w +b, z). So the correct approach is to scale a and b by w and add that before the divde: vec4(x+a*w, y+b*w, z, w).

Note that when you move your camera closer to the geometry, the effective w value will approach towards zero, so (x+a)/w will be a greater than x/w + a, resulting in your geometry getting bigger.

derhass
  • 43,833
  • 2
  • 57
  • 78
  • It worked! But i still got one question. I changed the `z` of vertices of the famous demo code: https://learnopengl.com/Getting-started/Hello-Triangle, and the resulting triangle changes. It seems that `z` will affect the triangle vertice on the final output(on screen). However, the tutorial said all points whose `x` or `y` is out of [-1,1] will not be plotted. It's a contradiction. I am a little confused between the `perspective projection` and `camera projection` calculated by similar triangles. Would you please explain for that? – YNX Jun 15 '21 at 15:30
  • What confused me more is that if I changed the vertices in Hello-Triangle to { -0.5f, -0.5f, -1.0f, // left 0.5f, -0.5f, 100.0f, // right 0.0f, 0.5f, 1.0f // top }; the right corner of the triangle even comes to the left half of the screen (however the it didn't go to the upper half) but its `x` is 0.5f. – YNX Jun 15 '21 at 15:38
  • 1
    @YNX the view volume is the cube `[-1,1]` allong all 3 axies in _normalized device coordinates_. If you set the 3 coordinates as you described above, the right vertex will lie outside of the vie volume, and the tirangle will get clipped against the z=1 plane, which should actually result in a trapezoid on the screen. So it is unclear what your issue here is, but if you have an issue, you should create a new querstion and describe it in enough detail. – derhass Jun 15 '21 at 21:07
  • Also: " I am a little confused between the perspective projection and camera projection calculated by similar triangles. " I have no idea what you even talk about here. Perspective projection is a well-know term from computer graphics, but the rest isn't, and again, you should ask a separate question where you actually explain what you're talking about. – derhass Jun 15 '21 at 21:09