浏览代码

Merge branch 'master' into DebugShader

# Conflicts:
#	Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
/main
Julien Ignace 8 年前
当前提交
60e032e0
共有 21 个文件被更改,包括 229 次插入124 次删除
  1. 2
      .gitignore
  2. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  3. 54
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/DisneyGGX.cs
  4. 22
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/DisneyGGX.shader
  5. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingDeferred.shader
  6. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/DisneyGGX.hlsl
  7. 5
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader
  8. 32
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl
  9. 57
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/TemplateDisneyGGX.hlsl
  10. 6
      Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
  11. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/API/Validate.hlsl
  12. 18
      Assets/ScriptableRenderLoop/ShaderLibrary/BSDF.hlsl
  13. 2
      Assets/ScriptableRenderLoop/ShaderLibrary/Color.hlsl
  14. 18
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  15. 2
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl
  16. 8
      Assets/ScriptableRenderLoop/ShaderLibrary/Filtering.hlsl
  17. 46
      Assets/ScriptableRenderLoop/fptl/ClusteredUtils.h
  18. 7
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  19. 9
      Assets/ScriptableRenderLoop/fptl/Internal-DeferredReflections.shader
  20. 11
      Assets/ScriptableRenderLoop/fptl/Internal-DeferredShading.shader
  21. 31
      Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute

2
.gitignore


*.exe
*.aspx
Assets/UnityHDRI.meta
Assets/UnityHDRI/Gareoult/GareoultWhiteBalanced.exr

4
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
// render opaque objects into GBuffer
DrawRendererSettings settings = new DrawRendererSettings(cull, camera, new ShaderPassName("GBuffer"));
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;

DrawRendererSettings settings = new DrawRendererSettings(cullResults, camera, new ShaderPassName("Forward"));
settings.rendererConfiguration = RendererConfiguration.ConfigureOneLightProbePerRenderer | RendererConfiguration.ConfigureReflectionProbesProbePerRenderer;
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;
settings.inputCullingOptions.SetQueuesTransparent();
renderLoop.DrawRenderers(ref settings);
}

RenderDeferredLighting(camera, renderLoop);
// RenderForward(cullResults, camera, renderLoop);
RenderForward(cullResults, camera, renderLoop);
FinalPass(renderLoop);
}

54
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/DisneyGGX.cs


