浏览代码

[PlanarReflection] Use non oblique projection matrix for light culling

/main
Frédéric Vauchelles 7 年前
当前提交
b3b971f1
共有 8 个文件被更改,包括 49 次插入118 次删除
  1. 12
      ScriptableRenderPipeline/Core/CoreRP/CameraUtils.cs
  2. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs
  3. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  4. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  5. 35
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  6. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystemInternal.cs
  7. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/CameraUtils.cs.meta
  8. 84
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/CameraUtils.cs

12
ScriptableRenderPipeline/Core/CoreRP/CameraUtils.cs


{
return camera.projectionMatrix * Matrix4x4.Scale(new Vector3(1, 1, -1));
}
public static Matrix4x4 CalculateProjectionMatrix(Camera camera)
{
if (camera.orthographic)
{
var h = camera.orthographicSize;
var w = camera.orthographicSize * camera.aspect;
return Matrix4x4.Ortho(-w, w, -h, h, camera.nearClipPlane, camera.farClipPlane);
}
else
return Matrix4x4.Perspective(camera.fieldOfView, camera.aspect, camera.nearClipPlane, camera.farClipPlane);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDAdditionalCameraData.cs


[RequireComponent(typeof(Camera))]
public class HDAdditionalCameraData : MonoBehaviour, ISerializationCallbackReceiver
{
public delegate Matrix4x4 NonObliqueProjectionGetter(Camera camera);
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
// We can't rely on Unity for our additional data, we need to version it ourself.
[SerializeField]

bool m_IsDebugRegistered = false;
Camera m_camera;
string m_CameraRegisterName;
// For custom projection matrixes
// Set the proper getter
public NonObliqueProjectionGetter nonObliqueProjectionGetter = CameraUtils.CalculateProjectionMatrix;
public Matrix4x4 GetNonObliqueProjection(Camera camera)
{
return nonObliqueProjectionGetter(camera);
}
void RegisterDebug()
{

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


public Vector4 viewParam;
public PostProcessRenderContext postprocessRenderContext;
// Non oblique projection matrix (RHS)
public Matrix4x4 nonObliqueProjMatrix { get { return m_AdditionalCameraData.GetNonObliqueProjection(camera); } }
public Matrix4x4 viewProjMatrix
{
get { return projMatrix * viewMatrix; }

static Dictionary<Camera, HDCamera> s_Cameras = new Dictionary<Camera, HDCamera>();
static List<Camera> s_Cleanup = new List<Camera>(); // Recycled to reduce GC pressure
HDAdditionalCameraData m_AdditionalCameraData;
public HDCamera(Camera cam)
{
camera = cam;

m_AdditionalCameraData = cam.GetComponent<HDAdditionalCameraData>() ?? ComponentSingleton<HDAdditionalCameraData>.instance;
Reset();
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


renderContext.ExecuteCommandBuffer(cmd);
cmd.Clear();
buildGPULightListsCompleteFence = m_LightLoop.BuildGPULightListsAsyncBegin(camera, renderContext, m_CameraDepthStencilBufferRT, m_CameraStencilBufferCopyRT, startFence, m_SkyManager.IsSkyValid());
buildGPULightListsCompleteFence = m_LightLoop.BuildGPULightListsAsyncBegin(hdCamera, renderContext, m_CameraDepthStencilBufferRT, m_CameraStencilBufferCopyRT, startFence, m_SkyManager.IsSkyValid());
}
using (new ProfilingSample(cmd, "Render shadows", CustomSamplerId.RenderShadows.GetSampler()))

{
using (new ProfilingSample(cmd, "Build Light list", CustomSamplerId.BuildLightList.GetSampler()))
{
m_LightLoop.BuildGPULightLists(camera, cmd, m_CameraDepthStencilBufferRT, m_CameraStencilBufferCopyRT, m_SkyManager.IsSkyValid());
m_LightLoop.BuildGPULightLists(hdCamera, cmd, m_CameraDepthStencilBufferRT, m_CameraStencilBufferCopyRT, m_SkyManager.IsSkyValid());
}
}

35
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


static Matrix4x4 WorldToCamera(Camera camera)
{
return IsRHS(camera.worldToCameraMatrix)
? camera.worldToCameraMatrix
: Matrix4x4.Scale(new Vector3(1, 1, -1)) * camera.worldToCameraMatrix;
}
static Matrix4x4 CameraProjection(Camera camera)
{
return IsRHS(camera.worldToCameraMatrix)
? camera.projectionMatrix
: camera.projectionMatrix * Matrix4x4.Scale(new Vector3(1, 1, -1));
// camera.worldToCameraMatrix is RHS and Unity's transforms are LHS
// We need to flip it to work with transforms
return Matrix4x4.Scale(new Vector3(1, 1, -1)) * camera.worldToCameraMatrix;
static bool IsRHS(Matrix4x4 mat)
// For light culling system, we need non oblique projection matrices
static Matrix4x4 CameraProjectionNonObliqueLHS(HDCamera camera)
return Vector3.Dot(Vector3.Cross(mat.GetColumn(0), mat.GetColumn(1)), mat.GetColumn(2)) > 0;
// camera.projectionMatrix expect RHS data and Unity's transforms are LHS
// We need to flip it to work with transforms
return camera.nonObliqueProjMatrix * Matrix4x4.Scale(new Vector3(1, 1, -1));
}
public Vector3 GetLightColor(VisibleLight light)

cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
}
public void BuildGPULightListsCommon(Camera camera, CommandBuffer cmd, RenderTargetIdentifier cameraDepthBufferRT, RenderTargetIdentifier stencilTextureRT, bool skyEnabled)
public void BuildGPULightListsCommon(HDCamera hdCamera, CommandBuffer cmd, RenderTargetIdentifier cameraDepthBufferRT, RenderTargetIdentifier stencilTextureRT, bool skyEnabled)
var camera = hdCamera.camera;
cmd.BeginSample("Build Light List");
var w = camera.pixelWidth;

var numBigTilesY = (h + 63) / 64;
// camera to screen matrix (and it's inverse)
var proj = CameraProjection(camera);
var proj = CameraProjectionNonObliqueLHS(hdCamera);
var temp = new Matrix4x4();
temp.SetRow(0, new Vector4(0.5f * w, 0.0f, 0.0f, 0.5f * w));
temp.SetRow(1, new Vector4(0.0f, 0.5f * h, 0.0f, 0.5f * h));

cmd.EndSample("Build Light List");
}
public void BuildGPULightLists(Camera camera, CommandBuffer cmd, RenderTargetIdentifier cameraDepthBufferRT, RenderTargetIdentifier stencilTextureRT, bool skyEnabled)
public void BuildGPULightLists(HDCamera hdCamera, CommandBuffer cmd, RenderTargetIdentifier cameraDepthBufferRT, RenderTargetIdentifier stencilTextureRT, bool skyEnabled)
BuildGPULightListsCommon(camera, cmd, cameraDepthBufferRT, stencilTextureRT, skyEnabled);
PushGlobalParams(camera, cmd);
BuildGPULightListsCommon(hdCamera, cmd, cameraDepthBufferRT, stencilTextureRT, skyEnabled);
PushGlobalParams(hdCamera.camera, cmd);
public GPUFence BuildGPULightListsAsyncBegin(Camera camera, ScriptableRenderContext renderContext, RenderTargetIdentifier cameraDepthBufferRT, RenderTargetIdentifier stencilTextureRT, GPUFence startFence, bool skyEnabled)
public GPUFence BuildGPULightListsAsyncBegin(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier cameraDepthBufferRT, RenderTargetIdentifier stencilTextureRT, GPUFence startFence, bool skyEnabled)
BuildGPULightListsCommon(camera, cmd, cameraDepthBufferRT, stencilTextureRT, skyEnabled);
BuildGPULightListsCommon(hdCamera, cmd, cameraDepthBufferRT, stencilTextureRT, skyEnabled);
GPUFence completeFence = cmd.CreateGPUFence();
renderContext.ExecuteCommandBufferAsync(cmd, ComputeQueueType.Background);
CommandBufferPool.Release(cmd);

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystemInternal.cs


captureRotation = Quaternion.LookRotation((Vector3)probe.influenceToWorld.GetColumn(3) - capturePosition, probe.transform.up);
projection = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane);
worldToCamera = CameraUtils.CalculateWorldToCameraMatrix(capturePosition, captureRotation);
worldToCamera = CameraUtils.CalculateWorldToCameraMatrixRHS(capturePosition, captureRotation);
}
static void CalculateMirroredCaptureCameraProperties(PlanarReflectionProbe probe, Camera viewerCamera, out float nearClipPlane, out float farClipPlane, out float aspect, out float fov, out CameraClearFlags clearFlags, out Color backgroundColor, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation)

