public static string GetBakedTextureFilePath(HDProbe probe) { return(GetBakedTextureFilePath( probe.settings.type, SceneObjectIDMap.GetOrCreateSceneObjectID( probe.gameObject, SceneObjectCategory.ReflectionProbe ), probe.gameObject.scene )); }
static ProbeCapturePositionSettings ComputeFrom( HDProbe probe, Vector3 referencePosition, Quaternion referenceRotation ) { var result = new ProbeCapturePositionSettings(); var proxyToWorld = probe.proxyToWorld; result.proxyPosition = proxyToWorld.GetColumn(3); result.proxyRotation = proxyToWorld.rotation; result.referencePosition = referencePosition; result.referenceRotation = referenceRotation; result.influenceToWorld = probe.influenceToWorld; return(result); }
void BuildEnvLightData(CommandBuffer cmd, HDCamera hdCamera, HDRayTracingLights lights) { int totalReflectionProbes = lights.reflectionProbeArray.Count; if (totalReflectionProbes == 0) { ResizeEnvLightDataBuffer(1); return; } // Also we need to build the light list data if (m_EnvLightDataCPUArray == null || m_EnvLightDataGPUArray == null || m_EnvLightDataGPUArray.count != totalReflectionProbes) { ResizeEnvLightDataBuffer(totalReflectionProbes); } // Make sure the Cpu list is empty m_EnvLightDataCPUArray.Clear(); ProcessedProbeData processedProbe = new ProcessedProbeData(); // Build the data for every light for (int lightIdx = 0; lightIdx < lights.reflectionProbeArray.Count; ++lightIdx) { HDProbe probeData = lights.reflectionProbeArray[lightIdx]; // Skip the probe if the probe has never rendered (in realtime cases) or if texture is null if (!probeData.HasValidRenderedData()) { continue; } HDRenderPipeline.PreprocessProbeData(ref processedProbe, probeData, hdCamera); var envLightData = new EnvLightData(); m_RenderPipeline.GetEnvLightData(cmd, hdCamera, processedProbe, ref envLightData); // We make the light position camera-relative as late as possible in order // to allow the preceding code to work with the absolute world space coordinates. Vector3 camPosWS = hdCamera.mainViewConstants.worldSpaceCameraPos; HDRenderPipeline.UpdateEnvLighCameraRelativetData(ref envLightData, camPosWS); m_EnvLightDataCPUArray.Add(envLightData); } // Push the data to the GPU m_EnvLightDataGPUArray.SetData(m_EnvLightDataCPUArray); }
/// <summary> /// Compute the probe capture settings from an HDProbe and a reference position. /// The position will be mirrored based on the mirror position of the probe. /// </summary> /// <param name="probe">The probe to extract settings from.</param> /// <param name="referencePosition">The reference position to use.</param> /// <returns>The probe capture position setting.</returns> public static ProbeCapturePositionSettings ComputeFromMirroredReference( HDProbe probe, Vector3 referencePosition ) { var positionSettings = ComputeFrom( probe, referencePosition, Quaternion.identity ); // Set proper orientation for the reference rotation var proxyMatrix = Matrix4x4.TRS( positionSettings.proxyPosition, positionSettings.proxyRotation, Vector3.one ); var mirrorPosition = proxyMatrix.MultiplyPoint(probe.settings.proxySettings.mirrorPositionProxySpace); positionSettings.referenceRotation = Quaternion.LookRotation(mirrorPosition - positionSettings.referencePosition); return(positionSettings); }
/// <summary> /// Compute the probe capture settings from an HDProbe and a reference transform. /// </summary> /// <param name="probe">The probe to extract settings from.</param> /// <param name="reference">The reference transform. Use <c>null</c> when no reference is available.</param> /// <returns>The probe capture position settings.</returns> public static ProbeCapturePositionSettings ComputeFrom(HDProbe probe, Transform reference) { var referencePosition = Vector3.zero; var referenceRotation = Quaternion.identity; if (reference != null) { referencePosition = reference.position; referenceRotation = reference.rotation; } else { if (probe.type == ProbeSettings.ProbeType.PlanarProbe) { var planar = (PlanarReflectionProbe)probe; return(ComputeFromMirroredReference(planar, planar.referencePosition)); } } var result = ComputeFrom(probe, referencePosition, referenceRotation); return(result); }
void BuildEnvLightData(CommandBuffer cmd, HDCamera hdCamera, HDRayTracingLights lights) { int totalReflectionProbes = lights.reflectionProbeArray.Count; if (totalReflectionProbes == 0) { ResizeEnvLightDataBuffer(1); return; } // Also we need to build the light list data if (m_EnvLightDataCPUArray == null || m_EnvLightDataGPUArray == null || m_EnvLightDataGPUArray.count != totalReflectionProbes) { ResizeEnvLightDataBuffer(totalReflectionProbes); } // Make sure the Cpu list is empty m_EnvLightDataCPUArray.Clear(); // Build the data for every light for (int lightIdx = 0; lightIdx < lights.reflectionProbeArray.Count; ++lightIdx) { HDProbe probeData = lights.reflectionProbeArray[lightIdx]; var envLightData = new EnvLightData(); m_RenderPipeline.GetEnvLightData(cmd, hdCamera, probeData, m_RenderPipeline.m_CurrentDebugDisplaySettings, ref envLightData); // We make the light position camera-relative as late as possible in order // to allow the preceding code to work with the absolute world space coordinates. Vector3 camPosWS = hdCamera.mainViewConstants.worldSpaceCameraPos; m_RenderPipeline.UpdateEnvLighCameraRelativetData(ref envLightData, camPosWS); m_EnvLightDataCPUArray.Add(envLightData); } // Push the data to the GPU m_EnvLightDataGPUArray.SetData(m_EnvLightDataCPUArray); }
static ProbeCapturePositionSettings ComputeFrom( HDProbe probe, Vector3 referencePosition, Quaternion referenceRotation ) { var result = new ProbeCapturePositionSettings(); var proxyToWorld = probe.proxyToWorld; result.proxyPosition = proxyToWorld.GetColumn(3); // If reference position and proxy position is exactly the same, we end up in some degeneracies triggered // by engine code when computing culling parameters. This is an extremely rare case, but can happen // in editor when focusing on the planar probe. So if that happens, we offset them 0.1 mm apart. if (Vector3.Distance(result.proxyPosition, referencePosition) < 1e-4f) { referencePosition += new Vector3(1e-4f, 1e-4f, 1e-4f); } result.proxyRotation = proxyToWorld.rotation; result.referencePosition = referencePosition; result.referenceRotation = referenceRotation; result.influenceToWorld = probe.influenceToWorld; return(result); }
void BuildGPULightVolumes(HDCamera hdCamera, HDRayTracingLights rayTracingLights) { int totalNumLights = rayTracingLights.lightCount; // Make sure the light volume buffer has the right size if (m_LightVolumesCPUArray == null || totalNumLights != m_LightVolumesCPUArray.Length) { ResizeVolumeBuffer(totalNumLights); } // Set Light volume data to the CPU buffer punctualLightCount = 0; areaLightCount = 0; envLightCount = 0; totalLightCount = 0; int realIndex = 0; for (int lightIdx = 0; lightIdx < rayTracingLights.hdLightArray.Count; ++lightIdx) { HDAdditionalLightData currentLight = rayTracingLights.hdLightArray[lightIdx]; // When the user deletes a light source in the editor, there is a single frame where the light is null before the collection of light in the scene is triggered // the workaround for this is simply to not add it if it is null for that invalid frame if (currentLight != null) { Light light = currentLight.gameObject.GetComponent <Light>(); if (light == null || !light.enabled) { continue; } if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && !currentLight.includeForRayTracing) { continue; } // Reserve space in the cookie atlas m_RenderPipeline.ReserveCookieAtlasTexture(currentLight, light, currentLight.type); // Compute the camera relative position Vector3 lightPositionRWS = currentLight.gameObject.transform.position; if (ShaderConfig.s_CameraRelativeRendering != 0) { lightPositionRWS -= hdCamera.camera.transform.position; } // Grab the light range float lightRange = light.range; if (currentLight.type != HDLightType.Area) { m_LightVolumesCPUArray[realIndex].range = new Vector3(lightRange, lightRange, lightRange); m_LightVolumesCPUArray[realIndex].position = lightPositionRWS; m_LightVolumesCPUArray[realIndex].active = (currentLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[realIndex].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[realIndex].shape = 0; m_LightVolumesCPUArray[realIndex].lightType = 0; punctualLightCount++; } else { // let's compute the oobb of the light influence volume first Vector3 oobbDimensions = new Vector3(currentLight.shapeWidth + 2 * lightRange, currentLight.shapeHeight + 2 * lightRange, lightRange); // One-sided Vector3 extents = 0.5f * oobbDimensions; Vector3 oobbCenter = lightPositionRWS + extents.z * currentLight.gameObject.transform.forward; // Let's now compute an AABB that matches the previously defined OOBB OOBBToAABBBounds(oobbCenter, extents, currentLight.gameObject.transform.up, currentLight.gameObject.transform.right, currentLight.gameObject.transform.forward, ref bounds); // Fill the volume data m_LightVolumesCPUArray[realIndex].range = bounds.extents; m_LightVolumesCPUArray[realIndex].position = bounds.center; m_LightVolumesCPUArray[realIndex].active = (currentLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[realIndex].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[realIndex].shape = 1; m_LightVolumesCPUArray[realIndex].lightType = 1; areaLightCount++; } realIndex++; } } int indexOffset = realIndex; // Set Env Light volume data to the CPU buffer for (int lightIdx = 0; lightIdx < rayTracingLights.reflectionProbeArray.Count; ++lightIdx) { HDProbe currentEnvLight = rayTracingLights.reflectionProbeArray[lightIdx]; // Compute the camera relative position Vector3 probePositionRWS = currentEnvLight.influenceToWorld.GetColumn(3); if (ShaderConfig.s_CameraRelativeRendering != 0) { probePositionRWS -= hdCamera.camera.transform.position; } if (currentEnvLight != null) { if (currentEnvLight.influenceVolume.shape == InfluenceShape.Sphere) { m_LightVolumesCPUArray[lightIdx + indexOffset].shape = 0; m_LightVolumesCPUArray[lightIdx + indexOffset].range = new Vector3(currentEnvLight.influenceVolume.sphereRadius, currentEnvLight.influenceVolume.sphereRadius, currentEnvLight.influenceVolume.sphereRadius); m_LightVolumesCPUArray[lightIdx + indexOffset].position = probePositionRWS; } else { m_LightVolumesCPUArray[lightIdx + indexOffset].shape = 1; m_LightVolumesCPUArray[lightIdx + indexOffset].range = new Vector3(currentEnvLight.influenceVolume.boxSize.x / 2.0f, currentEnvLight.influenceVolume.boxSize.y / 2.0f, currentEnvLight.influenceVolume.boxSize.z / 2.0f); m_LightVolumesCPUArray[lightIdx + indexOffset].position = probePositionRWS; } m_LightVolumesCPUArray[lightIdx + indexOffset].active = (currentEnvLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[lightIdx + indexOffset].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[lightIdx + indexOffset].lightType = 2; envLightCount++; } } totalLightCount = punctualLightCount + areaLightCount + envLightCount; // Push the light volumes to the GPU m_LightVolumeGPUArray.SetData(m_LightVolumesCPUArray); }
void BuildGPULightVolumes(HDRayTracingLights lightArray) { int totalNumLights = lightArray.hdLightArray.Count + lightArray.reflectionProbeArray.Count; // Make sure the light volume buffer has the right size if (m_LightVolumesCPUArray == null || totalNumLights != m_LightVolumesCPUArray.Length) { ResizeVolumeBuffer(totalNumLights); } // Set Light volume data to the CPU buffer punctualLightCount = 0; areaLightCount = 0; envLightCount = 0; totalLightCount = 0; int realIndex = 0; for (int lightIdx = 0; lightIdx < lightArray.hdLightArray.Count; ++lightIdx) { HDAdditionalLightData currentLight = lightArray.hdLightArray[lightIdx]; // When the user deletes a light source in the editor, there is a single frame where the light is null before the collection of light in the scene is triggered // the workaround for this is simply to not add it if it is null for that invalid frame if (currentLight != null) { Light light = currentLight.gameObject.GetComponent <Light>(); if (light == null || !light.enabled) { continue; } float lightRange = light.range; m_LightVolumesCPUArray[realIndex].range = new Vector3(lightRange, lightRange, lightRange); m_LightVolumesCPUArray[realIndex].position = currentLight.gameObject.transform.position; m_LightVolumesCPUArray[realIndex].active = (currentLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[realIndex].lightIndex = (uint)lightIdx; if (currentLight.lightTypeExtent == LightTypeExtent.Punctual) { m_LightVolumesCPUArray[realIndex].lightType = 0; punctualLightCount++; } else { m_LightVolumesCPUArray[realIndex].lightType = 1; areaLightCount++; } realIndex++; } } int indexOffset = realIndex; // Set Env Light volume data to the CPU buffer for (int lightIdx = 0; lightIdx < lightArray.reflectionProbeArray.Count; ++lightIdx) { HDProbe currentEnvLight = lightArray.reflectionProbeArray[lightIdx]; if (currentEnvLight != null) { if (currentEnvLight.influenceVolume.shape == InfluenceShape.Sphere) { m_LightVolumesCPUArray[lightIdx + indexOffset].shape = 0; m_LightVolumesCPUArray[lightIdx + indexOffset].range = new Vector3(currentEnvLight.influenceVolume.sphereRadius, currentEnvLight.influenceVolume.sphereRadius, currentEnvLight.influenceVolume.sphereRadius); m_LightVolumesCPUArray[lightIdx + indexOffset].position = currentEnvLight.influenceToWorld.GetColumn(3); } else { m_LightVolumesCPUArray[lightIdx + indexOffset].shape = 1; m_LightVolumesCPUArray[lightIdx + indexOffset].range = new Vector3(currentEnvLight.influenceVolume.boxSize.x / 2.0f, currentEnvLight.influenceVolume.boxSize.y / 2.0f, currentEnvLight.influenceVolume.boxSize.z / 2.0f); m_LightVolumesCPUArray[lightIdx + indexOffset].position = currentEnvLight.influenceToWorld.GetColumn(3); } m_LightVolumesCPUArray[lightIdx + indexOffset].active = (currentEnvLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[lightIdx + indexOffset].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[lightIdx + indexOffset].lightType = 2; envLightCount++; } } totalLightCount = punctualLightCount + areaLightCount + envLightCount; // Push the light volumes to the GPU m_LightVolumeGPUArray.SetData(m_LightVolumesCPUArray); }
internal void AddProbe(HDProbe visibleProbes) { Assert.IsNotNull(m_VisibleProbes); m_VisibleProbes.Add(visibleProbes); }