Skip to content

Commit

Permalink
Add hardware node coloring. Includes:
Browse files Browse the repository at this point in the history
- Increase ContentFeatures serialization version
- Color property and palettes for nodes
- paramtype2 = "color", "colored facedir" or "colored wallmounted"
  • Loading branch information
juhdanad authored and Ekdohibs committed Jan 23, 2017
1 parent 43822de commit d04d8ab
Show file tree
Hide file tree
Showing 27 changed files with 1,207 additions and 554 deletions.
43 changes: 19 additions & 24 deletions client/shaders/nodes_shader/opengl_vertex.glsl
@@ -1,7 +1,8 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;

uniform float dayNightRatio;
// Color of the light emitted by the sun.
uniform vec3 dayLight;
uniform vec3 eyePosition;
uniform float animationTimer;

Expand All @@ -14,6 +15,8 @@ varying vec3 tsEyeVec;
varying vec3 tsLightVec;
varying float area_enable_parallax;

// Color of the light emitted by the light sources.
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
const float e = 2.718281828459;
const float BS = 10.0;

Expand Down Expand Up @@ -119,31 +122,23 @@ float disp_z;
v.z = dot(eyeVec, normal);
tsEyeVec = normalize (v);

// Calculate color.
// Red, green and blue components are pre-multiplied with
// the brightness, so now we have to multiply these
// colors with the color of the incoming light.
// The pre-baked colors are halved to prevent overflow.
vec4 color;
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;

float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;

// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 23.0;

// The alpha gives the ratio of sunlight in the incoming light.
float nightRatio = 1 - gl_Color.a;
color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb +
nightRatio * artificialLight.rgb) * 2;
color.a = 1;

// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13) / 0.17) * 0.025);

// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85) / 0.15) * 0.065);

color.r = rg;
color.g = rg;
color.b = b;

color.a = gl_Color.a;
float brightness = (color.r + color.g + color.b) / 3;
color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
0.07 * brightness);

gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0);
}
45 changes: 20 additions & 25 deletions client/shaders/water_surface_shader/opengl_vertex.glsl
@@ -1,7 +1,8 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;

uniform float dayNightRatio;
// Color of the light emitted by the sun.
uniform vec3 dayLight;
uniform vec3 eyePosition;
uniform float animationTimer;

Expand All @@ -13,6 +14,8 @@ varying vec3 lightVec;
varying vec3 tsEyeVec;
varying vec3 tsLightVec;

// Color of the light emitted by the light sources.
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
const float e = 2.718281828459;
const float BS = 10.0;

Expand Down Expand Up @@ -112,31 +115,23 @@ void main(void)
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
tsEyeVec = eyeVec * tbnMatrix;

// Calculate color.
// Red, green and blue components are pre-multiplied with
// the brightness, so now we have to multiply these
// colors with the color of the incoming light.
// The pre-baked colors are halved to prevent overflow.
vec4 color;
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;

float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;

// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 23.0;

// The alpha gives the ratio of sunlight in the incoming light.
float nightRatio = 1 - gl_Color.a;
color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb +
nightRatio * artificialLight.rgb) * 2;
color.a = 1;

// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);

// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);

color.r = rg;
color.g = rg;
color.b = b;

color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);
float brightness = (color.r + color.g + color.b) / 3;
color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
0.07 * brightness);

gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0);
}
1 change: 0 additions & 1 deletion client/shaders/wielded_shader/opengl_vertex.glsl
@@ -1,7 +1,6 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;

uniform float dayNightRatio;
uniform vec3 eyePosition;
uniform float animationTimer;

