aboutsummaryrefslogtreecommitdiff
path: root/client/shaders
Commit message (Collapse)AuthorAge
* Improve shadow filters (#12195)x20482022-05-21
| | | | | | | | | * Rewrite shadow filtering for the new distortion * Calculate penumbra radius using a single sample * Avoid peter-panning effect due to filtering of short shadows * Add adaptive filter quality for soft shadows * Avoid sharp shadows on surfaces without normals (e.g. plants) * Increase default and maximum soft shadow radius * Make line numbers in shader errors match the code
* Implement shadow offsets for the new SM distortion function (#12191)x20482022-04-14
| | | | | | | | * Move shadow position calculation to vertex shaders * Animate entire scene before rendering shadows to prevent lagging of shadows * Remove unnecessary use of PolygonOffsetFactor * Apply normal offset to both nodes and objects * Rename getPerspectiveFactor -> applyPerspectiveDistortion * Remove perspective distortion from fragment shaders
* Spacing fixesShadowNinja2022-04-08
|
* Adjust shadowmap distortion to use entire SM texture (#12166)x20482022-04-07
|
* Tune shadow perspective distortion (#12146)x20482022-03-31
| | | | | * Pass perspective distortion parameters as uniforms * Set all perspective bias parameters via ShadowRenderer * Recalibrate perspective distortion and shadow range to render less shadow geometry with the same quality and observed shadow distance
* Add API to control shadow intensity from the game/mod (#11944)x20482022-03-26
| | | * Also Disable shadows when sun/moon is hidden. Fixes #11972.
* Reuse normal offset calculation for nodesDmitry Kostenko2022-03-07
|
* Correct normal bias for entitiesDmitry Kostenko2022-03-07
| | | | | | Remove use of magic constants. Apply cameraOffset Calculate distance projected on SM plane
* Change normal bias for entities to avoid shadow acneDmitry Kostenko2022-03-07
|
* Remove debugging codeDmitry Kostenko2022-03-07
|
* Ensure nightRatio is greater than zero in object shaderDmitry Kostenko2022-03-07
|
* Apply texture matrix when rendering shadowmapDmitry Kostenko2022-03-07
| | | | Fixes shadows of animated sprite entities
* Fix shadow rendering with filtering disabledDmitry Kostenko2022-03-07
|
* Improve lighting of entities.Dmitry Kostenko2022-03-07
| | | | | Pass correct natural & artificial light to the shaders Use natural/artificial light ratio for correct rendering of shadows
* Improve self-shadowing based on light/normal angleDmitry Kostenko2022-03-07
| | | | Add compatibility with colored shadows.
* Copy shadow mapping shader from nodes to objectsDmitry Kostenko2022-03-07
|
* Make sure nightRatio is always greater than zero.Dmitry Kostenko2022-01-22
| | | | To avoid underfined behavior of GLSL pow()
* Fix shadow mapping when PCF is disabled (#11888)x20482022-01-02
|
* Apply shadow only to the naturally lit part of the fragment color (#11722)x20482021-10-31
| | | | | | | | | Fragment color for nodes is now calculated from: * Texture color, highlighted by artificial light if present (light color conveyed via vertex color). * Texture color highlighted by natural light (conveyed via vertex color) filtered by shadow. * Reflected day/moonlight filtered by shadow (color and intensity), assuming some portion of the light is directly reflected from the materials.
* Improvements to colored shadows (#11516)x20482021-10-01
|
* Fix GLES2 discard behaviour (texture transparency)sfan52021-09-17
|
* Distribute shadow map update over multiple frames to reduce stutter (#11422)x20482021-07-25
| | | | | | | | | | Reduces stutter and freezes when playing. * Maintains double SM and SM Color textures * Light frustum update triggers incremental generation of shadow map into secondary 'future' textures. * Every incremental update renders a portion of the shadow draw list (split equally). * After defined number of frames (currently, 4), 'future' and 'current' textures are swapped, and DirectionalLight 'commits' the new frustum to use when rendering shadows on screen. Co-authored-by: sfan5 <sfan5@live.de>
* Add smooth light-shadow transition at noon (#11430)x20482021-07-25
| | | | Node faces with normals pointing East/West (+X/-X) will transition between light and shadow at noon. This code makes the transition smooth.
* Improve shadow rendering with non-default camera FOV (#11385)x20482021-07-11
| | | | | | | | | | | * Adjust minimum filter radius for perspective * Expand shadow frustum when camera FOV changes, reuse FOV distance adjustment from numeric.cpp * Read shadow_soft_radius setting as float * Use adaptive filter radius to accomodate for PSM distortion * Adjust filter radius for texture resolution
* Shadow mapping render pass (#11244)Liso2021-06-06
| | | Co-authored-by: x2048 <codeforsmile@gmail.com>
* Fix swapped vertex colors on GLES2sfan52021-05-11
|
* Use vec4 for varTexCoord in interlaced shader (#11004)Muhammad Rifqi Priyo Susanto2021-03-01
| | | Somewhen in the past, inTexCoord0 was a vec2. Now, it is a vec4.
* Fix GLES shader support after #9247 (#10727)Vitaliy2020-12-22
|
* Cleanup shader generation code (#10663)Vitaliy2020-12-19
| | | Shader generation is a mess. This commit cleans some parts up, including dropping remains of HLSL support which was never actually implemented.
* Fix MSAA stripes (#9247)HybridDog2020-12-04
| | | | | This only works when shaders are enabled. The centroid varying avoids that the textures (which repeat themselves out of bounds) are sampled out of bounds in MSAA. If MSAA (called FSAA in minetest) is disabled, the centroid keyword does nothing.
* Sky: support GLES2numzero2020-11-26
| | | | IrrLicht built-in shader is broken, have to write my own
* Shaders for Android (GLES 2) (#10506)Vitaliy2020-10-25
| | | | | Shader support for OpenGL ES 2 devices (Android) Co-authored-by: sfan5 <sfan5@live.de>
* Remove all bump mapping and parallax occlusion related code.Lars2020-10-17
|
* Remove "generate normal maps" feature (#10313)hecks2020-09-14
| | | | | Erase all traces of normal "generation" from fragment shaders Remove the "feature" from the engine and default config Remove any leftover documentation of it
* shaders: Fix transparency on GC7000L (#10036)mntmn2020-08-25
| | | Workaround for the missing GL_ALPHA_TEST implementation in Mesa (etnaviv driver).
* Make shading of CAOs optional (#10033)Danila Shutov2020-06-16
|
* Fix broken coloring of wielditems (#9969)Danila Shutov2020-06-09
| | | Fixes a regression that appeared in 5.3.0-dev.
* Reuse object_shader for "wielditem" and "item" entity drawtypes (#9537)Danila Shutov2020-04-19
|
* Shaders: Complete 478e753. OpenGL 4.3 compatiblitySmallJoker2020-04-18
|
* Add tone mapping for entities (#9521)Danila Shutov2020-04-06
| | | fixes #9301
* Transform texture UVs with provided tex. matrix (#9515)Danila Shutov2020-03-16
| | | fixes #9481
* Basic model shading (#9374)Danila Shutov2020-02-16
|
* Shaders: Fix OpenGL < 4.3 compatibilitySmallJoker2020-02-16
|
* Waves generated with Perlin-type noise #8994Lars Hofhansl2019-11-19
|
* Simple shader fixes. (#8991)lhofhansl2019-09-26
| | | | | 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)
* Require 'waving = 3' in a nodedef to apply the liquid waving shader (#8418)Paramat2019-03-27
| | | | | | | | Makes the liquid waving shader per-nodedef like waving leaves/plants, instead of being applied to all liquids. Like the waving leaves/plants shaders, the liquid waving shader can also be applied to meshes and nodeboxes. Derived from a PR by t0ny2.
* Shaders: Fix comment line (#7668)xzcx2018-08-30
| | | Fixed comment as finalColorBlend() does not exist in the code base.
* Rewrite rendering engine (#6253)Vitaliy2017-10-31
| | | | | | | | | | | | * Clean draw_*() arguments * Split rendering core * Add anaglyph 3D * Interlaced 3D * Drop obsolete methods
* Shaders: Remove unused water surface shaderparamat2017-05-08
| | | | | | | | | | Also remove hardcoded MTGame node. The 'water surface shader' was duplicated shader code in preparation for intended new water surface shaders. For development purposes the MTGame node 'default:water_source' had it's top tile assigned to 'water surface shader'. Due to shader duplication this commit does not cause any change to shader behaviour.
* Fix fog weirdness (#5146)numberZero2017-01-31
|
lass="hl com"> */ bool hasEmptyExtent() const { return MaxEdge - MinEdge == v3s16(-1, -1, -1); } s32 getVolume() const { v3s16 e = getExtent(); return (s32)e.X * (s32)e.Y * (s32)e.Z; } bool contains(const VoxelArea &a) const { // No area contains an empty area // NOTE: Algorithms depend on this, so do not change. if(a.hasEmptyExtent()) return false; return( a.MinEdge.X >= MinEdge.X && a.MaxEdge.X <= MaxEdge.X && a.MinEdge.Y >= MinEdge.Y && a.MaxEdge.Y <= MaxEdge.Y && a.MinEdge.Z >= MinEdge.Z && a.MaxEdge.Z <= MaxEdge.Z ); } bool contains(v3s16 p) const { return( p.X >= MinEdge.X && p.X <= MaxEdge.X && p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y && p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z ); } bool contains(s32 i) const { return (i >= 0 && i < getVolume()); } bool operator==(const VoxelArea &other) const { return (MinEdge == other.MinEdge && MaxEdge == other.MaxEdge); } VoxelArea operator+(v3s16 off) const { return VoxelArea(MinEdge+off, MaxEdge+off); } VoxelArea operator-(v3s16 off) const { return VoxelArea(MinEdge-off, MaxEdge-off); } /* Returns 0-6 non-overlapping areas that can be added to a to make up this area. a: area inside *this */ void diff(const VoxelArea &a, std::list<VoxelArea> &result) { /* This can result in a maximum of 6 areas */ // If a is an empty area, return the current area as a whole if(a.getExtent() == v3s16(0,0,0)) { VoxelArea b = *this; if(b.getVolume() != 0) result.push_back(b); return; } assert(contains(a)); // pre-condition // Take back area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1); v3s16 max(MaxEdge.X, MaxEdge.Y, MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take front area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, MinEdge.Z); v3s16 max(MaxEdge.X, MaxEdge.Y, a.MinEdge.Z-1); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take top area, X inclusive { v3s16 min(MinEdge.X, a.MaxEdge.Y+1, a.MinEdge.Z); v3s16 max(MaxEdge.X, MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take bottom area, X inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MinEdge.Z); v3s16 max(MaxEdge.X, a.MinEdge.Y-1, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take left area, non-inclusive { v3s16 min(MinEdge.X, a.MinEdge.Y, a.MinEdge.Z); v3s16 max(a.MinEdge.X-1, a.MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } // Take right area, non-inclusive { v3s16 min(a.MaxEdge.X+1, a.MinEdge.Y, a.MinEdge.Z); v3s16 max(MaxEdge.X, a.MaxEdge.Y, a.MaxEdge.Z); VoxelArea b(min, max); if(b.getVolume() != 0) result.push_back(b); } } /* Translates position from virtual coordinates to array index */ s32 index(s16 x, s16 y, s16 z) const { v3s16 em = getExtent(); v3s16 off = MinEdge; s32 i = (s32)(z-off.Z)*em.Y*em.X + (y-off.Y)*em.X + (x-off.X); //dstream<<" i("<<x<<","<<y<<","<<z<<")="<<i<<" "; return i; } s32 index(v3s16 p) const { return index(p.X, p.Y, p.Z); } // Translate index in the X coordinate void add_x(const v3s16 &extent, u32 &i, s16 a) { i += a; } // Translate index in the Y coordinate void add_y(const v3s16 &extent, u32 &i, s16 a) { i += a * extent.X; } // Translate index in the Z coordinate void add_z(const v3s16 &extent, u32 &i, s16 a) { i += a * extent.X*extent.Y; } // Translate index in space void add_p(const v3s16 &extent, u32 &i, v3s16 a) { i += a.Z*extent.X*extent.Y + a.Y*extent.X + a.X; } /* Print method for debugging */ void print(std::ostream &o) const { v3s16 e = getExtent(); o<<"("<<MinEdge.X <<","<<MinEdge.Y <<","<<MinEdge.Z <<")("<<MaxEdge.X <<","<<MaxEdge.Y <<","<<MaxEdge.Z <<")" <<"="<<e.X<<"x"<<e.Y<<"x"<<e.Z<<"="<<getVolume(); } // Edges are inclusive v3s16 MinEdge; v3s16 MaxEdge; }; // unused #define VOXELFLAG_UNUSED (1<<0) // no data about that node #define VOXELFLAG_NO_DATA (1<<1) // Algorithm-dependent #define VOXELFLAG_CHECKED1 (1<<2) // Algorithm-dependent #define VOXELFLAG_CHECKED2 (1<<3) // Algorithm-dependent #define VOXELFLAG_CHECKED3 (1<<4) // Algorithm-dependent #define VOXELFLAG_CHECKED4 (1<<5) enum VoxelPrintMode { VOXELPRINT_NOTHING, VOXELPRINT_MATERIAL, VOXELPRINT_WATERPRESSURE, VOXELPRINT_LIGHT_DAY, }; class VoxelManipulator /*: public NodeContainer*/ { public: VoxelManipulator(); virtual ~VoxelManipulator(); /* Virtuals from NodeContainer */ /*virtual u16 nodeContainerId() const { return NODECONTAINER_ID_VOXELMANIPULATOR; } bool isValidPosition(v3s16 p) { addArea(p); return !(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA); }*/ /* These are a bit slow and shouldn't be used internally. Use m_data[m_area.index(p)] instead. */ MapNode getNode(v3s16 p) { VoxelArea voxel_area(p); addArea(voxel_area); if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) { /*dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<", index="<<m_area.index(p) <<", flags="<<(int)m_flags[m_area.index(p)] <<" is inexistent"<<std::endl;*/ throw InvalidPositionException ("VoxelManipulator: getNode: inexistent"); } return m_data[m_area.index(p)]; } MapNode getNodeNoEx(v3s16 p) { VoxelArea voxel_area(p); addArea(voxel_area); if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) { return MapNode(CONTENT_IGNORE); } return m_data[m_area.index(p)]; } MapNode getNodeNoExNoEmerge(v3s16 p) { if(m_area.contains(p) == false) return MapNode(CONTENT_IGNORE); if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) return MapNode(CONTENT_IGNORE); return m_data[m_area.index(p)]; } // Stuff explodes if non-emerged area is touched with this. // Emerge first, and check VOXELFLAG_NO_DATA if appropriate. MapNode & getNodeRefUnsafe(const v3s16 &p) { return m_data[m_area.index(p)]; } const MapNode & getNodeRefUnsafeCheckFlags(const v3s16 &p) { s32 index = m_area.index(p); if (m_flags[index] & VOXELFLAG_NO_DATA) return ContentIgnoreNode; return m_data[index]; } u8 & getFlagsRefUnsafe(v3s16 p) { return m_flags[m_area.index(p)]; } bool exists(v3s16 p) { return m_area.contains(p) && !(getFlagsRefUnsafe(p) & VOXELFLAG_NO_DATA); } MapNode & getNodeRef(v3s16 p) { VoxelArea voxel_area(p); addArea(voxel_area); if(getFlagsRefUnsafe(p) & VOXELFLAG_NO_DATA) { /*dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<", index="<<m_area.index(p) <<", flags="<<(int)getFlagsRefUnsafe(p) <<" is inexistent"<<std::endl;*/ throw InvalidPositionException ("VoxelManipulator: getNode: inexistent"); } return getNodeRefUnsafe(p); } void setNode(v3s16 p, const MapNode &n) { VoxelArea voxel_area(p); addArea(voxel_area); m_data[m_area.index(p)] = n; m_flags[m_area.index(p)] &= ~VOXELFLAG_NO_DATA; } // TODO: Should be removed and replaced with setNode void setNodeNoRef(v3s16 p, const MapNode &n) { setNode(p, n); } /*void setExists(VoxelArea a) { addArea(a); for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++) for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++) { m_flags[m_area.index(x,y,z)] &= ~VOXELFLAG_NO_DATA; } }*/ /*MapNode & operator[](v3s16 p) { //dstream<<"operator[] p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl; if(isValidPosition(p) == false) addArea(VoxelArea(p)); return m_data[m_area.index(p)]; }*/ /* Set stuff if available without an emerge. Return false if failed. This is convenient but slower than playing around directly with the m_data table with indices. */ bool setNodeNoEmerge(v3s16 p, MapNode n) { if(m_area.contains(p) == false) return false; m_data[m_area.index(p)] = n; return true; } bool setNodeNoEmerge(s32 i, MapNode n) { if(m_area.contains(i) == false) return false; m_data[i] = n; return true; } /*bool setContentNoEmerge(v3s16 p, u8 c) { if(isValidPosition(p) == false) return false; m_data[m_area.index(p)].d = c; }*/ /* Control */ virtual void clear(); void print(std::ostream &o, INodeDefManager *nodemgr, VoxelPrintMode mode=VOXELPRINT_MATERIAL); void addArea(const VoxelArea &area); /* Copy data and set flags to 0 dst_area.getExtent() <= src_area.getExtent() */ void copyFrom(MapNode *src, const VoxelArea& src_area, v3s16 from_pos, v3s16 to_pos, v3s16 size); // Copy data void copyTo(MapNode *dst, const VoxelArea& dst_area, v3s16 dst_pos, v3s16 from_pos, v3s16 size); /* Algorithms */ void clearFlag(u8 flag); // TODO: Move to voxelalgorithms.h void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, std::set<v3s16> & light_sources, INodeDefManager *nodemgr); void unspreadLight(enum LightBank bank, std::map<v3s16, u8> & from_nodes, std::set<v3s16> & light_sources, INodeDefManager *nodemgr); void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr); void spreadLight(enum LightBank bank, std::set<v3s16> & from_nodes, INodeDefManager *nodemgr); /* Virtual functions */ /* Member variables */ /* The area that is stored in m_data. addInternalBox should not be used if getExtent() == v3s16(0,0,0) MaxEdge is 1 higher than maximum allowed position */ VoxelArea m_area; /* NULL if data size is 0 (extent (0,0,0)) Data is stored as [z*h*w + y*h + x] */ MapNode *m_data; /* Flags of all nodes */ u8 *m_flags; static const MapNode ContentIgnoreNode; //TODO: Use these or remove them //TODO: Would these make any speed improvement? //bool m_pressure_route_valid; //v3s16 m_pressure_route_surface; /* Some settings */ //bool m_disable_water_climb; private: }; #endif