浏览代码

Merge remote-tracking branch 'refs/remotes/origin/master' into Add-clear-coat

/main
sebastienlagarde 7 年前
当前提交
4ed252e3
共有 21 个文件被更改,包括 351 次插入173 次删除
  1. 2
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs.hlsl
  2. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs
  3. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  4. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDShaderIDs.cs
  5. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  6. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  7. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/LightingConvexHullUtils.hlsl
  8. 33
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  9. 43
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-bigtile.compute
  10. 43
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-clustered.compute
  11. 33
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild.compute
  12. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/scrbound.compute
  13. 143
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  14. 88
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  15. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawSssProfile.shader
  16. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader
  17. 28
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl
  18. 2
      ProjectSettings/ProjectVersion.txt
  19. 10
      Packages/Config.meta
  20. 4
      Packages/manifest.json
  21. 9
      Packages/manifest.json.meta

2
Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/core/Shadow/ShadowBase.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs. Please don't edit by hand.
//
#ifndef SHADOWBASE_CS_HLSL

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs


[Range(0.0f, 20.0f)]
public float lightWidth = 0.0f; // Area & projector lights
[Range(0.0f, 1.0f)]
public float maxSmoothness = 1.0f; // this is use with punctual light to fake an area lights
public bool applyRangeAttenuation = true; // If true, we apply the smooth attenuation factor on the range attenuation to get 0 value, else the attenuation is juste inverse square and never reach 0
}
}

19
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


}
// Broadcast SSS parameters to all shaders.
Shader.SetGlobalInt(HDShaderIDs._EnableSSSAndTransmission, m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission ? 1 : 0);
Shader.SetGlobalInt(HDShaderIDs._TexturingModeFlags, (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt(HDShaderIDs._TransmissionFlags, (int)sssParameters.transmissionFlags);
cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, sssParameters.thicknessRemaps);
// We are currently supporting two different SSS mode: Jimenez (with 2-Gaussian profile) and Disney
// We have added the ability to switch between each other for subsurface scattering, but for transmittance this is more tricky as we need to add
// shader variant for forward, gbuffer and deferred shader. We want to avoid this.
// So for transmittance we use Disney profile formulation (that we know is more correct) in both case, and in the case of Jimenez we hack the parameters with 2-Gaussian parameters (Ideally we should fit but haven't find good fit) so it approximately match.
// Note: Jimenez SSS is in cm unit whereas Disney is in mm unit making an inconsistency here to compare model side by side
cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.useDisneySSS ? sssParameters.shapeParams : sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTints, sssParameters.transmissionTints);
Shader.SetGlobalInt( HDShaderIDs._EnableSSSAndTransmission, m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission ? 1 : 0);
Shader.SetGlobalInt( HDShaderIDs._TexturingModeFlags, (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt( HDShaderIDs._TransmissionFlags, (int)sssParameters.transmissionFlags);
Shader.SetGlobalInt( HDShaderIDs._UseDisneySSS, sssParameters.useDisneySSS ? 1 : 0);
cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetGlobalVectorArray(HDShaderIDs._HalfRcpVariancesAndWeights, sssParameters.halfRcpVariancesAndWeights);
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTints, sssParameters.transmissionTints);
}
}

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDShaderIDs.cs


internal static readonly int g_LayeredSingleIdxBuffer = Shader.PropertyToID("g_LayeredSingleIdxBuffer");
internal static readonly int _EnvLightIndexShift = Shader.PropertyToID("_EnvLightIndexShift");
internal static readonly int g_isOrthographic = Shader.PropertyToID("g_isOrthographic");
internal static readonly int g_iNrVisibLights = Shader.PropertyToID("g_iNrVisibLights");
internal static readonly int g_mScrProjection = Shader.PropertyToID("g_mScrProjection");
internal static readonly int g_mInvScrProjection = Shader.PropertyToID("g_mInvScrProjection");

internal static readonly int _AmbientOcclusionDirectLightStrenght = Shader.PropertyToID("_AmbientOcclusionDirectLightStrenght");
internal static readonly int _SkyTexture = Shader.PropertyToID("_SkyTexture");
internal static readonly int _UseDisneySSS = Shader.PropertyToID("_UseDisneySSS");
internal static readonly int _HalfRcpVariancesAndWeights = Shader.PropertyToID("_HalfRcpVariancesAndWeights");
internal static readonly int _TransmissionTints = Shader.PropertyToID("_TransmissionTints");
internal static readonly int specularLightingUAV = Shader.PropertyToID("specularLightingUAV");
internal static readonly int diffuseLightingUAV = Shader.PropertyToID("diffuseLightingUAV");

