Skip to content

Commit

Permalink
[Port] [2022.3] Fix HDRP sky rendering when Camera Relative Rendering…
Browse files Browse the repository at this point in the history
… is disabled

This PR fixes HDRP sky rendering when Camera Relative Rendering is disabled.

`ComputePixelCoordToWorldSpaceViewDirectionMatrix()` in `HDCamera.cs` contains:

```
...
if (useGenericMatrix)
{
    var viewSpaceRasterTransform = new Matrix4x4(
        new Vector4(2.0f * resolution.z, 0.0f, 0.0f, -1.0f),
        new Vector4(0.0f, -2.0f * resolution.w, 0.0f, 1.0f),
        new Vector4(0.0f, 0.0f, 1.0f, 0.0f),
        new Vector4(0.0f, 0.0f, 0.0f, 1.0f));

    var transformT = viewConstants.invViewProjMatrix.transpose * Matrix4x4.Scale(new Vector3(-1.0f, -1.0f, -1.0f));
    return viewSpaceRasterTransform * transformT;
}
...
```

Here the view matrix that was used to build `viewConstants.invViewProjMatrix` has translation component if Camera Relative Rendering is disabled when it shouldn't.

![scene_view](https://github.cds.internal.unity3d.com/unity/unity/assets/7006/95047d07-52f3-4d19-8698-0120ad86987f)
Scene View

![game_view_wrong](https://github.cds.internal.unity3d.com/unity/unity/assets/7006/2cb0b898-ddb2-4819-ae58-7900ce0c4221)
Game View, bugged

![game_view_fixed](https://github.cds.internal.unity3d.com/unity/unity/assets/7006/0a9b4699-9737-426f-a605-fd51a5ae72eb)
Game View, fixed
  • Loading branch information
svc-reach-platform-support authored and Evergreen committed Jan 20, 2025
1 parent a59444a commit 9d4a304
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1134,12 +1134,12 @@ internal void GetPixelCoordToViewDirWS(Vector4 resolution, float aspect, ref Mat
{
for (int viewIndex = 0; viewIndex < viewCount; ++viewIndex)
{
transforms[viewIndex] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(m_XRViewConstants[viewIndex], resolution, aspect);
transforms[viewIndex] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(m_XRViewConstants[viewIndex], resolution, aspect, ShaderConfig.s_CameraRelativeRendering);
}
}
else
{
transforms[0] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(mainViewConstants, resolution, aspect);
transforms[0] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(mainViewConstants, resolution, aspect, ShaderConfig.s_CameraRelativeRendering);
}
}

Expand Down Expand Up @@ -1720,7 +1720,7 @@ void UpdateViewConstants(ref ViewConstants viewConstants, Matrix4x4 projMatrix,
viewConstants.viewProjectionNoCameraTrans = gpuVPNoTrans;

var gpuProjAspect = HDUtils.ProjectionMatrixAspect(gpuProj);
viewConstants.pixelCoordToViewDirWS = ComputePixelCoordToWorldSpaceViewDirectionMatrix(viewConstants, screenSize, gpuProjAspect);
viewConstants.pixelCoordToViewDirWS = ComputePixelCoordToWorldSpaceViewDirectionMatrix(viewConstants, screenSize, gpuProjAspect, ShaderConfig.s_CameraRelativeRendering);

if (updatePreviousFrameConstants)
{
Expand Down Expand Up @@ -1957,8 +1957,9 @@ internal Matrix4x4 GetJitteredProjectionMatrix(Matrix4x4 origProj)
///
/// It is different from the aspect ratio of <paramref name="resolution"/> for anamorphic projections.
/// </param>
/// <param name="cameraRelativeRendering">If non-zero, then assume Camera Relative Rendering is enabled.</param>
/// <returns></returns>
Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(ViewConstants viewConstants, Vector4 resolution, float aspect = -1)
internal Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(ViewConstants viewConstants, Vector4 resolution, float aspect = -1, int cameraRelativeRendering = 1)
{
// In XR mode, or if explicitely required, use a more generic matrix to account for asymmetry in the projection
var useGenericMatrix = xr.enabled || frameSettings.IsEnabled(FrameSettingsField.AsymmetricProjection);
Expand All @@ -1977,7 +1978,20 @@ Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(ViewConstants viewCon
new Vector4(0.0f, 0.0f, 1.0f, 0.0f),
new Vector4(0.0f, 0.0f, 0.0f, 1.0f));

var transformT = viewConstants.invViewProjMatrix.transpose * Matrix4x4.Scale(new Vector3(-1.0f, -1.0f, -1.0f));
Matrix4x4 transformT;
if (cameraRelativeRendering == 0)
{
// In case we are not camera relative, the view matrix used to calculate viewConstants.invViewProjMatrix
// contains translation component, so we need to remove it.
var viewNoTrans = viewConstants.viewMatrix;
viewNoTrans.SetColumn(3, new Vector4(0, 0, 0, 1));
var invViewProj = (viewConstants.projMatrix * viewNoTrans).inverse;
transformT = invViewProj.transpose * Matrix4x4.Scale(new Vector3(-1.0f, -1.0f, -1.0f));
}
else
{
transformT = viewConstants.invViewProjMatrix.transpose * Matrix4x4.Scale(new Vector3(-1.0f, -1.0f, -1.0f));
}
return viewSpaceRasterTransform * transformT;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using NUnit.Framework;
using UnityEngine.Experimental.Rendering;

namespace UnityEngine.Rendering.HighDefinition.Tests
{
class HDCameraTests
{
[SetUp]
public void Setup()
{
if (GraphicsSettings.currentRenderPipeline is not HDRenderPipelineAsset)
Assert.Ignore("This is an HDRP Tests, and the current pipeline is not HDRP.");
}

[Test]
public void TestCameraRelativeRendering()
{
GameObject cameraGameObject = new GameObject("Camera");
var camera = cameraGameObject.AddComponent<Camera>();
var hdCamera = new HDCamera(camera);

var positionSettings = new CameraPositionSettings();
positionSettings.position = new Vector3(100.0f, 300.0f, 500.0f);
positionSettings.rotation = Quaternion.Euler(62.34f, 185.53f, 323.563f);

var resolution = new Vector4(1920.0f, 1080.0f, 1.0f / 1920.0f, 1.0f / 1080.0f);
float aspect = resolution.x * resolution.w;

camera.worldToCameraMatrix = positionSettings.ComputeWorldToCameraMatrix();
camera.projectionMatrix = Matrix4x4.Perspective(75.0f, aspect, 0.1f, 1000.0f);

var view = camera.worldToCameraMatrix;
var proj = camera.projectionMatrix;

// Minimal setup for ComputePixelCoordToWorldSpaceViewDirectionMatrix().
var viewConstants = new HDCamera.ViewConstants();
viewConstants.viewMatrix = view;
viewConstants.projMatrix = proj;
viewConstants.invViewProjMatrix = (proj * view).inverse;

// hdCamera.xr must be initialized for ComputePixelCoordToWorldSpaceViewDirectionMatrix().
var hdrp = HDRenderPipeline.currentPipeline;
hdCamera.Update(hdCamera.frameSettings, hdrp, XRSystem.emptyPass, allocateHistoryBuffers: false);

var matrix0 = hdCamera.ComputePixelCoordToWorldSpaceViewDirectionMatrix(viewConstants, resolution, aspect, 0);
var matrix1 = hdCamera.ComputePixelCoordToWorldSpaceViewDirectionMatrix(viewConstants, resolution, aspect, 1);

// These matrices convert a clip space position to a world space view direction,
// therefore should be same regardless of Camera Relative Rendering.
Assert.AreEqual(matrix0, matrix1, $"{matrix0} != {matrix1}");

CoreUtils.Destroy(cameraGameObject);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9d4a304

Please sign in to comment.