Skip to content

Commit 6958071

Browse files
authoredFeb 16, 2020
Basic model shading (#9374)
1 parent 478e753 commit 6958071

File tree

9 files changed

+338
-41
lines changed

9 files changed

+338
-41
lines changed
 

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

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
uniform sampler2D baseTexture;
2+
uniform sampler2D normalTexture;
3+
uniform sampler2D textureFlags;
4+
5+
uniform vec4 emissiveColor;
6+
uniform vec4 skyBgColor;
7+
uniform float fogDistance;
8+
uniform vec3 eyePosition;
9+
10+
varying vec3 vNormal;
11+
varying vec3 vPosition;
12+
varying vec3 worldPosition;
13+
14+
varying vec3 eyeVec;
15+
varying vec3 lightVec;
16+
varying float vIDiff;
17+
18+
bool normalTexturePresent = false;
19+
bool texTileableHorizontal = false;
20+
bool texTileableVertical = false;
21+
bool texSeamless = false;
22+
23+
const float e = 2.718281828459;
24+
const float BS = 10.0;
25+
const float fogStart = FOG_START;
26+
const float fogShadingParameter = 1 / ( 1 - fogStart);
27+
28+
void get_texture_flags()
29+
{
30+
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
31+
if (flags.r > 0.5) {
32+
normalTexturePresent = true;
33+
}
34+
if (flags.g > 0.5) {
35+
texTileableHorizontal = true;
36+
}
37+
if (flags.b > 0.5) {
38+
texTileableVertical = true;
39+
}
40+
if (texTileableHorizontal && texTileableVertical) {
41+
texSeamless = true;
42+
}
43+
}
44+
45+
float intensity(vec3 color)
46+
{
47+
return (color.r + color.g + color.b) / 3.0;
48+
}
49+
50+
float get_rgb_height(vec2 uv)
51+
{
52+
if (texSeamless) {
53+
return intensity(texture2D(baseTexture, uv).rgb);
54+
} else {
55+
return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
56+
}
57+
}
58+
59+
vec4 get_normal_map(vec2 uv)
60+
{
61+
vec4 bump = texture2D(normalTexture, uv).rgba;
62+
bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
63+
return bump;
64+
}
65+
66+
void main(void)
67+
{
68+
vec3 color;
69+
vec4 bump;
70+
vec2 uv = gl_TexCoord[0].st;
71+
bool use_normalmap = false;
72+
get_texture_flags();
73+
74+
#if USE_NORMALMAPS == 1
75+
if (normalTexturePresent) {
76+
bump = get_normal_map(uv);
77+
use_normalmap = true;
78+
}
79+
#endif
80+
81+
#if GENERATE_NORMALMAPS == 1
82+
if (normalTexturePresent == false) {
83+
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
84+
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
85+
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
86+
float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
87+
float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
88+
float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
89+
float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
90+
float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
91+
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
92+
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
93+
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
94+
use_normalmap = true;
95+
}
96+
#endif
97+
98+
vec4 base = texture2D(baseTexture, uv).rgba;
99+
100+
#ifdef ENABLE_BUMPMAPPING
101+
if (use_normalmap) {
102+
vec3 L = normalize(lightVec);
103+
vec3 E = normalize(eyeVec);
104+
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
105+
float diffuse = dot(-E,bump.xyz);
106+
color = (diffuse + 0.1 * specular) * base.rgb;
107+
} else {
108+
color = base.rgb;
109+
}
110+
#else
111+
color = base.rgb;
112+
#endif
113+
114+
vec4 col = vec4(color.rgb, base.a);
115+
116+
col.rgb *= emissiveColor.rgb * vIDiff;
117+
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
118+
// the fog will only be rendered correctly if the last operation before the
119+
// clamp() is an addition. Else, the clamp() seems to be ignored.
120+
// E.g. the following won't work:
121+
// float clarity = clamp(fogShadingParameter
122+
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
123+
// As additions usually come for free following a multiplication, the new formula
124+
// should be more efficient as well.
125+
// Note: clarity = (1 - fogginess)
126+
float clarity = clamp(fogShadingParameter
127+
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
128+
col = mix(skyBgColor, col, clarity);
129+
130+
gl_FragColor = vec4(col.rgb, base.a);
131+
}

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

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
uniform mat4 mWorldViewProj;
2+
uniform mat4 mWorld;
3+
4+
uniform vec3 eyePosition;
5+
uniform float animationTimer;
6+
7+
varying vec3 vNormal;
8+
varying vec3 vPosition;
9+
varying vec3 worldPosition;
10+
11+
varying vec3 eyeVec;
12+
varying vec3 lightVec;
13+
varying float vIDiff;
14+
15+
const float e = 2.718281828459;
16+
const float BS = 10.0;
17+
18+
float directional_ambient(vec3 normal)
19+
{
20+
vec3 v = normal * normal;
21+
22+
if (normal.y < 0)
23+
return dot(v, vec3(0.670820f, 0.447213f, 0.836660f));
24+
25+
return dot(v, vec3(0.670820f, 1.000000f, 0.836660f));
26+
}
27+
28+
void main(void)
29+
{
30+
gl_TexCoord[0] = gl_MultiTexCoord0;
31+
gl_Position = mWorldViewProj * gl_Vertex;
32+
33+
vPosition = gl_Position.xyz;
34+
vNormal = gl_Normal;
35+
worldPosition = (mWorld * gl_Vertex).xyz;
36+
37+
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
38+
39+
lightVec = sunPosition - worldPosition;
40+
eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
41+
vIDiff = directional_ambient(normalize(gl_Normal));
42+
43+
gl_FrontColor = gl_BackColor = gl_Color;
44+
}

Diff for: ‎src/client/client.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,7 @@ ITextureSource* Client::getTextureSource()
18601860
{
18611861
return m_tsrc;
18621862
}
1863-
IShaderSource* Client::getShaderSource()
1863+
IWritableShaderSource* Client::getShaderSource()
18641864
{
18651865
return m_shsrc;
18661866
}

Diff for: ‎src/client/client.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
367367
const NodeDefManager* getNodeDefManager() override;
368368
ICraftDefManager* getCraftDefManager() override;
369369
ITextureSource* getTextureSource();
370-
virtual IShaderSource* getShaderSource();
370+
virtual IWritableShaderSource* getShaderSource();
371371
u16 allocateUnknownNodeId(const std::string &name) override;
372372
virtual ISoundManager* getSoundManager();
373373
MtEventManager* getEventManager();

Diff for: ‎src/client/clientenvironment.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,65 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3232
#include "raycast.h"
3333
#include "voxelalgorithms.h"
3434
#include "settings.h"
35+
#include "shader.h"
3536
#include "content_cao.h"
3637
#include <algorithm>
3738
#include "client/renderingengine.h"
3839

40+
/*
41+
CAOShaderConstantSetter
42+
*/
43+
44+
//! Shader constant setter for passing material emissive color to the CAO object_shader
45+
class CAOShaderConstantSetter : public IShaderConstantSetter
46+
{
47+
public:
48+
CAOShaderConstantSetter():
49+
m_emissive_color_setting("emissiveColor")
50+
{}
51+
52+
~CAOShaderConstantSetter() override = default;
53+
54+
void onSetConstants(video::IMaterialRendererServices *services,
55+
bool is_highlevel) override
56+
{
57+
if (!is_highlevel)
58+
return;
59+
60+
// Ambient color
61+
video::SColorf emissive_color(m_emissive_color);
62+
63+
float as_array[4] = {
64+
emissive_color.r,
65+
emissive_color.g,
66+
emissive_color.b,
67+
emissive_color.a,
68+
};
69+
m_emissive_color_setting.set(as_array, services);
70+
}
71+
72+
void onSetMaterial(const video::SMaterial& material) override
73+
{
74+
m_emissive_color = material.EmissiveColor;
75+
}
76+
77+
private:
78+
video::SColor m_emissive_color;
79+
CachedPixelShaderSetting<float, 4> m_emissive_color_setting;
80+
};
81+
82+
class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory
83+
{
84+
public:
85+
CAOShaderConstantSetterFactory()
86+
{}
87+
88+
virtual IShaderConstantSetter* create()
89+
{
90+
return new CAOShaderConstantSetter();
91+
}
92+
};
93+
3994
/*
4095
ClientEnvironment
4196
*/
@@ -47,6 +102,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map,
47102
m_texturesource(texturesource),
48103
m_client(client)
49104
{
105+
auto *shdrsrc = m_client->getShaderSource();
106+
shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory());
50107
}
51108

52109
ClientEnvironment::~ClientEnvironment()

0 commit comments

Comments
 (0)
Please sign in to comment.