Expand Down
27 changes: 26 additions & 1 deletion doc/lua_api.txt
Expand Up @@ -638,6 +638,19 @@ node definition:
bit 4 (0x10) - Makes the plant mesh 1.4x larger
bit 5 (0x20) - Moves each face randomly a small bit down (1/8 max)
bits 6-7 are reserved for future use.
paramtype2 == "color"
^ `param2` tells which color is picked from the palette.
The palette should have 256 pixels.
paramtype2 == "colorfacedir"
^ Same as `facedir`, but with colors.
The first three bits of `param2` tells which color
is picked from the palette.
The palette should have 8 pixels.
paramtype2 == "colorwallmounted"
^ Same as `wallmounted`, but with colors.
The first five bits of `param2` tells which color
is picked from the palette.
The palette should have 32 pixels.
collision_box = {
type = "fixed",
fixed = {
Expand Down Expand Up @@ -3707,6 +3720,9 @@ Definition tables
when displacement mapping is used
Directions are from the point of view of the tile texture,
not the node it's on
* `{name="image.png", color=ColorSpec}`
* the texture's color will be multiplied with this color.
* the tile's color overrides the owning node's color in all cases.
* deprecated, yet still supported field names:
* `image` (name)

Expand Down Expand Up @@ -3749,8 +3765,17 @@ Definition tables
special_tiles = {tile definition 1, Tile definition 2}, --[[
^ Special textures of node; used rarely (old field name: special_materials)
^ List can be shortened to needed length ]]
alpha = 255,
color = ColorSpec, --[[
^ The node's original color will be multiplied with this color.
^ If the node has a palette, then this setting only has an effect
^ in the inventory and on the wield item. ]]
use_texture_alpha = false, -- Use texture's alpha channel
palette = "palette.png", --[[
^ The node's `param2` is used to select a pixel from the image
^ (pixels are arranged from left to right and from top to bottom).
^ The node's color will be multiplied with the selected pixel's
^ color. Tiles can override this behavior.
^ Only when `paramtype2` supports palettes. ]]
post_effect_color = "green#0F", -- If player is inside node, see "ColorSpec"
paramtype = "none", -- See "Nodes" --[[
^ paramtype = "light" allows light to propagate from or through the node with light value
Expand Down
3 changes: 0 additions & 3 deletions src/client/tile.cpp
Expand Up @@ -378,9 +378,6 @@ class TextureSource : public IWritableTextureSource
video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params);

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

video::ITexture* getNormalTexture(const std::string &name);
Expand Down
34 changes: 27 additions & 7 deletions src/client/tile.h
Expand Up @@ -108,6 +108,12 @@ class ITextureSource : public ISimpleTextureSource
const std::string &name, u32 *id = NULL) = 0;
virtual IrrlichtDevice* getDevice()=0;
virtual bool isKnownSourceImage(const std::string &name)=0;
/*! Generates an image from a full string like
* "stone.png^mineral_coal.png^[crack:1:0".
* Shall be called from the main thread.
* The returned Image should be dropped.
*/
virtual video::IImage* generateImage(const std::string &name)=0;
virtual video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params)=0;
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
Expand Down Expand Up @@ -192,7 +198,6 @@ struct TileSpec
texture(NULL),
normal_texture(NULL),
flags_texture(NULL),
alpha(255),
material_type(TILE_MATERIAL_BASIC),
material_flags(
//0 // <- DEBUG, Use the one below
Expand All @@ -201,22 +206,30 @@ struct TileSpec
shader_id(0),
animation_frame_count(1),
animation_frame_length_ms(0),
rotation(0)
rotation(0),
has_color(false),
color(),
emissive_light(0)
{
}

/*!
* Two tiles are equal if they can be appended to
* the same mesh buffer.
*/
bool operator==(const TileSpec &other) const
{
return (
texture_id == other.texture_id &&
/* texture == other.texture && */
alpha == other.alpha &&
material_type == other.material_type &&
material_flags == other.material_flags &&
rotation == other.rotation
);
}

/*!
* Two tiles are not equal if they must be in different mesh buffers.
*/
bool operator!=(const TileSpec &other) const
{
return !(*this == other);
Expand All @@ -233,7 +246,7 @@ struct TileSpec
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break;
case TILE_MATERIAL_LIQUID_TRANSPARENT:
material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break;
case TILE_MATERIAL_LIQUID_OPAQUE:
material.MaterialType = video::EMT_SOLID;
Expand Down Expand Up @@ -274,8 +287,6 @@ struct TileSpec
video::ITexture *normal_texture;
video::ITexture *flags_texture;

// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
u8 alpha;
// Material parameters
u8 material_type;
u8 material_flags;
Expand All @@ -286,5 +297,14 @@ struct TileSpec
std::vector<FrameSpec> frames;

u8 rotation;
//! If true, the tile has its own color.
bool has_color;
/*!
* The color of the tile, or if the tile does not own
* a color then the color of the node owning this tile.
*/
video::SColor color;
//! This much light does the tile emit.
u8 emissive_light;
};
#endif
4 changes: 1 addition & 3 deletions src/clientenvironment.cpp
Expand Up @@ -334,9 +334,7 @@ void ClientEnvironment::step(float dtime)
node_at_lplayer = m_map->getNodeNoEx(p);

u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef());
u8 day = light & 0xff;
u8 night = (light >> 8) & 0xff;
finalColorBlend(lplayer->light_color, day, night, day_night_ratio);
final_color_blend(&lplayer->light_color, light, day_night_ratio);
}

/*
Expand Down

2 comments on commit d04d8ab

@sfan5
Copy link
Member

@sfan5 sfan5 commented on d04d8ab Jan 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Please sign in to comment.