EditorGUI.showMixedValue = false;
}
static public void SetupMaterialWithBlendMode(Material material, bool alphaTestEnable, SurfaceType surfaceType, BlendMode blendMode, DoubleSidedMode doubleSidedMode)
static public void SetupMaterial(Material material)
if (alphaTestEnable)
material.EnableKeyword("_ALPHATEST_ON");
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
bool alphaTestEnable = material.GetFloat("_AlphaCutoffEnable") == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat("_SurfaceType");
BlendMode blendMode = (BlendMode)material.GetFloat("_BlendMode");
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat("_DoubleSidedMode");
if (surfaceType == SurfaceType.Opaque)
{

}
}
if (doubleSidedMode != DoubleSidedMode.None)
if (doubleSidedMode != DoubleSidedMode.None || surfaceType == SurfaceType.Transparent)
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
if (doubleSidedMode == DoubleSidedMode.DoubleSided)
if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingFlip)
else
else if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingMirror)
}
}
static bool ShouldEmissionBeEnabled(Material mat, Color color)
{
//var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
//return color.maxColorComponent > 0.1f / 255.0f || realtimeEmission;
return false;
}
}
else
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
static void SetMaterialKeywords(Material material)
{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetKeyword(material, "_NORMALMAP", material.GetTexture("_NormalMap"));
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", (NormalMapSpace)material.GetFloat("_NormalMapSpace") == NormalMapSpace.TangentSpace);
SetKeyword(material, "_MASKMAP", material.GetTexture("_MaskMap"));

*/
}
static bool ShouldEmissionBeEnabled(Material mat, Color color)
{
//var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
//return color.maxColorComponent > 0.1f / 255.0f || realtimeEmission;
return false;
}
bool HasValidEmissiveKeyword (Material material)
{
/*

static void MaterialChanged(Material material)
{
SetupMaterialWithBlendMode(material, material.GetFloat("_AlphaCutoffEnable") == 1.0, (SurfaceType)material.GetFloat("_SurfaceType"), (BlendMode)material.GetFloat("_BlendMode"), (DoubleSidedMode)material.GetFloat("_DoubleSidedMode"));
SetMaterialKeywords(material);
SetupMaterial(material);
}
static void SetKeyword(Material m, string keyword, bool state)

22
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/DisneyGGX.shader


[HideInInspector] _SrcBlend ("__src", Float) = 1.0
[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0 // Back by default: MEGA WARNING - if we override this, how it work with MIRROR ? (to check if the engine correctly flip stuff)
[HideInInspector] _CullMode("__cullmode", Float) = 2.0 // Back by default: MEGA WARNING - if we override this, how it work with reflection plane ? (to check if the engine correctly flip stuff)
// Material Id
[HideInInspector] _MaterialId("_MaterialId", FLoat) = 0

}
CGINCLUDE
HLSLINCLUDE
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR

#pragma shader_feature _HEIGHTMAP
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
ENDCG
ENDHLSL
SubShader
{

ZWrite [_ZWrite]
Cull [_CullMode]
CGPROGRAM
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev

float4 specularLighting;
ForwardLighting(V, positionWS, bsdfData, diffuseLighting, specularLighting);
return float4(diffuseLighting.rgb + specularLighting.rgb, 1.0);
return float4(diffuseLighting.rgb + specularLighting.rgb, surfaceData.opacity);
ENDCG
ENDHLSL
}
// ------------------------------------------------------------------

Name "GBuffer" // Name is not used
Tags { "LightMode" = "GBuffer" } // This will be only for opaque object based on the RenderQueue index
Cull[_CullMode]
Cull [_CullMode]
CGPROGRAM
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev

ENCODE_INTO_GBUFFER(surfaceData, outGBuffer);
}
ENDCG
ENDHLSL
}
// ------------------------------------------------------------------

Cull[_CullMode]
CGPROGRAM
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev

return float4(result, 0.0);
}
ENDCG
ENDHLSL
}
}

4
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingDeferred.shader


ZWrite Off
Blend[_SrcBlend][_DstBlend]
CGPROGRAM
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev

return float4(diffuseLighting.rgb + specularLighting.rgb, 1.0);
}
ENDCG
ENDHLSL
}
}

6
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/DisneyGGX.hlsl


// float distortionBlur; // Define the mipmap level to use
// float2 velocityVector;
float opacity; // Not store, use for blending
};
struct BSDFData

attenuation *= GetAngleAttenuation(L, light.forward, light.angleScale, light.angleOffset);
float illuminance = saturate(dot(bsdfData.normalWS, L)) * attenuation;
diffuseLighting = float4(0.0f, 0.0f, 0.0f, 1.0f);
specularLighting = float4(0.0f, 0.0f, 0.0f, 1.0f);
diffuseLighting = float4(0.0, 0.0, 0.0, 1.0);
specularLighting = float4(0.0, 0.0, 0.0, 1.0);
if (illuminance > 0.0f)
{

5
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader


Pass {
ZTest Always Cull Off ZWrite Off
CGPROGRAM
HLSLPROGRAM
#include "../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderLibrary/Color.hlsl"
#include "../ShaderVariables.hlsl"

}
ENDCG
ENDHLSL
}
}

32
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl


// UNITY_SHADER_NO_UPGRADE
#ifndef UNITY_SHADER_VARIABLES_INCLUDED
#define UNITY_SHADER_VARIABLES_INCLUDED
// CAUTION:
// Currently the shaders compiler always include regualr Unity shaderVariables, so I get a conflict here were UNITY_SHADER_VARIABLES_INCLUDED is already define, this need to be fixed.
// As I haven't change the variables name yet, I simply don't define anything, and I put the transform function at the end of the file outside the guard header.

#ifndef UNITY_SHADER_VARIABLES_INCLUDED
#define UNITY_SHADER_VARIABLES_INCLUDED
#define UNITY_MATRIX_M unity_ObjectToWorld
// These are updated per eye in VR

float4x4 unity_MatrixVP;
#endif
fixed4 glstate_lightmodel_ambient;
fixed4 unity_AmbientSky;
fixed4 unity_AmbientEquator;
fixed4 unity_AmbientGround;
fixed4 unity_IndirectSpecColor;
float4 glstate_lightmodel_ambient;
float4 unity_AmbientSky;
float4 unity_AmbientEquator;
float4 unity_AmbientGround;
float4 unity_IndirectSpecColor;
#endif // UNITY_SHADER_VARIABLES_INCLUDED
float4x4 GetObjectToWorldMatrix()

return glstate_matrix_inv_projection;
}
float GetOdddNegativeScale()
{
return unity_WorldTransformParams.w;
}
float4x4 GetObjectToWorldViewMatrix()
{

float3 TransformObjectToWorld(float3 positionOS)
{
return mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0));
return mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)).xyz;
return mul(GetObjectToWorldViewMatrix(), float4(positionOS, 1.0));
return mul(GetObjectToWorldViewMatrix(), float4(positionOS, 1.0)).xyz;
}
float3 TransformObjectToWorldDir(float3 dirOS)

float3x3 CreateTangentToWorld(float3 normal, float3 tangent, float tangentSign)
{
// For odd-negative scale transforms we need to flip the sign
float sign = tangentSign * unity_WorldTransformParams.w;
float sign = tangentSign * GetOdddNegativeScale();
float3 binormal = cross(normal, tangent) * sign;
return float3x3(tangent, binormal, normal);

{
return normalize(_WorldSpaceCameraPos.xyz - positionWS);
}
#endif // UNITY_SHADER_VARIABLES_INCLUDED

57
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/TemplateDisneyGGX.hlsl


float3 positionWS;
float2 texCoord0;
float4 tangentToWorld[3]; // [3x3:tangentToWorld | 1x3:viewDirForParallax]
/*
#ifdef SHADER_STAGE_FRAGMENT
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
FRONT_FACE_TYPE cullFace;
#endif
#endif
*/
};
struct PackedVaryings

