mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-07 20:16:08 +01:00
fix(shaders): parallax mapping of the opengl33 materials is shared by the four parallax shaders in parallax.glsl and samples its depth with the gradients of the surface instead of letting a loop of varying length pick the mip level, picks the number of layers by the angle of view alone and refines the hit with a binary search instead of one linear step, so stones near the camera no longer show combs of layer slices; it fades out between 60 and 100 m instead of stopping at a hard line and fades out at grazing angles, and the simple offset without extra effects no longer divides by an unbounded cosine of the view
This commit is contained in:
@@ -38,13 +38,13 @@ uniform sampler2D detailnormalmap;
|
|||||||
#include <apply_fog.glsl>
|
#include <apply_fog.glsl>
|
||||||
#include <tonemapping.glsl>
|
#include <tonemapping.glsl>
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir);
|
#include <parallax.glsl>
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//parallax mapping
|
//parallax mapping
|
||||||
vec3 viewDir = normalize(-TangentFragPos); //tangent view pos - tangent frag pos
|
vec3 viewDir = normalize(-TangentFragPos); //tangent view pos - tangent frag pos
|
||||||
vec2 f_coord_p = ParallaxMapping(f_coord, viewDir);
|
vec2 f_coord_p = ParallaxMapping(f_coord, viewDir, param[2].z, param[2].w);
|
||||||
vec4 normal_map = texture(normalmap, f_coord_p);
|
vec4 normal_map = texture(normalmap, f_coord_p);
|
||||||
vec4 detailnormal_map = texture(detailnormalmap, f_coord_p * param[2].x);
|
vec4 detailnormal_map = texture(detailnormalmap, f_coord_p * param[2].x);
|
||||||
vec4 tex_color = texture(diffuse, f_coord_p);
|
vec4 tex_color = texture(diffuse, f_coord_p);
|
||||||
@@ -87,48 +87,3 @@ void main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir)
|
|
||||||
{
|
|
||||||
float pos_len = length(f_pos.xyz);
|
|
||||||
|
|
||||||
if (pos_len > 100.0) {
|
|
||||||
return f_coord;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if EXTRAEFFECTS_ENABLED
|
|
||||||
const float minLayers = 8.0;
|
|
||||||
const float maxLayers = 32.0;
|
|
||||||
float LayersWeight = pos_len / 20.0;
|
|
||||||
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, clamp(LayersWeight, 0.0, 1.0)); // 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].z; // 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, prevTexCoords).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].z - param[2].w) * 0.2);
|
|
||||||
return f_coord - p;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ uniform sampler2D detailnormalmap;
|
|||||||
#include <apply_fog.glsl>
|
#include <apply_fog.glsl>
|
||||||
#include <tonemapping.glsl>
|
#include <tonemapping.glsl>
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir);
|
#include <parallax.glsl>
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//parallax mapping
|
//parallax mapping
|
||||||
vec3 viewDir = normalize(vec3(0.0f, 0.0f, 0.0f) - TangentFragPos); //tangent view pos - tangent frag pos
|
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);
|
vec2 f_coord_p = ParallaxMapping(f_coord, viewDir, param[2].z, param[2].w);
|
||||||
|
|
||||||
vec4 normal_map = texture(normalmap, f_coord_p);
|
vec4 normal_map = texture(normalmap, f_coord_p);
|
||||||
vec4 detailnormal_map = texture(detailnormalmap, f_coord_p * param[2].x);
|
vec4 detailnormal_map = texture(detailnormalmap, f_coord_p * param[2].x);
|
||||||
@@ -93,49 +93,3 @@ void main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir)
|
|
||||||
{
|
|
||||||
|
|
||||||
float pos_len = length(f_pos.xyz);
|
|
||||||
|
|
||||||
if (pos_len > 100.0) {
|
|
||||||
return f_coord;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if EXTRAEFFECTS_ENABLED
|
|
||||||
const float minLayers = 8.0;
|
|
||||||
const float maxLayers = 32.0;
|
|
||||||
float LayersWeight = pos_len / 20.0;
|
|
||||||
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, clamp(LayersWeight, 0.0, 1.0)); // 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].z; // 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, prevTexCoords).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].z - param[2].w) * 0.2);
|
|
||||||
return f_coord - p;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ uniform sampler2D normalmap;
|
|||||||
#include <apply_fog.glsl>
|
#include <apply_fog.glsl>
|
||||||
#include <tonemapping.glsl>
|
#include <tonemapping.glsl>
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir);
|
#include <parallax.glsl>
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//parallax mapping
|
//parallax mapping
|
||||||
vec3 viewDir = normalize(vec3(0.0f, 0.0f, 0.0f) - TangentFragPos); //tangent view pos - tangent frag pos
|
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);
|
vec2 f_coord_p = ParallaxMapping(f_coord, viewDir, param[2].y, param[2].z);
|
||||||
|
|
||||||
vec4 tex_color = texture(diffuse, f_coord_p);
|
vec4 tex_color = texture(diffuse, f_coord_p);
|
||||||
|
|
||||||
@@ -74,48 +74,3 @@ void main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir)
|
|
||||||
{
|
|
||||||
float pos_len = length(f_pos.xyz);
|
|
||||||
|
|
||||||
if (pos_len > 100.0) {
|
|
||||||
return f_coord;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if EXTRAEFFECTS_ENABLED
|
|
||||||
const float minLayers = 8.0;
|
|
||||||
const float maxLayers = 32.0;
|
|
||||||
float LayersWeight = pos_len / 20.0;
|
|
||||||
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, clamp(LayersWeight, 0.0, 1.0)); // 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, prevTexCoords).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) * 0.2);
|
|
||||||
return f_coord - p;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ uniform sampler2D specgloss;
|
|||||||
#include <apply_fog.glsl>
|
#include <apply_fog.glsl>
|
||||||
#include <tonemapping.glsl>
|
#include <tonemapping.glsl>
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir);
|
#include <parallax.glsl>
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//parallax mapping
|
//parallax mapping
|
||||||
vec3 viewDir = normalize(vec3(0.0f, 0.0f, 0.0f) - TangentFragPos); //tangent view pos - tangent frag pos
|
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);
|
vec2 f_coord_p = ParallaxMapping(f_coord, viewDir, param[2].y, param[2].z);
|
||||||
|
|
||||||
vec4 tex_color = texture(diffuse, f_coord_p);
|
vec4 tex_color = texture(diffuse, f_coord_p);
|
||||||
|
|
||||||
@@ -80,48 +80,3 @@ void main()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir)
|
|
||||||
{
|
|
||||||
float pos_len = length(f_pos.xyz);
|
|
||||||
|
|
||||||
if (pos_len > 100.0) {
|
|
||||||
return f_coord;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if EXTRAEFFECTS_ENABLED
|
|
||||||
const float minLayers = 8.0;
|
|
||||||
const float maxLayers = 32.0;
|
|
||||||
float LayersWeight = pos_len / 20.0;
|
|
||||||
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, clamp(LayersWeight, 0.0, 1.0)); // 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, prevTexCoords).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) * 0.2);
|
|
||||||
return f_coord - p;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|||||||
45
shaders/parallax.glsl
Normal file
45
shaders/parallax.glsl
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
vec2 ParallaxMapping(vec2 f_coord, vec3 viewDir, float scale, float offset)
|
||||||
|
{
|
||||||
|
vec2 dx = dFdx(f_coord);
|
||||||
|
vec2 dy = dFdy(f_coord);
|
||||||
|
float fade = (1.0 - smoothstep(60.0, 100.0, length(f_pos.xyz))) * smoothstep(0.0, 0.1, viewDir.z);
|
||||||
|
if (fade <= 0.0) {
|
||||||
|
return f_coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if EXTRAEFFECTS_ENABLED
|
||||||
|
const float minLayers = 8.0;
|
||||||
|
const float maxLayers = 32.0;
|
||||||
|
float numLayers = mix(maxLayers, minLayers, clamp(viewDir.z, 0.0, 1.0));
|
||||||
|
float layerDepth = 1.0 / numLayers;
|
||||||
|
vec2 deltaTexCoords = viewDir.xy * scale * fade / numLayers;
|
||||||
|
vec2 currentTexCoords = f_coord;
|
||||||
|
float currentLayerDepth = 0.0;
|
||||||
|
float currentDepthMapValue = textureGrad(normalmap, currentTexCoords, dx, dy).b;
|
||||||
|
for (int i = 0; i < 40 && currentLayerDepth < currentDepthMapValue; ++i)
|
||||||
|
{
|
||||||
|
currentTexCoords -= deltaTexCoords;
|
||||||
|
currentLayerDepth += layerDepth;
|
||||||
|
currentDepthMapValue = textureGrad(normalmap, currentTexCoords, dx, dy).b;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
deltaTexCoords *= 0.5;
|
||||||
|
layerDepth *= 0.5;
|
||||||
|
if (currentLayerDepth < currentDepthMapValue) {
|
||||||
|
currentTexCoords -= deltaTexCoords;
|
||||||
|
currentLayerDepth += layerDepth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentTexCoords += deltaTexCoords;
|
||||||
|
currentLayerDepth -= layerDepth;
|
||||||
|
}
|
||||||
|
currentDepthMapValue = textureGrad(normalmap, currentTexCoords, dx, dy).b;
|
||||||
|
}
|
||||||
|
return currentTexCoords;
|
||||||
|
#else
|
||||||
|
float height = textureGrad(normalmap, f_coord, dx, dy).b;
|
||||||
|
vec2 p = viewDir.xy / max(viewDir.z, 0.2) * (height * (scale - offset) * 0.2 * fade);
|
||||||
|
return f_coord - p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user