internal static readonly int _StdDev1 = Shader.PropertyToID("_StdDev1");
internal static readonly int _StdDev2 = Shader.PropertyToID("_StdDev2");
internal static readonly int _LerpWeight = Shader.PropertyToID("_LerpWeight");
internal static readonly int _HalfRcpVarianceAndWeight1 = Shader.PropertyToID("_HalfRcpVarianceAndWeight1");
internal static readonly int _HalfRcpVarianceAndWeight2 = Shader.PropertyToID("_HalfRcpVarianceAndWeight2");
internal static readonly int _TransmissionTint = Shader.PropertyToID("_TransmissionTint");
internal static readonly int _ThicknessRemap = Shader.PropertyToID("_ThicknessRemap");

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


[GenerateHLSL]
public struct LightData
{
// DirectionalLightData >>>
public Vector3 positionWS;
public float invSqrAttenuationRadius;

public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by * (2 / lightWidth)
public float diffuseScale;
// <<< DirectionalLightData
public float angleScale; // Spot light
public float angleOffset; // Spot light
public float shadowDimmer;

public GPULightType lightType;
public float unused;
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.
};

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


int unused0;
float2 size;
int lightType;
float unused;
float minRoughness;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData

{
return value.lightType;
}
float GetUnused(LightData value)
float GetMinRoughness(LightData value)
return value.unused;
return value.minRoughness;
}
//

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/LightingConvexHullUtils.hlsl


return float4(vN, -dot(vN,p0));
}
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen, float sphRadiusIn)
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen_in, float sphRadiusIn, bool isOrthographic)
float3 V = dir; // ray direction down center of tile (does not need to be normalized).
float3 V = float3(isOrthographic ? 0.0 : dir.x, isOrthographic ? 0.0 : dir.y, dir.z); // ray direction down center of tile (does not need to be normalized).
float3 sphCen = float3(sphCen_in.x - (isOrthographic ? dir.x : 0.0), sphCen_in.y - (isOrthographic ? dir.y : 0.0), sphCen_in.z);
#if 1
float3 maxZdir = float3(-sphCen.z*sphCen.x, -sphCen.z*sphCen.y, sphCen.x*sphCen.x + sphCen.y*sphCen.y); // cross(sphCen,cross(Zaxis,sphCen))

// enlarge sphere so it overlaps the center of the tile assuming it overlaps the tile to begin with.
#if USE_LEFT_HAND_CAMERA_SPACE
float sphRadius = sphRadiusIn + (sphCen.z+offs)*halfTileSizeAtZDistOne;
float s = sphCen.z+offs;
float sphRadius = sphRadiusIn - (sphCen.z-offs)*halfTileSizeAtZDistOne;
float s = -(sphCen.z-offs);
float sphRadius = sphRadiusIn + (isOrthographic ? 1.0 : s)*halfTileSizeAtZDistOne;
float a = dot(V,V);
float CdotV = dot(sphCen,V);

33
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


lightData.lightType = gpuLightType;
lightData.positionWS = light.light.transform.position;
lightData.invSqrAttenuationRadius = 1.0f / (light.range * light.range);
// Setting 0 for invSqrAttenuationRadius mean we have no range attenuation, but still have inverse square attenuation.
lightData.invSqrAttenuationRadius = additionalLightData.applyRangeAttenuation ? 1.0f / (light.range * light.range) : 0.0f;
lightData.color = GetLightColor(light);
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)

{
lightData.shadowIndex = shadowIdx;
}
// Value of max smoothness is from artists point of view, need to convert from perceptual smoothness to roughness
lightData.minRoughness = (1.0f - additionalLightData.maxSmoothness) * (1.0f - additionalLightData.maxSmoothness);
m_lightList.lights.Add(lightData);

cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, HDShaderIDs.g_LayeredSingleIdxBuffer, s_GlobalLightListAtomic);
cmd.DispatchCompute(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, 1, 1, 1);
bool isOrthographic = camera.orthographic;
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs.g_isOrthographic, isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs._EnvLightIndexShift, m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, HDShaderIDs.g_mScrProjection, projscr);

temp.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
var projscr = temp * proj;
var invProjscr = projscr.inverse;
bool isOrthographic = camera.orthographic;
cmd.SetRenderTarget(new RenderTargetIdentifier((Texture)null));

