public void PushGlobalParams(HDCamera camera, CommandBuffer cmd) { if (preset == VolumetricLightingPreset.Off) { return; } HomogeneousFog globalFogComponent = HomogeneousFog.GetGlobalFogComponent(); // TODO: may want to cache these results somewhere. VolumeProperties globalFogProperties = (globalFogComponent != null) ? globalFogComponent.volumeParameters.GetProperties() : VolumeProperties.GetNeutralVolumeProperties(); cmd.SetGlobalVector(HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering); cmd.SetGlobalFloat(HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction); cmd.SetGlobalFloat(HDShaderIDs._GlobalFog_Asymmetry, globalFogComponent != null ? globalFogComponent.volumeParameters.asymmetry : 0); int w = 0, h = 0, d = 0; Vector2 scale = ComputeVBufferResolutionAndScale(preset, (int)camera.screenSize.x, (int)camera.screenSize.y, ref w, ref h, ref d); VBuffer vBuffer = FindVBuffer(camera.GetViewID()); Debug.Assert(vBuffer != null); cmd.SetGlobalVector(HDShaderIDs._VBufferResolution, new Vector4(w, h, 1.0f / w, 1.0f / h)); cmd.SetGlobalVector(HDShaderIDs._VBufferScaleAndSliceCount, new Vector4(scale.x, scale.y, d, 1.0f / d)); cmd.SetGlobalVector(HDShaderIDs._VBufferDepthEncodingParams, ComputeLogarithmicDepthEncodingParams(m_VBufferNearPlane, m_VBufferFarPlane, k_LogScale)); cmd.SetGlobalVector(HDShaderIDs._VBufferDepthDecodingParams, ComputeLogarithmicDepthDecodingParams(m_VBufferNearPlane, m_VBufferFarPlane, k_LogScale)); cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, vBuffer.GetLightingIntegralBuffer()); }
// Returns NULL if a global fog component does not exist, or is not enabled. public static HomogeneousFog GetGlobalFogComponent() { HomogeneousFog globalFogComponent = null; HomogeneousFog[] fogComponents = Object.FindObjectsOfType(typeof(HomogeneousFog)) as HomogeneousFog[]; foreach (HomogeneousFog fogComponent in fogComponents) { if (fogComponent.enabled && fogComponent.volumeParameters.IsVolumeUnbounded()) { globalFogComponent = fogComponent; break; } } return(globalFogComponent); }
public void SetVolumetricLightingData(HDCamera camera, CommandBuffer cmd) { HomogeneousFog globalFogComponent = GetGlobalFogComponent(); // TODO: may want to cache these results somewhere. VolumeProperties globalFogProperties = (globalFogComponent != null) ? globalFogComponent.volumeParameters.GetProperties() : VolumeProperties.GetNeutralVolumeProperties(); cmd.SetGlobalVector(HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering); cmd.SetGlobalFloat(HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction); int w = 0, h = 0, d = 0; Vector2 scale = ComputeVBufferResolutionAndScale(camera.screenSize.x, camera.screenSize.y, ref w, ref h, ref d); int viewId = camera.camera.GetInstanceID(); int viewOffset = ViewOffsetFromViewId(viewId); Debug.Assert(viewOffset >= 0 && viewOffset < 8); cmd.SetGlobalVector(HDShaderIDs._VBufferResolution, new Vector4(w, h, 1.0f / w, 1.0f / h)); cmd.SetGlobalVector(HDShaderIDs._VBufferScaleAndSliceCount, new Vector4(scale.x, scale.y, d, 1.0f / d)); cmd.SetGlobalVector(HDShaderIDs._VBufferDepthEncodingParams, ComputeLogarithmicDepthEncodingParams(m_VBufferNearPlane, m_VBufferFarPlane)); cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, GetVBufferLightingIntegral(viewOffset)); }
public void VolumetricLightingPass(HDCamera camera, CommandBuffer cmd, FrameSettings frameSettings) { if (preset == VolumetricLightingPreset.Off) { return; } using (new ProfilingSample(cmd, "Volumetric Lighting")) { VBuffer vBuffer = FindVBuffer(camera.GetViewID()); Debug.Assert(vBuffer != null); if (HomogeneousFog.GetGlobalFogComponent() == null) { // Clear the render target instead of running the shader. // CoreUtils.SetRenderTarget(cmd, GetVBufferLightingIntegral(viewOffset), ClearFlag.Color, CoreUtils.clearColorAllBlack); // return; // Clearing 3D textures does not seem to work! // Use the workaround by running the full shader with no volume. } bool enableClustered = frameSettings.lightLoopSettings.enableTileAndCluster; bool enableReprojection = Application.isPlaying && camera.camera.cameraType == CameraType.Game; int kernel; if (enableReprojection) { // Only available in the Play Mode because all the frame counters in the Edit Mode are broken. kernel = m_VolumetricLightingCS.FindKernel(enableClustered ? "VolumetricLightingClusteredReproj" : "VolumetricLightingAllLightsReproj"); } else { kernel = m_VolumetricLightingCS.FindKernel(enableClustered ? "VolumetricLightingClustered" : "VolumetricLightingAllLights"); } int w = 0, h = 0, d = 0; Vector2 scale = ComputeVBufferResolutionAndScale(preset, (int)camera.screenSize.x, (int)camera.screenSize.y, ref w, ref h, ref d); float vFoV = camera.camera.fieldOfView * Mathf.Deg2Rad; // Compose the matrix which allows us to compute the world space view direction. // Compute it using the scaled resolution to account for the visible area of the VBuffer. Vector4 scaledRes = new Vector4(w * scale.x, h * scale.y, 1.0f / (w * scale.x), 1.0f / (h * scale.y)); Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, scaledRes, camera.viewMatrix, false); camera.SetupComputeShader(m_VolumetricLightingCS, cmd); Vector2[] xySeq = GetHexagonalClosePackedSpheres7(); // This is a sequence of 7 equidistant numbers from 1/14 to 13/14. // Each of them is the centroid of the interval of length 2/14. // They've been rearranged in a sequence of pairs {small, large}, s.t. (small + large) = 1. // That way, the running average position is close to 0.5. // | 6 | 2 | 4 | 1 | 5 | 3 | 7 | // | | | | o | | | | // | | o | | x | | | | // | | x | | x | | o | | // | | x | o | x | | x | | // | | x | x | x | o | x | | // | o | x | x | x | x | x | | // | x | x | x | x | x | x | o | // | x | x | x | x | x | x | x | float[] zSeq = { 7.0f / 14.0f, 3.0f / 14.0f, 11.0f / 14.0f, 5.0f / 14.0f, 9.0f / 14.0f, 1.0f / 14.0f, 13.0f / 14.0f }; int rfc = Time.renderedFrameCount; int sampleIndex = rfc % 7; Vector4 offset = new Vector4(xySeq[sampleIndex].x, xySeq[sampleIndex].y, zSeq[sampleIndex], rfc); // TODO: set 'm_VolumetricLightingPreset'. cmd.SetComputeVectorParam(m_VolumetricLightingCS, HDShaderIDs._VBufferSampleOffset, offset); cmd.SetComputeMatrixParam(m_VolumetricLightingCS, HDShaderIDs._VBufferCoordToViewDirWS, transform); cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingIntegral, vBuffer.GetLightingIntegralBuffer()); // Write if (enableReprojection) { cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingFeedback, vBuffer.GetLightingFeedbackBuffer()); // Write cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingHistory, vBuffer.GetLightingHistoryBuffer()); // Read } // The shader defines GROUP_SIZE_1D = 16. cmd.DispatchCompute(m_VolumetricLightingCS, kernel, (w + 15) / 16, (h + 15) / 16, 1); } }