From 5fde69798c69b26b8f1cc5c3ed5b823d691599fd Mon Sep 17 00:00:00 2001 From: lhofhansl Date: Thu, 26 Sep 2019 13:57:39 -0700 Subject: [PATCH] Simple shader fixes. (#8991) 1. Pass current camera offset to shader, so shader have access to the global coordinates 2. Pass animation timer to fragment shader. C++ code is already there, just wasn't declared in the shader 3. Delay animation timer wrap-around (from 100s to about 16 minutes) --- .../shaders/nodes_shader/opengl_fragment.glsl | 9 +++++++++ client/shaders/nodes_shader/opengl_vertex.glsl | 8 ++++++++ src/client/game.cpp | 18 +++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 7c5b9b613..19e6c2d86 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -6,7 +6,16 @@ uniform vec4 skyBgColor; uniform float fogDistance; uniform vec3 eyePosition; +// The cameraOffset is the current center of the visible world. +uniform vec3 cameraOffset; +uniform float animationTimer; + varying vec3 vPosition; +// World position in the visible world (i.e. relative to the cameraOffset.) +// This can be used for many shader effects without loss of precision. +// If the absolute position is required it can be calculated with +// cameraOffset + worldPosition (for large coordinates the limits of float +// precision must be considered). varying vec3 worldPosition; varying float area_enable_parallax; diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl index f1e63d5d9..bbf7b1d65 100644 --- a/client/shaders/nodes_shader/opengl_vertex.glsl +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -4,9 +4,17 @@ uniform mat4 mWorld; // Color of the light emitted by the sun. uniform vec3 dayLight; uniform vec3 eyePosition; + +// The cameraOffset is the current center of the visible world. +uniform vec3 cameraOffset; uniform float animationTimer; varying vec3 vPosition; +// World position in the visible world (i.e. relative to the cameraOffset.) +// This can be used for many shader effects without loss of precision. +// If the absolute position is required it can be calculated with +// cameraOffset + worldPosition (for large coordinates the limits of float +// precision must be considered). varying vec3 worldPosition; varying vec3 eyeVec; diff --git a/src/client/game.cpp b/src/client/game.cpp index 722e6d0ad..fb2a81973 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -413,6 +413,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_eye_position_pixel; CachedVertexShaderSetting m_eye_position_vertex; CachedPixelShaderSetting m_minimap_yaw; + CachedPixelShaderSetting m_camera_offset_pixel; + CachedPixelShaderSetting m_camera_offset_vertex; CachedPixelShaderSetting m_base_texture; CachedPixelShaderSetting m_normal_texture; CachedPixelShaderSetting m_texture_flags; @@ -445,6 +447,8 @@ public: m_eye_position_pixel("eyePosition"), m_eye_position_vertex("eyePosition"), m_minimap_yaw("yawVec"), + m_camera_offset_pixel("cameraOffset"), + m_camera_offset_vertex("cameraOffset"), m_base_texture("baseTexture"), m_normal_texture("normalTexture"), m_texture_flags("textureFlags"), @@ -493,7 +497,7 @@ public: sunlight.b }; m_day_light.set(dnc, services); - u32 animation_timer = porting::getTimeMs() % 100000; + u32 animation_timer = porting::getTimeMs() % 1000000; float animation_timer_f = (float)animation_timer / 100000.f; m_animation_timer_vertex.set(&animation_timer_f, services); m_animation_timer_pixel.set(&animation_timer_f, services); @@ -523,6 +527,18 @@ public: m_minimap_yaw.set(minimap_yaw_array, services); } + float camera_offset_array[3]; + v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS); +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) + camera_offset_array[0] = offset.X; + camera_offset_array[1] = offset.Y; + camera_offset_array[2] = offset.Z; +#else + offset.getAs3Values(camera_offset_array); +#endif + m_camera_offset_pixel.set(camera_offset_array, services); + m_camera_offset_vertex.set(camera_offset_array, services); + SamplerLayer_t base_tex = 0, normal_tex = 1, flags_tex = 2;