diff --git a/shaders/conversion.glsl b/shaders/conversion.glsl new file mode 100644 index 00000000..b6b6a3b1 --- /dev/null +++ b/shaders/conversion.glsl @@ -0,0 +1,108 @@ +vec3 rgb2yuv(vec3 input) +{ + return + clamp( + vec3( + (0.257 * input.r) + (0.504 * input.g) + (0.098 * input.b) + 0.0625, + -(0.148 * input.r) - (0.291 * input.g) + (0.439 * input.b) + 0.5, + (0.439 * input.r) - (0.368 * input.g) - (0.071 * input.b) + 0.5 ), + 0.0, 1.0); +} + +vec3 yuv2rgb(vec3 input) +{ + input -= vec3(0.0625, 0.5, 0.5); + return + clamp( + vec3( + (1.164 * input.r) + (1.596 * input.b), + (1.164 * input.r) - (0.391 * input.g) - (0.813 * input.b), + (1.164 * input.r) + (2.018 * input.g) ), + 0.0, 1.0); +} + +vec3 rgb2hsl( vec3 col ) +{ + float red = col.r; + float green = col.g; + float blue = col.b; + + float minc = min( col.r, min( col.g, col.b )); + float maxc = max( col.r, max( col.g, col.b )); + float delta = maxc - minc; + + float lum = (minc + maxc) * 0.5; + float sat = 0.0; + float hue = 0.0; + + if (lum > 0.0 && lum < 1.0) { + float mul = (lum < 0.5) ? (lum) : (1.0-lum); + sat = delta / (mul * 2.0); + } + + vec3 masks = vec3( + (maxc == red && maxc != green) ? 1.0 : 0.0, + (maxc == green && maxc != blue) ? 1.0 : 0.0, + (maxc == blue && maxc != red) ? 1.0 : 0.0 + ); + + vec3 adds = vec3( + ((green - blue ) / delta), + 2.0 + ((blue - red ) / delta), + 4.0 + ((red - green) / delta) + ); + + float deltaGtz = (delta > 0.0) ? 1.0 : 0.0; + + hue += dot( adds, masks ); + hue *= deltaGtz; + hue /= 6.0; + + if (hue < 0.0) + hue += 1.0; + + return vec3( hue, sat, lum ); +} + +vec3 hsl2rgb( vec3 col ) +{ + const float onethird = 1.0 / 3.0; + const float twothird = 2.0 / 3.0; + const float rcpsixth = 6.0; + + float hue = col.x; + float sat = col.y; + float lum = col.z; + + vec3 xt = vec3( + rcpsixth * (hue - twothird), + 0.0, + rcpsixth * (1.0 - hue) + ); + + if (hue < twothird) { + xt.r = 0.0; + xt.g = rcpsixth * (twothird - hue); + xt.b = rcpsixth * (hue - onethird); + } + + if (hue < onethird) { + xt.r = rcpsixth * (onethird - hue); + xt.g = rcpsixth * hue; + xt.b = 0.0; + } + + xt = min( xt, 1.0 ); + + float sat2 = 2.0 * sat; + float satinv = 1.0 - sat; + float luminv = 1.0 - lum; + float lum2m1 = (2.0 * lum) - 1.0; + vec3 ct = (sat2 * xt) + satinv; + + vec3 rgb; + if (lum >= 0.5) { rgb = (luminv * ct) + lum2m1; } + else { rgb = lum * ct; } + + return rgb; +} diff --git a/shaders/light_common.glsl b/shaders/light_common.glsl index 02b27bc2..79b8ce1e 100644 --- a/shaders/light_common.glsl +++ b/shaders/light_common.glsl @@ -5,6 +5,10 @@ uniform sampler2DArrayShadow shadowmap; uniform sampler2D headlightmap; #include +#include + +float glossiness = 1.0; +bool metalic = false; float length2(vec3 v) { @@ -42,9 +46,6 @@ float calc_shadow() #endif } -float glossiness = 1.0; -// [0] - diffuse, [1] - specular -// do magic here vec2 calc_light(vec3 light_dir, vec3 fragnormal) { vec3 view_dir = normalize(vec3(0.0f, 0.0f, 0.0f) - f_pos.xyz); @@ -107,19 +108,31 @@ vec2 calc_headlights(light_s light, vec3 fragnormal) return part * atten * lightintensity; } - bool metalic = false; - +// [0] - diffuse, [1] - specular +// do magic here vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) { - fragcolor *= param[1].x; - - vec3 emissioncolor = param[0].rgb * emission; + vec3 basecolor = param[0].rgb; + + fragcolor *= basecolor; + + vec3 emissioncolor = basecolor * emission; vec3 envcolor = envmap_color(fragnormal); +// yuv path + vec3 texturecoloryuv = rgb2yuv(texturecolor); + vec3 texturecolorfullv = yuv2rgb(vec3(0.2176, texturecoloryuv.gb)); +// hsl path +// vec3 texturecolorhsl = rgb2hsl(texturecolor); +// vec3 texturecolorfullv = hsl2rgb(vec3(texturecolorhsl.rg, 0.5)); + + vec3 envyuv = rgb2yuv(envcolor); + texturecolor = mix(texturecolor, texturecolorfullv, envyuv.r * reflectivity); + if(lights_count == 0U) return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor; -// fragcolor *= lights[0].intensity; +// fragcolor *= lights[0].intensity; vec2 sunlight = calc_dir_light(lights[0], fragnormal); float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity; @@ -153,6 +166,7 @@ vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float refl } fragcolor += emissioncolor; vec3 specularcolor = specularamount * lights[0].color; + if ((param[1].w < 0.0) || (metalic == true)) { fragcolor += specularcolor; diff --git a/shaders/mat_sunlessnormalmap.frag b/shaders/mat_sunlessnormalmap.frag index 361b00db..4f4e3bd8 100644 --- a/shaders/mat_sunlessnormalmap.frag +++ b/shaders/mat_sunlessnormalmap.frag @@ -1,111 +1,125 @@ -in vec3 f_normal; -in vec2 f_coord; -in vec4 f_pos; -in mat3 f_tbn; - -in vec4 f_clip_pos; -in vec4 f_clip_future_pos; - -#include - -layout(location = 0) out vec4 out_color; -#if MOTIONBLUR_ENABLED -layout(location = 1) out vec4 out_motion; -#endif - -#param (color, 0, 0, 4, diffuse) -#param (diffuse, 1, 0, 1, diffuse) -#param (specular, 1, 1, 1, specular) -#param (reflection, 1, 2, 1, zero) -#param (glossiness, 1, 3, 1, glossiness) - -#texture (diffuse, 0, sRGB_A) -uniform sampler2D diffuse; - -#texture (normalmap, 1, RGBA) -uniform sampler2D normalmap; - -#define NORMALMAP -#include -#include -#include - -vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) -{ - vec3 emissioncolor = param[0].rgb * emission; - vec3 envcolor = envmap_color(fragnormal); - - if(lights_count == 0U) - return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor; - - vec2 sunlight = calc_dir_light(lights[0], fragnormal); - - float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity; - fragcolor += envcolor * reflectivity; - float specularamount = (sunlight.y * param[1].y * specularity) * lights[0].intensity; - glossiness = abs(param[1].w); - - for (uint i = 1U; i < lights_count; i++) - { - light_s light = lights[i]; - vec2 part = vec2(0.0); - -// if (light.type == LIGHT_SPOT) -// part = calc_spot_light(light, fragnormal); -// else if (light.type == LIGHT_POINT) -// part = calc_point_light(light, fragnormal); -// else if (light.type == LIGHT_DIR) -// part = calc_dir_light(light, fragnormal); -// else if (light.type == LIGHT_HEADLIGHTS) - part = calc_headlights(light, fragnormal); - - fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; - } - - if (shadowtone < 1.0) - { - float shadow = calc_shadow(); - specularamount *= clamp(1.0 - shadow, 0.0, 1.0); - fragcolor = mix(fragcolor, fragcolor * shadowtone, clamp(diffuseamount * shadow + specularamount, 0.0, 1.0)); - } - fragcolor += emissioncolor; - fragcolor *= texturecolor; - - return fragcolor; -} - -void main() -{ - vec4 tex_color = texture(diffuse, f_coord); - - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); - if(alphatestfail) - discard; -// if (tex_color.a < opacity) -// discard; - - vec3 fragcolor = ambient; - - vec3 normal; - normal.xy = (texture(normalmap, f_coord).rg * 2.0 - 1.0); - normal.z = sqrt(1.0 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); - vec3 fragnormal = normalize(f_tbn * normalize(normal.xyz)); - float reflectivity = param[1].z * texture(normalmap, f_coord).a; - float specularity = (tex_color.r + tex_color.g + tex_color.b) * 0.5; - - fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); -#if POSTFX_ENABLED - out_color = color; -#else - out_color = tonemap(color); -#endif -#if MOTIONBLUR_ENABLED - { - vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;; - vec2 b = (f_clip_pos.xy / f_clip_pos.w) * 0.5 + 0.5;; - - out_motion = vec4(a - b, 0.0f, 0.0f); - } -#endif -} +in vec3 f_normal; +in vec2 f_coord; +in vec4 f_pos; +in mat3 f_tbn; + +in vec4 f_clip_pos; +in vec4 f_clip_future_pos; + +#include + +layout(location = 0) out vec4 out_color; +#if MOTIONBLUR_ENABLED +layout(location = 1) out vec4 out_motion; +#endif + +#param (color, 0, 0, 4, diffuse) +#param (diffuse, 1, 0, 1, diffuse) +#param (specular, 1, 1, 1, specular) +#param (reflection, 1, 2, 1, zero) +#param (glossiness, 1, 3, 1, glossiness) + +#texture (diffuse, 0, sRGB_A) +uniform sampler2D diffuse; + +#texture (normalmap, 1, RGBA) +uniform sampler2D normalmap; + +#define NORMALMAP +#include +#include +#include + +vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) +{ + vec3 basecolor = param[0].rgb; + + fragcolor *= basecolor; + + vec3 emissioncolor = basecolor * emission; + vec3 envcolor = envmap_color(fragnormal); + +// yuv path + vec3 texturecoloryuv = rgb2yuv(texturecolor); + vec3 texturecolorfullv = yuv2rgb(vec3(0.2176, texturecoloryuv.gb)); +// hsl path +// vec3 texturecolorhsl = rgb2hsl(texturecolor); +// vec3 texturecolorfullv = hsl2rgb(vec3(texturecolorhsl.rg, 0.5)); + + vec3 envyuv = rgb2yuv(envcolor); + texturecolor = mix(texturecolor, texturecolorfullv, envyuv.r * reflectivity); + + if(lights_count == 0U) + return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor; + + vec2 sunlight = calc_dir_light(lights[0], fragnormal); + + float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity; + fragcolor += envcolor * reflectivity; + float specularamount = (sunlight.y * param[1].y * specularity) * lights[0].intensity; + glossiness = abs(param[1].w); + + for (uint i = 1U; i < lights_count; i++) + { + light_s light = lights[i]; + vec2 part = vec2(0.0); + +// if (light.type == LIGHT_SPOT) +// part = calc_spot_light(light, fragnormal); +// else if (light.type == LIGHT_POINT) +// part = calc_point_light(light, fragnormal); +// else if (light.type == LIGHT_DIR) +// part = calc_dir_light(light, fragnormal); +// else if (light.type == LIGHT_HEADLIGHTS) + part = calc_headlights(light, fragnormal); + + fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; + } + + if (shadowtone < 1.0) + { + float shadow = calc_shadow(); + specularamount *= clamp(1.0 - shadow, 0.0, 1.0); + fragcolor = mix(fragcolor, fragcolor * shadowtone, clamp(diffuseamount * shadow + specularamount, 0.0, 1.0)); + } + fragcolor += emissioncolor; + fragcolor *= texturecolor; + + return fragcolor; +} + +void main() +{ + vec4 tex_color = texture(diffuse, f_coord); + + bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + if(alphatestfail) + discard; +// if (tex_color.a < opacity) +// discard; + + vec3 fragcolor = ambient; + + vec3 normal; + normal.xy = (texture(normalmap, f_coord).rg * 2.0 - 1.0); + normal.z = sqrt(1.0 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); + vec3 fragnormal = normalize(f_tbn * normalize(normal.xyz)); + float reflectivity = param[1].z * texture(normalmap, f_coord).a; + float specularity = (tex_color.r + tex_color.g + tex_color.b) * 0.5; + + fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); + vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); +#if POSTFX_ENABLED + out_color = color; +#else + out_color = tonemap(color); +#endif +#if MOTIONBLUR_ENABLED + { + vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;; + vec2 b = (f_clip_pos.xy / f_clip_pos.w) * 0.5 + 0.5;; + + out_motion = vec4(a - b, 0.0f, 0.0f); + } +#endif +} diff --git a/shaders/mat_sunlessnormalmap_specgloss.frag b/shaders/mat_sunlessnormalmap_specgloss.frag index f3b6af1b..ca84c346 100644 --- a/shaders/mat_sunlessnormalmap_specgloss.frag +++ b/shaders/mat_sunlessnormalmap_specgloss.frag @@ -1,116 +1,130 @@ -in vec3 f_normal; -in vec2 f_coord; -in vec4 f_pos; -in mat3 f_tbn; - -in vec4 f_clip_pos; -in vec4 f_clip_future_pos; - -#include - -layout(location = 0) out vec4 out_color; -#if MOTIONBLUR_ENABLED -layout(location = 1) out vec4 out_motion; -#endif - -#param (color, 0, 0, 4, diffuse) -#param (diffuse, 1, 0, 1, diffuse) -#param (specular, 1, 1, 1, specular) -#param (reflection, 1, 2, 1, zero) -#param (glossiness, 1, 3, 1, glossiness) - -#texture (diffuse, 0, sRGB_A) -uniform sampler2D diffuse; - -#texture (normalmap, 1, RGBA) -uniform sampler2D normalmap; - -#texture (specgloss, 2, RGBA) -uniform sampler2D specgloss; - - -#define NORMALMAP -#include -#include -#include - -vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) -{ - vec3 emissioncolor = param[0].rgb * emission; - vec3 envcolor = envmap_color(fragnormal); - - if(lights_count == 0U) - return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor; - - vec2 sunlight = calc_dir_light(lights[0], fragnormal); - - float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity; - fragcolor += envcolor * reflectivity; - float specularamount = (sunlight.y * param[1].y * specularity) * lights[0].intensity; - - for (uint i = 1U; i < lights_count; i++) - { - light_s light = lights[i]; - vec2 part = vec2(0.0); - -// if (light.type == LIGHT_SPOT) -// part = calc_spot_light(light, fragnormal); -// else if (light.type == LIGHT_POINT) -// part = calc_point_light(light, fragnormal); -// else if (light.type == LIGHT_DIR) -// part = calc_dir_light(light, fragnormal); -// else if (light.type == LIGHT_HEADLIGHTS) - part = calc_headlights(light, fragnormal); - - fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; - } - - if (shadowtone < 1.0) - { - float shadow = calc_shadow(); - specularamount *= clamp(1.0 - shadow, 0.0, 1.0); - fragcolor = mix(fragcolor, fragcolor * shadowtone, clamp(diffuseamount * shadow + specularamount, 0.0, 1.0)); - } - fragcolor += emissioncolor; - fragcolor *= texturecolor; - - return fragcolor; -} - -void main() -{ - vec4 tex_color = texture(diffuse, f_coord); - - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); - if(alphatestfail) - discard; -// if (tex_color.a < opacity) -// discard; - - vec3 fragcolor = ambient; - - vec3 normal; - normal.xy = (texture(normalmap, f_coord).rg * 2.0 - 1.0); - normal.z = sqrt(1.0 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); - vec3 fragnormal = normalize(f_tbn * normalize(normal.xyz)); - float reflectivity = param[1].z * texture(normalmap, f_coord).a; - float specularity = texture(specgloss, f_coord).r; - glossiness = texture(specgloss, f_coord).g * abs(param[1].w); - metalic = (texture(specgloss, f_coord).b > 0.5) ? true : false; - - fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); -#if POSTFX_ENABLED - out_color = color; -#else - out_color = tonemap(color); -#endif -#if MOTIONBLUR_ENABLED - { - vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;; - vec2 b = (f_clip_pos.xy / f_clip_pos.w) * 0.5 + 0.5;; - - out_motion = vec4(a - b, 0.0f, 0.0f); - } -#endif -} +in vec3 f_normal; +in vec2 f_coord; +in vec4 f_pos; +in mat3 f_tbn; + +in vec4 f_clip_pos; +in vec4 f_clip_future_pos; + +#include + +layout(location = 0) out vec4 out_color; +#if MOTIONBLUR_ENABLED +layout(location = 1) out vec4 out_motion; +#endif + +#param (color, 0, 0, 4, diffuse) +#param (diffuse, 1, 0, 1, diffuse) +#param (specular, 1, 1, 1, specular) +#param (reflection, 1, 2, 1, zero) +#param (glossiness, 1, 3, 1, glossiness) + +#texture (diffuse, 0, sRGB_A) +uniform sampler2D diffuse; + +#texture (normalmap, 1, RGBA) +uniform sampler2D normalmap; + +#texture (specgloss, 2, RGBA) +uniform sampler2D specgloss; + + +#define NORMALMAP +#include +#include +#include + +vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) +{ + vec3 basecolor = param[0].rgb; + + fragcolor *= basecolor; + + vec3 emissioncolor = basecolor * emission; + vec3 envcolor = envmap_color(fragnormal); + +// yuv path + vec3 texturecoloryuv = rgb2yuv(texturecolor); + vec3 texturecolorfullv = yuv2rgb(vec3(0.2176, texturecoloryuv.gb)); +// hsl path +// vec3 texturecolorhsl = rgb2hsl(texturecolor); +// vec3 texturecolorfullv = hsl2rgb(vec3(texturecolorhsl.rg, 0.5)); + + vec3 envyuv = rgb2yuv(envcolor); + texturecolor = mix(texturecolor, texturecolorfullv, envyuv.r * reflectivity); + + if(lights_count == 0U) + return (fragcolor + emissioncolor + envcolor * reflectivity) * texturecolor; + + vec2 sunlight = calc_dir_light(lights[0], fragnormal); + + float diffuseamount = (sunlight.x * param[1].x) * lights[0].intensity; + fragcolor += envcolor * reflectivity; + float specularamount = (sunlight.y * param[1].y * specularity) * lights[0].intensity; + + for (uint i = 1U; i < lights_count; i++) + { + light_s light = lights[i]; + vec2 part = vec2(0.0); + +// if (light.type == LIGHT_SPOT) +// part = calc_spot_light(light, fragnormal); +// else if (light.type == LIGHT_POINT) +// part = calc_point_light(light, fragnormal); +// else if (light.type == LIGHT_DIR) +// part = calc_dir_light(light, fragnormal); +// else if (light.type == LIGHT_HEADLIGHTS) + part = calc_headlights(light, fragnormal); + + fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; + } + + if (shadowtone < 1.0) + { + float shadow = calc_shadow(); + specularamount *= clamp(1.0 - shadow, 0.0, 1.0); + fragcolor = mix(fragcolor, fragcolor * shadowtone, clamp(diffuseamount * shadow + specularamount, 0.0, 1.0)); + } + fragcolor += emissioncolor; + fragcolor *= texturecolor; + + return fragcolor; +} + +void main() +{ + vec4 tex_color = texture(diffuse, f_coord); + + bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + if(alphatestfail) + discard; +// if (tex_color.a < opacity) +// discard; + + vec3 fragcolor = ambient; + + vec3 normal; + normal.xy = (texture(normalmap, f_coord).rg * 2.0 - 1.0); + normal.z = sqrt(1.0 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); + vec3 fragnormal = normalize(f_tbn * normalize(normal.xyz)); + float reflectivity = param[1].z * texture(normalmap, f_coord).a; + float specularity = texture(specgloss, f_coord).r; + glossiness = texture(specgloss, f_coord).g * abs(param[1].w); + metalic = (texture(specgloss, f_coord).b > 0.5) ? true : false; + + fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); + vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); +#if POSTFX_ENABLED + out_color = color; +#else + out_color = tonemap(color); +#endif +#if MOTIONBLUR_ENABLED + { + vec2 a = (f_clip_future_pos.xy / f_clip_future_pos.w) * 0.5 + 0.5;; + vec2 b = (f_clip_pos.xy / f_clip_pos.w) * 0.5 + 0.5;; + + out_motion = vec4(a - b, 0.0f, 0.0f); + } +#endif +}