浏览代码

Remove the pre-generated mesh dependency from the GGX convolution shader

/main
Evgenii Golubev 7 年前
当前提交
07664395
共有 3 个文件被更改,包括 38 次插入34 次删除
  1. 43
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/GGXConvolve.shader
  2. 23
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs
  3. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs

43
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/GGXConvolve.shader


#include "../../ShaderLibrary/ImageBasedLighting.hlsl"
#include "SkyManager.cs.hlsl"
TEXTURECUBE(_MainTex);
SAMPLERCUBE(sampler_MainTex);
TEXTURE2D_FLOAT(_GgxIblSamples);
#ifdef USE_MIS
TEXTURE2D(_MarginalRowDensities);
TEXTURE2D(_ConditionalDensities);
#endif
float _Level;
float _LastLevel;
float _InvOmegaP;
float4x4 _PixelCoordToViewDirWS; // Actually just 3x3, but Unity can only set 4x4
float3 positionCS : POSITION;
float3 eyeVector : NORMAL;
uint vertexID : SV_VertexID;
float3 eyeVector : TEXCOORD0;
// Unity renders upside down, so the clip space coordinates have to be flipped.
output.positionCS = float4(input.positionCS.x, -input.positionCS.y, UNITY_RAW_FAR_CLIP_VALUE, 1.0);
output.eyeVector = input.eyeVector;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
TEXTURECUBE(_MainTex);
SAMPLERCUBE(sampler_MainTex);
TEXTURE2D_FLOAT(_GgxIblSamples);
#ifdef USE_MIS
TEXTURE2D(_MarginalRowDensities);
TEXTURE2D(_ConditionalDensities);
#endif
float _Level;
float _LastLevel;
float _InvOmegaP;
// Vector interpolation is not magnitude-preserving.
float3 N = normalize(input.eyeVector);
// Points towards the camera
float3 viewDirWS = normalize(mul(float3(input.positionCS.xy, 1.0), (float3x3)_PixelCoordToViewDirWS));
// Reverse it to point into the scene
float3 N = -viewDirWS;
// Remove view-dependency from GGX, effectively making the BSDF isotropic.
float3 V = N;

23
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs


void FilterCubemapCommon(CommandBuffer cmd,
Texture source, RenderTexture target, int mipCount,
Mesh[] cubemapFaceMesh)
Matrix4x4[] worldToViewMatrices)
{
// Solid angle associated with a texel of the cubemap.
float invOmegaP = (6.0f * source.width * source.width) / (4.0f * Mathf.PI);

string sampleName = String.Format("Filter Cubemap Mip {0}", mip);
cmd.BeginSample(sampleName);
MaterialPropertyBlock props = new MaterialPropertyBlock();
props.SetFloat("_Level", mip);
Vector4 faceSize = new Vector4(source.width >> mip, source.height >> mip, 1.0f / (source.width >> mip), 1.0f / (source.height >> mip));
Matrix4x4 transform = SkyManager.ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, faceSize, worldToViewMatrices[face], true);
MaterialPropertyBlock props = new MaterialPropertyBlock();
props.SetFloat("_Level", mip);
props.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
cmd.DrawMesh(cubemapFaceMesh[face], Matrix4x4.identity, m_GgxConvolveMaterial, 0, 0, props);
Utilities.DrawFullScreen(cmd, m_GgxConvolveMaterial, props);
}
cmd.EndSample(sampleName);
}

public void FilterCubemap(CommandBuffer cmd,
Texture source, RenderTexture target, int mipCount,
Mesh[] cubemapFaceMesh)
Matrix4x4[] worldToViewMatrices)
FilterCubemapCommon(cmd, source, target, mipCount, cubemapFaceMesh);
FilterCubemapCommon(cmd, source, target, mipCount, worldToViewMatrices);
}
// Filters MIP map levels (other than 0) with GGX using multiple importance sampling.

Mesh[] cubemapFaceMesh)
Matrix4x4[] worldToViewMatrices)
{
// Bind the input cubemap.
m_BuildProbabilityTablesCS.SetTexture(m_ConditionalDensitiesKernel, "envMap", source);

m_GgxConvolveMaterial.SetTexture("_ConditionalDensities", conditionalCdf);
m_GgxConvolveMaterial.SetTexture("_MarginalRowDensities", marginalRowCdf);
FilterCubemapCommon(cmd, source, target, mipCount, cubemapFaceMesh);
FilterCubemapCommon(cmd, source, target, mipCount, worldToViewMatrices);
}
}
}

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs


IBLFilterGGX m_iblFilterGgx = null;
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceWorldToViewMatrixMatrices = new Matrix4x4[6];
Matrix4x4[] m_facePixelCoordToViewDirMatrices = new Matrix4x4[6];
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];

Matrix4x4 worldToView = 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. ...
Vector4 screenSize = new Vector4((int)m_SkySettings.resolution, (int)m_SkySettings.resolution, 1.0f / (int)m_SkySettings.resolution, 1.0f / (int)m_SkySettings.resolution);
m_faceWorldToViewMatrixMatrices[i] = worldToView;
m_facePixelCoordToViewDirMatrices[i] = ComputePixelCoordToWorldSpaceViewDirectionMatrix(0.5f * Mathf.PI, screenSize, worldToView, true);
m_faceCameraInvViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj).inverse;

{
if (m_useMIS && m_iblFilterGgx.SupportMIS)
{
m_iblFilterGgx.FilterCubemapMIS(cmd, input, target, mipCount, m_SkyboxConditionalCdfRT, m_SkyboxMarginalRowCdfRT, m_CubemapFaceMesh);
m_iblFilterGgx.FilterCubemapMIS(cmd, input, target, mipCount, m_SkyboxConditionalCdfRT, m_SkyboxMarginalRowCdfRT, m_faceWorldToViewMatrixMatrices);
m_iblFilterGgx.FilterCubemap(cmd, input, target, mipCount, m_CubemapFaceMesh);
m_iblFilterGgx.FilterCubemap(cmd, input, target, mipCount, m_faceWorldToViewMatrixMatrices);
}
}
}

正在加载...
取消
保存