3

I want to show some fog / aerial view in my application. But I only want to use the x,y world distance from camera to the model to determine the appearance.

I already managed to get the signed z-distance from camera to the models with this calculation.

VTM depth

The red objects have positive z distance to camera, the blue ones are negative in contrast to this implementation, where all values seem positive.

Vertex shader:

uniform mat4 u_mvp;   // Model-View-Projection-Matrix
uniform mat4 u_mv;    // Model-View-Matrix
uniform vec4 u_color; // Object color
attribute vec4 a_pos; // Vertex position
varying vec4 color;   // Out color

// Fog
const float density = 0.007;
const float gradient = 1.5;

void main() {
    gl_Position = u_mvp * a_pos;

    // Fog
    float distance = -(u_mv * a_pos).z; // Direct distance from camera

    // 4000 is some invented constant to bring distance to ~[-1,1].
    float visibility = clamp((distance / 4000.0), 0.0, 1.0);

    color = mix(vec4(1.0, 0.0, 0.0, 1.0), u_color, visibility);

    if(distance < 0){
        color = vec4(0.0, 0.0, 1.0, 1.0);
    }
}

Fragment shader:

varying vec4 color;

void main() {
    gl_FragColor = color;
}
  • Why there can be a negative z-value? Or is it common?
  • How can I calculate the x,y world distance to camera?
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
User Rebo
  • 3,056
  • 25
  • 30
  • 1
    Are you sure that `u_mv` is the model view matrix and not the model view projection matrix again? – Rabbid76 Apr 24 '19 at 14:19
  • Wasn't sure either, if `u_mv` matrix tracks the right values, but it definitely differs from the others. May forgot a translation here (kind of hard to debug the work of others). – User Rebo Apr 24 '19 at 20:20

1 Answers1

2

If you want to get the distance to the camera, in the range [-1, 1], then you can use the clips pace coordinated. The clipspace coordinate can be transformed to a normalized device coordinate by Perspective divide. The normalized device coordinates (x, y and z) are in range [-1, 1] and can be transformed to the range [0, 1] with ease:

gl_Position = u_mvp * a_pos;                 // clip space

vec3 ndc = gl_Position.xyz / gl_Position.w;  // NDC in [-1, 1] (by perspective divide)

float depth = ndc.z * 0.5 + 0.5;             // depth in [0, 1]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174