浏览代码

Merge pull request #100 from EvgeniiG/master

Precompute IBL samples on GPU
/main
GitHub 8 年前
当前提交
b03bf46b
共有 11 个文件被更改,包括 311 次插入126 次删除
  1. 11
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.cs
  2. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.hlsl
  3. 26
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader
  4. 65
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyManager.cs
  5. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/BSDF.hlsl
  6. 14
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  7. 106
      Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl
  8. 49
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute
  9. 9
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute.meta
  10. 134
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/RuntimeFilterIBL.cs
  11. 12
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/RuntimeFilterIBL.cs.meta

11
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.cs


// Init precomputed texture
//-----------------------------------------------------------------------------
public bool isInit;
public bool isInit;
private Material m_InitPreFGD;
private Material m_InitPreFGD;
private RenderTexture m_PreIntegratedFGD;
// For area lighting

Material mat = new Material(Shader.Find(shaderPath) as Shader);
mat.hideFlags = HideFlags.HideAndDontSave;
return mat;
}
}
Texture2D CreateLUT(int width, int height, TextureFormat format, Color[] pixels)
{

const int count = k_LtcLUTResolution * k_LtcLUTResolution;
Color[] pixels = new Color[count];
// amplitude
for (int i = 0; i < count; i++)
{
pixels[i] = new Color(0, 0, 0, LUTScalar[i]);

const int count = k_LtcLUTResolution * k_LtcLUTResolution;
Color[] pixels = new Color[count];
// transformInv
for (int i = 0; i < count; i++)
{
// Both GGX and Disney Diffuse BRDFs have zero values in columns 1, 3, 5, 7.

}
return CreateLUT(k_LtcLUTResolution, k_LtcLUTResolution, format, pixels);
}
}
// TODO: switch to RGBA64 when it becomes available.
m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGBHalf);

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.hlsl


float3 iblR = reflect(-V, iblNormalWS);
preLightData.iblDirWS = GetSpecularDominantDir(bsdfData.normalWS, iblR, bsdfData.roughness, preLightData.NdotV);
preLightData.iblMipLevel = perceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
preLightData.iblMipLevel = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
// Area light specific
// UVs for sampling the LUTs

26
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader


TEXTURECUBE(_MainTex);
SAMPLERCUBE(sampler_MainTex);
TEXTURE2D(_GgxIblSamples);
#ifdef USE_MIS
TEXTURE2D(_MarginalRowDensities);
TEXTURE2D(_ConditionalDensities);

float _MaxLevel;
float _LastLevel;
float _InvOmegaP;
half4 Frag(Varyings input) : SV_Target

// Remove view-dependency from GGX, effectively making the BSDF isotropic.
float3 V = N;
float perceptualRoughness = mipmapLevelToPerceptualRoughness(_Level);
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float perceptualRoughness = MipmapLevelToPerceptualRoughness(_Level);
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
uint sampleCount = GetIBLRuntimeFilterSampleCount(_Level);
#ifdef USE_MIS
float4 val = IntegrateLD_MIS(TEXTURECUBE_PARAM(_MainTex, sampler_MainTex),

1024,
false);
#else
uint sampleCount = 0;
switch (_Level)
{
case 1: sampleCount = 21; break;
case 2: sampleCount = 34; break;
case 3: sampleCount = 55; break;
case 4: sampleCount = 89; break;
case 5: sampleCount = 89; break;
case 6: sampleCount = 89; break; // UNITY_SPECCUBE_LOD_STEPS
}
_GgxIblSamples,
_MaxLevel,
_Level - 1,
_LastLevel,
true,
true);
#endif

65
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/SkyManager.cs


RenderTexture m_SkyboxConditionalCdfRT = null;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
ComputeShader m_BuildProbabilityTablesCS = null;
int m_ConditionalDensitiesKernel = -1;
int m_MarginalRowDensitiesKernel = -1;
IBLFilterGGX m_iblFilterGgx = null;
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceCameraViewProjectionMatrix = new Matrix4x4[6];

