void RenderSkyToCubemap(BuiltinSkyParameters builtinParams, SkySettings skySettings, RenderTexture target) { for (int i = 0; i < 6; ++i) { builtinParams.pixelCoordToViewDirMatrix[0] = m_facePixelCoordToViewDirMatrices[i]; builtinParams.invViewProjMatrix[0] = m_faceCameraInvViewProjectionMatrix[i]; builtinParams.colorBuffer = target; builtinParams.depthBuffer = BuiltinSkyParameters.nullRT; CoreUtils.SetRenderTarget(builtinParams.commandBuffer, target, ClearFlag.None, 0, (CubemapFace)i); m_Renderer.RenderSky(builtinParams, false, true); } // Generate mipmap for our cubemap Debug.Assert(target.autoGenerateMips == false); builtinParams.commandBuffer.GenerateMips(target); }
void RenderCubemapGGXConvolution(CommandBuffer cmd, BuiltinSkyParameters builtinParams, SkySettings skyParams, Texture input, RenderTexture target) { using (new ProfilingSample(cmd, "Update Env: GGX Convolution")) { int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f); if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1)) { Debug.LogWarning("RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ((int)EnvConstants.SpecCubeLodStep + 1) + " mip levels"); return; } if (!m_iblFilterGgx.IsInitialized()) { m_iblFilterGgx.Initialize(cmd); } // Copy the first mip using (new ProfilingSample(cmd, "Copy Original Mip")) { for (int f = 0; f < 6; f++) { cmd.CopyTexture(input, f, 0, target, f, 0); } } using (new ProfilingSample(cmd, "GGX Convolution")) { if (m_useMIS && m_iblFilterGgx.supportMis) { m_iblFilterGgx.FilterCubemapMIS(cmd, input, target, mipCount, m_SkyboxConditionalCdfRT, m_SkyboxMarginalRowCdfRT, m_faceWorldToViewMatrixMatrices); } else { m_iblFilterGgx.FilterCubemap(cmd, input, target, mipCount, m_faceWorldToViewMatrixMatrices); } } } }
void RebuildTextures(SkySettings skySettings) { int resolution = 256; // Parameters not set yet. We need them for the resolution. if (skySettings != null) { resolution = (int)skySettings.resolution; } if ((m_SkyboxCubemapRT != null) && (m_SkyboxCubemapRT.width != resolution)) { CoreUtils.Destroy(m_SkyboxCubemapRT); CoreUtils.Destroy(m_SkyboxGGXCubemapRT); CoreUtils.Destroy(m_SkyboxMarginalRowCdfRT); CoreUtils.Destroy(m_SkyboxConditionalCdfRT); m_SkyboxCubemapRT = null; m_SkyboxGGXCubemapRT = null; m_SkyboxMarginalRowCdfRT = null; m_SkyboxConditionalCdfRT = null; } if (m_SkyboxCubemapRT == null) { m_SkyboxCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear) { dimension = TextureDimension.Cube, useMipMap = true, autoGenerateMips = false, // We will generate regular mipmap for filtered importance sampling manually filterMode = FilterMode.Trilinear }; m_SkyboxCubemapRT.Create(); m_SkyboxGGXCubemapRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear) { dimension = TextureDimension.Cube, useMipMap = true, autoGenerateMips = false, filterMode = FilterMode.Trilinear }; m_SkyboxGGXCubemapRT.Create(); if (m_useMIS) { int width = (int)LightSamplingParameters.TextureWidth; int height = (int)LightSamplingParameters.TextureHeight; // + 1 because we store the value of the integral of the cubemap at the end of the texture. m_SkyboxMarginalRowCdfRT = new RenderTexture(height + 1, 1, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear) { useMipMap = false, autoGenerateMips = false, enableRandomWrite = true, filterMode = FilterMode.Point }; m_SkyboxMarginalRowCdfRT.Create(); // TODO: switch the format to R16 (once it's available) to save some bandwidth. m_SkyboxConditionalCdfRT = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear) { useMipMap = false, autoGenerateMips = false, enableRandomWrite = true, filterMode = FilterMode.Point }; m_SkyboxConditionalCdfRT.Create(); } m_UpdatedFramesRequired = 2; // Special case. Even if update mode is set to OnDemand, we need to regenerate the environment after destroying the texture. } m_CubemapScreenSize = new Vector4((float)resolution, (float)resolution, 1.0f / (float)resolution, 1.0f / (float)resolution); }