Skip to content

Commit 6035069

Browse files
committedJul 21, 2015
Add wielded (and CAOs) shader
1 parent 5b0c719 commit 6035069

File tree

11 files changed

+224
-40
lines changed

11 files changed

+224
-40
lines changed
 

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

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
uniform sampler2D baseTexture;
2+
uniform sampler2D normalTexture;
3+
uniform sampler2D textureFlags;
4+
5+
uniform vec4 skyBgColor;
6+
uniform float fogDistance;
7+
uniform vec3 eyePosition;
8+
9+
varying vec3 vPosition;
10+
varying vec3 worldPosition;
11+
12+
varying vec3 eyeVec;
13+
varying vec3 lightVec;
14+
15+
bool normalTexturePresent = false;
16+
bool texTileableHorizontal = false;
17+
bool texTileableVertical = false;
18+
bool texSeamless = false;
19+
20+
const float e = 2.718281828459;
21+
const float BS = 10.0;
22+
23+
void get_texture_flags()
24+
{
25+
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
26+
if (flags.r > 0.5) {
27+
normalTexturePresent = true;
28+
}
29+
if (flags.g > 0.5) {
30+
texTileableHorizontal = true;
31+
}
32+
if (flags.b > 0.5) {
33+
texTileableVertical = true;
34+
}
35+
if (texTileableHorizontal && texTileableVertical) {
36+
texSeamless = true;
37+
}
38+
}
39+
40+
float intensity(vec3 color)
41+
{
42+
return (color.r + color.g + color.b) / 3.0;
43+
}
44+
45+
float get_rgb_height(vec2 uv)
46+
{
47+
if (texSeamless) {
48+
return intensity(texture2D(baseTexture, uv).rgb);
49+
} else {
50+
return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
51+
}
52+
}
53+
54+
vec4 get_normal_map(vec2 uv)
55+
{
56+
vec4 bump = texture2D(normalTexture, uv).rgba;
57+
bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
58+
return bump;
59+
}
60+
61+
void main(void)
62+
{
63+
vec3 color;
64+
vec4 bump;
65+
vec2 uv = gl_TexCoord[0].st;
66+
bool use_normalmap = false;
67+
get_texture_flags();
68+
69+
#if USE_NORMALMAPS == 1
70+
if (normalTexturePresent) {
71+
bump = get_normal_map(uv);
72+
use_normalmap = true;
73+
}
74+
#endif
75+
76+
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
77+
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
78+
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
79+
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
80+
float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
81+
float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
82+
float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
83+
float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
84+
float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
85+
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
86+
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
87+
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
88+
use_normalmap = true;
89+
}
90+
91+
vec4 base = texture2D(baseTexture, uv).rgba;
92+
93+
#ifdef ENABLE_BUMPMAPPING
94+
if (use_normalmap) {
95+
vec3 L = normalize(lightVec);
96+
vec3 E = normalize(eyeVec);
97+
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
98+
float diffuse = dot(-E,bump.xyz);
99+
color = (diffuse + 0.1 * specular) * base.rgb;
100+
} else {
101+
color = base.rgb;
102+
}
103+
#else
104+
color = base.rgb;
105+
#endif
106+
107+
vec4 col = vec4(color.rgb, base.a);
108+
col *= gl_Color;
109+
if (fogDistance != 0.0) {
110+
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
111+
col = mix(col, skyBgColor, d);
112+
}
113+
gl_FragColor = vec4(col.rgb, base.a);
114+
}

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

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
uniform mat4 mWorldViewProj;
2+
uniform mat4 mInvWorld;
3+
uniform mat4 mTransWorld;
4+
uniform mat4 mWorld;
5+
6+
uniform float dayNightRatio;
7+
uniform vec3 eyePosition;
8+
uniform float animationTimer;
9+
10+
varying vec3 vPosition;
11+
varying vec3 worldPosition;
12+
13+
varying vec3 eyeVec;
14+
varying vec3 lightVec;
15+
varying vec3 tsEyeVec;
16+
varying vec3 tsLightVec;
17+
18+
const float e = 2.718281828459;
19+
const float BS = 10.0;
20+
21+
void main(void)
22+
{
23+
gl_TexCoord[0] = gl_MultiTexCoord0;
24+
gl_Position = mWorldViewProj * gl_Vertex;
25+
26+
vPosition = gl_Position.xyz;
27+
worldPosition = (mWorld * gl_Vertex).xyz;
28+
29+
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
30+
31+
lightVec = sunPosition - worldPosition;
32+
eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
33+
34+
gl_FrontColor = gl_BackColor = gl_Color;
35+
}