if (m_Renderer != null)
m_Renderer.Build();
// Create unititialized. Lazy initialization is performed later.
m_iblFilterGgx = new IBLFilterGGX();
m_GGXConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/GGXConvolve");
m_BuildProbabilityTablesCS = Resources.Load<ComputeShader>("BuildProbabilityTables");
m_ConditionalDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeConditionalDensities");
m_MarginalRowDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeMarginalRowDensities");
m_CurrentUpdateTime = 0.0f;
}

Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_GGXConvolveMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
Utilities.Destroy(m_SkyboxMarginalRowCdfRT);

}
}
private void BuildProbabilityTables(ScriptableRenderContext renderContext)
{
// Bind the input cubemap.
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "envMap", m_SkyboxCubemapRT);
// Bind the outputs.
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "marginalRowDensities", m_SkyboxMarginalRowCdfRT);
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "conditionalDensities", m_SkyboxConditionalCdfRT);
m_BuildProbabilityTablesCS.SetTexture(m_MarginalRowDensitiesKernel, "marginalRowDensities", m_SkyboxMarginalRowCdfRT);
var cmd = new CommandBuffer() { name = "" };
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_ConditionalDensitiesKernel, (int)LightSamplingParameters.TextureHeight, 1, 1);
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_MarginalRowDensitiesKernel, 1, 1, 1);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
private void RenderCubemapGGXConvolution(ScriptableRenderContext renderContext, BuiltinSkyParameters builtinParams, SkyParameters skyParams, Texture input, RenderTexture target)
{
using (new Utilities.ProfilingSample("Sky Pass: GGX Convolution", renderContext))

return;
}
if (m_useMIS)
if (!m_iblFilterGgx.IsInitialized())
BuildProbabilityTables(renderContext);
m_iblFilterGgx.Initialize(renderContext);
}
// Copy the first mip.

if (m_useMIS)
{
m_GGXConvolveMaterial.EnableKeyword("USE_MIS");
m_GGXConvolveMaterial.SetTexture("_MarginalRowDensities", m_SkyboxMarginalRowCdfRT);
m_GGXConvolveMaterial.SetTexture("_ConditionalDensities", m_SkyboxConditionalCdfRT);
m_iblFilterGgx.FilterCubemapGgxMis(renderContext, mipCount, input, target, m_SkyboxConditionalCdfRT, m_SkyboxMarginalRowCdfRT, m_CubemapFaceMesh);
m_GGXConvolveMaterial.DisableKeyword("USE_MIS");
}
// Do the convolution on remaining mipmaps
float invOmegaP = (6.0f * input.width * input.width) / (4.0f * Mathf.PI); // Solid angle associated to a pixel of the cubemap;
m_GGXConvolveMaterial.SetTexture("_MainTex", input);
m_GGXConvolveMaterial.SetFloat("_MaxLevel", mipCount - 1);
m_GGXConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
{
Utilities.SetRenderTarget(renderContext, target, ClearFlag.ClearNone, mip, (CubemapFace)face);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(m_CubemapFaceMesh[face], Matrix4x4.identity, m_GGXConvolveMaterial, 0, 0, propertyBlock);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
m_iblFilterGgx.FilterCubemapGgx(renderContext, mipCount, input, target, m_CubemapFaceMesh);
}
}

9
Assets/ScriptableRenderLoop/ShaderLibrary/BSDF.hlsl


return INV_PI * D_GGXNoPI(NdotH, roughness);
}
float D_GGX_Inverse(float NdotH, float roughness)
{
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
float g = (f * f) / a2;
return PI * g;
}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 19, 29.
float G_MaskingSmithGGX(float NdotV, float VdotH, float roughness)
{

14
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


return x * x * (3.0 - (2.0 * x));
}
const float3x3 k_identity3x3 = {1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0};
static const float3x3 k_identity3x3 = {1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0};
const float4x4 k_identity4x4 = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
static const float4x4 k_identity4x4 = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0};
// Using pow often result to a warning like this
// "pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them"

