diff --git a/shaders/light_common.glsl b/shaders/light_common.glsl index aed7d107..8fc8216f 100644 --- a/shaders/light_common.glsl +++ b/shaders/light_common.glsl @@ -30,9 +30,11 @@ float calc_shadow() vec2 calc_light(vec3 light_dir) { #ifdef NORMALMAP - vec3 normal = normalize(f_tbn * normalize(texture(normalmap, f_coord).rgb * 2.0 - 1.0)); + vec3 normal = normal; #elif defined(WATER) vec3 normal = normal_d; +#elif defined(PARALLAX) + vec3 normal = normal_p; #else vec3 normal = normalize(f_normal); #endif diff --git a/shaders/mat_normalmap.frag b/shaders/mat_normalmap.frag index c4b7a4fa..cae429aa 100644 --- a/shaders/mat_normalmap.frag +++ b/shaders/mat_normalmap.frag @@ -33,6 +33,8 @@ uniform sampler2DShadow shadowmap; uniform samplerCube envmap; #endif +vec3 normal; + #define NORMALMAP #include #include @@ -44,7 +46,10 @@ void main() if (tex_color.a < opacity) discard; - vec3 normal = normalize(f_tbn * normalize(texture(normalmap, f_coord).rgb * 2.0 - 1.0)); + normal.xy = (texture(normalmap, f_coord).rg * 2.0 - 1.0); + normal.z = sqrt(1 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); + normal = normalize(f_tbn * normalize(normal.xyz)); + //vec3 normal = normalize(f_tbn * normalize(texture(normalmap, f_coord).rgb * 2.0 - 1.0)); vec3 refvec = reflect(f_pos.xyz, normal); #if ENVMAP_ENABLED vec3 envcolor = texture(envmap, refvec).rgb; diff --git a/shaders/mat_parallax.frag b/shaders/mat_parallax.frag new file mode 100644 index 00000000..41b11a63 --- /dev/null +++ b/shaders/mat_parallax.frag @@ -0,0 +1,146 @@ +in vec3 f_normal; +in vec2 f_coord; +in vec4 f_pos; +in mat3 f_tbn; //tangent matrix nietransponowany; mnożyć przez f_tbn dla TangentLightPos; TangentViewPos; TangentFragPos; +in vec4 f_light_pos; +in vec4 f_clip_pos; +in vec4 f_clip_future_pos; +in vec3 TangentFragPos; + +#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 (height_scale, 2, 1, 1, zero) +#param (height_offset, 2, 2, 1, zero) + +#texture (diffuse, 0, sRGB_A) +uniform sampler2D diffuse; + +#texture (normalmap, 1, RGBA) +uniform sampler2D normalmap; + +#if SHADOWMAP_ENABLED +uniform sampler2DShadow shadowmap; +#endif + +#if ENVMAP_ENABLED +uniform samplerCube envmap; +#endif + +vec3 normal_p; +#define PARALLAX +#include +#include + +vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir); + +void main() +{ +//parallex mapping + vec3 viewDir = normalize(vec3(0.0f, 0.0f, 0.0f) - TangentFragPos); //tangent view pos - tangent frag pos + vec2 f_coord_p = ParallaxMapping(f_coord, viewDir); + + vec4 tex_color = texture(diffuse, f_coord_p); + + if (tex_color.a < opacity) + discard; + vec3 normal; + normal.xy = (texture(normalmap, f_coord_p).rg * 2.0 - 1.0); + normal.z = sqrt(1 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); + normal_p = normalize(f_tbn * normalize(normal.xyz)); + vec3 refvec = reflect(f_pos.xyz, normal_p); +#if ENVMAP_ENABLED + vec3 envcolor = texture(envmap, refvec).rgb; +#else + vec3 envcolor = vec3(0.5); +#endif + + vec3 result = ambient * 0.5 + param[0].rgb * emission; + + if (lights_count > 0U) + { + vec2 part = calc_dir_light(lights[0]); + vec3 c = (part.x * param[1].x + part.y * param[1].y) * calc_shadow() * lights[0].color; + result += mix(c, envcolor, param[1].z * texture(normalmap, f_coord_p).a); + } + + 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); + else if (light.type == LIGHT_POINT) + part = calc_point_light(light); + else if (light.type == LIGHT_DIR) + part = calc_dir_light(light); + + result += light.color * (part.x * param[1].x + part.y * param[1].y); + } + + vec4 color = vec4(apply_fog(result * tex_color.rgb), 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 +} +vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir) +{ +#if ENVMAP_ENABLED + const float minLayers = 8.0; + const float maxLayers = 32.0; + float LayersWeight = 1; + if (length(f_pos.xyz) > 20) + LayersWeight = 1; + else + LayersWeight = (length(f_pos.xyz) / 20); + vec2 currentTexCoords = f_coord; + float currentDepthMapValue = texture(normalmap, currentTexCoords).b; + LayersWeight = min(abs(dot(vec3(0.0, 0.0, 1.0), viewDir)),LayersWeight); + float numLayers = mix(maxLayers, minLayers, LayersWeight); // number of depth layers + float layerDepth = 1.0 / numLayers; // calculate the size of each layer + float currentLayerDepth = 0.0; // depth of current layer + vec2 P = viewDir.xy * param[2].y; // the amount to shift the texture coordinates per layer (from vector P) + vec2 deltaTexCoords = P / numLayers; + + + while(currentLayerDepth < currentDepthMapValue) + { + currentTexCoords -= deltaTexCoords; // shift texture coordinates along direction of P + currentDepthMapValue = texture(normalmap, currentTexCoords).b; // get depthmap value at current texture coordinates + currentLayerDepth += layerDepth; // get depth of next layer + } + + vec2 prevTexCoords = currentTexCoords + deltaTexCoords; // get texture coordinates before collision (reverse operations) + + float afterDepth = currentDepthMapValue - currentLayerDepth; // get depth after and before collision for linear interpolation + float beforeDepth = texture(normalmap, currentTexCoords).b - currentLayerDepth + layerDepth; + + float weight = afterDepth / (afterDepth - beforeDepth); // interpolation of texture coordinates + vec2 finalTexCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight); + + return finalTexCoords; +#else + float height = texture(normalmap, f_coord).b; + vec2 p = viewDir.xy / viewDir.z * (height * param[2].y - param[2].z); + return f_coord - p; +#endif +} \ No newline at end of file diff --git a/shaders/mat_water.frag b/shaders/mat_water.frag index 2b0649bf..3eba83ea 100644 --- a/shaders/mat_water.frag +++ b/shaders/mat_water.frag @@ -56,7 +56,10 @@ void main() vec2 total_distorted_tex_coord = (texture(dudvmap, distorted_tex_coord).rg * 2.0 - 1.0 ) * param[2].y; texture_coords += total_distorted_tex_coord; - normal_d = f_tbn * normalize(texture(normalmap, texture_coords).rgb * 2.0 - 1.0); + vec3 normal; + normal.xy = (texture(normalmap, texture_coords).rg * 2.0 - 1.0); + normal.z = sqrt(1 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0)); + normal_d = normalize(f_tbn * normalize(normal.xyz)); vec3 refvec = reflect(f_pos.xyz, normal_d); #if ENVMAP_ENABLED vec3 envcolor = texture(envmap, refvec).rgb; diff --git a/shaders/vertex.vert b/shaders/vertex.vert index b13031d5..76a4f93b 100644 --- a/shaders/vertex.vert +++ b/shaders/vertex.vert @@ -8,20 +8,24 @@ flat out vec3 f_normal_raw; out vec2 f_coord; out vec4 f_pos; out mat3 f_tbn; -out vec4 f_tangent; +//out vec4 f_tangent; out vec4 f_light_pos; out vec4 f_clip_pos; out vec4 f_clip_future_pos; +//out vec3 TangentLightPos; +//out vec3 TangentViewPos; +out vec3 TangentFragPos; + #include void main() { - f_normal = modelviewnormal * v_normal; + f_normal = normalize(modelviewnormal * v_normal); f_normal_raw = v_normal; f_coord = v_coord; - f_tangent = v_tangent; +// f_tangent = v_tangent; f_pos = modelview * vec4(v_vert, 1.0f); f_light_pos = lightview * f_pos; @@ -32,7 +36,12 @@ void main() gl_PointSize = param[1].x; vec3 T = normalize(modelviewnormal * v_tangent.xyz); - vec3 B = normalize(modelviewnormal * cross(v_normal, v_tangent.xyz) * v_tangent.w); - vec3 N = normalize(modelviewnormal * v_normal); + vec3 N = f_normal; + vec3 B = normalize(cross(N, T)); f_tbn = mat3(T, B, N); + + mat3 TBN = transpose(f_tbn); +// TangentLightPos = TBN * f_light_pos.xyz; +// TangentViewPos = TBN * vec3(0.0f, 0.0f, 0.0f); + TangentFragPos = TBN * f_pos.xyz; }