Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add multi-layers lighting model and fix direct specular #15778

Merged
merged 9 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions editor/assets/chunks/common/lighting/brdf.chunk
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <common/math/number>

// for dielectric(non-metal) surfaces
float F0ToIor(float F0)
{
return 2.0f / (1.0f - sqrt(F0)) - 1.0f;
Expand All @@ -11,9 +12,15 @@ float IorToF0(float ior)
return F0_sqrt * F0_sqrt;
}

float V_Kelemen(float LoH)
float square(float a) { return a * a;}
vec2 square(vec2 a) { return a * a;}
vec3 square(vec3 a) { return a * a;}
float G_Schlick( float roughness, float NoV, float NoL )
{
return 0.25 / (LoH * LoH);
float k = square( 0.5 + 0.5*roughness );
float G_SchlickV = NoV * (1.0 - k) + k;
float G_SchlickL = NoL * (1.0 - k) + k;
return 0.25 / ( G_SchlickV * G_SchlickL );
}

vec3 F_Schlick( vec3 specularColor, float VoH )
Expand All @@ -22,6 +29,12 @@ vec3 F_Schlick( vec3 specularColor, float VoH )
float selfShadowTerm = saturate(50.0 * specularColor.g);
return specularColor * (1.0 - Fc) + vec3(selfShadowTerm * Fc);
}
vec3 F_SchlickMultiplier( vec3 specularColor, float VoH )
{
float Fc = exp2( (-5.55473 * VoH - 6.98316) * VoH );
float selfShadowTerm = saturate(50.0 * specularColor.g);
return vec3(1.0 - Fc) + vec3(selfShadowTerm * Fc) / (specularColor + vec3(EPSILON));
}