106
Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl


// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution.
float perceptualRoughnessToMipmapLevel(float perceptualRoughness)
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness)
{
perceptualRoughness = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness);

// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution and adds reflection (contact) hardening.
// TODO: optimize!
float perceptualRoughnessToMipmapLevel(float perceptualRoughness, float NdotR)
float PerceptualRoughnessToMipmapLevel(float perceptualRoughness, float NdotR)
{
float m = PerceptualRoughnessToRoughness(perceptualRoughness);

}
// The inverse of the *approximated* version of perceptualRoughnessToMipmapLevel().
float mipmapLevelToPerceptualRoughness(float mipmapLevel)
float MipmapLevelToPerceptualRoughness(float mipmapLevel)
{
float perceptualRoughness = saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);

return acc / sampleCount;
}
uint GetIBLRuntimeFilterSampleCount(uint mipLevel)
{
uint sampleCount = 0;
switch (mipLevel)
{
case 1: sampleCount = 21; break;
case 2: sampleCount = 34; break;
case 3: sampleCount = 55; break;
case 4: sampleCount = 89; break;
case 5: sampleCount = 89; break;
case 6: sampleCount = 89; break; // UNITY_SPECCUBE_LOD_STEPS
}
return sampleCount;
}
float3 V,
float3 N,
float roughness,
float maxMipLevel,
float invOmegaP,
uint sampleCount, // Must be a Fibonacci number
bool prefilter)
TEXTURE2D(iblGgxSamples),
float3 V,
float3 N,
float roughness,
float index, // Current MIP level minus one
float lastMipLevel,
float invOmegaP,
uint sampleCount, // Must be a Fibonacci number
bool prefilter,
bool usePrecomputedSamples)
// Bias samples towards the mirror direction to reduce variance.
// This will have a side effect of making the reflection sharper.
// Ref: Stochastic Screen-Space Reflections, p. 67.
const float bias = 0.5 * roughness;
float2 u = Fibonacci2d(i, sampleCount);
// Bias samples towards the mirror direction to reduce variance.
// This will have a side effect of making the reflection sharper.
// Ref: Stochastic Screen-Space Reflections, p. 67.
const float bias = 0.1 + 0.2 * roughness;
u.x = lerp(u.x, 0.0, bias);
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH, true);
bool isValid;
if (usePrecomputedSamples)
{
float3 localL = LOAD_TEXTURE2D(iblGgxSamples, uint2(i, index)).xyz;
L = mul(localL, localToWorld);
NdotL = localL.z;
isValid = true;
}
else
{
float2 u = Fibonacci2d(i, sampleCount);
u.x = lerp(u.x, 0.0, bias);
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH, true);
isValid = NdotL > 0.0;
}
float mipLevel;

// can be simplified:
// pdf = D * NdotH / (4 * LdotH) = D * 0.25;
//
// - OmegaS : Solid angle associated to a sample
// - OmegaP : Solid angle associated to a pixel of the cubemap
// - OmegaS : Solid angle associated with the sample
// - OmegaP : Solid angle associated with the texel of the cubemap
float invPdf = D_GGX_Inverse(NdotH, roughness) * 4.0;
// TODO: check the accuracy of the sample's solid angle fit for GGX.
float omegaS = rcp(sampleCount) * invPdf;
float omegaS;
if (usePrecomputedSamples)
{
omegaS = LOAD_TEXTURE2D(iblGgxSamples, uint2(i, index)).w;
}
else
{
float pdf = D_GGX(NdotH, roughness) * 0.25;
// TODO: check the accuracy of the sample's solid angle fit for GGX.
omegaS = rcp(sampleCount) / pdf;
}
}
if (isValid)
{
mipLevel = lerp(mipLevel, maxMipLevel, bias);
mipLevel = lerp(mipLevel, lastMipLevel, bias);
// TODO: There is a bug currently where autogenerate mipmap for the cubemap seems to clamp the mipLevel to 6. correct it! Then remove this clamp
// TODO: There is a bug currently where autogenerate mipmap for the cubemap seems to
// clamp the mipLevel to 6. correct it! Then remove this clamp
}
if (NdotL > 0.0)
{
// TODO: use a Gaussian-like filter to generate the MIP pyramid.
float3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;

// (LdotH == NdotH) && (NdotV == 1) && (Weight == F * G).
// We use the approximation of Brian Karis from "Real Shading in Unreal Engine 4":
// Weight ≈ NdotL, which produces nearly identical results in practice.
lightInt += NdotL * val;
cbsdfInt += NdotL;
}

