浏览代码

[PlanarReflection] (wip) simple reflection

/main
Frédéric Vauchelles 7 年前
当前提交
0f4291cb
共有 10 个文件被更改,包括 155 次插入132 次删除
  1. 2
      ScriptableRenderPipeline/Core/CoreRP/Editor/CameraEditorUtils.cs
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/CameraUtils.cs
  3. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/PlanarReflectionProbeUI.Handles.cs
  4. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl
  6. 43
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/PlanarReflectionProbe.cs
  7. 45
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs
  8. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystem.cs
  9. 120
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ReflectionSystemInternal.cs
  10. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl

2
ScriptableRenderPipeline/Core/CoreRP/Editor/CameraEditorUtils.cs


points[2] = new Vector3(1, 1, distance); // rightTopFar
points[3] = new Vector3(1, -1, distance); // rightBottomFar
for (var i = 0; i < 4; ++i)
points[i] = CameraEditorUtils.PerspectiveClipToWorld(clipToWorld, viewPosition, points[i]);
points[i] = PerspectiveClipToWorld(clipToWorld, viewPosition, points[i]);
}
static Vector3 MidPointPositionSlider(Vector3 position1, Vector3 position2, Vector3 direction)

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


public static Matrix4x4 CalculateWorldToCameraMatrixMirror(Matrix4x4 worldToCamera, Matrix4x4 reflection)
{
return worldToCamera * reflection * Matrix4x4.Scale(new Vector3(-1, 1, 1));
return worldToCamera * reflection;
}
public static Matrix4x4 CalculateReflectionMatrix(Vector4 plane)

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


static void DrawGizmos_CaptureFrustrum(PlanarReflectionProbeUI s, PlanarReflectionProbe d)
{
var viewerCamera = Camera.current;
var captureToWorld = d.GetCaptureToWorld(viewerCamera);
var capturePosition = captureToWorld.GetColumn(3);
var captureRotation = captureToWorld.rotation;
//var fov = ReflectionSystem.GetCaptureCameraFOVFor(d, viewerCamera);
//var clipToWorld = CameraEditorUtils.GetCameraClipToWorld(
// capturePosition, captureRotation,
// d.captureNearPlane, d.captureFarPlane,
// fov, 1);
float nearClipPlane, farClipPlane, aspect, fov;
Color backgroundColor;
CameraClearFlags clearFlags;
Vector3 capturePosition;
Quaternion captureRotation;
Matrix4x4 worldToCamera, projection;
//var near = new Vector3[4];
//var far = new Vector3[4];
//CameraEditorUtils.GetFrustrumPlaneAt(clipToWorld, capturePosition, d.captureFarPlane, far);
//CameraEditorUtils.GetFrustrumPlaneAt(clipToWorld, capturePosition, d.captureNearPlane, near);
ReflectionSystem.CalculateCaptureCameraProperties(d,
out nearClipPlane, out farClipPlane,
out aspect, out fov, out clearFlags, out backgroundColor,
out worldToCamera, out projection,
out capturePosition, out captureRotation, viewerCamera);
//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]);
//}
// TODO: draw frustrum gizmo
Gizmos.DrawSphere(capturePosition, HandleUtility.GetHandleSize(capturePosition) * 0.2f);
Gizmos.color = c;

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


switch (probe.texture.dimension)
{
case TextureDimension.Tex2D:
{
m_Env2DCapturePositionWS.Add(Vector3.zero);
m_Env2DCaptureVP.Add(Matrix4x4.identity);
Matrix4x4 worldToCamera, projection;
Vector3 capturePosition;
Quaternion captureRotation;
ReflectionSystem.CalculateCaptureCameraViewProj(
probe.planarReflectionProbe,
out worldToCamera, out projection,
out capturePosition, out captureRotation,
camera);
var vp = projection * worldToCamera;
m_Env2DCapturePositionWS.Add(capturePosition);
m_Env2DCaptureVP.Add(Matrix4x4.Scale(new Vector3(1, -1, 1)) * vp);
}
case TextureDimension.Cube:
envIndex = m_ReflectionProbeCache.FetchSlice(cmd, probe.texture);
envIndex = envIndex << 1 | (int)EnvCacheType.Cubemap;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl


if (cacheType == ENVCACHETYPE_TEXTURE2D)
{
float2 positionNCD = ComputeNormalizedDeviceCoordinates(_Env2DCapturePositionWS[index] + texCoord, _Env2DCaptureVP[index]);
outWeight = any(positionNCD > 1) || any(positionNCD < 0) ? 0 : 1;
outWeight = any(positionNCD.xy > 1) || any(positionNCD.xy < 0) ? 0 : 1;
return float3(positionNCD, 1);
}
else if (cacheType == ENVCACHETYPE_CUBEMAP)

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


ReflectionSystem.RegisterProbe(this);
}
}
public Matrix4x4 GetCaptureToWorld(Camera viewerCamera)
{
if (refreshMode == ReflectionProbeRefreshMode.EveryFrame
&& capturePositionMode == CapturePositionMode.MirrorCamera)
{
var planeCenter = influenceToWorld.MultiplyPoint(m_CaptureMirrorPlaneLocalPosition);
var planeNormal = influenceToWorld.MultiplyVector(m_CaptureMirrorPlaneLocalNormal.normalized);
var sourcePosition = viewerCamera.transform.position;
var r = sourcePosition - planeCenter;
var capturePosition = r - 2 * Vector3.Dot(planeNormal, r) * planeNormal + planeCenter;
var tr = transform;
var influencePosition = influenceVolume.GetWorldPosition(tr);
return Matrix4x4.TRS(
capturePosition,
Quaternion.LookRotation(influencePosition - capturePosition, tr.up),
Vector3.one
);
}
else
{
var tr = transform;
var capturePosition = tr.TransformPoint(m_CaptureLocalPosition);
var influencePosition = influenceVolume.GetWorldPosition(tr);
return Matrix4x4.TRS(
capturePosition,
Quaternion.LookRotation(influencePosition - capturePosition, tr.up),
Vector3.one
);
}
}
public Matrix4x4 GetInfluenceToWorld()
{
var tr = transform;
var influencePosition = influenceVolume.GetWorldPosition(tr);
return Matrix4x4.TRS(
influencePosition,
tr.rotation,
Vector3.one
);
}
}
}

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


}
}
public ReflectionProbe reflectionProbe { get; protected set; }
public PlanarReflectionProbe planarReflectionProbe { get; protected set; }
public abstract ReflectionProbeMode mode { get; }
public abstract Texture texture { get; }
// Position of the center of the probe in capture space