var projh = temp * proj;
var invProjh = projh.inverse;
cmd.SetComputeIntParam(buildScreenAABBShader, HDShaderIDs.g_isOrthographic, isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildScreenAABBShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);
cmd.SetComputeBufferParam(buildScreenAABBShader, s_GenAABBKernel, HDShaderIDs.g_data, s_ConvexBoundsBuffer);

// enable coarse 2D pass on 64x64 tiles (used for both fptl and clustered).
if (m_TileSettings.enableBigTilePrepass)
{
cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs.g_isOrthographic, isOrthographic ? 1 : 0);
cmd.SetComputeIntParams(buildPerBigTileLightListShader, HDShaderIDs.g_viDimensions, w, h);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs._EnvLightIndexShift, m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);

if (usingFptl) // optimized for opaques only
{
cmd.SetComputeIntParam(buildPerTileLightListShader, HDShaderIDs.g_isOrthographic, isOrthographic ? 1 : 0);
cmd.SetComputeIntParams(buildPerTileLightListShader, HDShaderIDs.g_viDimensions, w, h);
cmd.SetComputeIntParam(buildPerTileLightListShader, HDShaderIDs._EnvLightIndexShift, m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerTileLightListShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);

int enableSSSAndTransmission = Shader.GetGlobalInt(HDShaderIDs._EnableSSSAndTransmission);
int texturingModeFlags = Shader.GetGlobalInt(HDShaderIDs._TexturingModeFlags);
int transmissionFlags = Shader.GetGlobalInt(HDShaderIDs._TransmissionFlags);
int useDisneySSS = Shader.GetGlobalInt(HDShaderIDs._UseDisneySSS);
Vector4[] halfRcpVariancesAndWeights = Shader.GetGlobalVectorArray(HDShaderIDs._HalfRcpVariancesAndWeights);
Texture skyTexture = Shader.GetGlobalTexture(HDShaderIDs._SkyTexture);

cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs._SkyTexture, skyTexture ? skyTexture : m_DefaultTexture2DArray);
// Set SSS parameters.
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._EnableSSSAndTransmission, enableSSSAndTransmission);
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._TexturingModeFlags, texturingModeFlags);
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._TransmissionFlags, transmissionFlags);
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._ThicknessRemaps, thicknessRemaps);
// We are currently supporting two different SSS mode: Jimenez (with 2-Gaussian profile) and Disney
// We have added the ability to switch between each other for subsurface scattering, but for transmittance this is more tricky as we need to add
// shader variant for forward, gbuffer and deferred shader. We want to avoid this.
// So for transmittance we use Disney profile formulation (that we know is more correct) in both case, and in the case of Jimenez we hack the parameters with 2-Gaussian parameters (Ideally we should fit but haven't find good fit) so it approximately match.
// Note: Jimenez SSS is in cm unit whereas Disney is in mm unit making an inconsistency here to compare model side by side
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._ShapeParams, shapeParams);
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._TransmissionTints, transmissionTints);
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._EnableSSSAndTransmission, enableSSSAndTransmission);
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._TexturingModeFlags, texturingModeFlags);
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._TransmissionFlags, transmissionFlags);
cmd.SetComputeIntParam( deferredComputeShader, HDShaderIDs._UseDisneySSS, useDisneySSS);
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._ThicknessRemaps, thicknessRemaps);
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._ShapeParams, shapeParams);
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._TransmissionTints, transmissionTints);
cmd.SetComputeVectorArrayParam(deferredComputeShader, HDShaderIDs._HalfRcpVariancesAndWeights, halfRcpVariancesAndWeights);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.specularLightingUAV, colorBuffers[0]);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.diffuseLightingUAV, colorBuffers[1]);

43
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-bigtile.compute


uniform float4x4 g_mScrProjection;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
uniform uint g_isOrthographic;
uniform int _EnvLightIndexShift;
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );

groupshared unsigned int lightsListLDS[MAX_NR_BIG_TILE_LIGHTS_PLUS_ONE];
groupshared uint lightOffs;
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;
return (m22*zDptBufSpace+m23) / (m32*zDptBufSpace+m33);
//float3 vP = float3(0.0f,0.0f,zDptBufSpace);
//float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
//return v4Pres.z / v4Pres.w;
}
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[lightsListLDS[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
lightsListLDS[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection == 0 ? vP0 : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
#if USE_LEFT_HAND_CAMERA_SPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection == 0 ? edgeSectionZero : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
}
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR)

43
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild-clustered.compute


int g_iNrVisibLights;
float4x4 g_mInvScrProjection;
float4x4 g_mScrProjection;
uint g_isOrthographic;
int _EnvLightIndexShift;
float g_fClustScale;

groupshared uint lightOffsSph;
#endif
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;
return (m22*zDptBufSpace+m23) / (m32*zDptBufSpace+m33);
//float3 vP = float3(0.0f,0.0f,zDptBufSpace);
//float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
//return v4Pres.z / v4Pres.w;
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
coarseList[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection==0 ? vP0 : (((iSwizzle&0x2)==0 ? 1.0f : (-1.0f))*((iSwizzle&0x1)==(iSwizzle>>1) ? float3(1,0,0) : float3(0,1,0)));
#if USE_LEFT_HAND_CAMERA_SPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection == 0 ? edgeSectionZero : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
}
int CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)

33
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/lightlistbuild.compute


uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform uint g_isOrthographic;
uniform int _EnvLightIndexShift;
uniform uint g_BaseFeatureFlags;

// return v4Pres.z / v4Pres.w;
//}
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;
return (m22*zDptBufSpace+m23) / (m32*zDptBufSpace+m33);
//float3 vP = float3(0.0f,0.0f,zDptBufSpace);
//float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
//return v4Pres.z / v4Pres.w;
}
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lightData = g_data[prunedList[l]];
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius, g_isOrthographic!=0) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/scrbound.compute


#include "../../../ShaderLibrary/common.hlsl"
#include "TilePass.cs.hlsl"
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvProjection;
uniform float4x4 g_mProjection;

else
{
//if((center.z+radius)<0.0)
if( length(center)>radius)
if(g_isOrthographic==0 && length(center)>radius)
{
float2 vMi, vMa;
bool2 bMi, bMa;

vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy;
}
else if(g_isOrthographic!=0)
{
float2 vMi = mul(g_mProjection, float4(center.xyz-radius,1)).xy; // no division needed for ortho
float2 vMa = mul(g_mProjection, float4(center.xyz+radius,1)).xy; // no division needed for ortho
vMin.xy = max(vMin.xy, vMi);
vMax.xy = min(vMax.xy, vMa);
}
#if USE_LEFT_HAND_CAMERA_SPACE

143
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


uint _EnableSSSAndTransmission; // Globally toggles subsurface and transmission scattering on/off
uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
uint _TransmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
// Old SSS Model >>>
uint _UseDisneySSS;
float4 _HalfRcpVariancesAndWeights[SSS_N_PROFILES][2]; // 2x Gaussians in RGB, A is interpolation weights
// <<< Old SSS Model
float4 _TransmissionTints[SSS_N_PROFILES]; // RGB = color, A = unused
float4 _TransmissionTints[SSS_N_PROFILES]; // RGB = 1/4 * color, A = unused
CBUFFER_END
//-----------------------------------------------------------------------------

bsdfData.enableTransmission = transmissionMode != SSS_TRSM_MODE_NONE && (_EnableSSSAndTransmission > 0);
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
if (bsdfData.enableTransmission)
{
bsdfData.transmittance = ComputeTransmittance(_ShapeParams[subsurfaceProfile].rgb,
_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, subsurfaceProfile);
bool enableSssAndTransmission = true;

{
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
}
}
if (bsdfData.enableTransmission)
{
if (_UseDisneySSS)
{
bsdfData.transmittance = ComputeTransmittance(_ShapeParams[subsurfaceProfile].rgb,
_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
else
{
bsdfData.transmittance = ComputeTransmittanceJimenez(_HalfRcpVariancesAndWeights[subsurfaceProfile][0].rgb,
_HalfRcpVariancesAndWeights[subsurfaceProfile][0].a,
_HalfRcpVariancesAndWeights[subsurfaceProfile][1].rgb,
_HalfRcpVariancesAndWeights[subsurfaceProfile][1].a,
_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
bsdfData.transmittance *= bsdfData.diffuseColor; // Premultiply
}
}

diffuseLighting = bsdfData.diffuseColor * diffuseTerm;
}
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
// We assume that the back side of the object is a uniformly illuminated infinite plane
// (we reuse the illumination) with the reversed normal of the current sample.
// We apply wrapped lighting instead of the regular Lambertian diffuse
// to compensate for these approximations.
float3 EvaluateTransmission(BSDFData bsdfData, float NdotL, float3 lightColor, float diffuseScale, float shadow)
{
float illuminance = ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
illuminance *= shadow;
float3 backLight = lightColor * (Lambert() * illuminance * diffuseScale);
return backLight * bsdfData.transmittance; // Premultiplied with the diffuse color
}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Directional (supports directional and box projector lights)
//-----------------------------------------------------------------------------

diffuseLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
specularLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
float3 cookie = float3(1, 1, 1);
float shadow = 1;
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0)
{

float3 positionLS = mul(lightToSurface, transpose(lightToWorld));
float2 positionNDC = positionLS.xy;
float clipFactor = 1.0f;
float clipFactor;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;

// Tile the texture if the 'repeat' wrap mode is enabled.
coord = frac(coord);
clipFactor = 1;
}
else
{

// We let the sampler handle tiling or clamping to border.
// Note: tiling (the repeat mode) is not currently supported.
float4 c = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
float4 cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
// Use premultiplied alpha to save 1x VGPR.
cookie = c.rgb * c.a * clipFactor;
// Premultiply.
cookie.a *= clipFactor;
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;
}
[branch] if (illuminance > 0.0)

diffuseLighting *= (cookie * lightData.color) * (illuminance * lightData.diffuseScale);
specularLighting *= (cookie * lightData.color) * (illuminance * lightData.specularScale);
diffuseLighting *= lightData.color * (illuminance * lightData.diffuseScale);
specularLighting *= lightData.color * (illuminance * lightData.specularScale);
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
// We assume that the back side of the object is a uniformly illuminated infinite plane
// (we reuse the illumination) with the reversed normal of the current sample.
// We apply wrapped lighting instead of the regular Lambertian diffuse
// to compensate for these approximations.
illuminance = ComputeWrappedDiffuseLighting(NdotL, SSS_WRAP_LIGHT);
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
illuminance *= shadow;
float3 backLight = (cookie * lightData.color) * (Lambert() * illuminance * lightData.diffuseScale);
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
float3 transmittedLight = backLight * (bsdfData.diffuseColor * bsdfData.transmittance);
diffuseLighting += transmittedLight;
diffuseLighting += EvaluateTransmission(bsdfData, NdotL, lightData.color, lightData.diffuseScale, shadow);
}
}

