fuckingtech/public/assets/glsl/lygia/space/parallaxMapping.glsl
Elias Rhouzlane bf76c6b086 fix: code
2025-04-06 17:23:52 +02:00

234 lines
No EOL
7.9 KiB
GLSL

#include "../sampler.glsl"
/*
contributors: Patricio Gonzalez Vivo
description: get parallax mapping coordinates
use: parallaxMapping(<SAMPLER_TYPE> tex, <vec3> V, <vec2> T, <float> parallaxHeight)
options:
- SAMPLER_FNC(TEX, UV): optional depending the target version of GLSL (texture2D(...) or texture(...))
- PARALLAXMAPPING_FNC()
- PARALLAXMAPPING_SAMPLER_FNC(UV)
- PARALLAXMAPPING_SCALE
- PARALLAXMAPPING_NUMSEARCHES
license:
- Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0
- Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license
*/
#ifndef PARALLAXMAPPING_SAMPLER_FNC
#define PARALLAXMAPPING_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV).r
#endif
#if defined(PARALLAXMAPPING_SEETP)
#define PARALLAXMAPPING_FNC parallaxMapping_steep
#elif defined(PARALLAXMAPPING_RELIEF)
#define PARALLAXMAPPING_FNC parallaxMapping_relief
#elif defined(PARALLAXMAPPING_OCCLUSION)
#define PARALLAXMAPPING_FNC parallaxMapping_occlusion
#else
#define PARALLAXMAPPING_FNC parallaxMapping_simple
#endif
#ifndef PARALLAXMAPPING_SCALE
#define PARALLAXMAPPING_SCALE 0.01
#endif
#ifndef PARALLAXMAPPING_NUMSEARCHES
#define PARALLAXMAPPING_NUMSEARCHES 10.0
#endif
#ifndef FNC_PARALLAXMAPPING
#define FNC_PARALLAXMAPPING
//////////////////////////////////////////////////////
// Implements Parallax Mapping technique
// Returns modified texture coordinates, and last used depth
//
// http://sunandblackcat.com/tipFullView.php?topicid=28
vec2 parallaxMapping_simple(in SAMPLER_TYPE tex, in vec3 V, in vec2 T, out float parallaxHeight) {
// get depth for this fragment
float initialHeight = PARALLAXMAPPING_SAMPLER_FNC(tex, T);
// calculate amount of offset for Parallax Mapping
vec2 texCoordOffset = PARALLAXMAPPING_SCALE * V.xy / V.z * initialHeight;
// calculate amount of offset for Parallax Mapping With Offset Limiting
texCoordOffset = PARALLAXMAPPING_SCALE * V.xy * initialHeight;
// retunr modified texture coordinates
return T - texCoordOffset;
}
vec2 parallaxMapping_steep(in SAMPLER_TYPE tex, in vec3 V, in vec2 T, out float parallaxHeight) {
// determine number of layers from angle between V and N
const float minLayers = PARALLAXMAPPING_NUMSEARCHES * 0.5;
const float maxLayers = 15.0;
float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), V)));
// height of each layer
float layerHeight = 1.0 / numLayers;
// depth of current layer
float currentLayerHeight = 0.0;
// shift of texture coordinates for each iteration
vec2 dtex = PARALLAXMAPPING_SCALE * V.xy / V.z / numLayers;
// current texture coordinates
vec2 currentTextureCoords = T;
// get first depth from heightmap
float heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
// while point is above surface
while(heightFromTexture > currentLayerHeight) {
// to the next layer
currentLayerHeight += layerHeight;
// shift texture coordinates along vector V
currentTextureCoords -= dtex;
// get new depth from heightmap
heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
}
// return results
parallaxHeight = currentLayerHeight;
return currentTextureCoords;
}
vec2 parallaxMapping_relief(in SAMPLER_TYPE tex, in vec3 V, in vec2 T, out float parallaxHeight) {
// determine required number of layers
const float minLayers = PARALLAXMAPPING_NUMSEARCHES;
const float maxLayers = 15.0;
float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), V)));
// height of each layer
float layerHeight = 1.0 / numLayers;
// depth of current layer
float currentLayerHeight = 0.0;
// shift of texture coordinates for each iteration
vec2 dtex = PARALLAXMAPPING_SCALE * V.xy / V.z / numLayers;
// current texture coordinates
vec2 currentTextureCoords = T;
// depth from heightmap
float heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
// while point is above surface
while (heightFromTexture > currentLayerHeight) {
// go to the next layer
currentLayerHeight += layerHeight;
// shift texture coordinates along V
currentTextureCoords -= dtex;
// new depth from heightmap
heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
}
///////////////////////////////////////////////////////////
// Start of Relief Parallax Mapping
// decrease shift and height of layer by half
vec2 deltaTexCoord = dtex * 0.5;
float deltaHeight = layerHeight * 0.5;
// return to the mid point of previous layer
currentTextureCoords += deltaTexCoord;
currentLayerHeight -= deltaHeight;
// binary search to increase precision of Steep Paralax Mapping
const int numSearches = 5;
for (int i = 0; i < numSearches; i++) {
// decrease shift and height of layer by half
deltaTexCoord *= 0.5;
deltaHeight *= 0.5;
// new depth from heightmap
heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
// shift along or agains vector V
if(heightFromTexture > currentLayerHeight) // below the surface
{
currentTextureCoords -= deltaTexCoord;
currentLayerHeight += deltaHeight;
}
else // above the surface
{
currentTextureCoords += deltaTexCoord;
currentLayerHeight -= deltaHeight;
}
}
// return results
parallaxHeight = currentLayerHeight;
return currentTextureCoords;
}
#if defined(PARALLAXMAPPING_OCCLUSION)
vec2 parallaxMapping_occlusion(in SAMPLER_TYPE tex, in vec3 V, in vec2 T, out float parallaxHeight) {
// determine optimal number of layers
const float minLayers = PARALLAXMAPPING_NUMSEARCHES;
const float maxLayers = 15.0;
float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), V)));
// height of each layer
float layerHeight = 1.0 / numLayers;
// current depth of the layer
float curLayerHeight = 0.0;
// shift of texture coordinates for each layer
vec2 dtex = PARALLAXMAPPING_SCALE * V.xy / V.z / numLayers;
// current texture coordinates
vec2 currentTextureCoords = T;
// depth from heightmap
float heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
// while point is above the surface
while(heightFromTexture > curLayerHeight) {
// to the next layer
curLayerHeight += layerHeight;
// shift of texture coordinates
currentTextureCoords -= dtex;
// new depth from heightmap
heightFromTexture = PARALLAXMAPPING_SAMPLER_FNC(tex, currentTextureCoords);
}
///////////////////////////////////////////////////////////
// vec3 L = normalize(v_toLightInTangentSpace);
// vec2 texStep = PARALLAXMAPPING_SCALE * L.xy / L.z / numLayers;
// previous texture coordinates
vec2 prevTCoords = currentTextureCoords;// + texStep;
// heights for linear interpolation
float nextH = heightFromTexture - curLayerHeight;
float prevH = PARALLAXMAPPING_SAMPLER_FNC(tex, prevTCoords) - curLayerHeight + layerHeight;
// proportions for linear interpolation
float weight = nextH / (nextH - prevH);
// interpolation of texture coordinates
vec2 finalTexCoords = prevTCoords * weight + currentTextureCoords * (1.0 - weight);
// interpolation of depth values
parallaxHeight = curLayerHeight + prevH * weight + nextH * (1.0 - weight);
// return result
return finalTexCoords;
}
#endif
vec2 parallaxMapping(in SAMPLER_TYPE tex, in vec3 V, in vec2 T, out float parallaxHeight) {
return PARALLAXMAPPING_FNC(tex, V, T, parallaxHeight);
}
vec2 parallaxMapping(in SAMPLER_TYPE tex, in vec3 V, in vec2 T) {
float height;
return PARALLAXMAPPING_FNC(tex, V, T, height);
}
#endif