public void VolumeVoxelizationPass(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex, DensityVolumeList densityVolumes, LightLoop lightLoop) { if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.Volumetrics)) { return; } var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>(); if (visualEnvironment.fogType.value != FogType.Volumetric) { return; } using (new ProfilingSample(cmd, "Volume Voxelization")) { int numVisibleVolumes = m_VisibleVolumeBounds.Count; bool tiledLighting = lightLoop.HasLightToCull() && hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); bool highQuality = preset == VolumetricLightingPreset.High; int kernel = (tiledLighting ? 1 : 0) | (highQuality ? 2 : 0); var currFrameParams = hdCamera.vBufferParams[0]; var cvp = currFrameParams.viewportSize; Vector4 resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); #if UNITY_2019_1_OR_NEWER var vFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; var lensShift = hdCamera.camera.GetGateFittedLensShift(); #else var vFoV = hdCamera.camera.fieldOfView * Mathf.Deg2Rad; var lensShift = Vector2.zero; #endif // Compose the matrix which allows us to compute the world space view direction. Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, lensShift, resolution, hdCamera.mainViewConstants.viewMatrix, false); // Compute texel spacing at the depth of 1 meter. float unitDepthTexelSpacing = HDUtils.ComputZPlaneTexelSpacing(1.0f, vFoV, resolution.y); Texture3D volumeAtlas = DensityVolumeManager.manager.volumeAtlas.GetAtlas(); Vector4 volumeAtlasDimensions = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); if (volumeAtlas != null) { volumeAtlasDimensions.x = (float)volumeAtlas.width / volumeAtlas.depth; // 1 / number of textures volumeAtlasDimensions.y = volumeAtlas.width; volumeAtlasDimensions.z = volumeAtlas.depth; volumeAtlasDimensions.w = Mathf.Log(volumeAtlas.width, 2); // Max LoD } else { volumeAtlas = CoreUtils.blackVolumeTexture; } if (hdCamera.frameSettings.VolumeVoxelizationRunsAsync()) { // We explicitly set the big tile info even though it is set globally, since this could be running async before the PushGlobalParams cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumTileBigTileX, lightLoop.GetNumTileBigTileX(hdCamera)); cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumTileBigTileY, lightLoop.GetNumTileBigTileY(hdCamera)); if (tiledLighting) { cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs.g_vBigTileLightList, lightLoop.GetBigTileLightList()); } } cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle); cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeBounds, s_VisibleVolumeBoundsBuffer); cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeData, s_VisibleVolumeDataBuffer); cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeMaskAtlas, volumeAtlas); // TODO: set the constant buffer data only once. cmd.SetComputeMatrixParam(m_VolumeVoxelizationCS, HDShaderIDs._VBufferCoordToViewDirWS, transform); cmd.SetComputeFloatParam(m_VolumeVoxelizationCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, unitDepthTexelSpacing); cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumVisibleDensityVolumes, numVisibleVolumes); cmd.SetComputeVectorParam(m_VolumeVoxelizationCS, HDShaderIDs._VolumeMaskDimensions, volumeAtlasDimensions); int w = (int)resolution.x; int h = (int)resolution.y; // The shader defines GROUP_SIZE_1D = 8. cmd.DispatchCompute(m_VolumeVoxelizationCS, kernel, (w + 7) / 8, (h + 7) / 8, hdCamera.computePassCount); } }
public void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex) { if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.Volumetrics)) { return; } var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>(); if (visualEnvironment.fogType.value != FogType.Volumetric) { return; } using (new ProfilingSample(cmd, "Volumetric Lighting")) { // Get the interpolated anisotropy value. var fog = VolumeManager.instance.stack.GetComponent <VolumetricFog>(); // Only available in the Play Mode because all the frame counters in the Edit Mode are broken. bool tiledLighting = hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); bool enableReprojection = Application.isPlaying && hdCamera.camera.cameraType == CameraType.Game && hdCamera.frameSettings.IsEnabled(FrameSettingsField.ReprojectionForVolumetrics); bool enableAnisotropy = fog.anisotropy.value != 0; bool highQuality = preset == VolumetricLightingPreset.High; int kernel = (tiledLighting ? 1 : 0) | (enableReprojection ? 2 : 0) | (enableAnisotropy ? 4 : 0) | (highQuality ? 8 : 0); var currFrameParams = hdCamera.vBufferParams[0]; var cvp = currFrameParams.viewportSize; Vector4 resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); #if UNITY_2019_1_OR_NEWER var vFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; var lensShift = hdCamera.camera.GetGateFittedLensShift(); #else var vFoV = hdCamera.camera.fieldOfView * Mathf.Deg2Rad; var lensShift = Vector2.zero; #endif // Compose the matrix which allows us to compute the world space view direction. Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, lensShift, resolution, hdCamera.mainViewConstants.viewMatrix, false); // Compute texel spacing at the depth of 1 meter. float unitDepthTexelSpacing = HDUtils.ComputZPlaneTexelSpacing(1.0f, vFoV, resolution.y); GetHexagonalClosePackedSpheres7(m_xySeq); int sampleIndex = (int)frameIndex % 7; // TODO: should we somehow reorder offsets in Z based on the offset in XY? S.t. the samples more evenly cover the domain. // Currently, we assume that they are completely uncorrelated, but maybe we should correlate them somehow. m_xySeqOffset.Set(m_xySeq[sampleIndex].x, m_xySeq[sampleIndex].y, m_zSeq[sampleIndex], frameIndex); // TODO: set 'm_VolumetricLightingPreset'. // TODO: set the constant buffer data only once. cmd.SetComputeMatrixParam(m_VolumetricLightingCS, HDShaderIDs._VBufferCoordToViewDirWS, transform); cmd.SetComputeFloatParam(m_VolumetricLightingCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, unitDepthTexelSpacing); cmd.SetComputeFloatParam(m_VolumetricLightingCS, HDShaderIDs._CornetteShanksConstant, CornetteShanksPhasePartConstant(fog.anisotropy.value)); cmd.SetComputeVectorParam(m_VolumetricLightingCS, HDShaderIDs._VBufferSampleOffset, m_xySeqOffset); cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle); // Read cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingIntegral, m_LightingBufferHandle); // Write if (enableReprojection) { var historyRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting); var feedbackRT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting); cmd.SetComputeIntParam(m_VolumetricLightingCS, HDShaderIDs._VBufferLightingHistoryIsValid, hdCamera.volumetricHistoryIsValid ? 1 : 0); cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingHistory, historyRT); // Read cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingFeedback, feedbackRT); // Write hdCamera.volumetricHistoryIsValid = true; // For the next frame... } int w = (int)resolution.x; int h = (int)resolution.y; // The shader defines GROUP_SIZE_1D = 8. cmd.DispatchCompute(m_VolumetricLightingCS, kernel, (w + 7) / 8, (h + 7) / 8, hdCamera.computePassCount); } }
public void VolumeVoxelizationPass(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex, DensityVolumeList densityVolumes) { if (!hdCamera.frameSettings.enableVolumetrics) { return; } var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>(); if (visualEnvironment.fogType.value != FogType.Volumetric) { return; } using (new ProfilingSample(cmd, "Volume Voxelization")) { int numVisibleVolumes = m_VisibleVolumeBounds.Count; bool tiledLighting = hdCamera.frameSettings.lightLoopSettings.enableBigTilePrepass; bool highQuality = preset == VolumetricLightingPreset.High; int kernel = (tiledLighting ? 1 : 0) | (highQuality ? 2 : 0); var currFrameParams = hdCamera.vBufferParams[0]; var cvp = currFrameParams.viewportSize; Vector4 resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); float vFoV = hdCamera.camera.fieldOfView * Mathf.Deg2Rad; // Compose the matrix which allows us to compute the world space view direction. Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, resolution, hdCamera.viewMatrix, false); // Compute texel spacing at the depth of 1 meter. float unitDepthTexelSpacing = HDUtils.ComputZPlaneTexelSpacing(1.0f, vFoV, resolution.y); Texture3D volumeAtlas = DensityVolumeManager.manager.volumeAtlas.GetAtlas(); Vector4 volumeAtlasDimensions = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); if (volumeAtlas != null) { volumeAtlasDimensions.x = (float)volumeAtlas.width / volumeAtlas.depth; // 1 / number of textures volumeAtlasDimensions.y = volumeAtlas.width; volumeAtlasDimensions.z = volumeAtlas.depth; volumeAtlasDimensions.w = Mathf.Log(volumeAtlas.width, 2); // Max LoD } else { volumeAtlas = CoreUtils.blackVolumeTexture; } cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle); cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeBounds, s_VisibleVolumeBoundsBuffer); cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeData, s_VisibleVolumeDataBuffer); cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeMaskAtlas, volumeAtlas); // TODO: set the constant buffer data only once. cmd.SetComputeMatrixParam(m_VolumeVoxelizationCS, HDShaderIDs._VBufferCoordToViewDirWS, transform); cmd.SetComputeFloatParam(m_VolumeVoxelizationCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, unitDepthTexelSpacing); cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumVisibleDensityVolumes, numVisibleVolumes); cmd.SetComputeVectorParam(m_VolumeVoxelizationCS, HDShaderIDs._VolumeMaskDimensions, volumeAtlasDimensions); int w = (int)resolution.x; int h = (int)resolution.y; // The shader defines GROUP_SIZE_1D = 8. cmd.DispatchCompute(m_VolumeVoxelizationCS, kernel, (w + 7) / 8, (h + 7) / 8, 1); } }