float D_GGX(float roughness, float NoH)
{
Expand Down Expand Up @@ -92,6 +105,16 @@ vec3 IntegratedGFApprox (vec3 specular, float roughness, float NoV) {
AB.y *= clamp(50.0 * specular.g, 0.0, 1.0);
return max(vec3(0.0), specular * AB.x + AB.y);
}
void IntegratedGFMultiplier (out vec3 integratedGF, out vec3 integratedF, vec3 specular, float roughness, float NoV) {
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
vec4 r = roughness * c0 + c1;
float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
AB.y *= clamp(50.0 * specular.g, 0.0, 1.0);
integratedF = vec3(max(0.0, AB.x));
integratedGF = max(vec3(0.0), vec3(AB.x) + vec3(AB.y) / (specular + EPSILON_LOWP));
}

//Diffuse_Lambert
#define DiffuseCoefficient_EnergyConservation INV_PI
49 changes: 44 additions & 5 deletions editor/assets/chunks/common/lighting/bxdf.chunk
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

// saturated N dot V
// for env reflection with dielectric(non-metal) and smooth surfaces
float CalculateFresnelCoefficient(float ior, float NoVSat)
{
float g, c, n, prev, next;
Expand All @@ -13,11 +14,49 @@ float CalculateFresnelCoefficient(float ior, float NoVSat)
return 0.5 * prev * (1.0 + next);
}

// for arbitary smooth surfaces
float CalculateFresnelCoefficient(float F0, float F90, float NoVSat)
{
return mix(F90, F0, NoVSat);
}

vec3 CalculateScattering(vec3 unscatteredColor, float distance, float outScatterExtinctCoef, float inScatterExtinctCoef, float inScatterCoef, vec3 inScatterColor, vec3 outScatterColor)
{
vec2 e = vec2(outScatterExtinctCoef, inScatterExtinctCoef * inScatterCoef);
vec2 extinction = exp(-e * distance);
vec3 inScattered = (1.0 - extinction.y) * inScatterColor;
vec3 outScattered = unscatteredColor * extinction.x * outScatterColor;
return outScattered + inScattered;
vec2 e = vec2(outScatterExtinctCoef, inScatterExtinctCoef * inScatterCoef);
vec2 extinction = exp(-e * distance);
vec3 inScattered = (1.0 - extinction.y) * inScatterColor;
vec3 outScattered = unscatteredColor * extinction.x * outScatterColor;
return outScattered + inScattered;
}


// LastLayerF for temporary use
// S is spec without GF
void InitializeLayerBlending(out vec3 blendedBaseLayerD, out vec3 blendedBaseLayerS,
out vec3 blendedSubLayerD, out vec3 blendedSubLayerS,
out vec3 lastLayerF,
in vec3 baseD, in vec3 baseS
)
{
blendedBaseLayerD = baseD;
blendedBaseLayerS = baseS;
blendedSubLayerD = blendedSubLayerS = vec3(0.0);
lastLayerF = vec3(1.0);
}

// use subLayerF instead of subLayerGF for ior-dependent 0-1 range
void CalculateLayerBlending(inout vec3 blendedBaseLayerD, inout vec3 blendedBaseLayerS,
inout vec3 blendedSubLayerD, inout vec3 blendedSubLayerS,
inout vec3 lastLayerF,
in vec3 subLayerD, in vec3 subLayerDiffuseColor,
in vec3 subLayerS, in vec3 subLayerSpecularColor,
in float subLayerOpacity, inout vec3 subLayerF
)
{
subLayerF = saturate(subLayerF * subLayerOpacity);
blendedSubLayerD = blendedSubLayerD * (vec3(1.0) - lastLayerF) + subLayerD * subLayerDiffuseColor * subLayerF;
blendedSubLayerS = blendedSubLayerS *(vec3(1.0) - lastLayerF) + subLayerS * subLayerSpecularColor * subLayerF;
blendedBaseLayerD *= vec3(1.0) - subLayerF;
blendedBaseLayerS *= vec3(1.0) - subLayerF;
lastLayerF = subLayerF;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ struct LightingIntermediateData
float distToCamera, distToCameraSqr; // pos->camera
float angleAttenuation, distAttenuation;

float NoL, NoV, NoH;//, VoH;
float NoL, NoV, NoH, VoH;
float NoLSat, NoVSat, NoHSat;//, VoHSat; // clamped to 0-1
float NoVAbsSat; // abs and clamped to 1
float NoVAbsSat, VoHAbsSat; // abs and clamped to 1

HIGHP_VALUE_STRUCT_DEFINE(vec3, worldPosition);

Expand All @@ -16,7 +16,8 @@ struct LightingIntermediateData

// material data
float specularParam; // roughness or specular power
float ior;
// todo: add F0 & F90
float ior, layerOpacity;

#if CC_SURFACES_LIGHTING_ANISOTROPIC
float anisotropyShape;
Expand Down Expand Up @@ -92,9 +93,11 @@ void CCSurfacesLightingGetIntermediateData_PerLight(inout LightingIntermediateDa
// dot
data.NoL = dot(data.N, data.L);
data.NoH = dot(data.N, data.H);
// data.VoH = dot(data.V, data.H);
data.VoH = dot(data.V, data.H);

data.NoLSat = max(data.NoL, 0.0);
data.NoHSat = max(data.NoH, 0.0);
// data.VoHSat = max(data.VoH, 0.0);

data.VoHAbsSat = max(abs(data.VoH), 0.0);
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,47 @@
struct LightingResult
{
// material-dependent lighting data
vec3 diffuseColorWithLighting, specularColorWithLighting, specularColorWithEnvLighting;
vec3 diffuseColorWithLighting, specularColorWithLighting;

// pure lighting
vec3 directDiffuse, directSpecular;
vec3 environmentDiffuse, environmentSpecular;
vec3 directDiffuse, directSpecular, directGF;
vec3 environmentDiffuse, environmentSpecular, environmentGF;
float shadow, ao;
vec3 lightmapColor;
vec3 emissive;

// advanced
#if CC_SURFACES_LIGHTING_USE_FRESNEL
float fresnel;
vec3 fresnel; // for transmit materials , rim or special effects

#if CC_SURFACES_LIGHTING_USE_MULTIPLE_LAYER_BLEND
vec3 directDiffuseSubLayers, directSpecularSubLayers;
vec3 environmentDiffuseSubLayers, environmentSpecularSubLayers;
#endif

#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR
vec3 directTransmitSpecular, environmentTransmitSpecular;
#endif
#if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE
vec3 directTransmitDiffuse, environmentTransmitDiffuse;
#endif
#endif
#if CC_SURFACES_LIGHTING_2ND_LAYER_SPECULAR
vec3 direct2ndSpecular, environment2ndSpecular;
vec3 specularColorWithLighting2ndSpecular, specularColorWithEnvLighting2ndSpecular;
vec3 specularColorWithLighting2ndSpecular;
vec3 directGF2ndSpecular, environmentGF2ndSpecular;
vec3 directSubLayerF, environmentSubLayerF;
#endif
#if CC_SURFACES_LIGHTING_TT
vec3 directTT;
vec3 diffuseColorWithLightingTT;
#endif
//vec3 scattered;
};


/* for multi-layer materials, should define:
struct LightingResultPerLayer
{
vec3 diffuseColorWithLighting, specularColorWithLighting;
vec3 directDiffuse, directSpecular, directGF;
vec3 environmentDiffuse, environmentSpecular, environmentGF;
}*/
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
CCSurfacesInitializeLightingIntermediateData(lightingData, surfaceData);

LightingResult lightingResult;
CCSurfacesLightingInitializeColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData);
CCSurfacesLightingInitializeColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData);
lightingResultAccumulated.diffuseColorWithLighting = lightingResult.diffuseColorWithLighting;
lightingResultAccumulated.specularColorWithLighting = lightingResult.specularColorWithLighting;
lightingResultAccumulated.specularColorWithEnvLighting = lightingResult.specularColorWithEnvLighting;

#if CC_SURFACES_LIGHTING_2ND_LAYER_SPECULAR
vec3 diff;
SurfacesMaterialData surfaceData2ndSpecular;
CCSurfacesGetSurfacesMaterialData2ndSpecular(surfaceData2ndSpecular, surfaceData);
CCSurfacesLightingInitializeColorWithLighting(diff, lightingResultAccumulated.specularColorWithLighting2ndSpecular, lightingResultAccumulated.specularColorWithEnvLighting2ndSpecular, surfaceData2ndSpecular, lightingData);
CCSurfacesLightingInitializeColorWithLighting(diff, lightingResultAccumulated.specularColorWithLighting2ndSpecular, surfaceData2ndSpecular, lightingData);
#endif

int numLights = CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_FORWARD ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);
Expand All @@ -29,15 +28,18 @@