49
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute


// Precomputes data for IntegrateLD(). See that function for a detailed description.
#include "Common.hlsl"
#include "ImageBasedLighting.hlsl"
#define MAX_IBL_SAMPLE_CNT 89
RWTexture2D<float4> output; // [MAX_SAMPLE_CNT x UNITY_SPECCUBE_LOD_STEPS]
#pragma kernel ComputeGgxIblSampleData
[numthreads(MAX_IBL_SAMPLE_CNT, UNITY_SPECCUBE_LOD_STEPS, 1)]
void ComputeGgxIblSampleData(uint3 groupThreadId : SV_GroupThreadID)
{
uint sampleIndex = groupThreadId.x;
uint mipLevel = groupThreadId.y + 1;
uint sampleCount = GetIBLRuntimeFilterSampleCount(mipLevel);
if (sampleIndex >= sampleCount)
{
output[groupThreadId.xy] = float4(0, 0, 0, 0);
return;
}
float perceptualRoughness = MipmapLevelToPerceptualRoughness(mipLevel);
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float bias = 0.5 * roughness;
float2 u = Fibonacci2d(sampleIndex, sampleCount);
u.x = lerp(u.x, 0, bias);
float3 localL;
float NdotL, NdotH, VdotH;
SampleGGXDir(u, float3(0, 0, 1), k_identity3x3, roughness, localL, NdotL, NdotH, VdotH, true);
if (NdotL <= 0)
{
// We are not supposed to generate wasteful samples.
output[groupThreadId.xy] = float4(0, 0, 0, 0);
return;
}
float pdf = D_GGX(NdotH, roughness) * 0.25;
float omegaS = rcp(sampleCount * pdf);
output[groupThreadId.xy] = float4(localL, omegaS);
}

9
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/ComputeGgxIblSampleData.compute.meta


fileFormatVersion: 2
guid: 764a24bb47ef5ba4781d9ae82ca07445
timeCreated: 1484572881
licenseType: Pro
ComputeShaderImporter:
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