/*
#ifdef SHADER_STAGE_FRAGMENT
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMATIC;
#endif
#endif
*/
};
// Function to pack data to use as few interpolator as possible, the ShaderGraph should generate these functions

output.tangentToWorld[0] = input.interpolators[1];
output.tangentToWorld[1] = input.interpolators[2];
output.tangentToWorld[2] = input.interpolators[3];
/*
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
output.cullFace = input.cullFace;
#endif
*/
return output;
}

output.tangentToWorld[1].w = 0;
output.tangentToWorld[2].w = 0;
/*
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
output.cullFace = FRONT_FACE_TYPE(0); // To avoid a warning
#endif
*/
return PackVaryings(output);
}

clip(alpha - _Cutoff);
#endif
data.opacity = alpha;
float mettalic = 1.0f;
float mettalic = 1.0;
data.diffuseColor = baseColor * (1.0f - mettalic);
data.diffuseColor = baseColor * (1.0 - mettalic);
float f0_dieletric = 0.04;
data.specularColor = lerp(float3(f0_dieletric, f0_dieletric, f0_dieletric), baseColor, mettalic);

#endif
// TODO: think about using BC5
float3 vertexNormalWS = input.tangentToWorld[2].xyz;
#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
float3 normalTS = UnpackNormalDXT5nm(tex2D(_NormalMap, input.texCoord0));

