Skip to content

Commit 655fc60

Browse files
committedJul 16, 2015
Fix relief mapping issues
1 parent b30e8d8 commit 655fc60

File tree

15 files changed

+206
-70
lines changed

15 files changed

+206
-70
lines changed
 

Diff for: ‎client/shaders/nodes_shader/opengl_fragment.glsl

+75-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
uniform sampler2D baseTexture;
22
uniform sampler2D normalTexture;
3-
uniform sampler2D useNormalmap;
3+
uniform sampler2D textureFlags;
44

55
uniform vec4 skyBgColor;
66
uniform float fogDistance;
@@ -15,19 +15,73 @@ varying vec3 tsEyeVec;
1515
varying vec3 lightVec;
1616
varying vec3 tsLightVec;
1717

18-
bool normalTexturePresent = false;
18+
bool normalTexturePresent = false;
19+
bool texTileableHorizontal = false;
20+
bool texTileableVertical = false;
21+
bool texSeamless = false;
1922

2023
const float e = 2.718281828459;
2124
const float BS = 10.0;
22-
23-
float intensity (vec3 color)
25+
26+
void get_texture_flags()
27+
{
28+
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
29+
if (flags.r > 0.5) {
30+
normalTexturePresent = true;
31+
}
32+
if (flags.g > 0.5) {
33+
texTileableHorizontal = true;
34+
}
35+
if (flags.b > 0.5) {
36+
texTileableVertical = true;
37+
}
38+
if (texTileableHorizontal && texTileableVertical) {
39+
texSeamless = true;
40+
}
41+
}
42+
43+
vec2 validate_displacement(vec2 uv, vec2 ds, float dist)
44+
{
45+
if (texSeamless) {
46+
uv += dist * ds;
47+
} else if (texTileableVertical == false) {
48+
vec2 uv2 = uv + dist * ds;
49+
// limit vertical texure displacement
50+
if ((uv.y + uv2.y) < 0.0) {
51+
uv.y = 0.0;
52+
} else if ((uv.y + uv2.y) > 1.999) {
53+
uv.y = 0.999;
54+
} else {
55+
uv.y = uv2.y;
56+
}
57+
uv.x = uv2.x;
58+
} else {
59+
vec2 uv2 = uv + dist * ds;
60+
// limit horizontal texure displacement
61+
if ((uv.x + uv2.x) < 0.0) {
62+
uv.x = 0.0;
63+
} else if ((uv.x + uv2.x) > 1.999) {
64+
uv.x = 0.999;
65+
} else {
66+
uv.x = uv2.x;
67+
}
68+
uv.y = uv2.y;
69+
}
70+
return uv;
71+
}
72+
73+
float intensity(vec3 color)
2474
{
2575
return (color.r + color.g + color.b) / 3.0;
2676
}
2777

28-
float get_rgb_height (vec2 uv)
78+
float get_rgb_height(vec2 uv)
2979
{
30-
return intensity(texture2D(baseTexture,uv).rgb);
80+
if (texSeamless) {
81+
return intensity(texture2D(baseTexture, uv).rgb);
82+
} else {
83+
return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
84+
}
3185
}
3286

3387
vec4 get_normal_map(vec2 uv)
@@ -50,7 +104,8 @@ float find_intersection(vec2 dp, vec2 ds)
50104
return depth;
51105
}
52106

53-
float find_intersectionRGB(vec2 dp, vec2 ds) {
107+
float find_intersectionRGB(vec2 dp, vec2 ds)
108+
{
54109
const float depth_step = 1.0 / 24.0;
55110
float depth = 1.0;
56111
for (int i = 0 ; i < 24 ; i++) {
@@ -62,24 +117,19 @@ float find_intersectionRGB(vec2 dp, vec2 ds) {
62117
return depth;
63118
}
64119

65-
void main (void)
120+
void main(void)
66121
{
67122
vec3 color;
68123
vec4 bump;
69124
vec2 uv = gl_TexCoord[0].st;
70125
bool use_normalmap = false;
71-
72-
#if USE_NORMALMAPS == 1
73-
if (texture2D(useNormalmap,vec2(1.0, 1.0)).r > 0.0) {
74-
normalTexturePresent = true;
75-
}
76-
#endif
126+
get_texture_flags();
77127

78128
#ifdef ENABLE_PARALLAX_OCCLUSION
79129
vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y);
80130
const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS;
81131
const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS;
82-
132+
83133
#if PARALLAX_OCCLUSION_MODE == 0
84134
// Parallax occlusion with slope information
85135
if (normalTexturePresent && area_enable_parallax > 0.0) {
@@ -89,28 +139,34 @@ void main (void)
89139
uv += h * normal.z * eyeRay;
90140
}
91141
#endif
142+
92143
#if PARALLAX_OCCLUSION_MODE == 1
93144
// Relief mapping
94145
if (normalTexturePresent && area_enable_parallax > 0.0) {
95146
vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
147+
// offset the texture by maximum possible displacement,
148+
// this will help align seamless and non seamless textures
149+
uv -= ds;
96150
float dist = find_intersection(uv, ds);
97-
uv += dist * ds;
151+
uv = validate_displacement(uv, ds, dist);
152+
98153
#endif
99154
} else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) {
100155
vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
156+
uv -= ds;
101157
float dist = find_intersectionRGB(uv, ds);
102-
uv += dist * ds;
158+
uv = validate_displacement(uv, ds, dist);
103159
}
104160
#endif
105161

106162
#if USE_NORMALMAPS == 1
107163
if (normalTexturePresent) {
108164
bump = get_normal_map(uv);
109165
use_normalmap = true;
110-
}
166+
}
111167
#endif
112168

113-
if (GENERATE_NORMALMAPS == 1 && use_normalmap == false) {
169+
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
114170
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
115171
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
116172
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));