134
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/RuntimeFilterIBL.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class IBLFilterGGX
{
RenderTexture m_GgxIblSampleData = null;
const int k_GgxIblMaxSampleCount = 89; // Width
const int k_GgxIblMipCountMinusOne = 6; // Height (UNITY_SPECCUBE_LOD_STEPS)
ComputeShader m_ComputeGgxIblSampleDataCS = null;
int m_ComputeIblGgxSampleDataKernel = -1;
ComputeShader m_BuildProbabilityTablesCS = null;
int m_ConditionalDensitiesKernel = -1;
int m_MarginalRowDensitiesKernel = -1;
Material m_GgxConvolveMaterial = null; // Convolves a cubemap with GGX
public bool IsInitialized()
{
return m_GgxIblSampleData != null;
}
public void Initialize(ScriptableRenderContext context)
{
if (!m_ComputeGgxIblSampleDataCS)
{
m_ComputeGgxIblSampleDataCS = Resources.Load<ComputeShader>("ComputeGgxIblSampleData");
m_ComputeIblGgxSampleDataKernel = m_ComputeGgxIblSampleDataCS.FindKernel("ComputeGgxIblSampleData");
}
if (!m_BuildProbabilityTablesCS)
{
m_BuildProbabilityTablesCS = Resources.Load<ComputeShader>("BuildProbabilityTables");
m_ConditionalDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeConditionalDensities");
m_MarginalRowDensitiesKernel = m_BuildProbabilityTablesCS.FindKernel("ComputeMarginalRowDensities");
}
if (!m_GgxConvolveMaterial)
{
m_GgxConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/GGXConvolve");
}
if (!m_GgxIblSampleData)
{
m_GgxIblSampleData = new RenderTexture(k_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, 1, RenderTextureFormat.ARGBFloat);
m_GgxIblSampleData.dimension = TextureDimension.Tex2D;
m_GgxIblSampleData.useMipMap = false;
m_GgxIblSampleData.autoGenerateMips = false;
m_GgxIblSampleData.enableRandomWrite = true;
m_GgxIblSampleData.filterMode = FilterMode.Point;
m_GgxIblSampleData.Create();
m_ComputeGgxIblSampleDataCS.SetTexture(m_ComputeIblGgxSampleDataKernel, "output", m_GgxIblSampleData);
var cmd = new CommandBuffer() { name = "Compute GGX IBL Sample Data" };
cmd.DispatchCompute(m_ComputeGgxIblSampleDataCS, m_ComputeIblGgxSampleDataKernel, 1, 1, 1);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
void FilterCubemapGgxCommon(ScriptableRenderContext context, int mipCount,
Texture source, RenderTexture target,
Mesh[] cubemapFaceMesh)
{
// Solid angle associated with a texel of the cubemap.
float invOmegaP = (6.0f * source.width * source.width) / (4.0f * Mathf.PI);
m_GgxConvolveMaterial.SetTexture("_MainTex", source);
m_GgxConvolveMaterial.SetTexture("_GgxIblSamples", m_GgxIblSampleData);
m_GgxConvolveMaterial.SetFloat("_LastLevel", mipCount - 1);
m_GgxConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock props = new MaterialPropertyBlock();
props.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
{
Utilities.SetRenderTarget(context, target, ClearFlag.ClearNone, mip, (CubemapFace)face);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(cubemapFaceMesh[face], Matrix4x4.identity, m_GgxConvolveMaterial, 0, 0, props);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}
// Filters MIP map levels (other than 0) with GGX using BRDF importance sampling.
public void FilterCubemapGgx(ScriptableRenderContext context, int mipCount,
Texture source, RenderTexture target,
Mesh[] cubemapFaceMesh)
{
m_GgxConvolveMaterial.DisableKeyword("USE_MIS");
FilterCubemapGgxCommon(context, mipCount, source, target, cubemapFaceMesh);
}
// Filters MIP map levels (other than 0) with GGX using multiple importance sampling.
public void FilterCubemapGgxMis(ScriptableRenderContext context, int mipCount,
Texture source, RenderTexture target,
RenderTexture conditionalCdf, RenderTexture marginalRowCdf,
Mesh[] cubemapFaceMesh)
{
// 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;
var cmd = new CommandBuffer() { name = "Build Probability Tables" };
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_ConditionalDensitiesKernel, numRows, 1, 1);
cmd.DispatchCompute(m_BuildProbabilityTablesCS, m_MarginalRowDensitiesKernel, 1, 1, 1);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
m_GgxConvolveMaterial.EnableKeyword("USE_MIS");
m_GgxConvolveMaterial.SetTexture("_ConditionalDensities", conditionalCdf);
m_GgxConvolveMaterial.SetTexture("_MarginalRowDensities", marginalRowCdf);
FilterCubemapGgxCommon(context, mipCount, source, target, cubemapFaceMesh);
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/RuntimeFilterIBL.cs.meta


fileFormatVersion: 2
guid: 827056f7b26e8a64883735043af76431
timeCreated: 1484572874
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存