cameraInfo property

ByteData get cameraInfo

A packed PostCameraInfo std140 uniform block for reconstructing world positions from sceneDepthLinear, for any camera projection. Layout:

  • vec4 projection: xy the view-space extent per unit of NDC (the half-fov tangents for perspective, the half width and height for orthographic), z near, w far.
  • vec4 camera_right, vec4 camera_up, vec4 camera_forward: the camera basis in xyz, matching the depth prepass's view space (the eye at the origin looking down +forward). camera_right.w and camera_up.w are the NDC position of the view axis (zero unless off-center), and camera_forward.w is 1 for an orthographic camera and 0 for perspective.
  • vec4 camera_position: the eye in xyz.

#include <view_projection.glsl> and reconstruct with ViewPositionFromUv(uv, depth, projection.xy, offset), where offset is vec3(camera_right.w, camera_up.w, camera_forward.w), then world = position + right * view.x + up * view.y + forward * view.z. Bind it under a PostCameraInfo block via applyShader's uniforms.

Implementation

ByteData get cameraInfo {
  final f = Float32List(20); // 5 vec4
  if (dimensions.height > 0) {
    final projection = ProjectionParams.of(camera.projection, dimensions);
    f[0] = projection.scaleX;
    f[1] = projection.scaleY;
    f[2] = projection.near;
    f[3] = projection.far;
    f[7] = projection.offsetX;
    f[11] = projection.offsetY;
    f[15] = projection.orthographicFlag;
  }
  // The same view basis the depth prepass encodes against (eye at origin
  // looking down +forward), so a reconstructed view point maps to world.
  final forward = camera.forward.normalized();
  final right = camera.up.cross(forward)..normalize();
  final up = forward.cross(right)..normalize();
  f[4] = right.x;
  f[5] = right.y;
  f[6] = right.z;
  f[8] = up.x;
  f[9] = up.y;
  f[10] = up.z;
  f[12] = forward.x;
  f[13] = forward.y;
  f[14] = forward.z;
  f[16] = camera.position.x;
  f[17] = camera.position.y;
  f[18] = camera.position.z;
  return ByteData.sublistView(f);
}