Diff for: ‎src/camera.cpp

+2-7
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,9 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
9292
// all other 3D scene nodes and before the GUI.
9393
m_wieldmgr = smgr->createNewSceneManager();
9494
m_wieldmgr->addCameraSceneNode();
95-
m_wieldnode = new WieldMeshSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr, -1, true);
95+
m_wieldnode = new WieldMeshSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr, -1, false);
9696
m_wieldnode->setItem(ItemStack(), m_gamedef);
9797
m_wieldnode->drop(); // m_wieldmgr grabbed it
98-
m_wieldlightnode = m_wieldmgr->addLightSceneNode(NULL, v3f(0.0, 50.0, 0.0));
9998

10099
/* TODO: Add a callback function so these can be updated when a setting
101100
* changes. At this point in time it doesn't matter (e.g. /set
@@ -451,11 +450,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
451450
m_wieldnode->setPosition(wield_position);
452451
m_wieldnode->setRotation(wield_rotation);
453452

454-
// Shine light upon the wield mesh
455-
video::SColor black(255,0,0,0);
456-
m_wieldmgr->setAmbientLight(player->light_color.getInterpolated(black, 0.7));
457-
m_wieldlightnode->getLightData().DiffuseColor = player->light_color.getInterpolated(black, 0.3);
458-
m_wieldlightnode->setPosition(v3f(30+5*sin(2*player->getYaw()*M_PI/180), -50, 0));
453+
m_wieldnode->setColor(player->light_color);
459454

460455
// Render distance feedback loop
461456
updateViewingRange(frametime, busytime);

Diff for: ‎src/camera.h

-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ class Camera
159159

160160
scene::ISceneManager* m_wieldmgr;
161161
WieldMeshSceneNode* m_wieldnode;
162-
scene::ILightSceneNode* m_wieldlightnode;
163162

164163
// draw control
165164
MapDrawControl& m_draw_control;

Diff for: ‎src/client/tile.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ class TextureSource : public IWritableTextureSource
385385

386386
video::ITexture* getNormalTexture(const std::string &name);
387387
video::SColor getTextureAverageColor(const std::string &name);
388-
video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile);
388+
video::ITexture *getShaderFlagsTexture(
389+
bool normamap_present, bool tileable_vertical, bool tileable_horizontal);
389390

390391
private:
391392

@@ -2050,14 +2051,14 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
20502051
return c;
20512052
}
20522053

2053-
video::ITexture *TextureSource::getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)
2054+
2055+
video::ITexture *TextureSource::getShaderFlagsTexture(
2056+
bool normalmap_present, bool tileable_vertical, bool tileable_horizontal)
20542057
{
20552058
std::string tname = "__shaderFlagsTexture";
2056-
2057-
bool normalmap_present = tile->normal_texture ? true : false;
20582059
tname += normalmap_present ? "1" : "0";
2059-
tname += tiledef->tileable_horizontal ? "1" : "0";
2060-
tname += tiledef->tileable_vertical ? "1" : "0";
2060+
tname += tileable_horizontal ? "1" : "0";
2061+
tname += tileable_vertical ? "1" : "0";
20612062

20622063
if (isKnownSourceImage(tname)) {
20632064
return getTexture(tname);
@@ -2069,8 +2070,8 @@ video::ITexture *TextureSource::getShaderFlagsTexture(TileDef *tiledef, TileSpec
20692070
video::SColor c(
20702071
255,
20712072
normalmap_present ? 255 : 0,
2072-
tiledef->tileable_horizontal ? 255 : 0,
2073-
tiledef->tileable_vertical ? 255 : 0);
2073+
tileable_horizontal ? 255 : 0,
2074+
tileable_vertical ? 255 : 0);
20742075
flags_image->setPixel(0, 0, c);
20752076
insertSourceImage(tname, flags_image);
20762077
flags_image->drop();

Diff for: ‎src/client/tile.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ class ITextureSource : public ISimpleTextureSource
113113
const TextureFromMeshParams &params)=0;
114114
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
115115
virtual video::SColor getTextureAverageColor(const std::string &name)=0;
116-
virtual video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)=0;
116+
virtual video::ITexture *getShaderFlagsTexture(bool normamap_present,
117+
bool tileable_vertical, bool tileable_horizontal)=0;
117118
};
118119

119120
class IWritableTextureSource : public ITextureSource
@@ -136,7 +137,8 @@ class IWritableTextureSource : public ITextureSource
136137
virtual void rebuildImagesAndTextures()=0;
137138
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
138139
virtual video::SColor getTextureAverageColor(const std::string &name)=0;
139-
virtual video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)=0;
140+
virtual video::ITexture *getShaderFlagsTexture(bool normamap_present,
141+
bool tileable_vertical, bool tileable_horizontal)=0;
140142
};
141143

142144
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);

Diff for: ‎src/mesh.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3333
#define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
3434
#endif
3535

36+
static void applyFacesShading(video::SColor& color, float factor)
37+
{
38+
color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255));
39+
color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255));
40+
color.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255));
41+
}
42+
3643
scene::IAnimatedMesh* createCubeMesh(v3f scale)
3744
{
3845
video::SColor c(255,255,255,255);
@@ -165,6 +172,35 @@ void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
165172
}
166173
}
167174

175+
void shadeMeshFaces(scene::IMesh *mesh)
176+
{
177+
if (mesh == NULL)
178+
return;
179+
180+
u32 mc = mesh->getMeshBufferCount();
181+
for (u32 j = 0; j < mc; j++) {
182+
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
183+
const u32 stride = getVertexPitchFromType(buf->getVertexType());
184+
u32 vertex_count = buf->getVertexCount();
185+
u8 *vertices = (u8 *)buf->getVertices();
186+
for (u32 i = 0; i < vertex_count; i++) {
187+
video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride);
188+
video::SColor &vc = vertex->Color;
189+
if (vertex->Normal.Y < -0.5) {
190+
applyFacesShading (vc, 0.447213);
191+
} else if (vertex->Normal.Z > 0.5) {
192+
applyFacesShading (vc, 0.670820);
193+
} else if (vertex->Normal.Z < -0.5) {
194+
applyFacesShading (vc, 0.670820);
195+
} else if (vertex->Normal.X > 0.5) {
196+
applyFacesShading (vc, 0.836660);
197+
} else if (vertex->Normal.X < -0.5) {
198+
applyFacesShading (vc, 0.836660);
199+
}
200+
}
201+
}
202+
}
203+
168204
void setMeshColorByNormalXYZ(scene::IMesh *mesh,
169205
const video::SColor &colorX,
170206
const video::SColor &colorY,

Diff for: ‎src/mesh.h

+6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ void translateMesh(scene::IMesh *mesh, v3f vec);
4848
*/
4949
void setMeshColor(scene::IMesh *mesh, const video::SColor &color);
5050