// For point light and directional GetAngleAttenuation() return 1
float3 lightToSurface = positionWS - lightData.positionWS;
float3 unL = -lightToSurface;
float3 L = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? normalize(unL) : -lightData.forward;
float3 unL = -lightToSurface;
float3 L = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? normalize(unL) : -lightData.forward;
float NdotL = dot(bsdfData.normalWS, L);
float illuminance = saturate(NdotL);
// Note: lightData.invSqrAttenuationRadius is 0 when applyRangeAttenuation is false
float NdotL = dot(bsdfData.normalWS, L);
float illuminance = saturate(NdotL * attenuation);
// Premultiply.
lightData.diffuseScale *= attenuation;
lightData.specularScale *= attenuation;
float3 cookie = float3(1, 1, 1);
float shadow = 1;
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0)
{

float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSurface, transpose(lightToWorld));
float4 cookie;
float4 c = SampleCookieCube(lightLoopContext, positionLS, lightData.cookieIndex);
// Use premultiplied alpha to save 1x VGPR.
cookie = c.rgb * c.a;
cookie = SampleCookieCube(lightLoopContext, positionLS, lightData.cookieIndex);
}
else
{

float2 coord = positionNDC * 0.5 + 0.5;
// We let the sampler handle clamping to border.
float4 c = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
// Use premultiplied alpha to save 1x VGPR.
cookie = c.rgb * (c.a * clipFactor);
cookie.a *= clipFactor;
// Premultiply.
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;
bsdfData.roughness = max(bsdfData.roughness, lightData.minRoughness); // Simulate that a punctual ligth have a radius with this hack
diffuseLighting *= (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale);
specularLighting *= (cookie.rgb * lightData.color) * (illuminance * lightData.specularScale);
diffuseLighting *= lightData.color * (illuminance * lightData.diffuseScale);
specularLighting *= lightData.color * (illuminance * lightData.specularScale);
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
// We assume that the back side of the object is a uniformly illuminated infinite plane
// (we reuse the illumination) with the reversed normal of the current sample.
// We apply wrapped lighting instead of the regular Lambertian diffuse
// to compensate for these approximations.
illuminance = ComputeWrappedDiffuseLighting(NdotL, SSS_WRAP_LIGHT) * attenuation;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;
illuminance *= shadow;
float3 backLight = (cookie.rgb * lightData.color) * (Lambert() * illuminance * lightData.diffuseScale);
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
float3 transmittedLight = backLight * (bsdfData.diffuseColor * bsdfData.transmittance);
diffuseLighting += transmittedLight;
diffuseLighting += EvaluateTransmission(bsdfData, NdotL, lightData.color, lightData.diffuseScale, shadow);
}
}

