Introduced Oren-Nayar as a possible diffuse BRDF alternative. We are still defaulting to lambertian diffuse, though. To use Oren-Nayar, set the OODIFFUSE_ORENNAYAR macro in the default planet and ship shaders to 1.

This commit is contained in:
AnotherCommander 2020-06-07 22:59:18 +02:00
parent 104f9c045d
commit 74b180735a
2 changed files with 55 additions and 3 deletions

View File

@ -85,6 +85,8 @@ uniform sampler2D uSpecularMap;
#define SPECULAR_FACTOR (texture2D(uSpecularMap, texCoords).r)
#elif OOSTD_NORMAL_AND_SPECULAR_MAP
#define SPECULAR_FACTOR (normalMapSample.a)
#else
#define SPECULAR_FACTOR 0.2
#endif
@ -125,6 +127,9 @@ uniform sampler2D uNormalMap;
#endif
#endif
// Diffuse model selection - if 0, then Lambert is selected
#define OODIFFUSE_ORENNAYAR 0
// Specular model selection
#ifndef OOSPECULAR_NEW_MODEL
#define OOSPECULAR_NEW_MODEL 1
@ -140,6 +145,23 @@ varying vec3 vLight1Vector;
varying vec3 vCoords;
#if OODIFFUSE_ORENNAYAR
// based on https://www.shadertoy.com/view/ltfyD8
float diffuseOrenNayar(vec3 lightVector, vec3 eyeVector, vec3 normal, float gloss, float albedoFactor)
{
float NdotL = dot(lightVector, normal);
float NdotV = dot(normal, eyeVector);
float roughness = 1.0 - gloss;
float sigma2 = roughness * roughness;
float A = 1.0 - 0.5 * (sigma2 / (((sigma2 + 0.33) + 0.000001)));
float B = 0.45 * sigma2 / ((sigma2 + 0.09) + 0.00001);
float ga = dot(eyeVector - normal * NdotV, normal - normal * NdotL);
return albedoFactor * max(0.0, NdotL) * (A + B * max(0.0, ga) * sqrt(max((1.0 - NdotV * NdotV) * (1.0 - NdotL * NdotL), 0.0)) / max(NdotL, NdotV));
}
#endif
vec3 CalcDiffuseIntensity(in vec3 lightVector, in vec3 normal)
{
float LdotN = lightVector.z;
@ -286,7 +308,11 @@ void main()
vec3 eyeVector = normalize(vEyeVector);
vec3 halfVector = normalize(light1Vector + eyeVector);
vec3 diffuseIntensity = CalcDiffuseIntensity(light1Vector, normal);
#if OODIFFUSE_ORENNAYAR
vec3 diffuseLight = DIFFUSE_LIGHT * diffuseOrenNayar(light1Vector, eyeVector, normal, max(SPECULAR_FACTOR * 0.64, 0.2), 1.0);
#else
vec3 diffuseLight = DIFFUSE_LIGHT * max(0.0, dot(normal, light1Vector));
#endif
#if OOSTD_CUBE_MAP
vec4 diffuseMapSample = textureCube(uDiffuseMap, vCoords);
#else

View File

@ -143,6 +143,9 @@ uniform float uGloss;
uniform bool uGammaCorrect;
// Diffuse model selection - if 0, then Lambert is selected
#define OODIFFUSE_ORENNAYAR 0
#ifndef OOSPECULAR_NEW_MODEL
#define OOSPECULAR_NEW_MODEL 1
#ifndef OOSPECULAR_NEW_MODEL_GGX
@ -158,7 +161,25 @@ uniform bool uGammaCorrect;
#define OOLINEAR_TO_SRGB (1.0 / 2.2)
#endif
vec4 CalcDiffuseLight(in vec3 lightVector, in vec3 normal, in vec4 lightColor)
#if OODIFFUSE_ORENNAYAR
// based on https://www.shadertoy.com/view/ltfyD8
float diffuseOrenNayar(vec3 lightVector, vec3 eyeVector, vec3 normal, float gloss, float albedoFactor)
{
float NdotL = dot(lightVector, normal);
float NdotV = dot(normal, eyeVector);
float roughness = 1.0 - gloss;
float sigma2 = roughness * roughness;
float A = 1.0 - 0.5 * (sigma2 / (((sigma2 + 0.33) + 0.000001)));
float B = 0.45 * sigma2 / ((sigma2 + 0.09) + 0.00001);
float ga = dot(eyeVector - normal * NdotV, normal - normal * NdotL);
return albedoFactor * max(0.0, NdotL) * (A + B * max(0.0, ga) * sqrt(max((1.0 - NdotV * NdotV) * (1.0 - NdotL * NdotL), 0.0)) / max(NdotL, NdotV));
}
#endif
vec3 CalcDiffuseLight(in vec3 lightVector, in vec3 normal, in vec3 lightColor)
{
#if OOSTD_NORMAL_MAP
float intensity = dot(normal, lightVector);
@ -339,7 +360,6 @@ void main(void)
#endif
vec4 diffuseLight = vec4(0);
diffuseLight += CalcDiffuseLight(lightVector, normal, LIGHTSRC_RADIANCE_DIFFUSE);
#if HAVE_ILLUMINATION
diffuseLight += illuminationMapLight;
@ -365,6 +385,7 @@ void main(void)
#endif
vec3 fresnel = vec3(0.0);
float gloss = uGloss;
// Calculate specular light
#if OOSTD_SPECULAR
vec4 specularLight = vec4(0);
@ -377,7 +398,6 @@ void main(void)
#else
fresnel = FresnelSchlick(specularColor.rgb, lightVector, halfVector);
#if OOSPECULAR_NEW_MODEL_GGX
float gloss = uGloss;
#if OOSTD_SPECULAR_MAP
gloss *= specularMapColor.a;
#endif
@ -405,6 +425,12 @@ void main(void)
diffuseColor *= diffuseMapColor;
ambientColor *= diffuseMapColor;
#endif
#if OODIFFUSE_ORENNAYAR
diffuseLight.rgb += diffuseOrenNayar(lightVector, eyeVector, normal, gloss, 1.0) * LIGHTSRC_RADIANCE_DIFFUSE.rgb;
#else
diffuseLight.rgb += CalcDiffuseLight(lightVector, normal, LIGHTSRC_RADIANCE_DIFFUSE.rgb);
#endif
// light energy conservation here
#if OOSPECULAR_NEW_MODEL