Add analytical approximation for specular BRDF lookup;
@@ -154,7 +154,6 @@ const char* lovrStandardFragmentShader = ""
"uniform vec3 lovrLightDirection; \n"
"uniform vec4 lovrLightColor; \n"
"uniform samplerCube lovrSpecularIrradianceTexture; \n"
-"uniform sampler2D lovrBRDFLookup; \n"
"uniform vec3 lovrIrradiance[9]; \n"
"uniform float lovrExposure; \n"
@@ -162,6 +161,7 @@ const char* lovrStandardFragmentShader = ""
"float G_SmithGGXCorrelated(float NoV, float NoL, float roughness); \n"
"vec3 F_Schlick(vec3 F0, float VoH); \n"
"vec3 E_SphericalHarmonics(vec3 sh[9], vec3 n); \n"
+"vec2 prefilteredBRDF(float NoV, float roughness); \n"
"vec3 tonemap_ACES(vec3 color); \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
@@ -196,9 +196,9 @@ const char* lovrStandardFragmentShader = ""
// Indirect lighting
"#ifdef FLAG_indirectLighting \n"
-" vec2 lookup = texture(lovrBRDFLookup, vec2(NoV, roughness)).rg; \n"
-" float mipmaps = log2(textureSize(lovrSpecularIrradianceTexture, 0).x); \n"
-" vec3 specularIndirect = (F0 * lookup.r + lookup.g) * textureLod(lovrSpecularIrradianceTexture, R, roughness * mipmaps).rgb; \n"
+" vec2 lookup = prefilteredBRDF(NoV, roughness); \n"
+" float mipmapCount = log2(textureSize(lovrSpecularIrradianceTexture, 0).x); \n"
+" vec3 specularIndirect = (F0 * lookup.r + lookup.g) * textureLod(lovrSpecularIrradianceTexture, R, roughness * mipmapCount).rgb; \n"
" vec3 diffuseIndirect = diffuseDirect * E_SphericalHarmonics(lovrIrradiance, N); \n"
"#ifdef FLAG_occlusion \n" // Occlusion only affects indirect diffuse light
" diffuseIndirect *= texture(lovrOcclusionTexture, uv).r; \n"
@@ -254,6 +254,15 @@ const char* lovrStandardFragmentShader = ""
", 0.); \n"
"} \n"
+// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
+"vec2 prefilteredBRDF(float NoV, float roughness) { \n"
+" vec4 c0 = vec4(-1., -.0275, -.572, .022); \n"
+" vec4 c1 = vec4(1., .0425, 1.04, -.04); \n"
+" vec4 r = roughness * c0 + c1; \n"
+" float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; \n"
+" return vec2(-1.04, 1.04) * a004 + r.zw; \n"
+"} \n"
+
"vec3 tonemap_ACES(vec3 color) { \n"
" float a = 2.51; \n"
" float b = 0.03; \n"