{
this.probe = probe;
additional = GetHDAdditionalReflectionData(probe);
reflectionProbe = probe.probe;
}
static HDAdditionalReflectionData GetHDAdditionalReflectionData(VisibleReflectionProbe probe)

class PlanarReflectionProbeWrapper : ProbeWrapper
{
PlanarReflectionProbe probe;
this.probe = probe;
planarReflectionProbe = probe;
public override Matrix4x4 influenceToWorld { get { return probe.influenceToWorld; } }
public override Texture texture { get { return probe.texture; } }
public override EnvShapeType influenceShapeType { get { return ConvertShape(probe.influenceVolume.shapeType); } }
public override float dimmer { get { return probe.dimmer; } }
public override Matrix4x4 influenceToWorld { get { return planarReflectionProbe.influenceToWorld; } }
public override Texture texture { get { return planarReflectionProbe.texture; } }
public override EnvShapeType influenceShapeType { get { return ConvertShape(planarReflectionProbe.influenceVolume.shapeType); } }
public override float dimmer { get { return planarReflectionProbe.dimmer; } }
switch (probe.influenceVolume.shapeType)
switch (planarReflectionProbe.influenceVolume.shapeType)
return probe.influenceVolume.boxBaseSize * 0.5f;
return planarReflectionProbe.influenceVolume.boxBaseSize * 0.5f;
return probe.influenceVolume.sphereBaseRadius * Vector3.one;
return planarReflectionProbe.influenceVolume.sphereBaseRadius * Vector3.one;
public override Vector3 blendNormalDistancePositive { get { return probe.influenceVolume.boxInfluenceNormalPositiveFade; } }
public override Vector3 blendNormalDistanceNegative { get { return probe.influenceVolume.boxInfluenceNormalNegativeFade; } }
public override Vector3 blendDistancePositive { get { return probe.influenceVolume.boxInfluencePositiveFade; } }
public override Vector3 blendDistanceNegative { get { return probe.influenceVolume.boxInfluenceNegativeFade; } }
public override Vector3 boxSideFadePositive { get { return probe.influenceVolume.boxPositiveFaceFade; } }
public override Vector3 boxSideFadeNegative { get { return probe.influenceVolume.boxNegativeFaceFade; } }
public override EnvShapeType proxyShapeType { get { return ConvertShape(probe.proxyShape); } }
public override Vector3 proxyExtents { get { return probe.proxyExtents; } }
public override bool infiniteProjection { get { return probe.infiniteProjection; } }
public override ReflectionProbeMode mode { get { return probe.mode; } }
public override Vector3 blendNormalDistancePositive { get { return planarReflectionProbe.influenceVolume.boxInfluenceNormalPositiveFade; } }
public override Vector3 blendNormalDistanceNegative { get { return planarReflectionProbe.influenceVolume.boxInfluenceNormalNegativeFade; } }
public override Vector3 blendDistancePositive { get { return planarReflectionProbe.influenceVolume.boxInfluencePositiveFade; } }
public override Vector3 blendDistanceNegative { get { return planarReflectionProbe.influenceVolume.boxInfluenceNegativeFade; } }
public override Vector3 boxSideFadePositive { get { return planarReflectionProbe.influenceVolume.boxPositiveFaceFade; } }
public override Vector3 boxSideFadeNegative { get { return planarReflectionProbe.influenceVolume.boxNegativeFaceFade; } }
public override EnvShapeType proxyShapeType { get { return ConvertShape(planarReflectionProbe.proxyShape); } }
public override Vector3 proxyExtents { get { return planarReflectionProbe.proxyExtents; } }
public override bool infiniteProjection { get { return planarReflectionProbe.infiniteProjection; } }
public override ReflectionProbeMode mode { get { return planarReflectionProbe.mode; } }
public override Matrix4x4 proxyToWorld { get { return probe.proxyToWorld; } }
public override Matrix4x4 proxyToWorld { get { return planarReflectionProbe.proxyToWorld; } }
}
}

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


