/// <summary> /// Apply <paramref name="settings"/> and <paramref name="probePosition"/> to /// <paramref name="cameraPosition"/> and <paramref name="cameraSettings"/>. /// </summary> /// <param name="settings">Settings to apply. (Read only)</param> /// <param name="probePosition">Position to apply. (Read only)</param> /// <param name="cameraSettings">Settings to update.</param> /// <param name="cameraPosition">Position to update.</param> public static void ApplySettings( ref ProbeSettings settings, // In Parameter ref ProbeCapturePositionSettings probePosition, // In parameter ref CameraSettings cameraSettings, // InOut parameter ref CameraPositionSettings cameraPosition // InOut parameter ) { cameraSettings = settings.camera; // Compute the modes for each probe type PositionMode positionMode; bool useReferenceTransformAsNearClipPlane; switch (settings.type) { case ProbeSettings.ProbeType.PlanarProbe: positionMode = PositionMode.MirrorReferenceTransformWithProbePlane; useReferenceTransformAsNearClipPlane = true; break; case ProbeSettings.ProbeType.ReflectionProbe: positionMode = PositionMode.UseProbeTransform; useReferenceTransformAsNearClipPlane = false; cameraSettings.frustum.mode = CameraSettings.Frustum.Mode.ComputeProjectionMatrix; cameraSettings.frustum.aspect = 1; cameraSettings.frustum.fieldOfView = 90; break; default: throw new ArgumentOutOfRangeException(); } // Update the position switch (positionMode) { case PositionMode.UseProbeTransform: { cameraPosition.mode = CameraPositionSettings.Mode.ComputeWorldToCameraMatrix; var proxyMatrix = Matrix4x4.TRS(probePosition.proxyPosition, probePosition.proxyRotation, Vector3.one); cameraPosition.position = proxyMatrix.MultiplyPoint(settings.proxySettings.capturePositionProxySpace); cameraPosition.rotation = proxyMatrix.rotation * settings.proxySettings.captureRotationProxySpace; // In case of probe baking, 99% of the time, orientation of the cubemap doesn't matters // so, we build one without any rotation, thus we don't have to change the basis // during sampling the cubemap. if (settings.type == ProbeSettings.ProbeType.ReflectionProbe) { cameraPosition.rotation = Quaternion.identity; } break; } case PositionMode.MirrorReferenceTransformWithProbePlane: { cameraPosition.mode = CameraPositionSettings.Mode.UseWorldToCameraMatrixField; ApplyMirroredReferenceTransform( ref settings, ref probePosition, ref cameraSettings, ref cameraPosition ); break; } } // Update the clip plane if (useReferenceTransformAsNearClipPlane) { ApplyObliqueNearClipPlane( ref settings, ref probePosition, ref cameraSettings, ref cameraPosition ); } // Frame Settings Overrides switch (settings.mode) { default: case ProbeSettings.Mode.Realtime: cameraSettings.defaultFrameSettings = FrameSettingsRenderType.RealtimeReflection; break; case ProbeSettings.Mode.Baked: case ProbeSettings.Mode.Custom: cameraSettings.defaultFrameSettings = FrameSettingsRenderType.CustomOrBakedReflection; break; } switch (settings.type) { case ProbeSettings.ProbeType.ReflectionProbe: cameraSettings.customRenderingSettings = true; // Disable specular lighting for reflection probes, they must not have view dependent information when baking cameraSettings.renderingPathCustomFrameSettings.SetEnabled(FrameSettingsField.SpecularLighting, false); cameraSettings.renderingPathCustomFrameSettingsOverrideMask.mask[(int)FrameSettingsField.SpecularLighting] = true; break; } }
public RenderData(CameraSettings camera, CameraPositionSettings position) { worldToCameraRHS = position.GetUsedWorldToCameraMatrix(); projectionMatrix = camera.frustum.GetUsedProjectionMatrix(); capturePosition = position.position; }
/// <summary> /// Apply <paramref name="settings"/> and <paramref name="probePosition"/> to /// <paramref name="cameraPosition"/> and <paramref name="cameraSettings"/>. /// </summary> /// <param name="settings">Settings to apply. (Read only)</param> /// <param name="probePosition">Position to apply. (Read only)</param> /// <param name="cameraSettings">Settings to update.</param> /// <param name="cameraPosition">Position to update.</param> public static void ApplySettings( ref ProbeSettings settings, // In Parameter ref ProbeCapturePositionSettings probePosition, // In parameter ref CameraSettings cameraSettings, // InOut parameter ref CameraPositionSettings cameraPosition // InOut parameter ) { cameraSettings = settings.camera; // Compute the modes for each probe type PositionMode positionMode; bool useReferenceTransformAsNearClipPlane; switch (settings.type) { case ProbeSettings.ProbeType.PlanarProbe: positionMode = PositionMode.MirrorReferenceTransfromWithProbePlane; useReferenceTransformAsNearClipPlane = true; break; case ProbeSettings.ProbeType.ReflectionProbe: positionMode = PositionMode.UseProbeTransform; useReferenceTransformAsNearClipPlane = false; cameraSettings.frustum.mode = CameraSettings.Frustum.Mode.ComputeProjectionMatrix; cameraSettings.frustum.aspect = 1; cameraSettings.frustum.fieldOfView = 90; break; default: throw new ArgumentOutOfRangeException(); } // Update the position switch (positionMode) { case PositionMode.UseProbeTransform: { cameraPosition.mode = CameraPositionSettings.Mode.ComputeWorldToCameraMatrix; var proxyMatrix = Matrix4x4.TRS(probePosition.proxyPosition, probePosition.proxyRotation, Vector3.one); cameraPosition.position = proxyMatrix.MultiplyPoint(settings.proxySettings.capturePositionProxySpace); cameraPosition.rotation = proxyMatrix.rotation * settings.proxySettings.captureRotationProxySpace; break; } case PositionMode.MirrorReferenceTransfromWithProbePlane: { cameraPosition.mode = CameraPositionSettings.Mode.UseWorldToCameraMatrixField; ApplyMirroredReferenceTransform( ref settings, ref probePosition, ref cameraSettings, ref cameraPosition ); break; } } // Update the clip plane if (useReferenceTransformAsNearClipPlane) { ApplyObliqueNearClipPlane( ref settings, ref probePosition, ref cameraSettings, ref cameraPosition ); } // Frame Settings Overrides var hd = (HDRenderPipeline)RenderPipelineManager.currentPipeline; switch (settings.mode) { default: case ProbeSettings.Mode.Realtime: hd.asset.GetRealtimeReflectionFrameSettings().CopyTo(s_ApplySettings_TMP); break; case ProbeSettings.Mode.Baked: case ProbeSettings.Mode.Custom: hd.asset.GetBakedOrCustomReflectionFrameSettings().CopyTo(s_ApplySettings_TMP); break; } cameraSettings.frameSettings.ApplyOverrideOn(s_ApplySettings_TMP); s_ApplySettings_TMP.CopyTo(cameraSettings.frameSettings); }
/// <summary>Perform a rendering into <paramref name="target"/>.</summary> /// <example> /// How to perform standard rendering: /// <code> /// class StandardRenderingExample /// { /// public void Render() /// { /// // Copy default settings /// var settings = CameraRenderSettings.Default; /// // Adapt default settings to our custom usage /// settings.position.position = new Vector3(0, 1, 0); /// settings.camera.frustum.fieldOfView = 60.0f; /// // Get our render target /// var rt = new RenderTexture(128, 128, 1, GraphicsFormat.B8G8R8A8_SNorm); /// HDRenderUtilities.Render(settings, rt); /// // Do something with rt /// rt.Release(); /// } /// } /// </code> /// /// How to perform a cubemap rendering: /// <code> /// class CubemapRenderExample /// { /// public void Render() /// { /// // Copy default settings /// var settings = CameraRenderSettings.Default; /// // Adapt default settings to our custom usage /// settings.position.position = new Vector3(0, 1, 0); /// settings.camera.physical.iso = 800.0f; /// // Frustum settings are ignored and driven by the cubemap rendering /// // Get our render target /// var rt = new RenderTexture(128, 128, 1, GraphicsFormat.B8G8R8A8_SNorm) /// { /// dimension = TextureDimension.Cube /// }; /// // The TextureDimension is detected and the renderer will perform a cubemap rendering. /// HDRenderUtilities.Render(settings, rt); /// // Do something with rt /// rt.Release(); /// } /// } /// </code> /// </example> /// <param name="settings">Settings for the camera.</param> /// <param name="position">Position for the camera.</param> /// <param name="target">Target to render to.</param> /// <param name="staticFlags">Only used in the Editor fo cubemaps. /// This is bitmask of <see cref="UnityEditor.StaticEditorFlags"/> only objects with these flags will be rendered /// </param> public static void Render( CameraSettings settings, CameraPositionSettings position, Texture target, uint staticFlags = 0 ) { // Argument checking if (target == null) { throw new ArgumentNullException(nameof(target)); } var rtTarget = target as RenderTexture; var cubeTarget = target as Cubemap; switch (target.dimension) { case TextureDimension.Tex2D: if (rtTarget == null) { throw new ArgumentException("'target' must be a RenderTexture when rendering into a 2D texture"); } break; case TextureDimension.Cube: break; default: throw new ArgumentException("Rendering into a target of dimension " + $"{target.dimension} is not supported"); } var camera = NewRenderingCamera(); try { camera.ApplySettings(settings); camera.ApplySettings(position); switch (target.dimension) { case TextureDimension.Tex2D: { #if DEBUG Debug.LogWarning( "A static flags bitmask was provided but this is ignored when rendering into a Tex2D" ); #endif Assert.IsNotNull(rtTarget); camera.targetTexture = rtTarget; camera.Render(); camera.targetTexture = null; target.IncrementUpdateCount(); break; } case TextureDimension.Cube: { Assert.IsTrue(rtTarget != null || cubeTarget != null); var canHandleStaticFlags = false; #if UNITY_EDITOR canHandleStaticFlags = true; #endif // ReSharper disable ConditionIsAlwaysTrueOrFalse if (canHandleStaticFlags && staticFlags != 0) // ReSharper restore ConditionIsAlwaysTrueOrFalse { #if UNITY_EDITOR UnityEditor.Rendering.EditorCameraUtils.RenderToCubemap( camera, rtTarget, -1, (UnityEditor.StaticEditorFlags)staticFlags ); #endif } else { // ReSharper disable ConditionIsAlwaysTrueOrFalse if (!canHandleStaticFlags && staticFlags != 0) // ReSharper restore ConditionIsAlwaysTrueOrFalse { Debug.LogWarning( "A static flags bitmask was provided but this is ignored in player builds" ); } if (rtTarget != null) { camera.RenderToCubemap(rtTarget); } if (cubeTarget != null) { camera.RenderToCubemap(cubeTarget); } } target.IncrementUpdateCount(); break; } } } finally { CoreUtils.Destroy(camera.gameObject); } }
/// <summary>Perform a rendering into <paramref name="target"/>.</summary> /// <example> /// How to perform standard rendering: /// <code> /// class StandardRenderingExample /// { /// public void Render() /// { /// // Copy default settings /// var settings = CameraRenderSettings.Default; /// // Adapt default settings to our custom usage /// settings.position.position = new Vector3(0, 1, 0); /// settings.camera.frustum.fieldOfView = 60.0f; /// // Get our render target /// var rt = new RenderTexture(128, 128, 1, GraphicsFormat.B8G8R8A8_SNorm); /// HDRenderUtilities.Render(settings, rt); /// // Do something with rt /// rt.Release(); /// } /// } /// </code> /// /// How to perform a cubemap rendering: /// <code> /// class CubemapRenderExample /// { /// public void Render() /// { /// // Copy default settings /// var settings = CameraRenderSettings.Default; /// // Adapt default settings to our custom usage /// settings.position.position = new Vector3(0, 1, 0); /// settings.camera.physical.iso = 800.0f; /// // Frustum settings are ignored and driven by the cubemap rendering /// // Get our render target /// var rt = new RenderTexture(128, 128, 1, GraphicsFormat.B8G8R8A8_SNorm) /// { /// dimension = TextureDimension.Cube /// }; /// // The TextureDimension is detected and the renderer will perform a cubemap rendering. /// HDRenderUtilities.Render(settings, rt); /// // Do something with rt /// rt.Release(); /// } /// } /// </code> /// </example> /// <param name="settings">Settings for the camera.</param> /// <param name="position">Position for the camera.</param> /// <param name="target">Target to render to.</param> public static void Render(CameraSettings settings, CameraPositionSettings position, Texture target) { // Argument checking if (target == null) { throw new ArgumentNullException("target"); } // Assert for frame settings if (settings.frameSettings == null) { throw new ArgumentNullException("settings"); } var rtTarget = target as RenderTexture; var cubeTarget = target as Cubemap; switch (target.dimension) { case TextureDimension.Tex2D: if (rtTarget == null) { throw new ArgumentException("'target' must be a RenderTexture when rendering into a 2D texture"); } break; case TextureDimension.Cube: break; default: throw new ArgumentException(string.Format("Rendering into a target of dimension " + "{0} is not supported", target.dimension)); } var camera = NewRenderingCamera(); try { camera.ApplySettings(settings); camera.ApplySettings(position); GL.invertCulling = settings.invertFaceCulling; switch (target.dimension) { case TextureDimension.Tex2D: { Assert.IsNotNull(rtTarget); camera.targetTexture = rtTarget; camera.Render(); camera.targetTexture = null; target.IncrementUpdateCount(); break; } case TextureDimension.Cube: { Assert.IsTrue(rtTarget != null || cubeTarget != null); if (rtTarget != null) { camera.RenderToCubemap(rtTarget); } if (cubeTarget != null) { camera.RenderToCubemap(cubeTarget); } target.IncrementUpdateCount(); break; } } GL.invertCulling = false; } finally { CoreUtils.Destroy(camera.gameObject); } }