aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-12-02 14:24:58 +0200
committerPerttu Ahola <celeron55@gmail.com>2012-12-02 14:24:58 +0200
commitcd1f604ffe6130fd7d3a8358a8cebd7f821f9a11 (patch)
tree01077b87b747e9c72d40656c274d4781542a755e
parent566f7f638a00a698a25b73adc2e619fe63e1a802 (diff)
downloadminetest-cd1f604ffe6130fd7d3a8358a8cebd7f821f9a11.tar.gz
minetest-cd1f604ffe6130fd7d3a8358a8cebd7f821f9a11.tar.bz2
minetest-cd1f604ffe6130fd7d3a8358a8cebd7f821f9a11.zip
Handle day-night transition in shader and make light sources brighter when shaders are used
-rw-r--r--client/shaders/test_shader_1/opengl_vertex.glsl45
-rw-r--r--client/shaders/test_shader_2/opengl_vertex.glsl37
-rw-r--r--src/content_mapblock.cpp21
-rw-r--r--src/game.cpp18
-rw-r--r--src/itemdef.cpp7
-rw-r--r--src/mapblock_mesh.cpp49
-rw-r--r--src/mapblock_mesh.h5
7 files changed, 132 insertions, 50 deletions
diff --git a/client/shaders/test_shader_1/opengl_vertex.glsl b/client/shaders/test_shader_1/opengl_vertex.glsl
index 498085053..e24f58c09 100644
--- a/client/shaders/test_shader_1/opengl_vertex.glsl
+++ b/client/shaders/test_shader_1/opengl_vertex.glsl
@@ -2,6 +2,7 @@
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
+uniform float dayNightRatio;
varying vec3 vPosition;
@@ -11,15 +12,43 @@ void main(void)
vPosition = (mWorldViewProj * gl_Vertex).xyz;
- if(gl_Normal.y > 0.5)
- gl_FrontColor = gl_BackColor = gl_Color;
- else
- gl_FrontColor = gl_BackColor = gl_Color * 0.7;
+ vec4 color;
+ //color = vec4(1.0, 1.0, 1.0, 1.0);
- /*if(gl_Normal.y > 0.5)
- gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0);
- else
- gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0) * 0.7;*/
+ float day = gl_Color.r;
+ float night = gl_Color.g;
+ float light_source = gl_Color.b;
+
+ /*color.r = mix(night, day, dayNightRatio);
+ color.g = color.r;
+ color.b = color.r;*/
+
+ float rg = mix(night, day, dayNightRatio);
+ rg += light_source * 1.0; // Make light sources brighter
+ float b = rg;
+
+ // Moonlight is blue
+ b += (day - night) / 13.0;
+ rg -= (day - night) / 13.0;
+
+ // 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;
+
+ if(gl_Normal.y <= 0.5)
+ color *= 0.7;
+
+ color.a = gl_Color.a;
+
+ gl_FrontColor = gl_BackColor = color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
diff --git a/client/shaders/test_shader_2/opengl_vertex.glsl b/client/shaders/test_shader_2/opengl_vertex.glsl
index 6286fc0d7..80fd6d427 100644
--- a/client/shaders/test_shader_2/opengl_vertex.glsl
+++ b/client/shaders/test_shader_2/opengl_vertex.glsl
@@ -2,6 +2,7 @@
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
+uniform float dayNightRatio;
varying vec3 vPosition;
@@ -13,8 +14,40 @@ void main(void)
vPosition = (mWorldViewProj * gl_Vertex).xyz;
- gl_FrontColor = gl_BackColor = gl_Color;
- //gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0);
+ vec4 color;
+ //color = vec4(1.0, 1.0, 1.0, 1.0);
+
+ float day = gl_Color.r;
+ float night = gl_Color.g;
+ float light_source = gl_Color.b;
+
+ /*color.r = mix(night, day, dayNightRatio);
+ color.g = color.r;
+ color.b = color.r;*/
+
+ float rg = mix(night, day, dayNightRatio);
+ rg += light_source * 1.0; // Make light sources brighter
+ float b = rg;
+
+ // Moonlight is blue
+ b += (day - night) / 13.0;
+ rg -= (day - night) / 13.0;
+
+ // 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 = color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index 68895c396..aa3c061d6 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -171,7 +171,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
continue;
u16 l = getInteriorLight(n, 0, data);
- video::SColor c = MapBlock_LightColor(f.alpha, l);
+ video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source));
video::S3DVertex vertices[4] =
{
@@ -226,7 +226,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// Otherwise use the light of this node (the liquid)
else
l = getInteriorLight(n, 0, data);
- video::SColor c = MapBlock_LightColor(f.alpha, l);
+ video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source));
// Neighbor liquid levels (key = relative position)
// Includes current node
@@ -544,7 +544,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 1, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
for(u32 j=0; j<6; j++)
{
@@ -604,7 +604,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer pa_leaves = tile_leaves.texture;
u16 l = getInteriorLight(n, 1, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
v3f pos = intToFloat(p, BS);
aabb3f box(-BS/2,-BS/2,-BS/2,BS/2,BS/2,BS/2);
@@ -638,7 +638,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer ap = tile.texture;
- video::SColor c(255,255,255,255);
+ u16 l = getInteriorLight(n, 1, data);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
// Wall at X+ of node
video::S3DVertex vertices[4] =
@@ -683,7 +684,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 0, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
float d = (float)BS/16;
// Wall at X+ of node
@@ -730,7 +731,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 1, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
for(u32 j=0; j<4; j++)
{
@@ -793,7 +794,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
tile.texture.id) + "^[transformR90");
u16 l = getInteriorLight(n, 1, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
const f32 post_rad=(f32)BS/8;
const f32 bar_rad=(f32)BS/16;
@@ -996,7 +997,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 0, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
float d = (float)BS/64;
@@ -1045,7 +1046,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
u16 l = getInteriorLight(n, 0, data);
- video::SColor c = MapBlock_LightColor(255, l);
+ video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
v3f pos = intToFloat(p, BS);
diff --git a/src/game.cpp b/src/game.cpp
index 0c1a21370..fc780a808 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -841,13 +841,15 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
Sky *m_sky;
bool *m_force_fog_off;
f32 *m_fog_range;
+ Client *m_client;
public:
GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
- f32 *fog_range):
+ f32 *fog_range, Client *client):
m_sky(sky),
m_force_fog_off(force_fog_off),
- m_fog_range(fog_range)
+ m_fog_range(fog_range),
+ m_client(client)
{}
~GameGlobalShaderConstantSetter() {}
@@ -873,10 +875,12 @@ public:
if(*m_force_fog_off)
fog_distance = 10000*BS;
services->setPixelShaderConstant("fogDistance", &fog_distance, 1);
- }
-private:
- IrrlichtDevice *m_device;
+ // Day-night ratio
+ u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
+ float daynight_ratio_f = (float)daynight_ratio / 1000.0;
+ services->setPixelShaderConstant("dayNightRatio", &daynight_ratio_f, 1);
+ }
};
void the_game(
@@ -1307,8 +1311,8 @@ void the_game(
/*
Shader constants
*/
- shsrc->addGlobalConstantSetter(
- new GameGlobalShaderConstantSetter(sky, &force_fog_off, &fog_range));
+ shsrc->addGlobalConstantSetter(new GameGlobalShaderConstantSetter(
+ sky, &force_fog_off, &fog_range, &client));
/*
Main loop
diff --git a/src/itemdef.cpp b/src/itemdef.cpp
index 9ce064ea4..260baadc0 100644
--- a/src/itemdef.cpp
+++ b/src/itemdef.cpp
@@ -30,6 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tile.h"
#endif
#include "log.h"
+#include "main.h" // g_settings
+#include "settings.h"
#include "util/serialize.h"
#include "util/container.h"
#include "util/thread.h"
@@ -356,7 +358,10 @@ public:
scene::IMesh *node_mesh = mapblock_mesh.getMesh();
assert(node_mesh);
- setMeshColor(node_mesh, video::SColor(255, 255, 255, 255));
+ video::SColor c(255, 255, 255, 255);
+ if(g_settings->getS32("enable_shaders") != 0)
+ c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source));
+ setMeshColor(node_mesh, c);
/*
Scale and translate the mesh so it's a unit cube
diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp
index a9f14f8f0..b2870509b 100644
--- a/src/mapblock_mesh.cpp
+++ b/src/mapblock_mesh.cpp
@@ -435,7 +435,7 @@ struct FastFace
};
static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
- v3f p, v3s16 dir, v3f scale, core::array<FastFace> &dest)
+ v3f p, v3s16 dir, v3f scale, u8 light_source, core::array<FastFace> &dest)
{
FastFace face;
@@ -477,16 +477,16 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
float h = tile.texture.size.Y;
face.vertices[0] = video::S3DVertex(vertex_pos[0], normal,
- MapBlock_LightColor(alpha, li0),
+ MapBlock_LightColor(alpha, li0, light_source),
core::vector2d<f32>(x0+w*abs_scale, y0+h));
face.vertices[1] = video::S3DVertex(vertex_pos[1], normal,
- MapBlock_LightColor(alpha, li1),
+ MapBlock_LightColor(alpha, li1, light_source),
core::vector2d<f32>(x0, y0+h));
face.vertices[2] = video::S3DVertex(vertex_pos[2], normal,
- MapBlock_LightColor(alpha, li2),
+ MapBlock_LightColor(alpha, li2, light_source),
core::vector2d<f32>(x0, y0));
face.vertices[3] = video::S3DVertex(vertex_pos[3], normal,
- MapBlock_LightColor(alpha, li3),
+ MapBlock_LightColor(alpha, li3, light_source),
core::vector2d<f32>(x0+w*abs_scale, y0));
face.tile = tile;
@@ -658,7 +658,8 @@ static void getTileInfo(
v3s16 &p_corrected,
v3s16 &face_dir_corrected,
u16 *lights,
- TileSpec &tile
+ TileSpec &tile,
+ u8 &light_source
)
{
VoxelManipulator &vmanip = data->m_vmanip;
@@ -688,18 +689,20 @@ static void getTileInfo(
tile = tile0;
p_corrected = p;
face_dir_corrected = face_dir;
+ light_source = ndef->get(n0).light_source;
}
else
{
tile = tile1;
p_corrected = p + face_dir;
face_dir_corrected = -face_dir;
+ light_source = ndef->get(n1).light_source;
}
// eg. water and glass
if(equivalent)
tile.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
-
+
if(data->m_smooth_lighting == false)
{
lights[0] = lights[1] = lights[2] = lights[3] =
@@ -743,9 +746,10 @@ static void updateFastFaceRow(
v3s16 face_dir_corrected;
u16 lights[4] = {0,0,0,0};
TileSpec tile;
+ u8 light_source = 0;
getTileInfo(data, p, face_dir,
makes_face, p_corrected, face_dir_corrected,
- lights, tile);
+ lights, tile, light_source);
for(u16 j=0; j<MAP_BLOCKSIZE; j++)
{
@@ -759,6 +763,7 @@ static void updateFastFaceRow(
v3s16 next_face_dir_corrected;
u16 next_lights[4] = {0,0,0,0};
TileSpec next_tile;
+ u8 next_light_source = 0;
// If at last position, there is nothing to compare to and
// the face must be drawn anyway
@@ -769,7 +774,7 @@ static void updateFastFaceRow(
getTileInfo(data, p_next, face_dir,
next_makes_face, next_p_corrected,
next_face_dir_corrected, next_lights,
- next_tile);
+ next_tile, next_light_source);
if(next_makes_face == makes_face
&& next_p_corrected == p_corrected + translate_dir
@@ -778,7 +783,8 @@ static void updateFastFaceRow(
&& next_lights[1] == lights[1]
&& next_lights[2] == lights[2]
&& next_lights[3] == lights[3]
- && next_tile == tile)
+ && next_tile == tile
+ && next_light_source == light_source)
{
next_is_different = false;
}
@@ -854,7 +860,7 @@ static void updateFastFaceRow(
}
makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
- sp, face_dir_corrected, scale,
+ sp, face_dir_corrected, scale, light_source,
dest);
g_profiler->avg("Meshgen: faces drawn by tiling", 0);
@@ -873,6 +879,7 @@ static void updateFastFaceRow(
lights[2] = next_lights[2];
lights[3] = next_lights[3];
tile = next_tile;
+ light_source = next_light_source;
}
p = p_next;
@@ -1058,18 +1065,20 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
os<<"^[verticalframe:"<<(int)p.tile.animation_frame_count<<":0";
p.tile.texture = tsrc->getTexture(os.str());
}
- // - Lighting
- for(u32 j = 0; j < p.vertices.size(); j++)
+ // - Classic lighting (shaders handle this by themselves)
+ if(!enable_shaders)
{
- video::SColor &vc = p.vertices[j].Color;
- u8 day = vc.getRed();
- u8 night = vc.getGreen();
- finalColorBlend(vc, day, night, 1000);
- if(day != night)
- m_daynight_diffs[i][j] = std::make_pair(day, night);
+ for(u32 j = 0; j < p.vertices.size(); j++)
+ {
+ video::SColor &vc = p.vertices[j].Color;
+ u8 day = vc.getRed();
+ u8 night = vc.getGreen();
+ finalColorBlend(vc, day, night, 1000);
+ if(day != night)
+ m_daynight_diffs[i][j] = std::make_pair(day, night);
+ }
}
-
// Create material
video::SMaterial material;
material.setFlag(video::EMF_LIGHTING, false);
diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h
index 82268efd2..c23b6cc5a 100644
--- a/src/mapblock_mesh.h
+++ b/src/mapblock_mesh.h
@@ -160,9 +160,10 @@ struct MeshCollector
// alpha in the A channel of the returned SColor
// day light (0-255) in the R channel of the returned SColor
// night light (0-255) in the G channel of the returned SColor
-inline video::SColor MapBlock_LightColor(u8 alpha, u16 light)
+// light source (0-255) in the B channel of the returned SColor
+inline video::SColor MapBlock_LightColor(u8 alpha, u16 light, u8 light_source=0)
{
- return video::SColor(alpha, (light & 0xff), (light >> 8), 0);
+ return video::SColor(alpha, (light & 0xff), (light >> 8), light_source);
}
// Compute light at node