1
0
mirror of https://github.com/luanti-org/luanti.git synced 2025-10-20 11:35:21 +02:00

Port shadow shaders to work with OpenGL3

Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
PtiLuky
2025-10-13 11:04:07 +02:00
committed by sfan5
parent 5e23e478b1
commit d834c45d1c
13 changed files with 128 additions and 264 deletions

View File

@@ -1,9 +1,15 @@
uniform sampler2D ColorMapSampler; uniform sampler2D ColorMapSampler;
varying vec4 tPos; varying vec4 tPos;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main() void main()
{ {
vec4 col = texture2D(ColorMapSampler, gl_TexCoord[0].st); vec4 col = texture2D(ColorMapSampler, varTexCoord);
if (col.a < 0.70) if (col.a < 0.70)
discard; discard;

View File

@@ -6,6 +6,12 @@ uniform float xyPerspectiveBias0;
uniform float xyPerspectiveBias1; uniform float xyPerspectiveBias1;
uniform float zPerspectiveBias; uniform float zPerspectiveBias;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
vec4 getRelativePosition(in vec4 position) vec4 getRelativePosition(in vec4 position)
{ {
vec2 l = position.xy - CameraPos.xy; vec2 l = position.xy - CameraPos.xy;
@@ -34,10 +40,10 @@ vec4 applyPerspectiveDistortion(in vec4 position)
void main() void main()
{ {
vec4 pos = LightMVP * gl_Vertex; vec4 pos = LightMVP * inVertexPosition;
tPos = applyPerspectiveDistortion(pos); tPos = applyPerspectiveDistortion(pos);
gl_Position = vec4(tPos.xyz, 1.0); gl_Position = vec4(tPos.xyz, 1.0);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; varTexCoord = (mTexture * vec4(inTexCoord0.xy, 0.0, 1.0)).xy;
} }

View File

@@ -1,6 +1,12 @@
uniform sampler2D ColorMapSampler; uniform sampler2D ColorMapSampler;
varying vec4 tPos; varying vec4 tPos;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
#ifdef COLORED_SHADOWS #ifdef COLORED_SHADOWS
varying vec3 varColor; varying vec3 varColor;
@@ -20,7 +26,7 @@ const vec3 black = vec3(0.0);
void main() void main()
{ {
vec4 col = texture2D(ColorMapSampler, gl_TexCoord[0].st); vec4 col = texture2D(ColorMapSampler, varTexCoord);
#ifndef COLORED_SHADOWS #ifndef COLORED_SHADOWS
if (col.a < 0.5) if (col.a < 0.5)
discard; discard;

View File

@@ -9,6 +9,12 @@ uniform float xyPerspectiveBias0;
uniform float xyPerspectiveBias1; uniform float xyPerspectiveBias1;
uniform float zPerspectiveBias; uniform float zPerspectiveBias;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
vec4 getRelativePosition(in vec4 position) vec4 getRelativePosition(in vec4 position)
{ {
vec2 l = position.xy - CameraPos.xy; vec2 l = position.xy - CameraPos.xy;
@@ -37,14 +43,14 @@ vec4 applyPerspectiveDistortion(in vec4 position)
void main() void main()
{ {
vec4 pos = LightMVP * gl_Vertex; vec4 pos = LightMVP * inVertexPosition;
tPos = applyPerspectiveDistortion(LightMVP * gl_Vertex); tPos = applyPerspectiveDistortion(pos);
gl_Position = vec4(tPos.xyz, 1.0); gl_Position = vec4(tPos.xyz, 1.0);
gl_TexCoord[0].st = gl_MultiTexCoord0.st; varTexCoord = inTexCoord0.xy;
#ifdef COLORED_SHADOWS #ifdef COLORED_SHADOWS
varColor = gl_Color.rgb; varColor = inVertexColor.rgb;
#endif #endif
} }

View File

@@ -4,20 +4,25 @@ uniform sampler2D ShadowMapClientMapTraslucent;
#endif #endif
uniform sampler2D ShadowMapSamplerdynamic; uniform sampler2D ShadowMapSamplerdynamic;
void main() { #ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main()
{
#ifdef COLORED_SHADOWS #ifdef COLORED_SHADOWS
vec2 first_depth = texture2D(ShadowMapClientMap, gl_TexCoord[0].st).rg; vec2 first_depth = texture2D(ShadowMapClientMap, varTexCoord).rg;
vec2 depth_splitdynamics = vec2(texture2D(ShadowMapSamplerdynamic, gl_TexCoord[2].st).r, 0.0); vec2 depth_splitdynamics = vec2(texture2D(ShadowMapSamplerdynamic, varTexCoord).r, 0.0);
if (first_depth.r > depth_splitdynamics.r) if (first_depth.r > depth_splitdynamics.r)
first_depth = depth_splitdynamics; first_depth = depth_splitdynamics;
vec2 depth_color = texture2D(ShadowMapClientMapTraslucent, gl_TexCoord[1].st).rg; vec2 depth_color = texture2D(ShadowMapClientMapTraslucent, varTexCoord).rg;
gl_FragColor = vec4(first_depth.r, first_depth.g, depth_color.r, depth_color.g); gl_FragColor = vec4(first_depth.r, first_depth.g, depth_color.r, depth_color.g);
#else #else
float first_depth = texture2D(ShadowMapClientMap, gl_TexCoord[0].st).r; float first_depth = texture2D(ShadowMapClientMap, varTexCoord).r;
float depth_splitdynamics = texture2D(ShadowMapSamplerdynamic, gl_TexCoord[2].st).r; float depth_splitdynamics = texture2D(ShadowMapSamplerdynamic, varTexCoord).r;
first_depth = min(first_depth, depth_splitdynamics); first_depth = min(first_depth, depth_splitdynamics);
gl_FragColor = vec4(first_depth, 0.0, 0.0, 1.0); gl_FragColor = vec4(first_depth, 0.0, 0.0, 1.0);
#endif #endif
} }

View File

@@ -0,0 +1,12 @@
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main()
{
vec4 uv = vec4(inVertexPosition.xyz, 1.0) * 0.5 + 0.5;
varTexCoord = uv.st;
gl_Position = vec4(inVertexPosition.xyz, 1.0);
}

View File

@@ -1,9 +0,0 @@
void main()
{
vec4 uv = vec4(gl_Vertex.xyz, 1.0) * 0.5 + 0.5;
gl_TexCoord[0] = uv;
gl_TexCoord[1] = uv;
gl_TexCoord[2] = uv;
gl_Position = vec4(gl_Vertex.xyz, 1.0);
}

View File

@@ -8,14 +8,11 @@
#include "client/shadows/shadowsScreenQuad.h" #include "client/shadows/shadowsScreenQuad.h"
#include "client/shadows/shadowsshadercallbacks.h" #include "client/shadows/shadowsshadercallbacks.h"
#include "settings.h" #include "settings.h"
#include "filesys.h"
#include "util/string.h" #include "util/string.h"
#include "client/shader.h" #include "client/shader.h"
#include "client/client.h" #include "client/client.h"
#include "client/clientmap.h" #include "client/clientmap.h"
#include "profiler.h"
#include "IGPUProgrammingServices.h" #include "IGPUProgrammingServices.h"
#include "IMaterialRenderer.h"
#include "IVideoDriver.h" #include "IVideoDriver.h"
ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) : ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
@@ -24,8 +21,6 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
m_time_day(0.0f), m_force_update_shadow_map(false), m_current_frame(0), m_time_day(0.0f), m_force_update_shadow_map(false), m_current_frame(0),
m_perspective_bias_xy(0.8f), m_perspective_bias_z(0.5f) m_perspective_bias_xy(0.8f), m_perspective_bias_z(0.5f)
{ {
(void) m_client;
m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize
m_shadows_enabled = true; m_shadows_enabled = true;
@@ -43,6 +38,8 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
m_shadow_samples = g_settings->getS32("shadow_filters"); m_shadow_samples = g_settings->getS32("shadow_filters");
m_map_shadow_update_frames = g_settings->getS16("shadow_update_frames"); m_map_shadow_update_frames = g_settings->getS16("shadow_update_frames");
m_screen_quad = new ShadowScreenQuad();
// add at least one light // add at least one light
addDirectionalLight(); addDirectionalLight();
} }
@@ -52,21 +49,23 @@ ShadowRenderer::~ShadowRenderer()
// call to disable releases dynamically allocated resources // call to disable releases dynamically allocated resources
disable(); disable();
if (m_shadow_depth_cb) if (m_shadow_depth_cb) {
delete m_shadow_depth_cb; m_shadow_depth_cb->drop();
if (m_shadow_depth_entity_cb) m_shadow_depth_cb = nullptr;
delete m_shadow_depth_entity_cb; }
if (m_shadow_depth_trans_cb) if (m_shadow_depth_trans_cb) {
delete m_shadow_depth_trans_cb; m_shadow_depth_trans_cb->drop();
if (m_shadow_mix_cb) m_shadow_depth_trans_cb = nullptr;
delete m_shadow_mix_cb; }
m_shadow_node_array.clear();
m_light_list.clear(); delete m_screen_quad;
m_screen_quad = nullptr;
} }
void ShadowRenderer::disable() void ShadowRenderer::disable()
{ {
m_shadows_enabled = false; m_shadows_enabled = false;
if (shadowMapTextureFinal) { if (shadowMapTextureFinal) {
m_driver->setRenderTarget(shadowMapTextureFinal, true, true, m_driver->setRenderTarget(shadowMapTextureFinal, true, true,
video::SColor(255, 255, 255, 255)); video::SColor(255, 255, 255, 255));
@@ -79,6 +78,11 @@ void ShadowRenderer::disable()
} }
if (shadowMapTextureFinal) { if (shadowMapTextureFinal) {
for (auto &node : m_shadow_node_array) {
node.node->forEachMaterial([] (auto &mat) {
mat.setTexture(TEXTURE_LAYER_SHADOW, nullptr);
});
}
m_driver->removeTexture(shadowMapTextureFinal); m_driver->removeTexture(shadowMapTextureFinal);
shadowMapTextureFinal = nullptr; shadowMapTextureFinal = nullptr;
} }
@@ -97,11 +101,6 @@ void ShadowRenderer::disable()
m_driver->removeTexture(shadowMapClientMapFuture); m_driver->removeTexture(shadowMapClientMapFuture);
shadowMapClientMapFuture = nullptr; shadowMapClientMapFuture = nullptr;
} }
for (auto node : m_shadow_node_array)
node.node->forEachMaterial([] (auto &mat) {
mat.setTexture(TEXTURE_LAYER_SHADOW, nullptr);
});
} }
void ShadowRenderer::preInit(IWritableShaderSource *shsrc) void ShadowRenderer::preInit(IWritableShaderSource *shsrc)
@@ -246,11 +245,12 @@ void ShadowRenderer::updateSMTextures()
frt, true); frt, true);
assert(shadowMapTextureFinal != nullptr); assert(shadowMapTextureFinal != nullptr);
for (auto &node : m_shadow_node_array) for (auto &node : m_shadow_node_array) {
node.node->forEachMaterial([this] (auto &mat) { node.node->forEachMaterial([this] (auto &mat) {
mat.setTexture(TEXTURE_LAYER_SHADOW, shadowMapTextureFinal); mat.setTexture(TEXTURE_LAYER_SHADOW, shadowMapTextureFinal);
}); });
} }
}
if (!m_shadow_node_array.empty()) { if (!m_shadow_node_array.empty()) {
bool reset_sm_texture = false; bool reset_sm_texture = false;
@@ -271,7 +271,7 @@ void ShadowRenderer::updateSMTextures()
// Update SM incrementally: // Update SM incrementally:
for (DirectionalLight &light : m_light_list) { for (DirectionalLight &light : m_light_list) {
// Static shader values. // Static shader values.
for (auto cb : {m_shadow_depth_cb, m_shadow_depth_entity_cb, m_shadow_depth_trans_cb}) { for (auto *cb : {m_shadow_depth_cb, m_shadow_depth_trans_cb}) {
if (cb) { if (cb) {
cb->MapRes = (u32)m_shadow_map_texture_size; cb->MapRes = (u32)m_shadow_map_texture_size;
cb->MaxFar = (f32)m_shadow_map_max_distance * BS; cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
@@ -336,14 +336,13 @@ void ShadowRenderer::update(video::ITexture *outputTarget)
if (!m_shadow_node_array.empty()) { if (!m_shadow_node_array.empty()) {
for (DirectionalLight &light : m_light_list) { for (DirectionalLight &light : m_light_list) {
// Static shader values for entities are set in updateSMTextures // Static shader values for entities are set in updateSMTextures
// SM texture for entities is not updated incrementally and // SM texture for entities is not updated incrementally and
// must by updated using current player position. // must by updated using current player position.
m_shadow_depth_entity_cb->CameraPos = light.getPlayerPos(); m_shadow_depth_cb->CameraPos = light.getPlayerPos();
// render shadows for the n0n-map objects. // render shadows for the non-map objects.
m_driver->setRenderTarget(shadowMapTextureDynamicObjects, true, m_driver->setRenderTarget(shadowMapTextureDynamicObjects, true,
true, video::SColor(255, 255, 255, 255)); true, video::SColor(255, 255, 255, 255));
renderShadowObjects(shadowMapTextureDynamicObjects, light); renderShadowObjects(shadowMapTextureDynamicObjects, light);
@@ -431,11 +430,9 @@ void ShadowRenderer::renderShadowMap(video::ITexture *target,
material.FrontfaceCulling = true; material.FrontfaceCulling = true;
if (m_shadow_map_colored && pass != scene::ESNRP_SOLID) { if (m_shadow_map_colored && pass != scene::ESNRP_SOLID) {
material.MaterialType = (video::E_MATERIAL_TYPE) depth_shader_trans; material.MaterialType = depth_shader_trans;
} } else {
else { material.MaterialType = depth_shader;
material.MaterialType = (video::E_MATERIAL_TYPE) depth_shader;
material.BlendOperation = video::EBO_MIN;
} }
m_driver->setTransform(video::ETS_WORLD, m_driver->setTransform(video::ETS_WORLD,
@@ -460,12 +457,10 @@ void ShadowRenderer::renderShadowObjects(
// render other objects // render other objects
u32 n_node_materials = shadow_node.node->getMaterialCount(); u32 n_node_materials = shadow_node.node->getMaterialCount();
std::vector<s32> BufferMaterialList; std::vector<video::E_MATERIAL_TYPE> BufferMaterialList;
std::vector<std::pair<bool, bool>> BufferMaterialCullingList; std::vector<std::pair<bool, bool>> BufferMaterialCullingList;
std::vector<video::E_BLEND_OPERATION> BufferBlendOperationList;
BufferMaterialList.reserve(n_node_materials); BufferMaterialList.reserve(n_node_materials);
BufferMaterialCullingList.reserve(n_node_materials); BufferMaterialCullingList.reserve(n_node_materials);
BufferBlendOperationList.reserve(n_node_materials);
// backup materialtype for each material // backup materialtype for each material
// (aka shader) // (aka shader)
@@ -474,13 +469,10 @@ void ShadowRenderer::renderShadowObjects(
auto &current_mat = shadow_node.node->getMaterial(m); auto &current_mat = shadow_node.node->getMaterial(m);
BufferMaterialList.push_back(current_mat.MaterialType); BufferMaterialList.push_back(current_mat.MaterialType);
current_mat.MaterialType = current_mat.MaterialType = depth_shader;
(video::E_MATERIAL_TYPE)depth_shader_entities;
BufferMaterialCullingList.emplace_back( BufferMaterialCullingList.emplace_back(
(bool)current_mat.BackfaceCulling, (bool)current_mat.FrontfaceCulling); (bool)current_mat.BackfaceCulling, (bool)current_mat.FrontfaceCulling);
BufferBlendOperationList.push_back(current_mat.BlendOperation);
current_mat.BackfaceCulling = true; current_mat.BackfaceCulling = true;
current_mat.FrontfaceCulling = false; current_mat.FrontfaceCulling = false;
} }
@@ -494,11 +486,10 @@ void ShadowRenderer::renderShadowObjects(
for (u32 m = 0; m < n_node_materials; m++) { for (u32 m = 0; m < n_node_materials; m++) {
auto &current_mat = shadow_node.node->getMaterial(m); auto &current_mat = shadow_node.node->getMaterial(m);
current_mat.MaterialType = (video::E_MATERIAL_TYPE) BufferMaterialList[m]; current_mat.MaterialType = BufferMaterialList[m];
current_mat.BackfaceCulling = BufferMaterialCullingList[m].first; current_mat.BackfaceCulling = BufferMaterialCullingList[m].first;
current_mat.FrontfaceCulling = BufferMaterialCullingList[m].second; current_mat.FrontfaceCulling = BufferMaterialCullingList[m].second;
current_mat.BlendOperation = BufferBlendOperationList[m];
} }
} // end for caster shadow nodes } // end for caster shadow nodes
@@ -508,183 +499,34 @@ void ShadowRenderer::mixShadowsQuad()
{ {
} }
/*
* @Liso's disclaimer ;) This function loads the Shadow Mapping Shaders.
* I used a custom loader because I couldn't figure out how to use the base
* Shaders system with custom IShaderConstantSetCallBack without messing up the
* code too much. If anyone knows how to integrate this with the standard MT
* shaders, please feel free to change it.
*
* TODO: as of now (2025) it should be possible to hook these up to the normal
* shader system.
*/
void ShadowRenderer::createShaders() void ShadowRenderer::createShaders()
{ {
auto *gpu = m_driver->getGPUProgrammingServices(); auto *shdsrc = m_client->getShaderSource();
if (depth_shader == -1) { assert(!m_shadow_depth_cb);
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
if (depth_shader_vs.empty()) {
m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
if (depth_shader_fs.empty()) {
m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
m_shadow_depth_cb = new ShadowDepthShaderCB();
depth_shader = gpu->addHighLevelShaderMaterial(
readShaderFile(depth_shader_vs).c_str(),
readShaderFile(depth_shader_fs).c_str(), nullptr,
m_shadow_depth_cb, video::EMT_ONETEXTURE_BLEND);
if (depth_shader == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_cb;
m_shadow_depth_cb = nullptr;
m_shadows_enabled = false;
m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader." << std::endl;
return;
}
// HACK, TODO: investigate this better
// Grab the material renderer once more so minetest doesn't crash
// on exit
m_driver->getMaterialRenderer(depth_shader)->grab();
}
// This creates a clone of depth_shader with base material set to EMT_SOLID,
// because entities won't render shadows with base material EMP_ONETEXTURE_BLEND
if (depth_shader_entities == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
if (depth_shader_vs.empty()) {
m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
if (depth_shader_fs.empty()) {
m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
m_shadow_depth_entity_cb = new ShadowDepthShaderCB();
depth_shader_entities = gpu->addHighLevelShaderMaterial(
readShaderFile(depth_shader_vs).c_str(),
readShaderFile(depth_shader_fs).c_str(), nullptr,
m_shadow_depth_entity_cb);
if (depth_shader_entities == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_entity_cb;
m_shadow_depth_entity_cb = nullptr;
m_shadows_enabled = false;
m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl;
return;
}
// HACK, TODO: investigate this better
// Grab the material renderer once more so minetest doesn't crash
// on exit
m_driver->getMaterialRenderer(depth_shader_entities)->grab();
}
if (mixcsm_shader == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass2_vertex.glsl");
if (depth_shader_vs.empty()) {
m_shadows_supported = false;
errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass2_fragment.glsl");
if (depth_shader_fs.empty()) {
m_shadows_supported = false;
errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
return;
}
m_shadow_mix_cb = new shadowScreenQuadCB();
m_screen_quad = new shadowScreenQuad();
mixcsm_shader = gpu->addHighLevelShaderMaterial(
readShaderFile(depth_shader_vs).c_str(),
readShaderFile(depth_shader_fs).c_str(), nullptr,
m_shadow_mix_cb);
m_screen_quad->getMaterial().MaterialType =
(video::E_MATERIAL_TYPE)mixcsm_shader;
if (mixcsm_shader == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_mix_cb;
delete m_screen_quad;
m_shadows_supported = false;
errorstream << "Error compiling cascade shadow mapping shader." << std::endl;
return;
}
// HACK, TODO: investigate this better
// Grab the material renderer once more so minetest doesn't crash
// on exit
m_driver->getMaterialRenderer(mixcsm_shader)->grab();
}
if (m_shadow_map_colored && depth_shader_trans == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_trans_vertex.glsl");
if (depth_shader_vs.empty()) {
m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_trans_fragment.glsl");
if (depth_shader_fs.empty()) {
m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
m_shadow_depth_trans_cb = new ShadowDepthShaderCB();
depth_shader_trans = gpu->addHighLevelShaderMaterial(
readShaderFile(depth_shader_vs).c_str(),
readShaderFile(depth_shader_fs).c_str(), nullptr,
m_shadow_depth_trans_cb);
if (depth_shader_trans == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_trans_cb;
m_shadow_depth_trans_cb = nullptr;
m_shadow_map_colored = false;
m_shadows_supported = false;
errorstream << "Error compiling colored shadow mapping shader." << std::endl;
return;
}
// HACK, TODO: investigate this better
// Grab the material renderer once more so minetest doesn't crash
// on exit
m_driver->getMaterialRenderer(depth_shader_trans)->grab();
}
}
std::string ShadowRenderer::readShaderFile(const std::string &path)
{ {
std::string prefix; m_shadow_depth_cb = new ShadowDepthUniformSetter();
if (m_shadow_map_colored) u32 shader_id = shdsrc->getShader("shadow/pass1", {},
prefix.append("#define COLORED_SHADOWS 1\n"); video::EMT_SOLID, m_shadow_depth_cb);
prefix.append("#line 0\n"); depth_shader = shdsrc->getShaderInfo(shader_id).material;
}
std::string content; if (m_shadow_map_colored) {
if (!fs::ReadFile(path, content, true)) m_shadow_depth_trans_cb = new ShadowDepthUniformSetter();
return ""; u32 shader_id = shdsrc->getShader("shadow/pass1_trans", {},
video::EMT_SOLID, m_shadow_depth_trans_cb);
depth_shader_trans = shdsrc->getShaderInfo(shader_id).material;
}
return prefix + content; {
auto *shadow_mix_cb = new ShadowScreenQuadUniformSetter();
u32 shader_id = shdsrc->getShader("shadow/pass2", {},
video::EMT_SOLID, shadow_mix_cb);
shadow_mix_cb->drop();
m_screen_quad->getMaterial().MaterialType =
shdsrc->getShaderInfo(shader_id).material;
}
} }
std::unique_ptr<ShadowRenderer> createShadowRenderer(IrrlichtDevice *device, Client *client) std::unique_ptr<ShadowRenderer> createShadowRenderer(IrrlichtDevice *device, Client *client)

View File

@@ -12,9 +12,9 @@
#include <ISceneNode.h> #include <ISceneNode.h>
#include <ISceneManager.h> #include <ISceneManager.h>
class ShadowDepthShaderCB; class ShadowDepthUniformSetter;
class shadowScreenQuad; class ShadowScreenQuad;
class shadowScreenQuadCB; class ShadowScreenQuadUniformSetter;
class IWritableShaderSource; class IWritableShaderSource;
enum E_SHADOW_MODE : u8 enum E_SHADOW_MODE : u8
@@ -144,19 +144,13 @@ private:
// Shadow Shader stuff // Shadow Shader stuff
void createShaders(); void createShaders();
std::string readShaderFile(const std::string &path);
s32 depth_shader{-1}; video::E_MATERIAL_TYPE depth_shader, depth_shader_trans;
s32 depth_shader_entities{-1};
s32 depth_shader_trans{-1};
s32 mixcsm_shader{-1};
ShadowDepthShaderCB *m_shadow_depth_cb{nullptr}; ShadowDepthUniformSetter *m_shadow_depth_cb{nullptr};
ShadowDepthShaderCB *m_shadow_depth_entity_cb{nullptr}; ShadowDepthUniformSetter *m_shadow_depth_trans_cb{nullptr};
ShadowDepthShaderCB *m_shadow_depth_trans_cb{nullptr};
shadowScreenQuad *m_screen_quad{nullptr}; ShadowScreenQuad *m_screen_quad{nullptr};
shadowScreenQuadCB *m_shadow_mix_cb{nullptr};
}; };
/** /**

View File

@@ -5,7 +5,7 @@
#include "shadowsScreenQuad.h" #include "shadowsScreenQuad.h"
#include <IVideoDriver.h> #include <IVideoDriver.h>
shadowScreenQuad::shadowScreenQuad() ShadowScreenQuad::ShadowScreenQuad()
{ {
Material.Wireframe = false; Material.Wireframe = false;
@@ -24,7 +24,7 @@ shadowScreenQuad::shadowScreenQuad()
1.0f, 1.0f, 0.0f, 0, 0, 1, color, 1.0f, 0.0f); 1.0f, 1.0f, 0.0f, 0, 0, 1, color, 1.0f, 0.0f);
} }
void shadowScreenQuad::render(video::IVideoDriver *driver) void ShadowScreenQuad::render(video::IVideoDriver *driver)
{ {
u16 indices[6] = {0, 1, 2, 3, 4, 5}; u16 indices[6] = {0, 1, 2, 3, 4, 5};
driver->setMaterial(Material); driver->setMaterial(Material);
@@ -32,8 +32,7 @@ void shadowScreenQuad::render(video::IVideoDriver *driver)
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2); driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
} }
void shadowScreenQuadCB::OnSetConstants( void ShadowScreenQuadUniformSetter::onSetUniforms(video::IMaterialRendererServices *services)
video::IMaterialRendererServices *services, s32 userData)
{ {
s32 TextureId = 0; s32 TextureId = 0;
m_sm_client_map_setting.set(&TextureId, services); m_sm_client_map_setting.set(&TextureId, services);

View File

@@ -4,13 +4,12 @@
#pragma once #pragma once
#include <IMaterialRendererServices.h> #include <IMaterialRendererServices.h>
#include <IShaderConstantSetCallBack.h>
#include "client/shader.h" #include "client/shader.h"
class shadowScreenQuad class ShadowScreenQuad
{ {
public: public:
shadowScreenQuad(); ShadowScreenQuad();
void render(video::IVideoDriver *driver); void render(video::IVideoDriver *driver);
video::SMaterial &getMaterial() { return Material; } video::SMaterial &getMaterial() { return Material; }
@@ -20,11 +19,11 @@ private:
video::SMaterial Material; video::SMaterial Material;
}; };
class shadowScreenQuadCB : public video::IShaderConstantSetCallBack class ShadowScreenQuadUniformSetter : public IShaderUniformSetterRC
{ {
public: public:
virtual void OnSetConstants(video::IMaterialRendererServices *services, virtual void onSetUniforms(video::IMaterialRendererServices *services) override;
s32 userData);
private: private:
CachedPixelShaderSetting<s32> m_sm_client_map_setting{"ShadowMapClientMap"}; CachedPixelShaderSetting<s32> m_sm_client_map_setting{"ShadowMapClientMap"};
CachedPixelShaderSetting<s32> CachedPixelShaderSetting<s32>

View File

@@ -52,10 +52,9 @@ void ShadowUniformSetter::onSetUniforms(video::IMaterialRendererServices *servic
m_perspective_zbias_pixel.set(&zbias, services); m_perspective_zbias_pixel.set(&zbias, services);
} }
void ShadowDepthShaderCB::OnSetConstants( void ShadowDepthUniformSetter::onSetUniforms(video::IMaterialRendererServices *services)
video::IMaterialRendererServices *services, s32 userData)
{ {
video::IVideoDriver *driver = services->getVideoDriver(); auto *driver = services->getVideoDriver();
core::matrix4 lightMVP = driver->getTransform(video::ETS_PROJECTION); core::matrix4 lightMVP = driver->getTransform(video::ETS_PROJECTION);
lightMVP *= driver->getTransform(video::ETS_VIEW); lightMVP *= driver->getTransform(video::ETS_VIEW);

View File

@@ -4,8 +4,8 @@
#pragma once #pragma once
#include <IMaterialRendererServices.h> #include <IMaterialRendererServices.h>
#include <IShaderConstantSetCallBack.h>
#include "client/shader.h" #include "client/shader.h"
#include "util/string.h"
// Used by main game rendering // Used by main game rendering
@@ -43,19 +43,18 @@ class ShadowUniformSetterFactory : public IShaderUniformSetterFactory
{ {
public: public:
virtual IShaderUniformSetter *create(const std::string &name) { virtual IShaderUniformSetter *create(const std::string &name) {
if (str_starts_with(name, "shadow/"))
return nullptr;
return new ShadowUniformSetter(); return new ShadowUniformSetter();
} }
}; };
// Used by depth shader // Used by depth shader
class ShadowDepthShaderCB : public video::IShaderConstantSetCallBack class ShadowDepthUniformSetter : public IShaderUniformSetterRC
{ {
public: public:
void OnSetMaterial(const video::SMaterial &material) override {} virtual void onSetUniforms(video::IMaterialRendererServices *services) override;
void OnSetConstants(video::IMaterialRendererServices *services,
s32 userData) override;
f32 MaxFar{2048.0f}, MapRes{1024.0f}; f32 MaxFar{2048.0f}, MapRes{1024.0f};
f32 PerspectiveBiasXY {0.9f}, PerspectiveBiasZ {0.5f}; f32 PerspectiveBiasXY {0.9f}, PerspectiveBiasZ {0.5f};