Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Basic model shading (#9374)
  • Loading branch information
FunkyDck committed Feb 16, 2020
1 parent 478e753 commit 6958071
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 41 deletions.
131 changes: 131 additions & 0 deletions client/shaders/object_shader/opengl_fragment.glsl
@@ -0,0 +1,131 @@
uniform sampler2D baseTexture;
uniform sampler2D normalTexture;
uniform sampler2D textureFlags;

uniform vec4 emissiveColor;
uniform vec4 skyBgColor;
uniform float fogDistance;
uniform vec3 eyePosition;

varying vec3 vNormal;
varying vec3 vPosition;
varying vec3 worldPosition;

varying vec3 eyeVec;
varying vec3 lightVec;
varying float vIDiff;

bool normalTexturePresent = false;
bool texTileableHorizontal = false;
bool texTileableVertical = false;
bool texSeamless = false;

const float e = 2.718281828459;
const float BS = 10.0;
const float fogStart = FOG_START;
const float fogShadingParameter = 1 / ( 1 - fogStart);

void get_texture_flags()
{
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
if (flags.r > 0.5) {
normalTexturePresent = true;
}
if (flags.g > 0.5) {
texTileableHorizontal = true;
}
if (flags.b > 0.5) {
texTileableVertical = true;
}
if (texTileableHorizontal && texTileableVertical) {
texSeamless = true;
}
}

float intensity(vec3 color)
{
return (color.r + color.g + color.b) / 3.0;
}

float get_rgb_height(vec2 uv)
{
if (texSeamless) {
return intensity(texture2D(baseTexture, uv).rgb);
} else {
return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
}
}

vec4 get_normal_map(vec2 uv)
{
vec4 bump = texture2D(normalTexture, uv).rgba;
bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
return bump;
}

void main(void)
{
vec3 color;
vec4 bump;
vec2 uv = gl_TexCoord[0].st;
bool use_normalmap = false;
get_texture_flags();

#if USE_NORMALMAPS == 1
if (normalTexturePresent) {
bump = get_normal_map(uv);
use_normalmap = true;
}
#endif

#if GENERATE_NORMALMAPS == 1
if (normalTexturePresent == false) {
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
use_normalmap = true;
}
#endif

vec4 base = texture2D(baseTexture, uv).rgba;

#ifdef ENABLE_BUMPMAPPING
if (use_normalmap) {
vec3 L = normalize(lightVec);
vec3 E = normalize(eyeVec);
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
float diffuse = dot(-E,bump.xyz);
color = (diffuse + 0.1 * specular) * base.rgb;
} else {
color = base.rgb;
}
#else
color = base.rgb;
#endif

vec4 col = vec4(color.rgb, base.a);

col.rgb *= emissiveColor.rgb * vIDiff;
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
// E.g. the following won't work:
// float clarity = clamp(fogShadingParameter
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
// As additions usually come for free following a multiplication, the new formula
// should be more efficient as well.
// Note: clarity = (1 - fogginess)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);

gl_FragColor = vec4(col.rgb, base.a);
}
44 changes: 44 additions & 0 deletions client/shaders/object_shader/opengl_vertex.glsl
@@ -0,0 +1,44 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;

uniform vec3 eyePosition;
uniform float animationTimer;

varying vec3 vNormal;
varying vec3 vPosition;
varying vec3 worldPosition;

varying vec3 eyeVec;
varying vec3 lightVec;
varying float vIDiff;

const float e = 2.718281828459;
const float BS = 10.0;

float directional_ambient(vec3 normal)
{
vec3 v = normal * normal;

if (normal.y < 0)
return dot(v, vec3(0.670820f, 0.447213f, 0.836660f));

return dot(v, vec3(0.670820f, 1.000000f, 0.836660f));
}

void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = mWorldViewProj * gl_Vertex;

vPosition = gl_Position.xyz;
vNormal = gl_Normal;
worldPosition = (mWorld * gl_Vertex).xyz;

vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);

lightVec = sunPosition - worldPosition;
eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
vIDiff = directional_ambient(normalize(gl_Normal));

gl_FrontColor = gl_BackColor = gl_Color;
}
2 changes: 1 addition & 1 deletion src/client/client.cpp
Expand Up @@ -1860,7 +1860,7 @@ ITextureSource* Client::getTextureSource()
{
return m_tsrc;
}
IShaderSource* Client::getShaderSource()
IWritableShaderSource* Client::getShaderSource()
{
return m_shsrc;
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/client.h
Expand Up @@ -367,7 +367,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
const NodeDefManager* getNodeDefManager() override;
ICraftDefManager* getCraftDefManager() override;
ITextureSource* getTextureSource();
virtual IShaderSource* getShaderSource();
virtual IWritableShaderSource* getShaderSource();
u16 allocateUnknownNodeId(const std::string &name) override;
virtual ISoundManager* getSoundManager();
MtEventManager* getEventManager();
Expand Down
57 changes: 57 additions & 0 deletions src/client/clientenvironment.cpp
Expand Up @@ -32,10 +32,65 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "raycast.h"
#include "voxelalgorithms.h"
#include "settings.h"
#include "shader.h"
#include "content_cao.h"
#include <algorithm>
#include "client/renderingengine.h"

/*
CAOShaderConstantSetter
*/

//! Shader constant setter for passing material emissive color to the CAO object_shader
class CAOShaderConstantSetter : public IShaderConstantSetter
{
public:
CAOShaderConstantSetter():
m_emissive_color_setting("emissiveColor")
{}

~CAOShaderConstantSetter() override = default;

void onSetConstants(video::IMaterialRendererServices *services,
bool is_highlevel) override
{
if (!is_highlevel)
return;

// Ambient color
video::SColorf emissive_color(m_emissive_color);

float as_array[4] = {
emissive_color.r,
emissive_color.g,
emissive_color.b,
emissive_color.a,
};
m_emissive_color_setting.set(as_array, services);
}

void onSetMaterial(const video::SMaterial& material) override
{
m_emissive_color = material.EmissiveColor;
}

private:
video::SColor m_emissive_color;
CachedPixelShaderSetting<float, 4> m_emissive_color_setting;
};

class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory
{
public:
CAOShaderConstantSetterFactory()
{}

virtual IShaderConstantSetter* create()
{
return new CAOShaderConstantSetter();
}
};

/*
ClientEnvironment
*/
Expand All @@ -47,6 +102,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map,
m_texturesource(texturesource),
m_client(client)
{
auto *shdrsrc = m_client->getShaderSource();
shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory());
}

ClientEnvironment::~ClientEnvironment()
Expand Down

0 comments on commit 6958071

Please sign in to comment.