Created SurfaceData structure to centralize computation of frequently used shader temporary values

This commit is contained in:
Olivier Prat 2017-12-21 17:41:36 +01:00
parent 5c476dc967
commit 053bd2ba98
14 changed files with 180 additions and 161 deletions

View file

@ -46,11 +46,14 @@ struct DeferredFragment {
float depthVal; float depthVal;
}; };
<@if not GETFRESNEL0@>
<@def GETFRESNEL0@>
vec3 getFresnelF0(float metallic, vec3 metalF0) { vec3 getFresnelF0(float metallic, vec3 metalF0) {
// Enable continuous metallness value by lerping between dielectric // Enable continuous metallness value by lerping between dielectric
// and metal fresnel F0 value based on the "metallic" parameter // and metal fresnel F0 value based on the "metallic" parameter
return mix(vec3(0.03), metalF0, metallic); return mix(vec3(0.03), metalF0, metallic);
} }
<@endif@>
DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
vec4 normalVal; vec4 normalVal;

View file

@ -65,10 +65,12 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
<$prepareGlobalLight($supportScattering$)$> <$prepareGlobalLight($supportScattering$)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> ); <@endif@> );
@ -79,7 +81,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> ); <@endif@> );
@ -110,10 +112,12 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
) { ) {
<$prepareGlobalLight($supportScattering$)$> <$prepareGlobalLight($supportScattering$)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
@ -123,7 +127,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
@ -174,19 +178,21 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) {
<$prepareGlobalLight()$> <$prepareGlobalLight()$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
color += emissive * isEmissiveEnabled(); color += emissive * isEmissiveEnabled();
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse; color += ambientDiffuse;
color += ambientSpecular / opacity; color += ambientSpecular / opacity;
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse; color += directionalDiffuse;
color += directionalSpecular / opacity; color += directionalSpecular / opacity;
@ -199,19 +205,21 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
{ {
<$prepareGlobalLight()$> <$prepareGlobalLight()$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
color += emissive * isEmissiveEnabled(); color += emissive * isEmissiveEnabled();
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse; color += ambientDiffuse;
color += ambientSpecular / opacity; color += ambientSpecular / opacity;
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse; color += directionalDiffuse;
color += directionalSpecular / opacity; color += directionalSpecular / opacity;

View file

@ -65,10 +65,12 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
<$prepareGlobalLight($supportScattering$)$> <$prepareGlobalLight($supportScattering$)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> ); <@endif@> );
@ -79,7 +81,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> ); <@endif@> );
@ -109,10 +111,12 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
) { ) {
<$prepareGlobalLight($supportScattering$)$> <$prepareGlobalLight($supportScattering$)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
@ -124,7 +128,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
@ -173,19 +177,21 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) {
<$prepareGlobalLight()$> <$prepareGlobalLight()$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
color += emissive * isEmissiveEnabled(); color += emissive * isEmissiveEnabled();
// Ambient // Ambient
vec3 ambientDiffuse; vec3 ambientDiffuse;
vec3 ambientSpecular; vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse; color += ambientDiffuse;
color += ambientSpecular / opacity; color += ambientSpecular / opacity;
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse; color += directionalDiffuse;
color += directionalSpecular / opacity; color += directionalSpecular / opacity;

View file

@ -22,8 +22,9 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
<@func declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@> <@func declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@>
vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) { vec3 fresnelSchlickAmbient(vec3 fresnelColor, SurfaceData surface) {
float f = pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5.0); float gloss = 1.0 - surface.roughness;
float f = pow(1.0 - surface.ldoth, 5.0);
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * f; return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * f;
// return mix(fresnelColor, vec3(1.0), f); // return mix(fresnelColor, vec3(1.0), f);
} }
@ -32,8 +33,8 @@ vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, floa
<$declareSkyboxMap()$> <$declareSkyboxMap()$>
<@endif@> <@endif@>
vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 fragNormal, float roughness) { vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, SurfaceData surface) {
vec3 lightDir = -reflect(fragEyeDir, fragNormal); vec3 lightDir = -reflect(surface.eyeDir, surface.normal);
vec3 specularLight; vec3 specularLight;
<@if supportIfAmbientMapElseAmbientSphere@> <@if supportIfAmbientMapElseAmbientSphere@>
if (getLightHasAmbientMap(ambient)) if (getLightHasAmbientMap(ambient))
@ -41,8 +42,8 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 f
<@if supportAmbientMap@> <@if supportAmbientMap@>
{ {
float levels = getLightAmbientMapNumMips(ambient); float levels = getLightAmbientMapNumMips(ambient);
float lod = min(((roughness)* levels), levels); float lod = min(((surface.roughness)* levels), levels);
specularLight = evalSkyboxLight(lightDir, lod).xyz; specularLight = evalSkyboxLight(surface.lightDir, lod).xyz;
// We multiply specular by Pi to match specular / diffuse normalization in // We multiply specular by Pi to match specular / diffuse normalization in
// LightingModel.slh where diffuse and specular arent divided by Pi (when they should, rigourously // LightingModel.slh where diffuse and specular arent divided by Pi (when they should, rigourously
// speaking, based on physical equations). The spherical harmonics evaluation, on // speaking, based on physical equations). The spherical harmonics evaluation, on
@ -56,7 +57,7 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 f
<@endif@> <@endif@>
<@if supportAmbientSphere@> <@if supportAmbientSphere@>
{ {
specularLight = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lightDir).xyz; specularLight = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), surface.lightDir).xyz;
} }
<@endif@> <@endif@>
@ -74,21 +75,21 @@ float curvatureAO(in float k) {
} }
<@endif@> <@endif@>
void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambient, vec3 eyeDir, vec3 normal, void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambient, SurfaceData surface,
float roughness, float metallic, vec3 fresnelF0, vec3 albedo, float obscurance float metallic, vec3 fresnelF0, vec3 albedo, float obscurance
<@if supportScattering@> <@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@> <@endif@>
) { ) {
// Fresnel // Fresnel
vec3 ambientFresnel = fresnelSchlickAmbient(fresnelF0, eyeDir, normal, 1.0 - roughness); vec3 ambientFresnel = fresnelSchlickAmbient(fresnelF0, surface);
// Diffuse from ambient // Diffuse from ambient
diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), normal).xyz; diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), surface.normal).xyz;
// Specular highlight from ambient // Specular highlight from ambient
specular = evalAmbientSpecularIrradiance(ambient, eyeDir, normal, roughness) * ambientFresnel; specular = evalAmbientSpecularIrradiance(ambient, surface) * ambientFresnel;
<@if supportScattering@> <@if supportScattering@>
if (scattering * isScatteringEnabled() > 0.0) { if (scattering * isScatteringEnabled() > 0.0) {

View file

@ -12,7 +12,7 @@
<@func declareLightingDirectional(supportScattering)@> <@func declareLightingDirectional(supportScattering)@>
void evalLightingDirectional(out vec3 diffuse, out vec3 specular, vec3 lightDir, vec3 lightIrradiance, void evalLightingDirectional(out vec3 diffuse, out vec3 specular, vec3 lightDir, vec3 lightIrradiance,
vec3 eyeDir, vec3 normal, float roughness, SurfaceData surface,
float metallic, vec3 fresnel, vec3 albedo, float shadow float metallic, vec3 fresnel, vec3 albedo, float shadow
<@if supportScattering@> <@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
@ -22,14 +22,17 @@ void evalLightingDirectional(out vec3 diffuse, out vec3 specular, vec3 lightDir,
// Attenuation // Attenuation
vec3 lightEnergy = shadow * lightIrradiance; vec3 lightEnergy = shadow * lightIrradiance;
evalFragShading(diffuse, specular, normal, -lightDir, eyeDir, metallic, fresnel, roughness, albedo updateSurfaceDataWithLight(surface, -lightDir);
evalFragShading(diffuse, specular, metallic, fresnel, surface, albedo
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
); );
diffuse *= lightEnergy * isDiffuseEnabled() * isDirectionalEnabled(); lightEnergy *= isDirectionalEnabled();
specular *= lightEnergy * isSpecularEnabled() * isDirectionalEnabled(); diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
} }
<@endfunc@> <@endfunc@>

View file

@ -12,7 +12,7 @@
<@func declareLightingPoint(supportScattering)@> <@func declareLightingPoint(supportScattering)@>
void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light,
vec4 fragLightDirLen, vec3 fragEyeDir, vec3 normal, float roughness, vec4 fragLightDirLen, SurfaceData surface,
float metallic, vec3 fresnel, vec3 albedo, float shadow float metallic, vec3 fresnel, vec3 albedo, float shadow
<@if supportScattering@> <@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
@ -23,19 +23,22 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light,
float fragLightDistance = fragLightDirLen.w; float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz; vec3 fragLightDir = fragLightDirLen.xyz;
updateSurfaceDataWithLight(surface, fragLightDir);
// Eval attenuation // Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
vec3 lightEnergy = radialAttenuation * shadow * getLightIrradiance(light); vec3 lightEnergy = radialAttenuation * shadow * getLightIrradiance(light);
// Eval shading // Eval shading
evalFragShading(diffuse, specular, normal, fragLightDir, fragEyeDir, metallic, fresnel, roughness, albedo evalFragShading(diffuse, specular, metallic, fresnel, surface, albedo
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
); );
diffuse *= lightEnergy * isDiffuseEnabled() * isPointEnabled(); lightEnergy *= isPointEnabled();
specular *= lightEnergy * isSpecularEnabled() * isPointEnabled(); diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
if (isShowLightContour() > 0.0) { if (isShowLightContour() > 0.0) {
// Show edge // Show edge

View file

@ -12,7 +12,7 @@
<@func declareLightingSpot(supportScattering)@> <@func declareLightingSpot(supportScattering)@>
void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light,
vec4 fragLightDirLen, float cosSpotAngle, vec3 fragEyeDir, vec3 normal, float roughness, vec4 fragLightDirLen, float cosSpotAngle, SurfaceData surface,
float metallic, vec3 fresnel, vec3 albedo, float shadow float metallic, vec3 fresnel, vec3 albedo, float shadow
<@if supportScattering@> <@if supportScattering@>
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
@ -23,6 +23,7 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light,
float fragLightDistance = fragLightDirLen.w; float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz; vec3 fragLightDir = fragLightDirLen.xyz;
updateSurfaceDataWithLight(surface, fragLightDir);
// Eval attenuation // Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
@ -30,14 +31,15 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light,
vec3 lightEnergy = angularAttenuation * radialAttenuation * shadow *getLightIrradiance(light); vec3 lightEnergy = angularAttenuation * radialAttenuation * shadow *getLightIrradiance(light);
// Eval shading // Eval shading
evalFragShading(diffuse, specular, normal, fragLightDir, fragEyeDir, metallic, fresnel, roughness, albedo evalFragShading(diffuse, specular, metallic, fresnel, surface, albedo
<@if supportScattering@> <@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature ,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> <@endif@>
); );
diffuse *= lightEnergy * isDiffuseEnabled() * isSpotEnabled(); lightEnergy *= isSpotEnabled();
specular *= lightEnergy * isSpecularEnabled() * isSpotEnabled(); diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
if (isShowLightContour() > 0.0) { if (isShowLightContour() > 0.0) {
// Show edges // Show edges

View file

@ -77,6 +77,30 @@ float isWireframeEnabled() {
<@endfunc@> <@endfunc@>
<$declareLightingModel()$> <$declareLightingModel()$>
struct SurfaceData {
vec3 normal;
vec3 eyeDir;
vec3 lightDir;
vec3 halfDir;
float roughness;
float roughness2;
float roughness4;
float ndotv;
float ndotl;
float ndoth;
float ldoth;
float smithInvG1NdotV;
};
<@if not GETFRESNEL0@>
<@def GETFRESNEL0@>
vec3 getFresnelF0(float metallic, vec3 metalF0) {
// Enable continuous metallness value by lerping between dielectric
// and metal fresnel F0 value based on the "metallic" parameter
return mix(vec3(0.03), metalF0, metallic);
}
<@endif@>
<@func declareBeckmannSpecular()@> <@func declareBeckmannSpecular()@>
uniform sampler2D scatteringSpecularBeckmann; uniform sampler2D scatteringSpecularBeckmann;
@ -85,17 +109,13 @@ float fetchSpecularBeckmann(float ndoth, float roughness) {
return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0); return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);
} }
vec2 skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) { vec2 skinSpecular(SurfaceData surface, float intensity) {
vec2 result = vec2(0.0, 1.0); vec2 result = vec2(0.0, 1.0);
float ndotl = dot(N, L); if (surface.ndotl > 0.0) {
if (ndotl > 0.0) { float PH = fetchSpecularBeckmann(surface.ndoth, surface.roughness);
vec3 h = L + V; float F = fresnelSchlickScalar(0.028, surface);
vec3 H = normalize(h); float frSpec = max(PH * F / dot(surface.halfDir, surface.halfDir), 0.0);
float ndoth = dot(N, H); result.x = surface.ndotl * intensity * frSpec;
float PH = fetchSpecularBeckmann(ndoth, roughness);
float F = fresnelSchlickScalar(0.028, H, V);
float frSpec = max(PH * F / dot(h, h), 0.0);
result.x = ndotl * intensity * frSpec;
result.y -= F; result.y -= F;
} }
@ -105,83 +125,105 @@ vec2 skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) {
<@func declareEvalPBRShading()@> <@func declareEvalPBRShading()@>
vec3 fresnelSchlickColor(vec3 fresnelColor, vec3 lightDir, vec3 halfDir) { float evalSmithInvG1(float roughness4, float ndotd) {
float base = 1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0); return ndotd + sqrt(roughness4+ndotd*ndotd*(1.0-roughness4));
}
SurfaceData initSurfaceData(float roughness, vec3 normal, vec3 eyeDir) {
SurfaceData surface;
surface.eyeDir = eyeDir;
surface.normal = normal;
surface.lightDir = vec3(0,0,0);
surface.halfDir = vec3(0,0,0);
surface.roughness = mix(0.001, 1.0, roughness);
surface.roughness2 = surface.roughness * surface.roughness;
surface.roughness4 = surface.roughness2 * surface.roughness2;
surface.ndotv = clamp(dot(normal, eyeDir), 0.0, 1.0);
surface.ndoth = 0.0;
surface.ndotl = 0.0;
surface.ldoth = 0.0;
surface.smithInvG1NdotV = evalSmithInvG1(surface.roughness4, surface.ndotv);
return surface;
}
void updateSurfaceDataWithLight(inout SurfaceData surface, vec3 lightDir) {
surface.lightDir = lightDir;
surface.halfDir = normalize(surface.eyeDir + lightDir);
vec3 dots;
dots.x = dot(surface.normal, surface.halfDir);
dots.y = dot(surface.normal, surface.lightDir);
dots.z = dot(surface.halfDir, surface.lightDir);
dots = clamp(dots, vec3(0), vec3(1));
surface.ndoth = dots.x;
surface.ndotl = dots.y;
surface.ldoth = dots.z;
}
vec3 fresnelSchlickColor(vec3 fresnelColor, SurfaceData surface) {
float base = 1.0 - surface.ldoth;
//float exponential = pow(base, 5.0); //float exponential = pow(base, 5.0);
float base2 = base * base; float base2 = base * base;
float exponential = base * base2 * base2; float exponential = base * base2 * base2;
return vec3(exponential) + fresnelColor * (1.0 - exponential); return vec3(exponential) + fresnelColor * (1.0 - exponential);
} }
float fresnelSchlickScalar(float fresnelScalar, vec3 lightDir, vec3 halfDir) { float fresnelSchlickScalar(float fresnelScalar, SurfaceData surface) {
float base = 1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0); float base = 1.0 - surface.ldoth;
//float exponential = pow(base, 5.0); //float exponential = pow(base, 5.0);
float base2 = base * base; float base2 = base * base;
float exponential = base * base2 * base2; float exponential = base * base2 * base2;
return (exponential) + fresnelScalar * (1.0 - exponential); return (exponential) + fresnelScalar * (1.0 - exponential);
} }
float specularDistribution(float roughness, vec3 normal, vec3 halfDir, vec3 eyeDir, float ndotl) { float specularDistribution(SurfaceData surface) {
// See https://www.khronos.org/assets/uploads/developers/library/2017-web3d/glTF-2.0-Launch_Jun17.pdf // See https://www.khronos.org/assets/uploads/developers/library/2017-web3d/glTF-2.0-Launch_Jun17.pdf
// for details of equations, especially page 20 // for details of equations, especially page 20
float ndoth = dot(halfDir, normal); float denom = (surface.ndoth*surface.ndoth * (surface.roughness2 - 1.0) + 1.0);
float ndotv = dot(eyeDir, normal);
vec3 nd = clamp(vec3(ndoth, ndotv, ndotl), vec3(0.0), vec3(1.0));
vec3 nd2 = nd * nd;
float roughness2 = mix(0.001, 1.0, roughness);
roughness2 *= roughness2; // pow 2
float roughness4 = roughness2;
roughness4 *= roughness4; // pow 4
float denom = (nd2.x * (roughness2 - 1.0) + 1.0);
denom *= denom; denom *= denom;
// Add geometric factors G1(n,l) and G1(n,v) // Add geometric factors G1(n,l) and G1(n,v)
float oneMinusRoughness4 = 1.0-roughness4; float smithInvG1NdotL = evalSmithInvG1(surface.roughness4, surface.ndotl);
vec2 invG = nd.yz + sqrt(vec2(roughness4)+nd2.yz*oneMinusRoughness4); denom *= surface.smithInvG1NdotV * smithInvG1NdotL;
denom *= invG.x * invG.y;
// Don't divide by PI as diffuse isn't either. The real PBR formula normalizes // Don't divide by PI as diffuse isn't either. The real PBR formula normalizes
// by PI on both but if we decide to not do it, it is just as if we // by PI on both but if we decide to not do it, it is just as if we
// multiplied all our lights by PI // multiplied all our lights by PI
//denom *= 3.1415926; //denom *= 3.1415926;
float power = roughness4 / denom; float power = surface.roughness4 / denom;
return power; return power;
} }
// Frag Shading returns the diffuse amount as W and the specular rgb as xyz // Frag Shading returns the diffuse amount as W and the specular rgb as xyz
vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) { vec4 evalPBRShading(float metallic, vec3 fresnel, SurfaceData surface) {
// Incident angle attenuation // Incident angle attenuation
float angleAttenuation = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); float angleAttenuation = surface.ndotl;
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); vec3 fresnelColor = fresnelSchlickColor(fresnel, surface);
vec3 fresnelColor = fresnelSchlickColor(fresnel, fragLightDir, halfDir); float power = specularDistribution(surface);
float power = specularDistribution(roughness, fragNormal, halfDir, fragEyeDir, angleAttenuation);
vec3 specular = fresnelColor * power * angleAttenuation; vec3 specular = fresnelColor * power * angleAttenuation;
return vec4(specular, (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x)); return vec4(specular, (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x));
} }
// Frag Shading returns the diffuse amount as W and the specular rgb as xyz // Frag Shading returns the diffuse amount as W and the specular rgb as xyz
vec4 evalPBRShadingDielectric(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float roughness, float fresnel) { vec4 evalPBRShadingDielectric(SurfaceData surface, float fresnel) {
// Incident angle attenuation // Incident angle attenuation
float angleAttenuation = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); float angleAttenuation = surface.ndotl;
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); float fresnelScalar = fresnelSchlickScalar(fresnel, surface);
float fresnelScalar = fresnelSchlickScalar(fresnel, fragLightDir, halfDir); float power = specularDistribution(surface);
float power = specularDistribution(roughness, fragNormal, halfDir, fragEyeDir, angleAttenuation);
vec3 specular = vec3(fresnelScalar) * power * angleAttenuation; vec3 specular = vec3(fresnelScalar) * power * angleAttenuation;
return vec4(specular, angleAttenuation * (1.0 - fresnelScalar)); return vec4(specular, angleAttenuation * (1.0 - fresnelScalar));
} }
vec4 evalPBRShadingMetallic(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float roughness, vec3 fresnel) { vec4 evalPBRShadingMetallic(SurfaceData surface, vec3 fresnel) {
// Incident angle attenuation // Incident angle attenuation
float angleAttenuation = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); float angleAttenuation = surface.ndotl;
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); vec3 fresnelColor = fresnelSchlickColor(fresnel, surface);
vec3 fresnelColor = fresnelSchlickColor(fresnel, fragLightDir, halfDir); float power = specularDistribution(surface);
float power = specularDistribution(roughness, fragNormal, halfDir, fragEyeDir, angleAttenuation);
vec3 specular = fresnelColor * power * angleAttenuation; vec3 specular = fresnelColor * power * angleAttenuation;
return vec4(specular, 0.f); return vec4(specular, 0.f);
@ -193,15 +235,9 @@ vec4 evalPBRShadingMetallic(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir,
<$declareEvalPBRShading()$> <$declareEvalPBRShading()$>
// Return xyz the specular/reflection component and w the diffuse component
//vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) {
// return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness);
//}
void evalFragShading(out vec3 diffuse, out vec3 specular, void evalFragShading(out vec3 diffuse, out vec3 specular,
vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo) {
float metallic, vec3 fresnel, float roughness, vec3 albedo) { vec4 shading = evalPBRShading(metallic, fresnel, surface);
vec4 shading = evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness);
diffuse = vec3(shading.w); diffuse = vec3(shading.w);
if (isAlbedoEnabled() > 0.0) { if (isAlbedoEnabled() > 0.0) {
diffuse *= albedo; diffuse *= albedo;
@ -215,22 +251,19 @@ void evalFragShading(out vec3 diffuse, out vec3 specular,
void evalFragShading(out vec3 diffuse, out vec3 specular, void evalFragShading(out vec3 diffuse, out vec3 specular,
vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo,
float metallic, vec3 fresnel, float roughness, vec3 albedo,
float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature) { float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature) {
if (scattering * isScatteringEnabled() > 0.0) { if (scattering * isScatteringEnabled() > 0.0) {
vec3 brdf = evalSkinBRDF(fragLightDir, fragNormal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w); vec3 brdf = evalSkinBRDF(surface.lightDir, surface.normal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w);
float NdotL = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); diffuse = mix(vec3(surface.ndotl), brdf, scattering);
diffuse = mix(vec3(NdotL), brdf, scattering);
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); vec2 specularBrdf = skinSpecular(surface, 1.0);
vec2 specularBrdf = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0);
diffuse *= specularBrdf.y; diffuse *= specularBrdf.y;
specular = vec3(specularBrdf.x); specular = vec3(specularBrdf.x);
} else { } else {
vec4 shading = evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, roughness); vec4 shading = evalPBRShading(metallic, fresnel, surface);
diffuse = vec3(shading.w); diffuse = vec3(shading.w);
specular = shading.xyz; specular = shading.xyz;
} }
@ -239,17 +272,15 @@ void evalFragShading(out vec3 diffuse, out vec3 specular,
void evalFragShadingScattering(out vec3 diffuse, out vec3 specular, void evalFragShadingScattering(out vec3 diffuse, out vec3 specular,
vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo
float metallic, vec3 fresnel, float roughness, vec3 albedo
,float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature ,float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
) { ) {
vec3 brdf = evalSkinBRDF(fragLightDir, fragNormal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w); vec3 brdf = evalSkinBRDF(surface.lightDir, surface.normal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w);
float NdotL = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); float NdotL = surface.ndotl;
diffuse = mix(vec3(NdotL), brdf, scattering); diffuse = mix(vec3(NdotL), brdf, scattering);
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); vec2 specularBrdf = skinSpecular(surface, 1.0);
vec2 specularBrdf = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0);
diffuse *= specularBrdf.y; diffuse *= specularBrdf.y;
specular = vec3(specularBrdf.x); specular = vec3(specularBrdf.x);
@ -257,10 +288,9 @@ void evalFragShadingScattering(out vec3 diffuse, out vec3 specular,
} }
void evalFragShadingGloss(out vec3 diffuse, out vec3 specular, void evalFragShadingGloss(out vec3 diffuse, out vec3 specular,
vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo
float metallic, vec3 fresnel, float gloss, vec3 albedo
) { ) {
vec4 shading = evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, fresnel, gloss); vec4 shading = evalPBRShading(metallic, fresnel, surface);
diffuse = vec3(shading.w); diffuse = vec3(shading.w);
diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled()); diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled());
specular = shading.xyz; specular = shading.xyz;

View file

@ -63,38 +63,6 @@ vec3 scatter(float r) {
<@endfunc@> <@endfunc@>
<@func declareSkinSpecularLighting()@>
uniform sampler2D scatteringSpecularBeckmann;
float fetchSpecularBeckmann(float ndoth, float roughness) {
return pow( 2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);
}
float fresnelReflectance(vec3 H, vec3 V, float Fo) {
float base = 1.0 - dot(V, H);
float exponential = pow(base, 5.0);
return exponential + Fo * (1.0 - exponential);
}
float skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) {
float result = 0.0;
float ndotl = dot(N, L);
if (ndotl > 0.0) {
vec3 h = L + V;
vec3 H = normalize(h);
float ndoth = dot(N, H);
float PH = fetchSpecularBeckmann(ndoth, roughness);
float F = fresnelReflectance(H, V, 0.028);
float frSpec = max(PH * F / dot(h, h), 0.0);
result = ndotl * intensity * frSpec;
}
return result;
}
<@endfunc@>
<@func declareSubsurfaceScatteringIntegrate(NumIntegrationSteps)@> <@func declareSubsurfaceScatteringIntegrate(NumIntegrationSteps)@>

View file

@ -84,9 +84,8 @@ void main(void) {
// Frag to eye vec // Frag to eye vec
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz); vec3 fragEyeDir = normalize(fragEyeVector.xyz);
// Compute the rougness into gloss2 once: SurfaceData surface = initSurfaceData(frag.roughness, frag.normal, fragEyeDir);
float fragGloss2 = pow(frag.roughness + 0.001, 4.0);
bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0); bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0);
int numLightTouching = 0; int numLightTouching = 0;
@ -119,16 +118,18 @@ void main(void) {
float fragLightDistance = fragLightDirLen.w; float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz; vec3 fragLightDir = fragLightDirLen.xyz;
updateSurfaceDataWithLight(surface, fragLightDir);
// Eval attenuation // Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light); vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
// Eval shading // Eval shading
if (withScattering) { if (withScattering) {
evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo evalFragShadingScattering(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo
,frag.scattering, midNormalCurvature, lowNormalCurvature ); ,frag.scattering, midNormalCurvature, lowNormalCurvature );
} else { } else {
evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo); evalFragShadingGloss(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo);
} }
diffuse *= lightEnergy * isDiffuseEnabled(); diffuse *= lightEnergy * isDiffuseEnabled();
@ -173,6 +174,8 @@ void main(void) {
float fragLightDistance = fragLightDirLen.w; float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz; vec3 fragLightDir = fragLightDirLen.xyz;
updateSurfaceDataWithLight(surface, fragLightDir);
// Eval attenuation // Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle); float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
@ -180,10 +183,10 @@ void main(void) {
// Eval shading // Eval shading
if (withScattering) { if (withScattering) {
evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo evalFragShadingScattering(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo
,frag.scattering, midNormalCurvature, lowNormalCurvature ); ,frag.scattering, midNormalCurvature, lowNormalCurvature );
} else { } else {
evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo); evalFragShadingGloss(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo);
} }
diffuse *= lightEnergy * isDiffuseEnabled(); diffuse *= lightEnergy * isDiffuseEnabled();

