On the heels of [Content removed] I think I have the custom projection matrix worked out such that I get the same view of the world as my original implementation. In my original implementation, I set
CaptureComponent->FOVAngle = HorizontalFOV;
(where HorizontalFOV is calculated from a focal length and image size above), and now I use
CaptureComponent->bUseCustomProjectionMatrix = true;
CaptureComponent->CustomProjectionMatrix = ProjectionMatrix(
FVector2d(focalLengthX, focalLengthY),
FVector2d(opticalCenterX, opticalCenterY),
FVector2d(float(ImageSizeX), float(ImageSizeY)),
CameraParameters.skew);
With this new implementation, the projection matrix defines the frustum (and thereby the field of view) that gets rendered. However, the new implementation also seems to have an impact on the lighting and coloration of the resulting image (attached as image.PNG).
The image on the left uses my original implementation (setting the horizontal field of view), and the one on the right uses the new projection matrix. That the rendered objects are in the same locations indicates the projection is done correctly, but I would not expect the color/shadow differences with this kind of a change. Specifically, in the new projection matrix implementation,
- The barrier has a subdued red color
- There’s much more road “speckle”
- The region under the barrier does not have any shadow
It’s tough for me to determine which of these is “better”, but I tend to think the one on the right is more realistic. Is it expected that using a custom projection matrix would change the coloration and details of the image this much?
For reference, here’s the code to generate that matrix:
FMatrix ProjectionMatrix(const FVector2d &FocalLengthPixels,
const FVector2d &PrincipalPointPixels,
const FVector2d &ImageSizePixels, const float Skew) {
constexpr float nearClipPlane = 10.0f;
constexpr float farClipPlane = 100000.0f;
const FVector2d Scale = nearClipPlane * 2.0f * FocalLengthPixels / ImageSizePixels;
const FVector2d Offset = FVector2d(1.0f, -1.0f) * (2.0f * PrincipalPointPixels / ImageSizePixels - 1.0);
const float Shear = 2.0f * Skew / ImageSizePixels.X;
return FMatrix(
FPlane(Scale.X, Shear, Offset.X, 0.0f),
FPlane(0.0f, Scale.Y, Offset.Y, 0.0f),
FPlane(0.0f, 0.0f, 0.0f, nearClipPlane),
FPlane(0.0f, 0.0f, 1.0f, 0.0f));
}
The only way I can imagine this changing the image’s color is if the near and far clip planes somehow tell the rendering pipeline to use alternative settings (perhaps for more or less detail?).
[Attachment Removed]