88
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


m_FilterKernelNearField[i].y = 1.0f / KernelPdf(r, s);
}
m_MaxRadius = m_FilterKernelNearField[SssConstants.SSS_N_SAMPLES_NEAR_FIELD - 1].x;
// Importance sample the far field kernel.
for (int i = 0, n = SssConstants.SSS_N_SAMPLES_FAR_FIELD; i < n; i++)
{

m_FilterKernelFarField[i].x = r;
m_FilterKernelFarField[i].y = 1.0f / KernelPdf(r, s);
}
m_MaxRadius = m_FilterKernelFarField[SssConstants.SSS_N_SAMPLES_FAR_FIELD - 1].x;
// Old SSS Model >>>
UpdateKernelAndVarianceData();

public int numProfiles; // Excluding the neutral profile
public SubsurfaceScatteringProfile[] profiles;
// Below are the cached values. TODO: uncomment when SSS profile asset serialization is fixed.
/*[NonSerialized]*/ public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
/*[NonSerialized]*/ public int transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
/*[NonSerialized]*/ public Vector4[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
/*[NonSerialized]*/ public Vector4[] worldScales; // Size of the world unit in meters (only the X component is used)
/*[NonSerialized]*/ public Vector4[] shapeParams; // RGB = S = 1 / D, A = filter radius
/*[NonSerialized]*/ public Vector4[] transmissionTints; // RGB = color, A = unused
/*[NonSerialized]*/ public Vector4[] filterKernels; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
/*[NonSerialized]*/ public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
/*[NonSerialized]*/ public int transmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
/*[NonSerialized]*/ public Vector4[] thicknessRemaps; // Remap: 0 = start, 1 = end - start
/*[NonSerialized]*/ public Vector4[] worldScales; // Size of the world unit in meters (only the X component is used)
/*[NonSerialized]*/ public Vector4[] shapeParams; // RGB = S = 1 / D, A = filter radius
/*[NonSerialized]*/ public Vector4[] transmissionTints; // RGB = color, A = unused
/*[NonSerialized]*/ public Vector4[] filterKernels; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
/*[NonSerialized]*/ public Vector4[] halfRcpWeightedVariances;
/*[NonSerialized]*/ public Vector4[] filterKernelsBasic;
/*[NonSerialized]*/ public Vector4[] halfRcpWeightedVariances;
/*[NonSerialized]*/ public Vector4[] halfRcpVariancesAndWeights;
/*[NonSerialized]*/ public Vector4[] filterKernelsBasic;
// <<< Old SSS Model
// --- Public Methods ---

numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
worldScales = null;
shapeParams = null;
transmissionTints = null;
filterKernels = null;
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
worldScales = null;
shapeParams = null;
transmissionTints = null;
filterKernels = null;
useDisneySSS = true;
halfRcpWeightedVariances = null;
filterKernelsBasic = null;
useDisneySSS = true;
halfRcpWeightedVariances = null;
halfRcpVariancesAndWeights = null;
filterKernelsBasic = null;
// <<< Old SSS Model
UpdateCache();

halfRcpWeightedVariances = new Vector4[SssConstants.SSS_N_PROFILES];
}
if (halfRcpVariancesAndWeights == null || halfRcpVariancesAndWeights.Length != 2 * SssConstants.SSS_N_PROFILES)
{
halfRcpVariancesAndWeights = new Vector4[2 * SssConstants.SSS_N_PROFILES];
}
const int filterKernelsLen = SssConstants.SSS_N_PROFILES * SssConstants.SSS_BASIC_N_SAMPLES;
if (filterKernelsBasic == null || filterKernelsBasic.Length != filterKernelsLen)
{

}
// Old SSS Model >>>
halfRcpWeightedVariances[i] = Vector4.one;
halfRcpWeightedVariances[i] = Vector4.one;
halfRcpVariancesAndWeights[2 * i + 0] = Vector4.one;
halfRcpVariancesAndWeights[2 * i + 1] = Vector4.one;
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{

worldScales[i] = new Vector4(profiles[i].worldScale, 0, 0, 0);
shapeParams[i] = profiles[i].shapeParameter;
shapeParams[i].w = profiles[i].maxRadius;
transmissionTints[i] = profiles[i].transmissionTint;
transmissionTints[i] = profiles[i].transmissionTint * 0.25f; // Premultiplied
for (int j = 0, n = SssConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++)
{

// Old SSS Model >>>
halfRcpWeightedVariances[i] = profiles[i].halfRcpWeightedVariances;
Vector4 stdDev1 = ((1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * profiles[i].scatterDistance1;
Vector4 stdDev2 = ((1.0f / 3.0f) * SssConstants.SSS_BASIC_DISTANCE_SCALE) * profiles[i].scatterDistance2;
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
// Rescale by 4 to counter rescaling of transmission tints.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
halfRcpVariancesAndWeights[2 * i + 0] = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4 * (1.0f - profiles[i].lerpWeight));
halfRcpVariancesAndWeights[2 * i + 1] = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4 * profiles[i].lerpWeight);
for (int j = 0, n = SssConstants.SSS_BASIC_N_SAMPLES; j < n; j++)
{

Vector2 R = m_ThicknessRemap.vector2Value;
bool transmissionEnabled = m_TransmissionMode.intValue != (int)SubsurfaceScatteringProfile.TransmissionMode.None;
// Draw the profile.
m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, r);
m_ProfileMaterial.SetVector(HDShaderIDs._ShapeParam, S);
// Old SSS Model >>>

float rMax = Mathf.Max(m_ScatterDistance1.colorValue.r, m_ScatterDistance1.colorValue.g, m_ScatterDistance1.colorValue.b,
m_ScatterDistance2.colorValue.r, m_ScatterDistance2.colorValue.g, m_ScatterDistance2.colorValue.b);
Vector4 stdDev1 = new Vector4(s * m_ScatterDistance1.colorValue.r, s * m_ScatterDistance1.colorValue.g, s * m_ScatterDistance1.colorValue.b);
Vector4 stdDev2 = new Vector4(s * m_ScatterDistance2.colorValue.r, s * m_ScatterDistance2.colorValue.g, s * m_ScatterDistance2.colorValue.b);
Vector4 stdDev1 = s * m_ScatterDistance1.colorValue;
Vector4 stdDev2 = s * m_ScatterDistance2.colorValue;
// Draw the profile.
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImage, m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();

EditorGUILayout.Space();
// Draw the transmittance graph.
// Old SSS Model >>>
// Multiply by 0.1 to convert from millimeters to centimeters. Apply the distance scale.
float a = 0.1f * SssConstants.SSS_BASIC_DISTANCE_SCALE;
Vector4 halfRcpVarianceAndWeight1 = new Vector4(a * a * 0.5f / (stdDev1.x * stdDev1.x), a * a * 0.5f / (stdDev1.y * stdDev1.y), a * a * 0.5f / (stdDev1.z * stdDev1.z), 4 * (1.0f - m_LerpWeight.floatValue));
Vector4 halfRcpVarianceAndWeight2 = new Vector4(a * a * 0.5f / (stdDev2.x * stdDev2.x), a * a * 0.5f / (stdDev2.y * stdDev2.y), a * a * 0.5f / (stdDev2.z * stdDev2.z), 4 * m_LerpWeight.floatValue);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight1, halfRcpVarianceAndWeight1);
m_TransmittanceMaterial.SetVector(HDShaderIDs._HalfRcpVarianceAndWeight2, halfRcpVarianceAndWeight2);
// <<< Old SSS Model
// Draw the transmittance graph.
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
serializedObject.ApplyModifiedProperties();

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawSssProfile.shader


// N.b.: we multiply by the surface albedo of the actual geometry during shading.
// Apply gamma for visualization only. Do not apply gamma to the color.
return float4(pow(M, 1.0 / 3.0) * A, 1);
return float4(sqrt(M) * A, 1);
#else
float r = (2 * length(input.texcoord - 0.5)) * _MaxRadius * SSS_BASIC_DISTANCE_SCALE;
float3 var1 = _StdDev1.rgb * _StdDev1.rgb;

float3 magnitude = lerp(exp(-r * r / (2 * var1)) / (TWO_PI * var1),
exp(-r * r / (2 * var2)) / (TWO_PI * var2), _LerpWeight);
return float4(magnitude, 1);
// N.b.: we multiply by the surface albedo of the actual geometry during shading.
// Apply gamma for visualization only.
return float4(sqrt(magnitude), 1);
#endif
}
ENDHLSL

