浏览代码

[PlanarReflection] small refactoring for frustrum calculation

/main
Frédéric Vauchelles 7 年前
当前提交
320917fd
共有 7 个文件被更改,包括 104 次插入142 次删除
  1. 20
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/CameraUtils.cs
  2. 34
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/PlanarReflectionProbeUI.Handles.cs
  3. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  4. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/PlanarReflectionProbe.cs
  5. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs
  6. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystem.cs
  7. 162
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystemInternal.cs

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


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;

projection[14] = c.w - projection[15];
return projection;
}
public static Matrix4x4 CalculateReflectionMatrix(Vector3 position, Vector3 normal)
{
return CalculateReflectionMatrix(Plane(position, normal));
}
public static Matrix4x4 CalculateWorldToCameraMatrixMirror(Matrix4x4 worldToCamera, Matrix4x4 reflection)
{
return worldToCamera * reflection * Matrix4x4.Scale(new Vector3(-1, 1, 1));
}
public static Matrix4x4 CalculateReflectionMatrix(Vector4 plane)

34
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/PlanarReflectionProbeUI.Handles.cs


var captureToWorld = d.GetCaptureToWorld(viewerCamera);
var capturePosition = captureToWorld.GetColumn(3);
var captureRotation = captureToWorld.rotation;
var c = Gizmos.color;
var fov = ReflectionSystem.GetCaptureCameraFOVFor(d, viewerCamera);
var clipToWorld = CameraEditorUtils.GetCameraClipToWorld(
capturePosition, captureRotation,
d.captureNearPlane, d.captureFarPlane,
fov, 1);
//var fov = ReflectionSystem.GetCaptureCameraFOVFor(d, viewerCamera);
//var clipToWorld = CameraEditorUtils.GetCameraClipToWorld(
// capturePosition, captureRotation,
// d.captureNearPlane, d.captureFarPlane,
// fov, 1);
var near = new Vector3[4];
var far = new Vector3[4];
CameraEditorUtils.GetFrustrumPlaneAt(clipToWorld, capturePosition, d.captureFarPlane, far);
CameraEditorUtils.GetFrustrumPlaneAt(clipToWorld, capturePosition, d.captureNearPlane, near);
//var near = new Vector3[4];
//var far = new Vector3[4];
//CameraEditorUtils.GetFrustrumPlaneAt(clipToWorld, capturePosition, d.captureFarPlane, far);
//CameraEditorUtils.GetFrustrumPlaneAt(clipToWorld, capturePosition, d.captureNearPlane, near);
var c = Gizmos.color;
Gizmos.color = k_GizmoCamera;
for (var i = 0; i < 4; ++i)
{
Gizmos.DrawLine(near[i], near[(i + 1) % 4]);
Gizmos.DrawLine(far[i], far[(i + 1) % 4]);
Gizmos.DrawLine(near[i], far[i]);
}
//Gizmos.color = k_GizmoCamera;
//for (var i = 0; i < 4; ++i)
//{
// Gizmos.DrawLine(near[i], near[(i + 1) % 4]);
// Gizmos.DrawLine(far[i], far[(i + 1) % 4]);
// Gizmos.DrawLine(near[i], far[i]);
//}
Gizmos.DrawSphere(capturePosition, HandleUtility.GetHandleSize(capturePosition) * 0.2f);
Gizmos.color = c;

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


if (probe.mode == ReflectionProbeMode.Realtime && camera.cameraType == CameraType.Reflection)
return false;
var captureToWorld = probe.GetCaptureToWorld(camera);
// 31 bits index, 1 bit cache type
var envIndex = -1;
switch (probe.texture.dimension)

envIndex = envIndex << 1 | (int)EnvCacheType.Texture2D;
m_Env2DCapturePositionWS.Add(captureToWorld.GetColumn(3));
m_Env2DCaptureVP.Add(probe.GetCaptureProjection(camera) * captureToWorld);
m_Env2DCapturePositionWS.Add(Vector3.zero);
m_Env2DCaptureVP.Add(Matrix4x4.identity);
break;
case TextureDimension.Cube:
envIndex = m_ReflectionProbeCache.FetchSlice(cmd, probe.texture);