Diff for: ‎client/shaders/nodes_shader/opengl_vertex.glsl

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void main(void)
9494

9595
// Don't generate heightmaps when too far from the eye
9696
float dist = distance (vec3(0.0, 0.0 ,0.0), vPosition);
97-
if (dist > 120.0) {
97+
if (dist > 300.0) {
9898
area_enable_parallax = 0.0;
9999
}
100100

Diff for: ‎client/shaders/water_surface_shader/opengl_fragment.glsl

+30-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
uniform sampler2D baseTexture;
22
uniform sampler2D normalTexture;
3-
uniform sampler2D useNormalmap;
3+
uniform sampler2D textureFlags;
44

55
uniform vec4 skyBgColor;
66
uniform float fogDistance;
@@ -15,37 +15,55 @@ varying vec3 lightVec;
1515
varying vec3 tsLightVec;
1616

1717
bool normalTexturePresent = false;
18+
bool texTileableHorizontal = false;
19+
bool texTileableVertical = false;
20+
bool texSeamless = false;
1821

1922
const float e = 2.718281828459;
2023
const float BS = 10.0;
21-
22-
float intensity (vec3 color){
24+
25+
void get_texture_flags()
26+
{
27+
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
28+
if (flags.r > 0.5) {
29+
normalTexturePresent = true;
30+
}
31+
if (flags.g > 0.5) {
32+
texTileableHorizontal = true;
33+
}
34+
if (flags.b > 0.5) {
35+
texTileableVertical = true;
36+
}
37+
if (texTileableHorizontal && texTileableVertical) {
38+
texSeamless = true;
39+
}
40+
}
41+
42+
float intensity(vec3 color)
43+
{
2344
return (color.r + color.g + color.b) / 3.0;
2445
}
2546

26-
float get_rgb_height (vec2 uv){
47+
float get_rgb_height(vec2 uv)
48+
{
2749
return intensity(texture2D(baseTexture,uv).rgb);
2850
}
2951

30-
vec4 get_normal_map(vec2 uv){
52+
vec4 get_normal_map(vec2 uv)
53+
{
3154
vec4 bump = texture2D(normalTexture, uv).rgba;
3255
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
3356
bump.y = -bump.y;
3457
return bump;
3558
}
3659

37-
void main (void)
60+
void main(void)
3861
{
3962
vec3 color;
4063
vec4 bump;
4164
vec2 uv = gl_TexCoord[0].st;
4265
bool use_normalmap = false;
43-
44-
#ifdef USE_NORMALMAPS
45-
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0) {
46-
normalTexturePresent = true;
47-
}
48-
#endif
66+
get_texture_flags();
4967

5068
#ifdef ENABLE_PARALLAX_OCCLUSION
5169
if (normalTexturePresent) {

Diff for: ‎doc/lua_api.txt

+7-2
Original file line numberDiff line numberDiff line change
@@ -3058,8 +3058,13 @@ Definition tables
30583058
### Tile definition
30593059
* `"image.png"`
30603060
* `{name="image.png", animation={Tile Animation definition}}`
3061-
* `{name="image.png", backface_culling=bool}`
3062-
* backface culling only supported in special tiles
3061+
* `{name="image.png", backface_culling=bool, tileable_vertical=bool,
3062+
tileable_horizontal=bool}`
3063+
* backface culling only supported in special tiles.
3064+
* tileable flags are info for shaders, how they should treat texture
3065+
when displacement mapping is used
Has a conversation. Original line has a conversation.
3066+
Directions are from the point of view of the tile texture,
3067+
not the node it's on
30633068
* deprecated, yet still supported field names:
30643069
* `image` (name)
30653070

Diff for: ‎games/minimal/mods/default/init.lua

+6-2
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,9 @@ minetest.register_node("default:stone_with_iron", {
722722

723723
minetest.register_node("default:dirt_with_grass", {
724724
description = "Dirt with grass",
725-
tiles ={"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
725+
tiles ={"default_grass.png", "default_dirt.png",
726+
{name = "default_dirt.png^default_grass_side.png",
727+
tileable_vertical = false}},
726728
groups = {crumbly=3, soil=1},
727729
drop = 'default:dirt',
728730
sounds = default.node_sound_dirt_defaults({
@@ -732,7 +734,9 @@ minetest.register_node("default:dirt_with_grass", {
732734

733735
minetest.register_node("default:dirt_with_grass_footsteps", {
734736
description = "Dirt with grass and footsteps",
735-
tiles ={"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
737+
tiles ={"default_grass_footsteps.png", "default_dirt.png",
738+
{name = "default_dirt.png^default_grass_side.png",
739+
tileable_vertical = false}},
736740
groups = {crumbly=3, soil=1},
737741
drop = 'default:dirt',
738742
sounds = default.node_sound_dirt_defaults({

Diff for: ‎src/client/tile.cpp

+35-6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3535
#include "util/string.h" // for parseColorString()
3636
#include "imagefilters.h"
3737
#include "guiscalingfilter.h"
38+
#include "nodedef.h"
39+
3840

3941
#ifdef __ANDROID__
4042
#include <GLES/gl.h>
@@ -330,7 +332,7 @@ class TextureSource : public IWritableTextureSource
330332
*/
331333
video::ITexture* getTexture(u32 id);
332334

333-
video::ITexture* getTexture(const std::string &name, u32 *id);
335+
video::ITexture* getTexture(const std::string &name, u32 *id = NULL);
334336

335337
/*
336338
Get a texture specifically intended for mesh
@@ -383,6 +385,7 @@ class TextureSource : public IWritableTextureSource
383385

384386
video::ITexture* getNormalTexture(const std::string &name);
385387
video::SColor getTextureAverageColor(const std::string &name);
388+
video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile);
386389

387390
private:
388391

@@ -1992,9 +1995,8 @@ void imageTransform(u32 transform, video::IImage *src, video::IImage *dst)
19921995

19931996
video::ITexture* TextureSource::getNormalTexture(const std::string &name)
19941997
{
1995-
u32 id;
19961998
if (isKnownSourceImage("override_normal.png"))
1997-
return getTexture("override_normal.png", &id);
1999+
return getTexture("override_normal.png");
19982000
std::string fname_base = name;
19992001
std::string normal_ext = "_normal.png";
20002002
size_t pos = fname_base.find(".");
@@ -2006,7 +2008,7 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name)
20062008
fname_base.replace(i, 4, normal_ext);
20072009
i += normal_ext.length();
20082010
}
2009-
return getTexture(fname_base, &id);
2011+
return getTexture(fname_base);
20102012
}
20112013
return NULL;
20122014
}
@@ -2015,8 +2017,7 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
20152017
{
20162018
video::IVideoDriver *driver = m_device->getVideoDriver();
20172019
video::SColor c(0, 0, 0, 0);
2018-
u32 id;
2019-
video::ITexture *texture = getTexture(name, &id);
2020+
video::ITexture *texture = getTexture(name);
20202021
video::IImage *image = driver->createImage(texture,
20212022
core::position2d<s32>(0, 0),
20222023
texture->getOriginalSize());
@@ -2048,3 +2049,31 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
20482049
c.setAlpha(255);
20492050
return c;
20502051
}
2052+
2053+
video::ITexture *TextureSource::getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)
2054+
{
2055+
std::string tname = "__shaderFlagsTexture";
2056+
2057+
bool normalmap_present = tile->normal_texture ? true : false;
2058+
tname += normalmap_present ? "1" : "0";
2059+
tname += tiledef->tileable_horizontal ? "1" : "0";
2060+
tname += tiledef->tileable_vertical ? "1" : "0";
2061+
2062+
if (isKnownSourceImage(tname)) {
2063+
return getTexture(tname);
2064+
} else {
2065+
video::IVideoDriver *driver = m_device->getVideoDriver();
2066+
video::IImage *flags_image = driver->createImage(
2067+
video::ECF_A8R8G8B8, core::dimension2d<u32>(1, 1));
2068+
sanity_check(flags_image != NULL);
2069+
video::SColor c(
2070+
255,
2071+
normalmap_present ? 255 : 0,
2072+
tiledef->tileable_horizontal ? 255 : 0,
2073+
tiledef->tileable_vertical ? 255 : 0);
2074+
flags_image->setPixel(0, 0, c);
2075+
insertSourceImage(tname, flags_image);
2076+
flags_image->drop();
2077+
return getTexture(tname);
2078+
}
2079+
}

0 commit comments

Comments
 (0)
Please sign in to comment.