From 425decdf7e9284d15aa726e3ae96b9942fb0e3ea Mon Sep 17 00:00:00 2001 From: IronClawTrem Date: Sun, 16 Feb 2020 03:40:06 +0000 Subject: create tremded branch --- src/renderergl2/glsl/lightall_fp.glsl | 429 ++++++++++++++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 src/renderergl2/glsl/lightall_fp.glsl (limited to 'src/renderergl2/glsl/lightall_fp.glsl') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl new file mode 100644 index 0000000..8e7c9b4 --- /dev/null +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -0,0 +1,429 @@ +uniform sampler2D u_DiffuseMap; + +#if defined(USE_LIGHTMAP) +uniform sampler2D u_LightMap; +#endif + +#if defined(USE_NORMALMAP) +uniform sampler2D u_NormalMap; +#endif + +#if defined(USE_DELUXEMAP) +uniform sampler2D u_DeluxeMap; +#endif + +#if defined(USE_SPECULARMAP) +uniform sampler2D u_SpecularMap; +#endif + +#if defined(USE_SHADOWMAP) +uniform sampler2D u_ShadowMap; +#endif + +#if defined(USE_CUBEMAP) +uniform samplerCube u_CubeMap; +#endif + +#if defined(USE_NORMALMAP) || defined(USE_DELUXEMAP) || defined(USE_SPECULARMAP) || defined(USE_CUBEMAP) +// y = deluxe, w = cube +uniform vec4 u_EnableTextures; +#endif + +#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) +uniform vec3 u_PrimaryLightColor; +uniform vec3 u_PrimaryLightAmbient; +#endif + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) +uniform vec4 u_NormalScale; +uniform vec4 u_SpecularScale; +#endif + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) +#if defined(USE_CUBEMAP) +uniform vec4 u_CubeMapInfo; +#endif +#endif + +uniform int u_AlphaTest; + +varying vec4 var_TexCoords; + +varying vec4 var_Color; +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) +varying vec4 var_ColorAmbient; +#endif + +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) +varying vec4 var_Normal; +varying vec4 var_Tangent; +varying vec4 var_Bitangent; +#endif + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) +varying vec4 var_LightDir; +#endif + +#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) +varying vec4 var_PrimaryLightDir; +#endif + + +#define EPSILON 0.00000001 + +#if defined(USE_PARALLAXMAP) +float SampleDepth(sampler2D normalMap, vec2 t) +{ + #if defined(SWIZZLE_NORMALMAP) + return 1.0 - texture2D(normalMap, t).r; + #else + return 1.0 - texture2D(normalMap, t).a; + #endif +} + +float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) +{ + const int linearSearchSteps = 16; + const int binarySearchSteps = 6; + + // current size of search window + float size = 1.0 / float(linearSearchSteps); + + // current depth position + float depth = 0.0; + + // best match found (starts with last position 1.0) + float bestDepth = 1.0; + + // texture depth at best depth + float texDepth = 0.0; + + float prevT = SampleDepth(normalMap, dp); + float prevTexDepth = prevT; + + // search front to back for first point inside object + for(int i = 0; i < linearSearchSteps - 1; ++i) + { + depth += size; + + float t = SampleDepth(normalMap, dp + ds * depth); + + if(bestDepth > 0.996) // if no depth found yet + if(depth >= t) + { + bestDepth = depth; // store best depth + texDepth = t; + prevTexDepth = prevT; + } + prevT = t; + } + + depth = bestDepth; + +#if !defined (USE_RELIEFMAP) + float div = 1.0 / (1.0 + (prevTexDepth - texDepth) * float(linearSearchSteps)); + bestDepth -= (depth - size - prevTexDepth) * div; +#else + // recurse around first point (depth) for closest match + for(int i = 0; i < binarySearchSteps; ++i) + { + size *= 0.5; + + float t = SampleDepth(normalMap, dp + ds * depth); + + if(depth >= t) + { + bestDepth = depth; + depth -= 2.0 * size; + } + + depth += size; + } +#endif + + return bestDepth; +} +#endif + +vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness) +{ +#if defined(USE_BURLEY) + // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf + float fd90 = -0.5 + EH * EH * roughness; + float burley = 1.0 + fd90 * 0.04 / NH; + burley *= burley; + return diffuseAlbedo * burley; +#else + return diffuseAlbedo; +#endif +} + +vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular) +{ + // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf + float v = 1.0 - max(roughness, NE); + v *= v * v; + return vec3(v) + specular; +} + +vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness) +{ + // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf + float rr = roughness*roughness; + float rrrr = rr*rr; + float d = (NH * NH) * (rrrr - 1.0) + 1.0; + float v = (EH * EH) * (roughness + 0.5); + return specular * (rrrr / (4.0 * d * d * v)); +} + + +float CalcLightAttenuation(float point, float normDist) +{ + // zero light at 1.0, approximating q3 style + // also don't attenuate directional light + float attenuation = (0.5 * normDist - 1.5) * point + 1.0; + + // clamp attenuation + #if defined(NO_LIGHT_CLAMP) + attenuation = max(attenuation, 0.0); + #else + attenuation = clamp(attenuation, 0.0, 1.0); + #endif + + return attenuation; +} + + +void main() +{ + vec3 viewDir, lightColor, ambientColor, reflectance; + vec3 L, N, E, H; + float NL, NH, NE, EH, attenuation; + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz); + viewDir = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w); + E = normalize(viewDir); +#endif + + lightColor = var_Color.rgb; + +#if defined(USE_LIGHTMAP) + vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw); + #if defined(RGBM_LIGHTMAP) + lightmapColor.rgb *= lightmapColor.a; + #endif + #if defined(USE_PBR) && !defined(USE_FAST_LIGHT) + lightmapColor.rgb *= lightmapColor.rgb; + #endif + lightColor *= lightmapColor.rgb; +#endif + + vec2 texCoords = var_TexCoords.xy; + +#if defined(USE_PARALLAXMAP) + vec3 offsetDir = viewDir * tangentToWorld; + + offsetDir.xy *= -u_NormalScale.a / offsetDir.z; + + texCoords += offsetDir.xy * RayIntersectDisplaceMap(texCoords, offsetDir.xy, u_NormalMap); +#endif + + vec4 diffuse = texture2D(u_DiffuseMap, texCoords); + + float alpha = diffuse.a * var_Color.a; + if (u_AlphaTest == 1) + { + if (alpha == 0.0) + discard; + } + else if (u_AlphaTest == 2) + { + if (alpha >= 0.5) + discard; + } + else if (u_AlphaTest == 3) + { + if (alpha < 0.5) + discard; + } + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + L = var_LightDir.xyz; + #if defined(USE_DELUXEMAP) + L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y; + #endif + float sqrLightDist = dot(L, L); + L /= sqrt(sqrLightDist); + + #if defined(USE_LIGHT_VECTOR) + attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); + #else + attenuation = 1.0; + #endif + + #if defined(USE_NORMALMAP) + #if defined(SWIZZLE_NORMALMAP) + N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5); + #else + N.xy = texture2D(u_NormalMap, texCoords).rg - vec2(0.5); + #endif + N.xy *= u_NormalScale.xy; + N.z = sqrt(clamp((0.25 - N.x * N.x) - N.y * N.y, 0.0, 1.0)); + N = tangentToWorld * N; + #else + N = var_Normal.xyz; + #endif + + N = normalize(N); + + #if defined(USE_SHADOWMAP) + vec2 shadowTex = gl_FragCoord.xy * r_FBufScale; + float shadowValue = texture2D(u_ShadowMap, shadowTex).r; + + // surfaces not facing the light are always shadowed + shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0); + + #if defined(SHADOWMAP_MODULATE) + lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; + #endif + #endif + + #if !defined(USE_LIGHT_VECTOR) + ambientColor = lightColor; + float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); + + // reserve 25% ambient to avoid black areas on normalmaps + lightColor *= 0.75; + + // Scale the incoming light to compensate for the baked-in light angle + // attenuation. + lightColor /= max(surfNL, 0.25); + + // Recover any unused light as ambient, in case attenuation is over 4x or + // light is below the surface + ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0)); + #else + ambientColor = var_ColorAmbient.rgb; + #endif + + NL = clamp(dot(N, L), 0.0, 1.0); + NE = clamp(dot(N, E), 0.0, 1.0); + + #if defined(USE_SPECULARMAP) + vec4 specular = texture2D(u_SpecularMap, texCoords); + #else + vec4 specular = vec4(1.0); + #endif + specular *= u_SpecularScale; + + #if defined(USE_PBR) + diffuse.rgb *= diffuse.rgb; + #endif + + #if defined(USE_PBR) + // diffuse rgb is base color + // specular red is gloss + // specular green is metallicness + float gloss = specular.r; + float metal = specular.g; + specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal); + diffuse.rgb *= 1.0 - metal; + #else + // diffuse rgb is diffuse + // specular rgb is specular reflectance at normal incidence + // specular alpha is gloss + float gloss = specular.a; + + // adjust diffuse by specular reflectance, to maintain energy conservation + diffuse.rgb *= vec3(1.0) - specular.rgb; + #endif + + #if defined(GLOSS_IS_GLOSS) + float roughness = exp2(-3.0 * gloss); + #elif defined(GLOSS_IS_SMOOTHNESS) + float roughness = 1.0 - gloss; + #elif defined(GLOSS_IS_ROUGHNESS) + float roughness = gloss; + #elif defined(GLOSS_IS_SHININESS) + float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25); + #endif + + reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness); + + gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); + gl_FragColor.rgb += ambientColor * diffuse.rgb; + + #if defined(USE_CUBEMAP) + reflectance = EnvironmentBRDF(roughness, NE, specular.rgb); + + vec3 R = reflect(E, N); + + // parallax corrected cubemap (cheaper trick) + // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ + vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; + + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w; + + // normalize cubemap based on last roughness mip (~diffuse) + // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation + //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, ROUGHNESS_MIPS).rgb, 0.5 / 255.0); + //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); + + #if defined(USE_PBR) + cubeLightColor *= cubeLightColor; + #endif + + // multiply cubemap values by lighting + // not technically correct, but helps make reflections look less unnatural + //cubeLightColor *= lightColor * (attenuation * NL) + ambientColor; + + gl_FragColor.rgb += cubeLightColor * reflectance; + #endif + + #if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE) + vec3 L2, H2; + float NL2, EH2, NH2; + + L2 = var_PrimaryLightDir.xyz; + + // enable when point lights are supported as primary lights + //sqrLightDist = dot(L2, L2); + //L2 /= sqrt(sqrLightDist); + + NL2 = clamp(dot(N, L2), 0.0, 1.0); + H2 = normalize(L2 + E); + EH2 = clamp(dot(E, H2), 0.0, 1.0); + NH2 = clamp(dot(N, H2), 0.0, 1.0); + + reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness); + + // bit of a hack, with modulated shadowmaps, ignore diffuse + #if !defined(SHADOWMAP_MODULATE) + reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness); + #endif + + lightColor = u_PrimaryLightColor; + + #if defined(USE_SHADOWMAP) + lightColor *= shadowValue; + #endif + + // enable when point lights are supported as primary lights + //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist); + + gl_FragColor.rgb += lightColor * reflectance * NL2; + #endif + + #if defined(USE_PBR) + gl_FragColor.rgb = sqrt(gl_FragColor.rgb); + #endif + +#else + + gl_FragColor.rgb = diffuse.rgb * lightColor; + +#endif + + gl_FragColor.a = alpha; +} -- cgit