Standard shader: Refactoring;

This commit is contained in:
bjorn 2019-08-09 17:31:30 -07:00
parent 948363e7df
commit b8cb53e021
1 changed files with 62 additions and 67 deletions

View File

@ -158,6 +158,68 @@ const char* lovrStandardFragmentShader = ""
"uniform vec3 lovrIrradiance[9]; \n"
"uniform float lovrExposure = 1.; \n"
"float D_GGX(float NoH, float roughness); \n"
"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"
"vec3 tonemap_ACES(vec3 color); \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" vec3 color = vec3(0.); \n"
// Parameters
" vec3 baseColor = texture(lovrDiffuseTexture, uv).rgb * lovrDiffuseColor.rgb; \n"
" float metalness = texture(lovrMetalnessTexture, uv).b * lovrMetalness; \n"
" float roughness = max(texture(lovrRoughnessTexture, uv).g * lovrRoughness, .05); \n"
"#ifdef FLAG_normalTexture \n"
" vec3 N = normalize(vTangentMatrix * (texture(lovrNormalTexture, uv).rgb * 2. - 1.)); \n"
"#else \n"
" vec3 N = normalize(vNormal); \n"
"#endif \n"
" vec3 V = normalize(vCameraPosition - vWorldPosition); \n"
" vec3 L = normalize(-lovrLightDirection); \n"
" vec3 H = normalize(V + L); \n"
" vec3 R = normalize(reflect(-V, N)); \n"
" float NoV = abs(dot(N, V)) + 1e-2; \n"
" float NoL = clamp(dot(N, L), 0., 1.); \n"
" float NoH = clamp(dot(N, H), 0., 1.); \n"
" float VoH = clamp(dot(V, H), 0., 1.); \n"
// Direct lighting
" vec3 F0 = mix(vec3(.04), baseColor, metalness); \n"
" float D = D_GGX(NoH, roughness); \n"
" float G = G_SmithGGXCorrelated(NoV, NoL, roughness); \n"
" vec3 F = F_Schlick(F0, VoH); \n"
" vec3 specularDirect = vec3(D * G * F); \n"
" vec3 diffuseDirect = (vec3(1.) - F) * (1. - metalness) * baseColor; \n"
" color += (diffuseDirect / PI + specularDirect) * NoL * lovrLightColor.rgb * lovrLightColor.a; \n"
// 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"
" vec3 diffuseIndirect = diffuseDirect * E_SphericalHarmonics(lovrIrradiance, N); \n"
"#ifdef FLAG_occlusion \n" // Occlusion only affects indirect diffuse light
" diffuseIndirect *= texture(lovrOcclusionTexture, uv).r; \n"
"#endif \n"
" color += diffuseIndirect + specularIndirect; \n"
"#endif \n"
// Emissive
"#ifdef FLAG_emissive \n" // Currently emissive texture and color have to be used together
" color += texture(lovrEmissiveTexture, uv).rgb * lovrEmissiveColor.rgb; \n"
"#endif \n"
// Tonemap
"#ifdef FLAG_tonemap \n"
" color = tonemap_ACES(color * lovrExposure); \n"
"#endif \n"
" return vec4(color, 1.); \n"
"}"
// Helpers
"float D_GGX(float NoH, float roughness) { \n"
" float alpha = roughness * roughness; \n"
" float alpha2 = alpha * alpha; \n"
@ -199,73 +261,6 @@ const char* lovrStandardFragmentShader = ""
" float d = 0.59; \n"
" float e = 0.14; \n"
" return (color * (a * color + b)) / (color * (c * color + d) + e); \n"
"} \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" vec3 color = vec3(0.); \n"
// Base color
" vec3 baseColor = lovrDiffuseColor.rgb; \n"
" baseColor *= texture(lovrDiffuseTexture, uv).rgb; \n"
// Metalness
" float metalness = lovrMetalness; \n"
" metalness *= texture(lovrMetalnessTexture, uv).b; \n"
// Roughness
" float roughness = lovrRoughness; \n"
" roughness *= texture(lovrRoughnessTexture, uv).g; \n"
" roughness = max(roughness, .05); \n"
// Parameters
"#ifdef FLAG_normalTexture \n"
" vec3 N = normalize(vTangentMatrix * (texture(lovrNormalTexture, uv).rgb * 2. - 1.)); \n"
"#else \n"
" vec3 N = normalize(vNormal); \n"
"#endif \n"
" vec3 V = normalize(vCameraPosition - vWorldPosition); \n"
" vec3 L = normalize(-lovrLightDirection); \n"
" vec3 H = normalize(V + L); \n"
" vec3 R = normalize(reflect(-V, N)); \n"
" float NoV = abs(dot(N, V)) + 1e-5; \n"
" float NoL = clamp(dot(N, L), 0., 1.); \n"
" float NoH = clamp(dot(N, H), 0., 1.); \n"
" float VoH = clamp(dot(V, H), 0., 1.); \n"
// Specular BRDF
" vec3 F0 = mix(vec3(.04), baseColor, metalness); \n"
" float D = D_GGX(NoH, roughness); \n"
" float G = G_SmithGGXCorrelated(NoV, NoL, roughness); \n"
" vec3 F = F_Schlick(F0, VoH); \n"
// Direct lighting
" vec3 specularDirect = vec3(D * G * F); \n"
" vec3 diffuseDirect = (vec3(1.) - F) * (1. - metalness) * baseColor; \n"
" color += (diffuseDirect / PI + specularDirect) * NoL * lovrLightColor.rgb * lovrLightColor.a; \n"
// 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"
" vec3 diffuseIndirect = diffuseDirect * E_SphericalHarmonics(lovrIrradiance, N); \n"
"#ifdef FLAG_occlusion \n" // Occlusion only affects indirect diffuse light
" diffuseIndirect *= texture(lovrOcclusionTexture, uv).r; \n"
"#endif \n"
" color += diffuseIndirect + specularIndirect; \n"
"#endif \n"
// Emissive
"#ifdef FLAG_emissive \n" // Currently emissive texture and color have to be used together
" color += texture(lovrEmissiveTexture, uv).rgb * lovrEmissiveColor.rgb; \n"
"#endif \n"
// Tonemapping
"#ifdef FLAG_tonemap \n"
" color = tonemap_ACES(color * lovrExposure); \n"
"#endif \n"
" return vec4(color, 1.); \n"
"}";
const char* lovrCubeVertexShader = ""