浏览代码

Use 16 profiles and vtx-NoV weighted thickness

/Branch_Batching2
Evgenii Golubev 8 年前
当前提交
04fd3af5
共有 6 个文件被更改,包括 69 次插入25 次删除
  1. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  2. 58
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  3. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  4. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  5. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.hlsl
  6. 19
      Assets/ScriptableRenderPipeline/ShaderLibrary/BSDF.hlsl

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


public readonly GUIContent shadowsAtlasHeight = new GUIContent("Atlas height");
// Subsurface Scattering Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SssConstants.SSS_N_PROFILES - 1] { new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"), new GUIContent("Profile #6"), new GUIContent("Profile #7") };
public readonly GUIContent[] sssProfiles = new GUIContent[SssConstants.SSS_N_PROFILES - 1] { new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"),
new GUIContent("Profile #6"), new GUIContent("Profile #7"), new GUIContent("Profile #8"), new GUIContent("Profile #9"), new GUIContent("Profile #10"),
new GUIContent("Profile #11"), new GUIContent("Profile #12"), new GUIContent("Profile #13"), new GUIContent("Profile #14"), new GUIContent("Profile #15") };
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
// Tile pass Settings

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


}
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_N_PROFILES - 1));
// Use 16 bits to encode the thickness, and up to 8 bits to encode the profile ID.
// We need a lot of precision to minimize banding of NdotV-weighted thickness.
int ip = surfaceData.subsurfaceProfile; // [0, 255]
float ft = surfaceData.thickness; // [0, 1]
int it = int(ft * ((1 << 16) - 1)); // [0, 65535]
int lo = it & ((1 << 8) - 1); // 8 bit low
int hi = (it >> 8) & ((1 << 8) - 1); // 8 bit high
float y = saturate(lo * rcp((1 << 8) - 1));
float z = saturate(hi * rcp((1 << 8) - 1));
float w = saturate(ip * rcp((1 << 8) - 1));
outGBuffer2 = float4(surfaceData.subsurfaceRadius, y, z, w);
}
else if (surfaceData.materialId == MATERIALID_LIT_SPECULAR)
{

}
else if (supportsSSS && bsdfData.materialId == MATERIALID_LIT_SSS)
{
int subsurfaceProfile = (SSS_N_PROFILES - 0.9) * inGBuffer2.a;
float thickness = inGBuffer2.g;
float y = inGBuffer2.g;
float z = inGBuffer2.b;
float w = inGBuffer2.a;
// Use 16 bits to encode the thickness, and up to 8 bits to encode the profile ID.
// We need a lot of precision to minimize banding of NdotV-weighted thickness.
int lo = int(y * ((1 << 8) - 1)); // 8 bit low
int hi = int(z * ((1 << 8) - 1)); // 8 bit high
int ip = int(w * ((1 << 8) - 1)); // [0, 255]
int it = lo + (hi << 8); // [0, 65535]
float ft = saturate(it * rcp((1 << 16) - 1)); // [0, 1]
float thickness = ft;
int subsurfaceProfile = ip;
FillMaterialIdSSSData(baseColor, subsurfaceProfile, subsurfaceRadius, thickness, bsdfData);
}
else if (supportsSpecular && bsdfData.materialId == MATERIALID_LIT_SPECULAR)

[branch] if (bsdfData.enableTransmission)
{
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
float LdotV = dot(L, V); // Also computed in BSDF()
// Compute the normal at the back of the object as R = reflect(N, -V)
// float RdotL = NdotL - 2 * preLightData.NdotV * LdotV;
float illuminance = saturate(-LdotV);
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;

[branch] if (bsdfData.enableTransmission)
{
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
illuminance *= attenuation;
float LdotV = dot(L, V); // Also computed in BSDF()
// Compute the normal at the back of the object as R = reflect(N, -V)
// float RdotL = NdotL - 2 * preLightData.NdotV * LdotV;
float illuminance = saturate(-LdotV * attenuation);
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;

[branch] if (bsdfData.enableTransmission)
{
// Reverse the normal + do some wrap lighting to have a nicer transition between regular lighting and transmittance
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
const float w = 0.15;
float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
illuminance *= clipFactor;
float LdotV = dot(L, V); // Also computed in BSDF()
// Compute the normal at the back of the object as R = reflect(N, -V)
// float RdotL = NdotL - 2 * preLightData.NdotV * LdotV;
float illuminance = saturate(-LdotV * clipFactor);
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = bsdfData.useThinObjectMode ? shadow : 1;

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
float3 interpolatedVertexNormal = input.worldToTangent[2].xyz;
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;

surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.worldToTangent[2].xyz, _HorizonFade);
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, interpolatedVertexNormal, _HorizonFade);
// Convert thickness along the normal to thickness along the viewing direction.
surfaceData.thickness *= saturate(dot(interpolatedVertexNormal, V));
// Caution: surfaceData must be fully initialize before calling GetBuiltinData
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);

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


[GenerateHLSL]
public class SssConstants
{
public const int SSS_N_PROFILES = 8; // Max. number of profiles, including the slot taken by the neutral profile
public const int SSS_N_PROFILES = 16; // Max. number of profiles, including the slot taken by the neutral profile
public const int SSS_NEUTRAL_PROFILE_ID = SSS_N_PROFILES - 1; // Does not result in blurring
public const int SSS_N_SAMPLES_NEAR_FIELD = 64; // Used for extreme close ups; must be a power of 2
public const int SSS_N_SAMPLES_FAR_FIELD = 32; // Used at a regular distance; must be a power of 2

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs.hlsl


//
// UnityEngine.Experimental.Rendering.HDPipeline.SssConstants: static fields
//
#define SSS_N_PROFILES (8)
#define SSS_NEUTRAL_PROFILE_ID (7)
#define SSS_N_PROFILES (16)
#define SSS_NEUTRAL_PROFILE_ID (15)
#define SSS_N_SAMPLES_NEAR_FIELD (64)
#define SSS_N_SAMPLES_FAR_FIELD (32)
#define SSS_TRSM_MODE_NONE (0)

19
Assets/ScriptableRenderPipeline/ShaderLibrary/BSDF.hlsl


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

{
float facing = 0.5 + 0.5 * LdotV;
float rough = facing * (0.9 - 0.4 * facing) * ((0.5 + NdotH) / NdotH);
float transmitL = 1 - F_Schlick(0, 1, NdotL);
float transmitV = 1 - F_Schlick(0, 1, NdotV);
float transmitL = F_t_Schlick(0, NdotL);
float transmitV = F_t_Schlick(0, NdotV);
float smooth = transmitL * transmitV * 1.05; // Normalize F_t over the hemisphere
float single = lerp(smooth, rough, perceptualRoughness); // Rescaled by PI
// This constant is picked s.t. setting perceptualRoughness, albedo and all angles to 1

正在加载...
取消
保存