public static void GetCornetteShanksPhaseFunction(ZonalHarmonicsL2 zh, float anisotropy) { float g = anisotropy; zh.coeffs[0] = 0.282095f; zh.coeffs[1] = 0.293162f * g * (4.0f + (g * g)) / (2.0f + (g * g)); zh.coeffs[2] = (0.126157f + 1.44179f * (g * g) + 0.324403f * (g * g) * (g * g)) / (2.0f + (g * g)); }
void SetPreconvolvedAmbientLightProbe(HDCamera hdCamera, CommandBuffer cmd, float dimmer, float anisotropy) { SphericalHarmonicsL2 probeSH = SphericalHarmonicMath.UndoCosineRescaling(m_SkyManager.GetAmbientProbe(hdCamera)); probeSH = SphericalHarmonicMath.RescaleCoefficients(probeSH, dimmer); ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(m_PhaseZH, anisotropy); SphericalHarmonicsL2 finalSH = SphericalHarmonicMath.PremultiplyCoefficients(SphericalHarmonicMath.Convolve(probeSH, m_PhaseZH)); SphericalHarmonicMath.PackCoefficients(m_PackedCoeffs, finalSH); cmd.SetGlobalVectorArray(HDShaderIDs._AmbientProbeCoeffs, m_PackedCoeffs); }
public float[] coeffs; // Must have the size of 3 public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float anisotropy) { float g = anisotropy; var zh = new ZonalHarmonicsL2(); zh.coeffs = new float[3]; zh.coeffs[0] = 0.5f * Mathf.Sqrt(1.0f / Mathf.PI); zh.coeffs[1] = 0.5f * Mathf.Sqrt(3.0f / Mathf.PI) * g; zh.coeffs[2] = 0.5f * Mathf.Sqrt(5.0f / Mathf.PI) * g * g; return(zh); }
// Function that fills the buffer with the ambient probe values unsafe void SetPreconvolvedAmbientLightProbe(ref ShaderVariablesClouds cb, HDCamera hdCamera, VolumetricClouds settings) { SphericalHarmonicsL2 probeSH = SphericalHarmonicMath.UndoCosineRescaling(m_SkyManager.GetAmbientProbe(hdCamera)); probeSH = SphericalHarmonicMath.RescaleCoefficients(probeSH, settings.ambientLightProbeDimmer.value); ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(m_PhaseZHClouds, 0.0f); SphericalHarmonicsL2 finalSH = SphericalHarmonicMath.PremultiplyCoefficients(SphericalHarmonicMath.Convolve(probeSH, m_PhaseZHClouds)); SphericalHarmonicMath.PackCoefficients(m_PackedCoeffsClouds, finalSH); for (int i = 0; i < 7; i++) { for (int j = 0; j < 4; ++j) { cb._AmbientProbeCoeffs[i * 4 + j] = m_PackedCoeffsClouds[i][j]; } } }
void InitializeVolumetricClouds() { // Keep track of the state for the release m_ActiveVolumetricClouds = m_Asset.currentPlatformRenderPipelineSettings.supportVolumetricClouds; if (!m_ActiveVolumetricClouds) { return; } // Allocate the buffers for ambient probe evaluation m_PhaseZHClouds = new ZonalHarmonicsL2(); m_PhaseZHClouds.coeffs = new float[3]; // Grab the kernels we need ComputeShader volumetricCloudsCS = m_Asset.renderPipelineResources.shaders.volumetricCloudsCS; m_ConvertObliqueDepthKernel = volumetricCloudsCS.FindKernel("ConvertObliqueDepth"); m_CloudDownscaleDepthKernel = volumetricCloudsCS.FindKernel("DownscaleDepth"); m_CloudRenderKernel = volumetricCloudsCS.FindKernel("RenderClouds"); m_ReprojectCloudsKernel = volumetricCloudsCS.FindKernel("ReprojectClouds"); m_ReprojectCloudsRejectionKernel = volumetricCloudsCS.FindKernel("ReprojectCloudsRejection"); m_PreUpscaleCloudsKernel = volumetricCloudsCS.FindKernel("PreUpscaleClouds"); m_PreUpscaleCloudsSkyKernel = volumetricCloudsCS.FindKernel("PreUpscaleCloudsSky"); m_UpscaleAndCombineCloudsKernelColorCopy = volumetricCloudsCS.FindKernel("UpscaleAndCombineClouds_ColorCopy"); m_UpscaleAndCombineCloudsKernelColorRW = volumetricCloudsCS.FindKernel("UpscaleAndCombineClouds_ColorRW"); m_UpscaleAndCombineCloudsSkyKernel = volumetricCloudsCS.FindKernel("UpscaleAndCombineCloudsSky"); m_CombineCloudsKernelColorCopy = volumetricCloudsCS.FindKernel("CombineClouds_ColorCopy"); m_CombineCloudsKernelColorRW = volumetricCloudsCS.FindKernel("CombineClouds_ColorRW"); m_CombineCloudsSkyKernel = volumetricCloudsCS.FindKernel("CombineCloudsSky"); // Create the material needed for the combination m_CloudCombinePass = CoreUtils.CreateEngineMaterial(defaultResources.shaders.volumetricCloudsCombinePS); // Allocate all the texture initially AllocatePresetTextures(); // Initialize the additional sub components InitializeVolumetricCloudsMap(); InitializeVolumetricCloudsShadows(); InitializeVolumetricCloudsAmbientProbe(); }
// Ref: "Stupid Spherical Harmonics Tricks", p. 6. public static SphericalHarmonicsL2 Convolve(SphericalHarmonicsL2 sh, ZonalHarmonicsL2 zh) { for (int l = 0; l <= 2; l++) { float n = Mathf.Sqrt((4.0f * Mathf.PI) / (2 * l + 1)); float k = zh.coeffs[l]; float p = n * k; for (int m = -l; m <= l; m++) { int i = l * (l + 1) + m; for (int c = 0; c < 3; c++) { sh[c, i] *= p; } } } return(sh); }
void InitializeVolumetricLighting() { m_SupportVolumetrics = asset.currentPlatformRenderPipelineSettings.supportVolumetrics; if (!m_SupportVolumetrics) { return; } m_VolumeVoxelizationCS = defaultResources.shaders.volumeVoxelizationCS; m_VolumetricLightingCS = defaultResources.shaders.volumetricLightingCS; m_VolumetricLightingFilteringCS = defaultResources.shaders.volumetricLightingFilteringCS; m_PackedCoeffs = new Vector4[7]; m_PhaseZH = new ZonalHarmonicsL2(); m_PhaseZH.coeffs = new float[3]; m_xySeq = new Vector2[7]; m_PixelCoordToViewDirWS = new Matrix4x4[ShaderConfig.s_XrMaxViews]; CreateVolumetricLightingBuffers(); }