View file

@ -50,13 +50,7 @@ void main(void) {
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>; <$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
float metallic = getMaterialMetallic(mat); float metallic = getMaterialMetallic(mat);
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value vec3 fresnel = getFresnelF0(metallic, albedo);
if (metallic <= 0.5) {
metallic = 0.0;
} else {
fresnel = albedo;
metallic = 1.0;
}
vec3 emissive = getMaterialEmissive(mat); vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;

View file

@ -60,13 +60,7 @@ void main(void) {
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>; <$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
float metallic = getMaterialMetallic(mat); float metallic = getMaterialMetallic(mat);
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value vec3 fresnel = getFresnelF0(metallic, albedo);
if (metallic <= 0.5) {
metallic = 0.0;
} else {
fresnel = albedo;
metallic = 1.0;
}
vec3 emissive = getMaterialEmissive(mat); vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;

View file

@ -40,12 +40,14 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 a
vec3 fragEyeDir; vec3 fragEyeDir;
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$> <$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
SurfaceData surface = initSurfaceData(roughness, normal, fragEyeDir);
vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(ambient); vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(ambient);
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled();
color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled();

View file

@ -40,12 +40,14 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 a
vec3 fragEyeDir; vec3 fragEyeDir;
<$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$> <$transformEyeToWorldDir(cam, fragEyeVectorView, fragEyeDir)$>
SurfaceData surface = initSurfaceData(roughness, normal, fragEyeDir);
vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(ambient); vec3 color = opacity * albedo * getLightColor(light) * getLightAmbientIntensity(ambient);
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse; color += directionalDiffuse;
color += directionalSpecular / opacity; color += directionalSpecular / opacity;