Skip to content

Commit d04d8ab

Browse files
juhdanadEkdohibs
authored andcommittedJan 23, 2017
Add hardware node coloring. Includes:
- Increase ContentFeatures serialization version - Color property and palettes for nodes - paramtype2 = "color", "colored facedir" or "colored wallmounted"
1 parent 43822de commit d04d8ab

27 files changed

+1207
-554
lines changed
 

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

+19-24
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
uniform mat4 mWorldViewProj;
22
uniform mat4 mWorld;
33

4-
uniform float dayNightRatio;
4+
// Color of the light emitted by the sun.
5+
uniform vec3 dayLight;
56
uniform vec3 eyePosition;
67
uniform float animationTimer;
78

@@ -14,6 +15,8 @@ varying vec3 tsEyeVec;
1415
varying vec3 tsLightVec;
1516
varying float area_enable_parallax;
1617

18+
// Color of the light emitted by the light sources.
19+
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
1720
const float e = 2.718281828459;
1821
const float BS = 10.0;
1922

@@ -119,31 +122,23 @@ float disp_z;
119122
v.z = dot(eyeVec, normal);
120123
tsEyeVec = normalize (v);
121124

125+
// Calculate color.
126+
// Red, green and blue components are pre-multiplied with
127+
// the brightness, so now we have to multiply these
128+
// colors with the color of the incoming light.
129+
// The pre-baked colors are halved to prevent overflow.
122130
vec4 color;
123-
float day = gl_Color.r;
124-
float night = gl_Color.g;
125-
float light_source = gl_Color.b;
126-
127-
float rg = mix(night, day, dayNightRatio);
128-
rg += light_source * 2.5; // Make light sources brighter
129-
float b = rg;
130-
131-
// Moonlight is blue
132-
b += (day - night) / 13.0;
133-
rg -= (day - night) / 23.0;
134-
131+
// The alpha gives the ratio of sunlight in the incoming light.
132+
float nightRatio = 1 - gl_Color.a;
133+
color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb +
134+
nightRatio * artificialLight.rgb) * 2;
135+
color.a = 1;
136+
135137
// Emphase blue a bit in darker places
136138
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
137-
b += max(0.0, (1.0 - abs(b - 0.13) / 0.17) * 0.025);
138-
139-
// Artificial light is yellow-ish
140-
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
141-
rg += max(0.0, (1.0 - abs(rg - 0.85) / 0.15) * 0.065);
142-
143-
color.r = rg;
144-
color.g = rg;
145-
color.b = b;
146-
147-
color.a = gl_Color.a;
139+
float brightness = (color.r + color.g + color.b) / 3;
140+
color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
141+
0.07 * brightness);
142+
148143
gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0);
149144
}

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

+20-25
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
uniform mat4 mWorldViewProj;
22
uniform mat4 mWorld;
33

4-
uniform float dayNightRatio;
4+
// Color of the light emitted by the sun.
5+
uniform vec3 dayLight;
56
uniform vec3 eyePosition;
67
uniform float animationTimer;
78

@@ -13,6 +14,8 @@ varying vec3 lightVec;
1314
varying vec3 tsEyeVec;
1415
varying vec3 tsLightVec;
1516

17+
// Color of the light emitted by the light sources.
18+
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
1619
const float e = 2.718281828459;
1720
const float BS = 10.0;
1821

@@ -112,31 +115,23 @@ void main(void)
112115
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
113116
tsEyeVec = eyeVec * tbnMatrix;
114117

118+
// Calculate color.
119+
// Red, green and blue components are pre-multiplied with
120+
// the brightness, so now we have to multiply these
121+
// colors with the color of the incoming light.
122+
// The pre-baked colors are halved to prevent overflow.
115123
vec4 color;
116-
float day = gl_Color.r;
117-
float night = gl_Color.g;
118-
float light_source = gl_Color.b;
119-
120-
float rg = mix(night, day, dayNightRatio);
121-
rg += light_source * 2.5; // Make light sources brighter
122-
float b = rg;
123-
124-
// Moonlight is blue
125-
b += (day - night) / 13.0;
126-
rg -= (day - night) / 23.0;
127-
124+
// The alpha gives the ratio of sunlight in the incoming light.
125+
float nightRatio = 1 - gl_Color.a;
126+
color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb +
127+
nightRatio * artificialLight.rgb) * 2;
128+
color.a = 1;
129+
128130
// Emphase blue a bit in darker places
129131
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
130-
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
131-
132-
// Artificial light is yellow-ish
133-
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
134-
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
135-
136-
color.r = rg;
137-
color.g = rg;
138-
color.b = b;
139-
140-
color.a = gl_Color.a;
141-
gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);
132+
float brightness = (color.r + color.g + color.b) / 3;
133+
color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
134+
0.07 * brightness);
135+
136+
gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0);
142137
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
uniform mat4 mWorldViewProj;
22
uniform mat4 mWorld;
33