19
Assets/ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/Resources/DrawTransmittanceGraph.shader


// Inputs & outputs
//-------------------------------------------------------------------------------------
uint _UseDisneySSS;
float4 _HalfRcpVarianceAndWeight1, _HalfRcpVarianceAndWeight2;
float4 _ShapeParam, _TransmissionTint, _ThicknessRemap;
//-------------------------------------------------------------------------------------

float4 Frag(Varyings input) : SV_Target
{
float d = (_ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x));
float3 T = ComputeTransmittance(_ShapeParam.rgb, float3(1, 1, 1), d, 1);
float3 T;
if (_UseDisneySSS)
{
T = ComputeTransmittance(_ShapeParam.rgb, float3(0.25, 0.25, 0.25), d, 1);
}
else
{
T = ComputeTransmittanceJimenez(_HalfRcpVarianceAndWeight1.rgb,
_HalfRcpVarianceAndWeight1.a,
_HalfRcpVarianceAndWeight2.rgb,
_HalfRcpVarianceAndWeight2.a,
float3(0.25, 0.25, 0.25), d, 1);
}
return float4(pow(T, 1.0 / 3) * _TransmissionTint.rgb, 1);
return float4(sqrt(T) * _TransmissionTint.rgb, 1);
}
ENDHLSL
}

