您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
170 行
7.5 KiB
170 行
7.5 KiB
using UnityEngine.Rendering;
|
|
using System;
|
|
|
|
namespace UnityEngine.Experimental.Rendering.HDPipeline
|
|
{
|
|
public class IBLFilterGGX
|
|
{
|
|
RenderTexture m_GgxIblSampleData;
|
|
int m_GgxIblMaxSampleCount = TextureCache.isMobileBuildTarget ? 34 : 89; // Width
|
|
const int k_GgxIblMipCountMinusOne = 6; // Height (UNITY_SPECCUBE_LOD_STEPS)
|
|
|
|
ComputeShader m_ComputeGgxIblSampleDataCS;
|
|
int m_ComputeGgxIblSampleDataKernel = -1;
|
|
|
|
ComputeShader m_BuildProbabilityTablesCS;
|
|
int m_ConditionalDensitiesKernel = -1;
|
|
int m_MarginalRowDensitiesKernel = -1;
|
|
|
|
Material m_GgxConvolveMaterial; // Convolves a cubemap with GGX
|
|
|
|
Matrix4x4[] m_faceWorldToViewMatrixMatrices = new Matrix4x4[6];
|
|
|
|
|
|
RenderPipelineResources m_RenderPipelineResources;
|
|
|
|
public bool supportMis
|
|
{
|
|
get { return !TextureCache.isMobileBuildTarget; }
|
|
}
|
|
|
|
public IBLFilterGGX(RenderPipelineResources renderPipelineResources)
|
|
{
|
|
m_RenderPipelineResources = renderPipelineResources;
|
|
}
|
|
|
|
public bool IsInitialized()
|
|
{
|
|
return m_GgxIblSampleData != null;
|
|
}
|
|
|
|
public void Initialize(CommandBuffer cmd)
|
|
{
|
|
if (!m_ComputeGgxIblSampleDataCS)
|
|
{
|
|
m_ComputeGgxIblSampleDataCS = m_RenderPipelineResources.computeGgxIblSampleData;
|
|
m_ComputeGgxIblSampleDataKernel = m_ComputeGgxIblSampleDataCS.FindKernel("ComputeGgxIblSampleData");
|
|
}
|
|
|
|
if (!m_BuildProbabilityTablesCS && supportMis)
|
|
{
|
|
m_BuildProbabilityTablesCS = m_RenderPipelineResources.buildProbabilityTables;
|
|
m_ConditionalDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeConditionalDensities");
|
|
m_MarginalRowDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeMarginalRowDensities");
|
|
}
|
|
|
|
if (!m_GgxConvolveMaterial)
|
|
{
|
|
m_GgxConvolveMaterial = CoreUtils.CreateEngineMaterial(m_RenderPipelineResources.GGXConvolve);
|
|
}
|
|
|
|
if (!m_GgxIblSampleData)
|
|
{
|
|
m_GgxIblSampleData = new RenderTexture(m_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
|
|
m_GgxIblSampleData.useMipMap = false;
|
|
m_GgxIblSampleData.autoGenerateMips = false;
|
|
m_GgxIblSampleData.enableRandomWrite = true;
|
|
m_GgxIblSampleData.filterMode = FilterMode.Point;
|
|
m_GgxIblSampleData.Create();
|
|
|
|
m_ComputeGgxIblSampleDataCS.SetTexture(m_ComputeGgxIblSampleDataKernel, "output", m_GgxIblSampleData);
|
|
|
|
using (new ProfilingSample(cmd, "Compute GGX IBL Sample Data"))
|
|
{
|
|
cmd.DispatchCompute(m_ComputeGgxIblSampleDataCS, m_ComputeGgxIblSampleDataKernel, 1, 1, 1);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 6; ++i)
|
|
{
|
|
var lookAt = Matrix4x4.LookAt(Vector3.zero, CoreUtils.lookAtList[i], CoreUtils.upVectorList[i]);
|
|
m_faceWorldToViewMatrixMatrices[i] = lookAt * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API. ...
|
|
}
|
|
}
|
|
|
|
void FilterCubemapCommon( CommandBuffer cmd,
|
|
Texture source, RenderTexture target,
|
|
Matrix4x4[] worldToViewMatrices)
|
|
{
|
|
int mipCount = 1 + (int)Mathf.Log(source.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;
|
|
}
|
|
|
|
// Copy the first mip
|
|
using (new ProfilingSample(cmd, "Copy Original Mip"))
|
|
{
|
|
for (int f = 0; f < 6; f++)
|
|
{
|
|
cmd.CopyTexture(source, f, 0, target, f, 0);
|
|
}
|
|
}
|
|
|
|
// Solid angle associated with a texel of the cubemap.
|
|
float invOmegaP = (6.0f * source.width * source.width) / (4.0f * Mathf.PI);
|
|
|
|
m_GgxConvolveMaterial.SetTexture("_GgxIblSamples", m_GgxIblSampleData);
|
|
|
|
var props = new MaterialPropertyBlock();
|
|
props.SetTexture("_MainTex", source);
|
|
props.SetFloat("_InvOmegaP", invOmegaP);
|
|
|
|
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
|
|
{
|
|
props.SetFloat("_Level", mip);
|
|
|
|
using (new ProfilingSample(cmd, "Filter Cubemap Mip {0}", mip))
|
|
{
|
|
for (int face = 0; face < 6; ++face)
|
|
{
|
|
var faceSize = new Vector4(source.width >> mip, source.height >> mip, 1.0f / (source.width >> mip), 1.0f / (source.height >> mip));
|
|
var transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, faceSize, worldToViewMatrices[face], true);
|
|
|
|
props.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
|
|
|
|
CoreUtils.SetRenderTarget(cmd, target, ClearFlag.None, mip, (CubemapFace)face);
|
|
CoreUtils.DrawFullScreen(cmd, m_GgxConvolveMaterial, props);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Filters MIP map levels (other than 0) with GGX using BRDF importance sampling.
|
|
public void FilterCubemap(CommandBuffer cmd, Texture source, RenderTexture target)
|
|
{
|
|
m_GgxConvolveMaterial.DisableKeyword("USE_MIS");
|
|
|
|
FilterCubemapCommon(cmd, source, target, m_faceWorldToViewMatrixMatrices);
|
|
}
|
|
|
|
// Filters MIP map levels (other than 0) with GGX using multiple importance sampling.
|
|
public void FilterCubemapMIS( CommandBuffer cmd,
|
|
Texture source, RenderTexture target,
|
|
RenderTexture conditionalCdf, RenderTexture marginalRowCdf)
|
|
{
|
|
// Bind the input cubemap.
|
|
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "envMap", source);
|
|
|
|
// Bind the outputs.
|
|
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "conditionalDensities", conditionalCdf);
|
|
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "marginalRowDensities", marginalRowCdf);
|
|
m_BuildProbabilityTablesCS.SetTexture(m_MarginalRowDensitiesKernel, "marginalRowDensities", marginalRowCdf);
|
|
|
|
int numRows = conditionalCdf.height;
|
|
|
|
using (new ProfilingSample(cmd, "Build Probability Tables"))
|
|
{
|
|
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_ConditionalDensitiesKernel, numRows, 1, 1);
|
|
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_MarginalRowDensitiesKernel, 1, 1, 1);
|
|
}
|
|
|
|
m_GgxConvolveMaterial.EnableKeyword("USE_MIS");
|
|
m_GgxConvolveMaterial.SetTexture("_ConditionalDensities", conditionalCdf);
|
|
m_GgxConvolveMaterial.SetTexture("_MarginalRowDensities", marginalRowCdf);
|
|
|
|
FilterCubemapCommon(cmd, source, target, m_faceWorldToViewMatrixMatrices);
|
|
}
|
|
}
|
|
}
|