envLightData.right = influenceToWorld.GetColumn(0).normalized;
envLightData.up = influenceToWorld.GetColumn(1).normalized;
envLightData.forward = influenceToWorld.GetColumn(2).normalized;
envLightData.capturePositionWS = captureToWorld.GetColumn(3);
envLightData.capturePositionWS = Vector3.zero; //captureToWorld.GetColumn(3);
envLightData.positionWS = influenceToWorld.GetColumn(3);
envLightData.envIndex = envIndex;

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/PlanarReflectionProbe.cs


}
}
public Matrix4x4 GetCaptureViewProj(Camera viewerCamera)
{
return GetCaptureProjection(viewerCamera) * GetCaptureToWorld(viewerCamera);
}
public Matrix4x4 GetCaptureProjection(Camera viewerCamera)
{
var fov = ReflectionSystem.GetCaptureCameraFOVFor(this, viewerCamera);
var proj = Matrix4x4.Perspective(fov, 1, captureNearPlane, captureFarPlane);
return proj;
}
public Matrix4x4 GetCaptureToWorld(Camera viewerCamera)
{
if (refreshMode == ReflectionProbeRefreshMode.EveryFrame

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs


public abstract Matrix4x4 proxyToWorld { get; }
public abstract Vector3 proxyExtents { get; }
public abstract bool infiniteProjection { get; }
public abstract Matrix4x4 GetCaptureToWorld(Camera viewCamera);
public abstract Matrix4x4 GetCaptureProjection(Camera viewCamera);
}
class VisibleReflectionProbeWrapper : ProbeWrapper

public override Vector3 proxyExtents { get { return influenceExtents; } }
public override bool infiniteProjection { get { return probe.boxProjection == 0; } }
public override Matrix4x4 proxyToWorld { get { return influenceToWorld; } }
public override Matrix4x4 GetCaptureToWorld(Camera viewCamera) { return probe.localToWorld; }
public override Matrix4x4 GetCaptureProjection(Camera viewCamera) { return Matrix4x4.identity; }
}
class PlanarReflectionProbeWrapper : ProbeWrapper

public override ReflectionProbeMode mode { get { return probe.mode; } }
public override Matrix4x4 proxyToWorld { get { return probe.proxyToWorld; } }
public override Matrix4x4 GetCaptureToWorld(Camera viewCamera) { return probe.GetCaptureToWorld(viewCamera); }
public override Matrix4x4 GetCaptureProjection(Camera viewCamera) { return probe.GetCaptureProjection(viewCamera); }
}
}

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystem.cs