28
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl


float PerceptualSmoothnessToRoughness(float perceptualSmoothness)
{
return (1 - perceptualSmoothness) * (1 - perceptualSmoothness);
return (1.0 - perceptualSmoothness) * (1.0 - perceptualSmoothness);
return (1 - perceptualSmoothness);
return (1.0 - perceptualSmoothness);
}
// ----------------------------------------------------------------------------

// Computes the fraction of light passing through the object.
// Evaluate Int{0, inf}{2 * Pi * r * R(sqrt(r^2 + d^2))}, where R is the diffusion profile.
// Note: 'volumeAlbedo' should be premultiplied by 0.25.
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar (BSSRDF only).
float3 ComputeTransmittance(float3 S, float3 volumeAlbedo, float thickness, float radiusScale)
{

float3 expOneThird = exp(((-1.0 / 3.0) * thickness) * S);
return 0.25 * (expOneThird + 3 * expOneThird * expOneThird * expOneThird) * volumeAlbedo;
// Premultiply & optimize: T = (1/4 * A) * (e^(-t * S) + 3 * e^(-1/3 * t * S))
return volumeAlbedo * (expOneThird * expOneThird * expOneThird + 3 * expOneThird);
}
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians.
// Ref: Real-Time Realistic Skin Translucency (2010), equation 9 (modified).
// Note: 'volumeAlbedo' should be premultiplied by 0.25, correspondingly 'lerpWeight' by 4,
// and 'halfRcpVariance1' should be prescaled by (0.1 * SssConstants.SSS_BASIC_DISTANCE_SCALE)^2.
float3 ComputeTransmittanceJimenez(float3 halfRcpVariance1, float lerpWeight1,
float3 halfRcpVariance2, float lerpWeight2,
float3 volumeAlbedo, float thickness, float radiusScale)
{
// Thickness and SSS radius are decoupled for artists.
// In theory, we should modify the thickness by the inverse of the radius scale of the profile.
// thickness /= radiusScale;
float t2 = thickness * thickness;
// T = A * lerp(exp(-t2 * halfRcpVariance1), exp(-t2 * halfRcpVariance2), lerpWeight2)
return volumeAlbedo * (exp(-t2 * halfRcpVariance1) * lerpWeight1 + exp(-t2 * halfRcpVariance2) * lerpWeight2);
return saturate((-NdotL + w) / ((1 + w) * (1 + w)));
return saturate((NdotL + w) / ((1 + w) * (1 + w)));
}
// MACRO from Legacy Untiy

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.3.0a3
m_EditorVersion: 2017.3.0a4

10
Packages/Config.meta


fileFormatVersion: 2
guid: 22bd21b14b6bd62419780a5148913c06
folderAsset: yes
timeCreated: 1501162961
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

4
Packages/manifest.json


{
"dependencies": {
}
}

9
Packages/manifest.json.meta


fileFormatVersion: 2
guid: a07771d9fceebb14b8c0701c90b62577
timeCreated: 1502115272
licenseType: Pro
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存