51+
/*
52+
Shade mesh faces according to their normals
53+
*/
54+
55+
void shadeMeshFaces(scene::IMesh *mesh);
56+
5157
/*
5258
Set the color of all vertices in the mesh.
5359
For each vertex, determine the largest absolute entry in

Diff for: ‎src/nodedef.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,9 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
10121012
if (use_normal_texture) {
10131013
tile->normal_texture = tsrc->getNormalTexture(tiledef->name);
10141014
}
1015-
tile->flags_texture = tsrc->getShaderFlagsTexture(tiledef, tile);
1015+
tile->flags_texture = tsrc->getShaderFlagsTexture(
1016+
tile->normal_texture ? true : false,
1017+
tiledef->tileable_horizontal, tiledef->tileable_vertical);
10161018

10171019
// Material flags
10181020
tile->material_flags = 0;

Diff for: ‎src/wieldmesh.cpp

+12-21
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3434
#define WIELD_SCALE_FACTOR 30.0
3535
#define WIELD_SCALE_FACTOR_EXTRUDED 40.0
3636

37-
#define MIN_EXTRUSION_MESH_RESOLUTION 32 // not 16: causes too many "holes"
37+
#define MIN_EXTRUSION_MESH_RESOLUTION 16
3838
#define MAX_EXTRUSION_MESH_RESOLUTION 512
3939

4040
static scene::IMesh* createExtrusionMesh(int resolution_x, int resolution_y)
@@ -114,6 +114,7 @@ static scene::IMesh* createExtrusionMesh(int resolution_x, int resolution_y)
114114
mesh->addMeshBuffer(buf);
115115
buf->drop();
116116
scaleMesh(mesh, scale); // also recalculates bounding box
117+
mesh = (scene::SMesh *)createForsythOptimizedMesh(mesh);
117118
return mesh;
118119
}
119120

@@ -281,7 +282,9 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
281282

282283
// Customize material
283284
video::SMaterial &material = m_meshnode->getMaterial(0);
284-
material.setTexture(0, tsrc->getTextureForMesh(imagename));
285+
material.setTexture(0, tsrc->getTexture(imagename));
286+
material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
287+
material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
285288
material.MaterialType = m_material_type;
286289
material.setFlag(video::EMF_BACK_FACE_CULLING, true);
287290
// Enable bi/trilinear filtering only for high resolution textures
@@ -297,31 +300,25 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
297300
#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
298301
material.setFlag(video::EMF_USE_MIP_MAPS, false);
299302
#endif
300-
301-
#if 0
302-
//// TODO(RealBadAngel): Reactivate when shader is added for wield items
303-
if (m_enable_shaders)
304-
material.setTexture(2, tsrc->getTexture("disable_img.png"));
305-
#endif
303+
if (m_enable_shaders) {
304+
material.setTexture(2, tsrc->getShaderFlagsTexture(false, true, true));
305+
}
306306
}
307307

308308
void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef)
309309
{
310310
ITextureSource *tsrc = gamedef->getTextureSource();
311311
IItemDefManager *idef = gamedef->getItemDefManager();
312-
//IShaderSource *shdrsrc = gamedef->getShaderSource();
312+
IShaderSource *shdrsrc = gamedef->getShaderSource();
313313
INodeDefManager *ndef = gamedef->getNodeDefManager();
314314
const ItemDefinition &def = item.getDefinition(idef);
315315
const ContentFeatures &f = ndef->get(def.name);
316316
content_t id = ndef->getId(def.name);
317317

318-
#if 0
319-
//// TODO(RealBadAngel): Reactivate when shader is added for wield items
320318
if (m_enable_shaders) {
321-
u32 shader_id = shdrsrc->getShader("nodes_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
319+
u32 shader_id = shdrsrc->getShader("wielded_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
322320
m_material_type = shdrsrc->getShaderInfo(shader_id).material;
323321
}
324-
#endif
325322

326323
// If wield_image is defined, it overrides everything else
327324
if (def.wield_image != "") {
@@ -345,8 +342,6 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef)
345342
} else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) {
346343
setCube(f.tiles, def.wield_scale, tsrc);
347344
} else {
348-
//// TODO: Change false in the following constructor args to
349-
//// appropriate value when shader is added for wield items (if applicable)
350345
MeshMakeData mesh_make_data(gamedef, false);
351346
MapNode mesh_make_node(id, 255, 0);
352347
mesh_make_data.fillSingleNode(&mesh_make_node);
@@ -376,8 +371,6 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef)
376371
material.setTexture(0, f.tiles[i].texture);
377372
}
378373
material.MaterialType = m_material_type;
379-
#if 0
380-
//// TODO(RealBadAngel): Reactivate when shader is added for wield items
381374
if (m_enable_shaders) {
382375
if (f.tiles[i].normal_texture) {
383376
if (animated) {
@@ -386,12 +379,9 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef)
386379
} else {
387380
material.setTexture(1, f.tiles[i].normal_texture);
388381
}
389-
material.setTexture(2, tsrc->getTexture("enable_img.png"));
390-
} else {
391-
material.setTexture(2, tsrc->getTexture("disable_img.png"));
392382
}
383+
material.setTexture(2, f.tiles[i].flags_texture);
393384
}
394-
#endif
395385
}
396386
return;
397387
}
@@ -408,6 +398,7 @@ void WieldMeshSceneNode::setColor(video::SColor color)
408398
{
409399
assert(!m_lighting);
410400
setMeshColor(m_meshnode->getMesh(), color);
401+
shadeMeshFaces(m_meshnode->getMesh());
411402
}
412403

413404
void WieldMeshSceneNode::render()

Diff for: ‎src/wieldmesh.h

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ class WieldMeshSceneNode: public scene::ISceneNode
4848
// Must only be used if the constructor was called with lighting = false
4949
void setColor(video::SColor color);
5050

51+
scene::IMesh *getMesh()
52+
{ return m_meshnode->getMesh(); }
53+
5154
virtual void render();
5255

5356
virtual const core::aabbox3d<f32>& getBoundingBox() const

0 commit comments

Comments
 (0)
Please sign in to comment.