4-
uniform float dayNightRatio;
54
uniform vec3 eyePosition;
65
uniform float animationTimer;
76

Diff for: ‎doc/lua_api.txt

+26-1
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,19 @@ node definition:
638638
bit 4 (0x10) - Makes the plant mesh 1.4x larger
639639
bit 5 (0x20) - Moves each face randomly a small bit down (1/8 max)
640640
bits 6-7 are reserved for future use.
641+
paramtype2 == "color"
642+
^ `param2` tells which color is picked from the palette.
643+
The palette should have 256 pixels.
644+
paramtype2 == "colorfacedir"
645+
^ Same as `facedir`, but with colors.
646+
The first three bits of `param2` tells which color
647+
is picked from the palette.
648+
The palette should have 8 pixels.
649+
paramtype2 == "colorwallmounted"
650+
^ Same as `wallmounted`, but with colors.
651+
The first five bits of `param2` tells which color
652+
is picked from the palette.
653+
The palette should have 32 pixels.
641654
collision_box = {
642655
type = "fixed",
643656
fixed = {
@@ -3707,6 +3720,9 @@ Definition tables
37073720
when displacement mapping is used
37083721
Directions are from the point of view of the tile texture,
37093722
not the node it's on
3723+
* `{name="image.png", color=ColorSpec}`
3724+
* the texture's color will be multiplied with this color.
3725+
* the tile's color overrides the owning node's color in all cases.
37103726
* deprecated, yet still supported field names:
37113727
* `image` (name)
37123728

@@ -3749,8 +3765,17 @@ Definition tables
37493765
special_tiles = {tile definition 1, Tile definition 2}, --[[
37503766
^ Special textures of node; used rarely (old field name: special_materials)
37513767
^ List can be shortened to needed length ]]
3752-
alpha = 255,
3768+
color = ColorSpec, --[[
3769+
^ The node's original color will be multiplied with this color.
3770+
^ If the node has a palette, then this setting only has an effect
3771+
^ in the inventory and on the wield item. ]]
37533772
use_texture_alpha = false, -- Use texture's alpha channel
3773+
palette = "palette.png", --[[
3774+
^ The node's `param2` is used to select a pixel from the image
3775+
^ (pixels are arranged from left to right and from top to bottom).
3776+
^ The node's color will be multiplied with the selected pixel's
3777+
^ color. Tiles can override this behavior.
3778+
^ Only when `paramtype2` supports palettes. ]]
37543779
post_effect_color = "green#0F", -- If player is inside node, see "ColorSpec"
37553780
paramtype = "none", -- See "Nodes" --[[
37563781
^ paramtype = "light" allows light to propagate from or through the node with light value

Diff for: ‎src/client/tile.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,6 @@ class TextureSource : public IWritableTextureSource
378378
video::ITexture* generateTextureFromMesh(
379379
const TextureFromMeshParams &params);
380380

381-
// Generates an image from a full string like
382-
// "stone.png^mineral_coal.png^[crack:1:0".
383-
// Shall be called from the main thread.
384381
video::IImage* generateImage(const std::string &name);
385382

386383
video::ITexture* getNormalTexture(const std::string &name);

Diff for: ‎src/client/tile.h

+27-7
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ class ITextureSource : public ISimpleTextureSource
108108
const std::string &name, u32 *id = NULL) = 0;
109109
virtual IrrlichtDevice* getDevice()=0;
110110
virtual bool isKnownSourceImage(const std::string &name)=0;
111+
/*! Generates an image from a full string like
112+
* "stone.png^mineral_coal.png^[crack:1:0".
113+
* Shall be called from the main thread.
114+
* The returned Image should be dropped.
115+
*/
116+
virtual video::IImage* generateImage(const std::string &name)=0;
111117
virtual video::ITexture* generateTextureFromMesh(
112118
const TextureFromMeshParams &params)=0;
113119
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
@@ -192,7 +198,6 @@ struct TileSpec
192198
texture(NULL),
193199
normal_texture(NULL),
194200
flags_texture(NULL),
195-
alpha(255),
196201
material_type(TILE_MATERIAL_BASIC),
197202
material_flags(
198203
//0 // <- DEBUG, Use the one below
@@ -201,22 +206,30 @@ struct TileSpec
201206
shader_id(0),
202207
animation_frame_count(1),
203208
animation_frame_length_ms(0),
204-
rotation(0)
209+
rotation(0),
210+
has_color(false),
211+
color(),
212+
emissive_light(0)
205213
{
206214
}
207215

216+
/*!
217+
* Two tiles are equal if they can be appended to
218+
* the same mesh buffer.
219+
*/
208220
bool operator==(const TileSpec &other) const
209221
{
210222
return (
211223
texture_id == other.texture_id &&
212-
/* texture == other.texture && */
213-
alpha == other.alpha &&
214224
material_type == other.material_type &&
215225
material_flags == other.material_flags &&
216226
rotation == other.rotation
217227
);
218228
}
219229

230+
/*!
231+
* Two tiles are not equal if they must be in different mesh buffers.
232+
*/
220233
bool operator!=(const TileSpec &other) const
221234
{
222235
return !(*this == other);
@@ -233,7 +246,7 @@ struct TileSpec
233246
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
234247
break;
235248
case TILE_MATERIAL_LIQUID_TRANSPARENT:
236-
material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
249+
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
237250
break;
238251
case TILE_MATERIAL_LIQUID_OPAQUE:
239252
material.MaterialType = video::EMT_SOLID;
@@ -274,8 +287,6 @@ struct TileSpec
274287
video::ITexture *normal_texture;
275288
video::ITexture *flags_texture;
276289

277-
// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
278-
u8 alpha;
279290
// Material parameters
280291
u8 material_type;
281292
u8 material_flags;
@@ -286,5 +297,14 @@ struct TileSpec
286297
std::vector<FrameSpec> frames;
287298

288299
u8 rotation;
300+
//! If true, the tile has its own color.
301+
bool has_color;
302+
/*!
303+
* The color of the tile, or if the tile does not own
304+
* a color then the color of the node owning this tile.
305+
*/
306+
video::SColor color;
307+
//! This much light does the tile emit.
308+
u8 emissive_light;
289309
};
290310
#endif

Diff for: ‎src/clientenvironment.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,7 @@ void ClientEnvironment::step(float dtime)
334334
node_at_lplayer = m_map->getNodeNoEx(p);
335335

336336
u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef());
337-
u8 day = light & 0xff;
338-
u8 night = (light >> 8) & 0xff;
339-
finalColorBlend(lplayer->light_color, day, night, day_night_ratio);
337+
final_color_blend(&lplayer->light_color, light, day_night_ratio);
340338
}
341339

342340
/*

2 commit comments

Comments
 (2)

sfan5 commented on Jan 24, 2017

@sfan5
Collaborator

This commit seems to introduce some warnings:

minetest/src/particles.h:35:1: warning: class 'MapNode' was previously declared as a struct [-Wmismatched-tags]
class MapNode;
^
minetest/src/mapnode.h:118:8: note: previous use is here
struct MapNode
       ^
minetest/src/particles.h:35:1: note: did you mean struct here?
class MapNode;
^~~~~
struct
minetest/src/particles.h:36:1: warning: class 'ContentFeatures' was previously declared as a struct [-Wmismatched-tags]
class ContentFeatures;
^
minetest/src/mapnode.h:111:8: note: previous use is here
struct ContentFeatures;
       ^
2 warnings generated.

nerzhul commented on Jan 25, 2017

@nerzhul
Contributor

@sfan5 i propose to add mismatched-tags as a blocking in travis, do you agree ?

Please sign in to comment.