clearFlags = viewerCamera.clearFlags;
backgroundColor = viewerCamera.backgroundColor;
var worldToCapture = CameraUtils.CalculateWorldToCameraMatrix(viewerCamera.transform);
var worldToCapture = CameraUtils.CalculateWorldToCameraMatrixRHS(viewerCamera.transform);
var reflectionMatrix = CameraUtils.CalculateReflectionMatrix(probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
worldToCamera = worldToCapture * reflectionMatrix;

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/CameraUtils.cs.meta


fileFormatVersion: 2
guid: 2c8e36e6456734643b4b2bde3c6c4c25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

84
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/CameraUtils.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public static class CameraUtils
{
public static Vector4 Plane(Vector3 position, Vector3 normal)
{
var n = normal;
var d = -Vector3.Dot(n, position);
var plane = new Vector4(n.x, n.y, n.z, d);
return plane;
}
public static Vector4 CameraSpacePlane(Matrix4x4 worldToCamera, Vector3 pos, Vector3 normal, float sideSign = 1, float clipPlaneOffset = 0)
{
var offsetPos = pos + normal * clipPlaneOffset;
var cpos = worldToCamera.MultiplyPoint(offsetPos);
var cnormal = worldToCamera.MultiplyVector(normal).normalized * sideSign;
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
}
public static Matrix4x4 CalculateWorldToCameraMatrix(Vector3 position, Quaternion rotation)
{
return Matrix4x4.Scale(new Vector3(1, 1, -1)) * Matrix4x4.TRS(position, rotation, Vector3.one).inverse;
}
public static Matrix4x4 CalculateWorldToCameraMatrix(Transform transform)
{
return Matrix4x4.Scale(new Vector3(1, 1, -1)) * transform.localToWorldMatrix.inverse;
}
public static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 sourceProjection, Vector4 clipPlane)
{
var projection = sourceProjection;
var inversion = sourceProjection.inverse;
var cps = new Vector4(
(clipPlane.x > 0 ? 1 : 0) - (clipPlane.x < 0 ? 1 : 0),
(clipPlane.y > 0 ? 1 : 0) - (clipPlane.y < 0 ? 1 : 0),
1.0f,
1.0f);
var q = inversion * cps;
var c = clipPlane * (2.0f / Vector4.Dot(clipPlane, q));
projection[2] = c.x - projection[3];
projection[6] = c.y - projection[7];
projection[10] = c.z - projection[11];
projection[14] = c.w - projection[15];
return projection;
}
public static Matrix4x4 CalculateReflectionMatrix(Vector3 position, Vector3 normal)
{
return CalculateReflectionMatrix(Plane(position, normal));
}
public static Matrix4x4 CalculateReflectionMatrix(Vector4 plane)
{
var reflectionMat = new Matrix4x4();
reflectionMat.m00 = (1F - 2F * plane[0] * plane[0]);
reflectionMat.m01 = (-2F * plane[0] * plane[1]);
reflectionMat.m02 = (-2F * plane[0] * plane[2]);
reflectionMat.m03 = (-2F * plane[3] * plane[0]);
reflectionMat.m10 = (-2F * plane[1] * plane[0]);
reflectionMat.m11 = (1F - 2F * plane[1] * plane[1]);
reflectionMat.m12 = (-2F * plane[1] * plane[2]);
reflectionMat.m13 = (-2F * plane[3] * plane[1]);
reflectionMat.m20 = (-2F * plane[2] * plane[0]);
reflectionMat.m21 = (-2F * plane[2] * plane[1]);
reflectionMat.m22 = (1F - 2F * plane[2] * plane[2]);
reflectionMat.m23 = (-2F * plane[3] * plane[2]);
reflectionMat.m30 = 0F;
reflectionMat.m31 = 0F;
reflectionMat.m32 = 0F;
reflectionMat.m33 = 1F;
return reflectionMat;
}
}
}
正在加载...
取消
保存