#endif
#else
data.normalWS = normalize(input.tangentToWorld[2].xyz);
data.normalWS = vertexNormalWS;
/*
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
#ifdef _DOUBLESIDED_LIGHTING_FLIP
float3 oppositeNormalWS = -data.normalWS;
#else
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalWS = reflect(data.normalWS, vertexNormalWS);
#endif
// TODO : Test if GetOdddNegativeScale() is necessary here in case of normal map, as GetOdddNegativeScale is take into account in CreateTangentToWorld();
//data.normalWS = IS_FRONT_VFACE(GetOdddNegativeScale() : -GetOdddNegativeScale()) >= 0.0 ? data.normalWS : oppositeNormalWS;
data.normalWS = IS_FRONT_VFACE(input.cullFace, data.normalWS, -data.normalWS);
#endif
*/
data.materialId = 0;
// TODO: Sample lightmap/lightprobe/volume proxy

#elif _MASKMAP // If we have a MaskMap, use emissive slot as a mask on baseColor
data.emissiveColor = data.baseColor * tex2D(_MaskMap, uv).b;
#else
data.emissiveColor = float3(0.0f, 0.0f, 0.0f);
data.emissiveColor = float3(0.0, 0.0, 0.0);
data.subSurfaceRadius = 1.0f; // tex2D(_SubSurfaceRadiusMap, input.texCoord0).r * _SubSurfaceRadius;
data.subSurfaceRadius = 1.0; // tex2D(_SubSurfaceRadiusMap, input.texCoord0).r * _SubSurfaceRadius;
// TODO
/*

6
Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl


#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define FRONT_FACE_SEMATIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };

9
Assets/ScriptableRenderLoop/ShaderLibrary/API/Validate.hlsl


// Upgrade NOTE: replaced 'defined in' with 'defined (in)'
// Wait for a fix from Trunk
// Wait for a fix from Trunk #error not supported yet
/*
#define REQUIRE_DEFINED(X_) \
#ifndef X_ \

REQUIRE_DEFINED(UNITY_UV_STARTS_AT_TOP)
REQUIRE_DEFINED(UNITY_REVERSED_Z)
REQUIRE_DEFINED(UNITY_NEAR_CLIP_VALUE)
REQUIRE_DEFINED(FACE)
REQUIRE_DEFINED(CBUFFER_START)
REQUIRE_DEFINED(CBUFFER_END)
*/

18
Assets/ScriptableRenderLoop/ShaderLibrary/BSDF.hlsl


float F_Schlick(float f0, float f90, float u)
{
float x = 1.0f - u;
float x = 1.0 - u;
float x5 = x * x;
x5 = x5 * x5 * x;
return (f90 - f0) * x5 + f0; // sub mul mul mul sub mad

{
return F_Schlick(f0, 1.0f, u);
return F_Schlick(f0, 1.0, u);
float x = 1.0f - u;
float x = 1.0 - u;
return (f90 - f0) * x5 + f0; // sub mul mul mul sub mad
return (float3(f90, f90, f90) - f0) * x5 + f0; // sub mul mul mul sub mad
return F_Schlick(f0, float3(1.0f, 1.0f, 1.0f), u);
return F_Schlick(f0, 1.0, u);
}
//-----------------------------------------------------------------------------

{
roughness = max(roughness, UNITY_MIN_ROUGHNESS);
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0f;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
return INV_PI * a2 / (f * f);
}

half lambdaV = NdotL * (NdotV * (1 - a) + a);
half lambdaL = NdotV * (NdotL * (1 - a) + a);
return 0.5f / (lambdaV + lambdaL);
return 0.5 / (lambdaV + lambdaL);
#endif
}

{
float fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
// Two schlick fresnel term
float lightScatter = F_Schlick(1.0f, fd90, NdotL);
float viewScatter = F_Schlick(1.0f, fd90, NdotV);
float lightScatter = F_Schlick(1.0, fd90, NdotL);
float viewScatter = F_Schlick(1.0, fd90, NdotV);
return INV_PI * lightScatter * viewScatter;
}