vec3 lightDirWithLength = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -normalize(cc_lightDir[i].xyz) : cc_lightPos[i].xyz - worldPos;
CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData, surfaceData, lightDirWithLength);
CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData);
CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData);

vec3 diffuseLighting, specularLighting;
CCSurfacesLightingCalculateDirect(diffuseLighting, specularLighting, lightingData, cc_lightColor[i]);

float fresnel = 1.0;
#if CC_SURFACES_LIGHTING_USE_FRESNEL
fresnel = lightingResult.fresnel = CCSurfaceLightingCalculateFresnel(lightingData);
vec3 fresnel = CCSurfaceLightingCalculateExtraFresnel(lightingData);
#else
vec3 fresnel = vec3(1.0);
#endif
lightingResult.fresnel = fresnel;


float shadow = 1.0;
#if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP
Expand Down Expand Up @@ -84,7 +86,8 @@
lightingData.angleAttenuation = angleAtt;
lightingData.distAttenuation = distAtt;
lightingResult.directDiffuse = diffuseLighting * multiplier;
lightingResult.directSpecular = specularLighting * multiplier * fresnel;
lightingResult.directSpecular = specularLighting * multiplier;
CCSurfaceLightingCalculateDirectFresnel(lightingResult.directGF, lightingData, lightingResult.specularColorWithLighting, vec3(1.0));

vec4 attenuatedLightColorAndIntensity = vec4(cc_lightColor[i].xyz, cc_lightColor[i].w * multiplier);

Expand All @@ -106,13 +109,18 @@
CCSurfacesInitializeLightingIntermediateData(lightingData2ndSpecular, surfaceData2ndSpecular);
CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData2ndSpecular, surfaceData, lightDirWithLength);
CCSurfacesLightingCalculateDirect2ndSpecular(lightingResult.direct2ndSpecular, lightingData2ndSpecular, attenuatedLightColorAndIntensity, surfaceData2ndSpecular.intensity2ndSpecular, lightingResult.directSpecular);
lightingResult.direct2ndSpecular *= multiplier * fresnel;
CCSurfaceLightingCalculateDirectFresnel(lightingResult.directGF2ndSpecular, lightingData2ndSpecular, lightingResult.specularColorWithLighting2ndSpecular, vec3(1.0));

lightingResult.direct2ndSpecular *= multiplier;
#endif

#if CC_SURFACES_LIGHTING_TT
CCSurfacesLightingCalculateDirectTT(lightingResult, lightingData, attenuatedLightColorAndIntensity);
#endif

#if CC_SURFACES_LIGHTING_USE_MULTIPLE_LAYER_BLEND
CCSurfacesLightingCalculateDirectMultiLayerBlending(lightingResult, lightingData2ndSpecular);
#endif

// user-defined lighting model
#ifdef CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT
Expand All @@ -139,7 +147,7 @@
CCSurfacesInitializeLightingIntermediateData(lightingData, surfaceData);
CCSurfacesInitializeLightingResult(lightingResult, surfaceData);

CCSurfacesLightingInitializeColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData);
CCSurfacesLightingInitializeColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData);

CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData, surfaceData, -cc_mainLitDir.xyz);

Expand Down Expand Up @@ -200,20 +208,24 @@
#endif


// apply SSR, local probe & global probe
vec3 unused;
CCSurfacesLightingCalculateEnvironment(lightingResult.environmentDiffuse, lightingResult.environmentSpecular, lightingData, cc_ambientSky.w);
CCSurfaceLightingCalculateEnvironmentFresnel(lightingResult.environmentGF, unused, lightingData, lightingResult.specularColorWithLighting);

// dynamic & stationary dir light
lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0);
#if !CC_DISABLE_DIRECTIONAL_LIGHT && !CC_FORWARD_ADD
CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData);
CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, surfaceData, lightingData);

CCSurfacesLightingCalculateDirect(lightingResult.directDiffuse, lightingResult.directSpecular, lightingData, cc_mainLitColor);
CCSurfaceLightingCalculateDirectFresnel(lightingResult.directGF, lightingData, lightingResult.specularColorWithLighting, lightingResult.environmentGF);
#endif

// apply SSR, local probe & global probe
CCSurfacesLightingCalculateEnvironment(lightingResult.environmentDiffuse, lightingResult.environmentSpecular, lightingData, cc_ambientSky.w);


#if CC_SURFACES_LIGHTING_USE_FRESNEL
lightingResult.fresnel = CCSurfaceLightingCalculateFresnel(lightingData);
lightingResult.fresnel = CCSurfaceLightingCalculateExtraFresnel(lightingData);
#else
lightingResult.fresnel = vec3(1.0);
#endif

#if CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR
Expand All @@ -236,17 +248,26 @@
LightingIntermediateData lightingData2ndSpecular;
CCSurfacesInitializeLightingIntermediateData(lightingData2ndSpecular, surfaceData2ndSpecular);
CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData2ndSpecular, surfaceData2ndSpecular, -cc_mainLitDir.xyz);
CCSurfacesLightingCalculateDirect2ndSpecular(lightingResult.direct2ndSpecular, lightingData2ndSpecular, cc_mainLitColor, surfaceData2ndSpecular.intensity2ndSpecular, lightingResult.directSpecular);
CCSurfacesLightingCalculateEnvironment2ndSpecular(lightingResult.environment2ndSpecular, lightingData2ndSpecular, cc_ambientSky.w, surfaceData2ndSpecular.intensity2ndSpecular, lightingResult.environmentSpecular);

vec3 diff;
CCSurfacesLightingInitializeColorWithLighting(diff, lightingResult.specularColorWithLighting2ndSpecular, lightingResult.specularColorWithEnvLighting2ndSpecular, surfaceData2ndSpecular, lightingData2ndSpecular);
CCSurfacesLightingInitializeColorWithLighting(diff, lightingResult.specularColorWithLighting2ndSpecular, surfaceData2ndSpecular, lightingData2ndSpecular);

CCSurfacesLightingCalculateEnvironment2ndSpecular(lightingResult.environment2ndSpecular, lightingData2ndSpecular, cc_ambientSky.w, surfaceData2ndSpecular.intensity2ndSpecular, lightingResult.environmentSpecular);
CCSurfaceLightingCalculateEnvironmentFresnel(lightingResult.environmentGF2ndSpecular, lightingResult.environmentSubLayerF, lightingData2ndSpecular, lightingResult.specularColorWithLighting2ndSpecular);

CCSurfacesLightingCalculateDirect2ndSpecular(lightingResult.direct2ndSpecular, lightingData2ndSpecular, cc_mainLitColor, surfaceData2ndSpecular.intensity2ndSpecular, lightingResult.directSpecular);
CCSurfaceLightingCalculateDirectFresnel(lightingResult.directGF2ndSpecular, lightingData2ndSpecular, lightingResult.specularColorWithLighting2ndSpecular, lightingResult.environmentGF2ndSpecular);
#endif

#if CC_SURFACES_LIGHTING_TT
CCSurfacesLightingCalculateDirectTT(lightingResult, lightingData, cc_mainLitColor);
#endif

#if CC_SURFACES_LIGHTING_USE_MULTIPLE_LAYER_BLEND
CCSurfacesLightingCalculateDirectMultiLayerBlending(lightingResult, lightingData2ndSpecular);
CCSurfacesLightingCalculateEnvironmentMultiLayerBlending(lightingResult, lightingData2ndSpecular);
#endif

// user-defined lighting model
#ifdef CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT
LightingMiscData miscData;
Expand Down
Loading
Loading