s_Instance.Render(probe, target);
}
public static float GetCaptureCameraFOVFor(PlanarReflectionProbe probe, Camera viewerCamera)
{
return s_Instance.GetCaptureCameraFOVFor(probe, viewerCamera);
}
public static void PrepareCull(Camera camera, ReflectionProbeCullResults results)
{
s_Instance.PrepareCull(camera, results);

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


return rt;
}
public float GetCaptureCameraFOVFor(PlanarReflectionProbe probe, Camera viewerCamera)
{
switch (probe.influenceVolume.shapeType)
{
case ShapeType.Box:
{
var captureToWorld = probe.GetCaptureToWorld(viewerCamera);
var influenceToWorld = Matrix4x4.TRS(probe.transform.TransformPoint(probe.influenceVolume.boxBaseOffset), probe.transform.rotation, Vector3.one);
var influenceToCapture = captureToWorld.inverse * influenceToWorld;
var min = influenceToCapture.MultiplyPoint(-probe.influenceVolume.boxBaseSize * 0.5f);
var max = influenceToCapture.MultiplyPoint(probe.influenceVolume.boxBaseSize * 0.5f);
var minAngle = Mathf.Atan2(Mathf.Sqrt(min.x * min.x + min.y * min.y), min.z) * Mathf.Rad2Deg;
var maxAngle = Mathf.Atan2(Mathf.Sqrt(max.x * max.x + max.y * max.y), max.z) * Mathf.Rad2Deg;
return Mathf.Max(minAngle, maxAngle) * 2;
}
default:
throw new NotImplementedException();
}
}
//public float GetCaptureCameraFOVFor(PlanarReflectionProbe probe, Camera viewerCamera)
//{
// switch (probe.influenceVolume.shapeType)
// {
// case ShapeType.Box:
// {
// var captureToWorld = probe.GetCaptureToWorld(viewerCamera);
// var influenceToWorld = Matrix4x4.TRS(probe.transform.TransformPoint(probe.influenceVolume.boxBaseOffset), probe.transform.rotation, Vector3.one);
// var influenceToCapture = captureToWorld.inverse * influenceToWorld;
// var min = influenceToCapture.MultiplyPoint(-probe.influenceVolume.boxBaseSize * 0.5f);
// var max = influenceToCapture.MultiplyPoint(probe.influenceVolume.boxBaseSize * 0.5f);
// var minAngle = Mathf.Atan2(Mathf.Sqrt(min.x * min.x + min.y * min.y), min.z) * Mathf.Rad2Deg;
// var maxAngle = Mathf.Atan2(Mathf.Sqrt(max.x * max.x + max.y * max.y), max.z) * Mathf.Rad2Deg;
// return Mathf.Max(minAngle, maxAngle) * 2;
// }
// default:
// throw new NotImplementedException();
// }
//}
bool IsRealtimeTextureValid(RenderTexture renderTexture, HDCamera hdCamera)
{

void SetupCameraForRender(Camera camera, PlanarReflectionProbe probe, Camera viewerCamera = null)
{
var ctr = camera.transform;
var captureToWorld = probe.GetCaptureToWorld(viewerCamera);
ctr.position = captureToWorld.GetColumn(3);
ctr.rotation = captureToWorld.rotation;
camera.ResetProjectionMatrix();
camera.ResetWorldToCameraMatrix();
float nearClipPlane, farClipPlane, aspect, fov;
Color backgroundColor;
CameraClearFlags clearFlags;
Vector3 capturePosition;
Quaternion captureRotation;
Matrix4x4 worldToCamera, projection;
if (viewerCamera == null)
if (viewerCamera != null)
camera.fieldOfView = GetCaptureCameraFOVFor(probe, viewerCamera);
camera.aspect = 1;
camera.nearClipPlane = probe.captureNearPlane;
camera.farClipPlane = probe.captureFarPlane;
}
else
{
camera.farClipPlane = viewerCamera.farClipPlane;
camera.nearClipPlane = viewerCamera.nearClipPlane;
camera.orthographic = viewerCamera.orthographic;
camera.fieldOfView = viewerCamera.fieldOfView;
camera.aspect = viewerCamera.aspect;
camera.orthographicSize = viewerCamera.orthographicSize;
camera.clearFlags = viewerCamera.clearFlags;
camera.backgroundColor = viewerCamera.backgroundColor;
nearClipPlane = viewerCamera.nearClipPlane;
farClipPlane = viewerCamera.farClipPlane;
aspect = viewerCamera.aspect;
fov = viewerCamera.fieldOfView;
clearFlags = viewerCamera.clearFlags;
backgroundColor = viewerCamera.backgroundColor;
var planeNormal = probe.captureMirrorPlaneNormal;
var planePosition = probe.captureMirrorPlanePosition;
var sourceProj = viewerCamera.projectionMatrix;
var worldToCapture = CameraUtils.CalculateWorldToCameraMatrix(viewerCamera.transform);
var reflectionMatrix = CameraUtils.CalculateReflectionMatrix(probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
worldToCamera = CameraUtils.CalculateWorldToCameraMatrixMirror(worldToCapture, reflectionMatrix);
var planeWS = CameraUtils.Plane(planePosition, planeNormal);
var reflectionMatrix = CameraUtils.CalculateReflectionMatrix(planeWS);
var worldToCameraMatrix = (viewerCamera.worldToCameraMatrix * reflectionMatrix) * Matrix4x4.Scale(new Vector3(-1, 1, 1));
var clipPlane = CameraUtils.CameraSpacePlane(camera.worldToCameraMatrix, planePosition, planeNormal);
var proj = CameraUtils.CalculateObliqueMatrix(sourceProj, clipPlane);
var clipPlane = CameraUtils.CameraSpacePlane(worldToCamera, probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
var sourceProj = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane);
projection = CameraUtils.CalculateObliqueMatrix(sourceProj, clipPlane);
var newPos = reflectionMatrix.MultiplyPoint(viewerCamera.transform.position);
camera.transform.position = newPos;
capturePosition = reflectionMatrix.MultiplyPoint(viewerCamera.transform.position);
camera.transform.rotation = Quaternion.LookRotation(forward, up);
camera.projectionMatrix = proj;
camera.worldToCameraMatrix = worldToCameraMatrix;
//camera.fieldOfView = GetCaptureCameraFOVFor(probe, viewerCamera);
//camera.aspect = 1;
//camera.nearClipPlane = probe.captureNearPlane;
//camera.farClipPlane = probe.captureFarPlane;
captureRotation = Quaternion.LookRotation(forward, up);
}
else
{
nearClipPlane = probe.captureNearPlane;
farClipPlane = probe.captureFarPlane;
aspect = 1f;
fov = 90f;
clearFlags = CameraClearFlags.Nothing;
backgroundColor = Color.white;
capturePosition = probe.transform.TransformPoint(probe.captureLocalPosition);
captureRotation = Quaternion.LookRotation((Vector3)probe.influenceToWorld.GetColumn(3) - capturePosition, probe.transform.up);
projection = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane);
worldToCamera = CameraUtils.CalculateWorldToCameraMatrix(capturePosition, captureRotation);
}
// Given position/normal of the plane, calculates plane in camera space.
static Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign, float clipPlaneOffset)
{
Vector3 offsetPos = pos + normal * clipPlaneOffset;
Matrix4x4 m = cam.worldToCameraMatrix;
Vector3 cpos = m.MultiplyPoint(offsetPos);
Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign;
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
}
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;
camera.farClipPlane = farClipPlane;
camera.nearClipPlane = nearClipPlane;
camera.fieldOfView = fov;
camera.aspect = aspect;
camera.clearFlags = clearFlags;
camera.backgroundColor = backgroundColor;
camera.projectionMatrix = projection;
camera.worldToCameraMatrix = worldToCamera;
return reflectionMat;
var ctr = camera.transform;
ctr.position = capturePosition;
ctr.rotation = captureRotation;
}
static HDCamera GetRenderHDCamera(PlanarReflectionProbe probe)

正在加载...
取消
保存