2
Assets/ScriptableRenderLoop/ShaderLibrary/Color.hlsl


float kOneOverRGBMMaxRange = 1.0 / maxRGBM;
const float kMinMultiplier = 2.0 * 1e-2;
float4 rgbm = float4(rgb * kOneOverRGBMMaxRange, 1.0f);
float4 rgbm = float4(rgb * kOneOverRGBMMaxRange, 1.0);
rgbm.a = max(max(rgbm.r, rgbm.g), max(rgbm.b, kMinMultiplier));
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;

18
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


float FastACos(float inX)
{
float x = abs(inX);
float res = -0.156583f * x + HALF_PI;
res *= sqrt(1.0f - x);
float res = -0.156583 * x + HALF_PI;
res *= sqrt(1.0 - x);
return (inX >= 0) ? res : PI - res;
}

// input [0, infinity] and output [0, PI/2]
float FastATanPos(float x)
{
float t0 = (x < 1.0f) ? x : 1.0f / x;
float t0 = (x < 1.0) ? x : 1.0 / x;
float poly = 0.0872929f;
poly = -0.301895f + poly * t1;
poly = 1.0f + poly * t1;
float poly = 0.0872929;
poly = -0.301895 + poly * t1;
poly = 1.0 + poly * t1;
return (x < 1.0f) ? poly : HALF_PI - poly;
return (x < 1.0) ? poly : HALF_PI - poly;
}
// 4 VGPR, 16 FR (12 FR, 1 QR), 2 scalar

float t0 = FastATanPos(abs(x));
return (x < 0.0f) ? -t0: t0;
return (x < 0.0f) ? -t0 : t0;
}
// ----------------------------------------------------------------------------

// TODO: How to detect automatically that we are a compute shader ?
#if 0
// In case of compute shader an extra half offset is added to the screenPos to shift the integer position to pixel center.
coord.positionSS.xy += float2(0.5f, 0.5f);
coord.positionSS.xy += float2(0.5, 0.5);
#endif
coord.positionSS *= invScreenSize;

2
Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl


#ifndef UNITY_COMMON_LIGHTING_INCLUDED
#define UNITY_COMMON_LIGHTING_INCLUDED
#include "Common.hlsl"
//-----------------------------------------------------------------------------
// Attenuation functions
//-----------------------------------------------------------------------------

8
Assets/ScriptableRenderLoop/ShaderLibrary/Filtering.hlsl


// Compute the Catmull-Rom weights using the fractional offset that we calculated earlier.
// These equations are pre-expanded based on our knowledge of where the texels will be located,
// which lets us avoid having to evaluate a piece-wise function.
float2 w0 = (1.0f / 6.0f) * (-3.0f * f3 + 6.0f * f2 - 3.0f * f);
float2 w1 = (1.0f / 6.0f) * (9.0f * f3 - 15.0f * f2 + 6.0f);
float2 w2 = (1.0f / 6.0f) * (-9.0f * f3 + 12.0f * f2 + 3.0f * f);
float2 w3 = (1.0f / 6.0f) * (3.0f * f3 - 3.0f * f2);
float2 w0 = (1.0f / 6.0) * (-3.0 * f3 + 6.0 * f2 - 3.0 * f);
float2 w1 = (1.0f / 6.0) * (9.0 * f3 - 15.0 * f2 + 6.0);
float2 w2 = (1.0f / 6.0) * (-9.0 * f3 + 12.0 * f2 + 3.0 * f);
float2 w3 = (1.0f / 6.0) * (3.0 * f3 - 3.0 * f2);
// Otim by Vlad, to test
// float2 w0 = (1.0 / 2.0) * f * (-1.0 + f * (2.0 - f));

46
Assets/ScriptableRenderLoop/fptl/ClusteredUtils.h


