public static float Evaluate(ref VolumeFalloffEngineData falloff, ref OrientedBBox obb, float3 positionWS, float distanceWS) { float3x3 obbFrame = new float3x3(obb.right, obb.up, math.cross(obb.up, obb.right)); float3 obbExtents = new float3(obb.extentX, obb.extentY, obb.extentZ); float3 samplePositionBS = math.mul(obbFrame, positionWS - obb.center); float3 samplePositionBCS = samplePositionBS / obbExtents; bool isInsideVolume = math.max(math.abs(samplePositionBCS.x), math.max(math.abs(samplePositionBCS.y), math.abs(samplePositionBCS.z))) < 1.0f; if (!isInsideVolume) { return(0.0f); } float3 samplePositionBNDC = samplePositionBCS * 0.5f + 0.5f; float volumeWeight = VolumeFalloff.ComputeVolumeFalloffWeight( samplePositionBNDC, distanceWS, falloff.rcpFaceFadePos, falloff.rcpFaceFadeNeg, falloff.rcpDistFadeLen, falloff.endTimesRcpDistFadeLen ); volumeWeight *= falloff.weight; return(volumeWeight); }
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd) { DensityVolumeList densityVolumes = new DensityVolumeList(); if (preset == VolumetricLightingPreset.Off) { return(densityVolumes); } using (new ProfilingSample(cmd, "Prepare Visible Density Volume List")) { Vector3 camPosition = camera.camera.transform.position; Vector3 camOffset = Vector3.zero; // World-origin-relative if (ShaderConfig.s_CameraRelativeRendering != 0) { camOffset = camPosition; // Camera-relative } m_VisibleVolumeBounds.Clear(); m_VisibleVolumeProperties.Clear(); // Collect all visible finite volume data, and upload it to the GPU. HomogeneousDensityVolume[] volumes = Object.FindObjectsOfType(typeof(HomogeneousDensityVolume)) as HomogeneousDensityVolume[]; for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++) { HomogeneousDensityVolume volume = volumes[i]; // Only test active finite volumes. if (volume.enabled && volume.parameters.IsLocalVolume()) { // TODO: cache these? var obb = OrientedBBox.Create(volume.transform); // Handle camera-relative rendering. obb.center -= camOffset; // Frustum cull on the CPU for now. TODO: do it on the GPU. if (GeometryUtils.Overlap(obb, camera.frustum, 6, 8)) { // TODO: cache these? var properties = volume.parameters.GetProperties(); m_VisibleVolumeBounds.Add(obb); m_VisibleVolumeProperties.Add(properties); } } } s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds); s_VisibleVolumePropertiesBuffer.SetData(m_VisibleVolumeProperties); // Fill the struct with pointers in order to share the data with the light loop. densityVolumes.bounds = m_VisibleVolumeBounds; densityVolumes.properties = m_VisibleVolumeProperties; return(densityVolumes); } }
public static void ComputeOrientedBBoxFromFalloffAndTransform(out OrientedBBox obb, ref VolumeFalloff falloff, Transform t) { Matrix4x4 m = falloff.isTransformScaleUsed ? (t.localToWorldMatrix * Matrix4x4.TRS(falloff.center, Quaternion.identity, falloff.size)) : Matrix4x4.TRS(t.position + (t.rotation * falloff.center), t.rotation, falloff.size); obb = new OrientedBBox(m); }
public void VoxelizeDensityVolumes(HDCamera camera, CommandBuffer cmd) { if (preset == VolumetricLightingPreset.Off) { return; } Vector3 camPosition = camera.camera.transform.position; Vector3 camOffset = Vector3.zero; // World-origin-relative if (ShaderConfig.s_CameraRelativeRendering != 0) { camOffset = -camPosition; // Camera-relative } m_VisibleVolumes.Clear(); m_VisibleVolumeProperties.Clear(); // Collect all the visible volume data, and upload it to the GPU. HomogeneousDensityVolume[] volumes = Object.FindObjectsOfType(typeof(HomogeneousDensityVolume)) as HomogeneousDensityVolume[]; foreach (HomogeneousDensityVolume volume in volumes) { // Only test active finite volumes. if (volume.enabled && volume.volumeParameters.IsLocalVolume()) { // TODO: cache these? var obb = OrientedBBox.Create(volume.transform); // Frustum cull on the CPU for now. TODO: do it on the GPU. if (GeometryUtils.Overlap(obb, camOffset, camera.frustum, 6, 8)) { // TODO: cache these? var properties = volume.volumeParameters.GetProperties(); m_VisibleVolumes.Add(obb); m_VisibleVolumeProperties.Add(properties); } } } s_VisibleVolumesBuffer.SetData(m_VisibleVolumes); s_VisibleVolumePropertiesBuffer.SetData(m_VisibleVolumeProperties); }
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera hdCamera, CommandBuffer cmd, float time) { DensityVolumeList densityVolumes = new DensityVolumeList(); if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.Volumetrics)) { return(densityVolumes); } var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>(); if (visualEnvironment.fogType.value != FogType.Volumetric) { return(densityVolumes); } using (new ProfilingSample(cmd, "Prepare Visible Density Volume List")) { Vector3 camPosition = hdCamera.camera.transform.position; Vector3 camOffset = Vector3.zero;// World-origin-relative if (ShaderConfig.s_CameraRelativeRendering != 0) { camOffset = camPosition; // Camera-relative } m_VisibleVolumeBounds.Clear(); m_VisibleVolumeData.Clear(); // Collect all visible finite volume data, and upload it to the GPU. DensityVolume[] volumes = DensityVolumeManager.manager.PrepareDensityVolumeData(cmd, hdCamera.camera, time); for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++) { DensityVolume volume = volumes[i]; // TODO: cache these? var obb = new OrientedBBox(Matrix4x4.TRS(volume.transform.position, volume.transform.rotation, volume.parameters.size)); // Handle camera-relative rendering. obb.center -= camOffset; // Frustum cull on the CPU for now. TODO: do it on the GPU. // TODO: account for custom near and far planes of the V-Buffer's frustum. // It's typically much shorter (along the Z axis) than the camera's frustum. // XRTODO: fix combined frustum culling if (GeometryUtils.Overlap(obb, hdCamera.frustum, 6, 8) || hdCamera.camera.stereoEnabled) { // TODO: cache these? var data = volume.parameters.ConvertToEngineData(); m_VisibleVolumeBounds.Add(obb); m_VisibleVolumeData.Add(data); } } s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds); s_VisibleVolumeDataBuffer.SetData(m_VisibleVolumeData); // Fill the struct with pointers in order to share the data with the light loop. densityVolumes.bounds = m_VisibleVolumeBounds; densityVolumes.density = m_VisibleVolumeData; return(densityVolumes); } }
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd) { DensityVolumeList densityVolumes = new DensityVolumeList(); if (preset == VolumetricLightingPreset.Off) { return(densityVolumes); } var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>(); if (visualEnvironment.fogType != FogType.Volumetric) { return(densityVolumes); } VBuffer vBuffer = FindVBuffer(camera.GetViewID()); if (vBuffer == null) { return(densityVolumes); } using (new ProfilingSample(cmd, "Prepare Visible Density Volume List")) { Vector3 camPosition = camera.camera.transform.position; Vector3 camOffset = Vector3.zero; // World-origin-relative if (ShaderConfig.s_CameraRelativeRendering != 0) { camOffset = camPosition; // Camera-relative } m_VisibleVolumeBounds.Clear(); m_VisibleVolumeData.Clear(); // Collect all visible finite volume data, and upload it to the GPU. DensityVolume[] volumes = DensityVolumeManager.manager.PrepareDensityVolumeData(cmd); for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++) { DensityVolume volume = volumes[i]; // TODO: cache these? var obb = OrientedBBox.Create(volume.transform); // Handle camera-relative rendering. obb.center -= camOffset; // Frustum cull on the CPU for now. TODO: do it on the GPU. if (GeometryUtils.Overlap(obb, camera.frustum, 6, 8)) { // TODO: cache these? var data = volume.parameters.GetData(); m_VisibleVolumeBounds.Add(obb); m_VisibleVolumeData.Add(data); } } s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds); s_VisibleVolumeDataBuffer.SetData(m_VisibleVolumeData); // Fill the struct with pointers in order to share the data with the light loop. densityVolumes.bounds = m_VisibleVolumeBounds; densityVolumes.density = m_VisibleVolumeData; return(densityVolumes); } }