{
s_Instance.RenderAllRealtimeProbesFor(camera);
}
public static void CalculateCaptureCameraProperties(PlanarReflectionProbe probe, 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, Camera viewerCamera = null)
{
ReflectionSystemInternal.CalculateCaptureCameraProperties(
probe,
out nearClipPlane, out farClipPlane,
out aspect, out fov, out clearFlags, out backgroundColor,
out worldToCamera, out projection, out capturePosition, out captureRotation,
viewerCamera);
}
public static void CalculateCaptureCameraViewProj(PlanarReflectionProbe probe, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera = null)
{
ReflectionSystemInternal.CalculateCaptureCameraViewProj(
probe,
out worldToCamera, out projection, out capturePosition, out captureRotation,
viewerCamera);
}
}
}

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


renderCamera.camera.targetTexture = target;
SetupCameraForRender(renderCamera.camera, probe, viewerCamera);
GL.invertCulling = IsProbeCaptureMirrored(probe, viewerCamera);
GL.invertCulling = false;
renderCamera.camera.targetTexture = null;
target.IncrementUpdateCount();
}

m_PlanarReflectionProbeBounds[planarReflectionProbe] = planarReflectionProbe.boundingSphere;
}
void SetupCameraForRender(Camera camera, PlanarReflectionProbe probe, Camera viewerCamera = null)
static void SetupCameraForRender(Camera camera, PlanarReflectionProbe probe, Camera viewerCamera = null)
{
float nearClipPlane, farClipPlane, aspect, fov;
Color backgroundColor;

Matrix4x4 worldToCamera, projection;
if (viewerCamera != null)
{
nearClipPlane = viewerCamera.nearClipPlane;
farClipPlane = viewerCamera.farClipPlane;
aspect = viewerCamera.aspect;
fov = viewerCamera.fieldOfView;
clearFlags = viewerCamera.clearFlags;
backgroundColor = viewerCamera.backgroundColor;
var worldToCapture = CameraUtils.CalculateWorldToCameraMatrix(viewerCamera.transform);
var reflectionMatrix = CameraUtils.CalculateReflectionMatrix(probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
worldToCamera = CameraUtils.CalculateWorldToCameraMatrixMirror(worldToCapture, reflectionMatrix);
var clipPlane = CameraUtils.CameraSpacePlane(worldToCamera, probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
var sourceProj = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane);
projection = CameraUtils.CalculateObliqueMatrix(sourceProj, clipPlane);
capturePosition = reflectionMatrix.MultiplyPoint(viewerCamera.transform.position);
var forward = reflectionMatrix.MultiplyVector(viewerCamera.transform.forward);
var up = reflectionMatrix.MultiplyVector(viewerCamera.transform.up);
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);
}
CalculateCaptureCameraProperties(probe,
out nearClipPlane, out farClipPlane,
out aspect, out fov, out clearFlags, out backgroundColor,
out worldToCamera, out projection,
out capturePosition, out captureRotation, viewerCamera);
camera.farClipPlane = farClipPlane;
camera.nearClipPlane = nearClipPlane;

var ctr = camera.transform;
ctr.position = capturePosition;
ctr.rotation = captureRotation;
}
public static void CalculateCaptureCameraViewProj(PlanarReflectionProbe probe, out Matrix4x4 worldToCamera, out Matrix4x4 projection, out Vector3 capturePosition, out Quaternion captureRotation, Camera viewerCamera = null)
{
float nearClipPlane, farClipPlane, aspect, fov;
CameraClearFlags clearFlags;
Color backgroundColor;
CalculateCaptureCameraProperties(
probe,
out nearClipPlane, out farClipPlane,
out aspect, out fov, out clearFlags, out backgroundColor,
out worldToCamera, out projection, out capturePosition, out captureRotation,
viewerCamera);
}
public static void CalculateCaptureCameraProperties(PlanarReflectionProbe probe, 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, Camera viewerCamera = null)
{
if (viewerCamera != null
&& probe.mode == ReflectionProbeMode.Realtime
&& probe.refreshMode == ReflectionProbeRefreshMode.EveryFrame
&& probe.capturePositionMode == PlanarReflectionProbe.CapturePositionMode.MirrorCamera)
CalculateMirroredCaptureCameraProperties(probe, viewerCamera, out nearClipPlane, out farClipPlane, out aspect, out fov, out clearFlags, out backgroundColor, out worldToCamera, out projection, out capturePosition, out captureRotation);
else
CalculateStaticCaptureCameraProperties(probe, out nearClipPlane, out farClipPlane, out aspect, out fov, out clearFlags, out backgroundColor, out worldToCamera, out projection, out capturePosition, out captureRotation);
}
static bool IsProbeCaptureMirrored(PlanarReflectionProbe probe, Camera viewerCamera)
{
return viewerCamera != null
&& probe.mode == ReflectionProbeMode.Realtime
&& probe.refreshMode == ReflectionProbeRefreshMode.EveryFrame
&& probe.capturePositionMode == PlanarReflectionProbe.CapturePositionMode.MirrorCamera;
}
static void CalculateStaticCaptureCameraProperties(PlanarReflectionProbe probe, 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)
{
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);
}
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)
{
nearClipPlane = viewerCamera.nearClipPlane;
farClipPlane = viewerCamera.farClipPlane;
aspect = viewerCamera.aspect;
fov = viewerCamera.fieldOfView;
clearFlags = viewerCamera.clearFlags;
backgroundColor = viewerCamera.backgroundColor;
var worldToCapture = CameraUtils.CalculateWorldToCameraMatrix(viewerCamera.transform);
var reflectionMatrix = CameraUtils.CalculateReflectionMatrix(probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
worldToCamera = CameraUtils.CalculateWorldToCameraMatrixMirror(worldToCapture, reflectionMatrix);
var clipPlane = CameraUtils.CameraSpacePlane(worldToCamera, probe.captureMirrorPlanePosition, probe.captureMirrorPlaneNormal);
var sourceProj = Matrix4x4.Perspective(fov, aspect, nearClipPlane, farClipPlane);
projection = CameraUtils.CalculateObliqueMatrix(sourceProj, clipPlane);
capturePosition = reflectionMatrix.MultiplyPoint(viewerCamera.transform.position);
var forward = reflectionMatrix.MultiplyVector(viewerCamera.transform.forward);
var up = reflectionMatrix.MultiplyVector(viewerCamera.transform.up);
captureRotation = Quaternion.LookRotation(forward, up);
}
static HDCamera GetRenderHDCamera(PlanarReflectionProbe probe)

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


float sampleWeight = 1;
float3 texCoord = GetSampleEnvCoordinates(lightLoopContext, lightData.envIndex, R, iblMipLevel, sampleWeight);
weight *= sampleWeight;
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, texCoord, iblMipLevel);
//weight *= sampleWeight;
float2 ndc = ComputeNormalizedDeviceCoordinates(positionWS, UNITY_MATRIX_VP);
//float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, texCoord, iblMipLevel);
float4 preLD = SAMPLE_TEXTURE2D_ARRAY_LOD(_Env2DTextures, s_trilinear_clamp_sampler, ndc.xy, lightData.envIndex >> 1, 0);
// Smooth weighting
weight = Smoothstep01(weight);

正在加载...
取消
保存