#ifndef __CLUSTEREDUTILS_H__
#define __CLUSTEREDUTILS_H__
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.192092896e-07f
#endif
int SnapToClusterIdx(float z_in, float fModulUserScale)
float GetScaleFromBase(float base)
{
const float C = (float) (1<<g_iLog2NumClusters);
const float geomSeries = (1.0 - pow(base, C))/(1-base); // geometric series: sum_k=0^{C-1} base^k
return geomSeries/(g_fFarPlane-g_fNearPlane);
}
int SnapToClusterIdx(float z_in, float suggestedBase)
{
#ifdef LEFT_HAND_COORDINATES
float z = z_in;

float userscale = g_fClustScale;
userscale *= fModulUserScale;
float userscale = GetScaleFromBase(suggestedBase);
#else
float userscale = g_fClustScale;
return (int) clamp( log2(dist*userscale*(g_fClustBase-1.0f) + 1) / log2(g_fClustBase), 0.0, (float) ((1<<g_iLog2NumClusters)-1) );
return (int) clamp( log2(dist*userscale*(suggestedBase-1.0f) + 1) / log2(suggestedBase), 0.0, (float) ((1<<g_iLog2NumClusters)-1) );
float ClusterIdxToZ(int k, float fModulUserScale)
float ClusterIdxToZ(int k, float suggestedBase)
float userscale = g_fClustScale;
userscale *= fModulUserScale;
float userscale = GetScaleFromBase(suggestedBase);
#else
float userscale = g_fClustScale;
float dist = (pow(g_fClustBase,(float) k)-1.0)/(userscale*(g_fClustBase-1.0f));
float dist = (pow(suggestedBase,(float) k)-1.0)/(userscale*(suggestedBase-1.0f));
res = dist+g_fNearPlane;
#ifdef LEFT_HAND_COORDINATES

#endif
}
// generate a log-base value such that half of the clusters are consumed from near plane to max. opaque depth of tile.
float SuggestLogBase50(float tileFarPlane)
{
const float C = (float) (1<<g_iLog2NumClusters);
float normDist = clamp( (tileFarPlane-g_fNearPlane) / (g_fFarPlane-g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow( (1.0 + sqrt(max(0.0,1.0-4.0*normDist*(1.0-normDist))))/(2.0*normDist), 2.0/C); //
return max(g_fClustBase, suggested_base);
}
// generate a log-base value such that (approximately) a quarter of the clusters are consumed from near plane to max. opaque depth of tile.
float SuggestLogBase25(float tileFarPlane)
{
const float C = (float) (1<<g_iLog2NumClusters);
float normDist = clamp( (tileFarPlane-g_fNearPlane) / (g_fFarPlane-g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow( (1/2.3)*max(0.0, (0.8/normDist)-1), 4.0/(C*2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
return max(g_fClustBase,suggested_base);
}

7
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


cmd.SetGlobalFloat("g_fClustScale", m_clustScale);
cmd.SetGlobalFloat("g_fClustBase", m_clustLogBase);
cmd.SetGlobalFloat("g_fNearPlane", camera.nearClipPlane);
cmd.SetGlobalFloat("g_fFarPlane", camera.farClipPlane);
cmd.SetGlobalFloat("g_fLog2NumClusters", (float) g_iLog2NumClusters);
m_DeferredMaterial.SetBuffer("g_vLayeredOffsetsBuffer", m_perVoxelOffset);

m_DeferredMaterial.SetBuffer("g_fModulUserscale", m_perTileLogBaseTweak);
m_DeferredReflectionMaterial.SetBuffer("g_fModulUserscale", m_perTileLogBaseTweak);
m_DeferredMaterial.SetBuffer("g_logBaseBuffer", m_perTileLogBaseTweak);
m_DeferredReflectionMaterial.SetBuffer("g_logBaseBuffer", m_perTileLogBaseTweak);
}
}

cmd.SetComputeBufferParam(m_BuildPerVoxelLightListShader, kGenListPerVoxelKernel, "g_LayeredOffset", m_perVoxelOffset);
cmd.SetComputeBufferParam(m_BuildPerVoxelLightListShader, kGenListPerVoxelKernel, "g_LayeredSingleIdxBuffer", m_globalLightListAtomic);
if(gUseDepthBuffer) cmd.SetComputeBufferParam(m_BuildPerVoxelLightListShader, kGenListPerVoxelKernel, "g_fModulUserscale", m_perTileLogBaseTweak);
if(gUseDepthBuffer) cmd.SetComputeBufferParam(m_BuildPerVoxelLightListShader, kGenListPerVoxelKernel, "g_logBaseBuffer", m_perTileLogBaseTweak);
int nrTilesX = (camera.pixelWidth + 15) / 16;
int nrTilesY = (camera.pixelHeight + 15) / 16;

9
Assets/ScriptableRenderLoop/fptl/Internal-DeferredReflections.shader


uniform float g_fClustScale;
uniform float g_fClustBase;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
//uniform int g_iLog2NumClusters; // numClusters = (1<<g_iLog2NumClusters)
uniform float g_fLog2NumClusters;
static int g_iLog2NumClusters;

Buffer<float> g_fModulUserscale;
Buffer<float> g_logBaseBuffer;
#endif
#include "ClusteredUtils.h"

g_iLog2NumClusters = (int) (g_fLog2NumClusters+0.5); // ridiculous
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
float modulScale = g_fModulUserscale[tileIDX.y*nrTilesX + tileIDX.x];
float logBase = g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x];
float modulScale = 1.0;
float logBase = g_fClustBase;
int clustIdx = SnapToClusterIdx(linDepth, modulScale);
int clustIdx = SnapToClusterIdx(linDepth, logBase);
int nrClusters = (1<<g_iLog2NumClusters);
const int idx = ((REFLECTION_LIGHT*nrClusters + clustIdx)*nrTilesY + tileIDX.y)*nrTilesX + tileIDX.x;

11
Assets/ScriptableRenderLoop/fptl/Internal-DeferredShading.shader


uniform float g_fClustScale;
uniform float g_fClustBase;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
//uniform int g_iLog2NumClusters; // numClusters = (1<<g_iLog2NumClusters)
uniform float g_fLog2NumClusters;
static int g_iLog2NumClusters;

Buffer<float> g_fModulUserscale;
Buffer<float> g_logBaseBuffer;
#endif
#include "ClusteredUtils.h"

g_iLog2NumClusters = (int) (g_fLog2NumClusters+0.5); // ridiculous
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
float modulScale = g_fModulUserscale[tileIDX.y*nrTilesX + tileIDX.x];
float logBase = g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x];
float modulScale = 1.0;
float logBase = g_fClustBase;
int clustIdx = SnapToClusterIdx(linDepth, modulScale);
int clustIdx = SnapToClusterIdx(linDepth, logBase);
int nrClusters = (1<<g_iLog2NumClusters);
const int idx = ((DIRECT_LIGHT*nrClusters + clustIdx)*nrTilesY + tileIDX.y)*nrTilesX + tileIDX.x;

GetLightCountAndStart(start, numLights, tileIDX, nrTilesX, nrTilesY, linDepth);
float3 c = ExecuteLightList(pixCoord, start, numLights, linDepth);
//c = OverlayHeatMap(numLights, c);
c = OverlayHeatMap(numLights, c);
return float4(c,1.0);
}

31
Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute


RWBuffer<uint> g_LayeredSingleIdxBuffer : register( u2 );
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
RWBuffer<float> g_fModulUserscale : register( u3 );
RWBuffer<float> g_logBaseBuffer : register( u3 );
#endif

float4 FetchPlane(int l, int p);
bool CheckIntersection(int l, int k, uint2 viTilLL, uint2 viTilUR, float fModulUserScale)
bool CheckIntersection(int l, int k, uint2 viTilLL, uint2 viTilUR, float suggestedBase)
{
unsigned int val = (clusterIdxs[l>>1]>>(16*(l&1)))&0xffff;
bool bIsHit = ((val>>0)&0xff)<=((uint) k) && ((uint) k)<=((val>>8)&0xff);

float depthAtNearZ = ClusterIdxToZ(k, fModulUserScale);
float depthAtFarZ = ClusterIdxToZ(k+1, fModulUserScale);
float depthAtNearZ = ClusterIdxToZ(k, suggestedBase);
float depthAtFarZ = ClusterIdxToZ(k+1, suggestedBase);
for(int p=0; p<6; p++)
{

#endif
float3 vTileLL = float3(viTilLL.x/(float) iWidth, viTilLL.y/(float) iHeight, 0.0);
float3 vTileUR = float3((viTilLL.x+16)/(float) iWidth, (viTilLL.y+16)/(float) iHeight, dpt_ma);
float3 vTileUR = float3((viTilLL.x+16)/(float) iWidth, (viTilLL.y+16)/(float) iHeight, 1.0);
vTileUR.xy = min(vTileUR.xy,float2(1.0,1.0)).xy;

const float3 vMi = g_vBoundsBuffer[l];
const float3 vMa = g_vBoundsBuffer[l+g_iNrVisibLights];
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
if( all(vMa.xy>vTileLL.xy) && all(vMi.xyz<vTileUR.xyz))
#else
#endif
{
unsigned int uInc = 1;
unsigned int uIndex;

#else
float fTileFarPlane = -GetLinearDepth(dpt_ma);
#endif
float fDenom = fTileFarPlane - g_fNearPlane;
float fModulUserScale = fDenom>0.0 ? ((g_fFarPlane-g_fNearPlane)/fDenom) : 1.0; // readjust to new range.
float suggestedBase = SuggestLogBase50(fTileFarPlane);
float fModulUserScale = 1.0;
float suggestedBase = g_fClustBase;
#endif

for(int l=(int) t; l<((iNrCoarseLights+1)>>1); l += NR_THREADS)
{
const int l0 = coarseList[2*l+0], l1 = coarseList[min(2*l+1,iNrCoarseLights)];
const unsigned int clustIdxMi0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0].z), fModulUserScale));
const unsigned int clustIdxMa0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0+g_iNrVisibLights].z), fModulUserScale));
const unsigned int clustIdxMi1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1].z), fModulUserScale));
const unsigned int clustIdxMa1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1+g_iNrVisibLights].z), fModulUserScale));
const unsigned int clustIdxMi0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0].z), suggestedBase));
const unsigned int clustIdxMa0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0+g_iNrVisibLights].z), suggestedBase));
const unsigned int clustIdxMi1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1].z), suggestedBase));
const unsigned int clustIdxMa1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1+g_iNrVisibLights].z), suggestedBase));
clusterIdxs[l] = (clustIdxMa1<<24) | (clustIdxMi1<<16) | (clustIdxMa0<<8) | (clustIdxMi0<<0);
}

for(int l=ll; l<min(iNrCoarseLights,(ll+4)); l++)
{
if(offs<(start+iSpaceAvail) && i<nrClusters && CheckIntersection(l, i, viTilLL.xy, viTilUR.xy, fModulUserScale) )
if(offs<(start+iSpaceAvail) && i<nrClusters && CheckIntersection(l, i, viTilLL.xy, viTilUR.xy, suggestedBase) )
{
uint lightModel = g_vLightData[ coarseList[l] ].uLightModel;
++modelListCount[ lightModel==REFLECTION_LIGHT ? 1 : 0];

}
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
g_fModulUserscale[tileIDX.y*nrTilesX + tileIDX.x] = fModulUserScale;
g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x] = suggestedBase;
#endif
}

正在加载...
取消
保存