~ shader precompilation should be done in order to ensure that the vertex shader has information discovered by the fragment shader (like new combos) should fix some effects on backgrounds

+ added partial support for shader constant values from the scene.json

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2021-08-08 08:41:03 +02:00
parent 8d0eb6d63c
commit 537acb97bd
3 changed files with 86 additions and 23 deletions

View File

@ -42,12 +42,18 @@ CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::I
irr::io::path fragPath = this->m_context->resolveFragmentShader (pass->getShader ()); irr::io::path fragPath = this->m_context->resolveFragmentShader (pass->getShader ());
// register fragment shader // register fragment shader
this->m_fragShader = new Render::Shaders::Compiler ( this->m_fragShader = new Render::Shaders::Compiler (
this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Pixel,
pass->getCombos (), pass->getConstants (), false
); );
// compile fragment shader
this->m_fragShader->precompile ();
// register vertex shader, combos come from the fragment as it can sometimes define them // register vertex shader, combos come from the fragment as it can sometimes define them
this->m_vertShader = new Render::Shaders::Compiler ( this->m_vertShader = new Render::Shaders::Compiler (
this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex, this->m_fragShader->getCombos (), false this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Vertex,
this->m_fragShader->getCombos (), pass->getConstants (), false
); );
// compile vertex shader
this->m_vertShader->precompile ();
this->setupTextures (); this->setupTextures ();
// initialize material data and compile shader used for this pass // initialize material data and compile shader used for this pass
this->m_irrlichtMaterial.Wireframe = false; this->m_irrlichtMaterial.Wireframe = false;
@ -56,8 +62,8 @@ CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::I
this->m_irrlichtMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true); this->m_irrlichtMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true);
this->m_irrlichtMaterial.MaterialType = (irr::video::E_MATERIAL_TYPE) this->m_irrlichtMaterial.MaterialType = (irr::video::E_MATERIAL_TYPE)
this->m_context->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()->addHighLevelShaderMaterial ( this->m_context->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()->addHighLevelShaderMaterial (
this->m_vertShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0, this->m_vertShader->getCompiled ().c_str (), "main", irr::video::EVST_VS_2_0,
this->m_fragShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0, this->m_fragShader->getCompiled ().c_str (), "main", irr::video::EPST_PS_2_0,
this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT
); );

View File

@ -9,6 +9,9 @@
// shader compiler // shader compiler
#include <WallpaperEngine/Render/Shaders/Compiler.h> #include <WallpaperEngine/Render/Shaders/Compiler.h>
#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h>
#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h>
#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h>
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h"
@ -21,14 +24,21 @@ using namespace WallpaperEngine::Core;
namespace WallpaperEngine::Render::Shaders namespace WallpaperEngine::Render::Shaders
{ {
Compiler::Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, std::map<std::string, int> combos, bool recursive) : Compiler::Compiler (
m_combos (std::move(combos)), Irrlicht::CContext* context,
irr::io::path& file,
Type type,
std::map<std::string, int> combos,
const std::map<std::string, CShaderConstant*>& constants,
bool recursive) :
m_combos (combos),
m_recursive (recursive), m_recursive (recursive),
m_type (type), m_type (type),
m_file (file), m_file (file),
m_error (""), m_error (""),
m_errorInfo (""), m_errorInfo (""),
m_context (context) m_context (context),
m_constants (constants)
{ {
this->m_content =WallpaperEngine::FileSystem::loadFullFile (file); this->m_content =WallpaperEngine::FileSystem::loadFullFile (file);
} }
@ -209,9 +219,11 @@ namespace WallpaperEngine::Render::Shaders
// now compile the new shader // now compile the new shader
// do not include the default header (as it's already included in the parent) // do not include the default header (as it's already included in the parent)
Compiler loader (this->m_context, shader, this->m_type, this->m_combos, true); Compiler loader (this->m_context, shader, this->m_type, this->m_combos, this->m_constants, true);
return loader.precompile (); loader.precompile ();
return loader.getCompiled ();
} }
std::string Compiler::lookupReplaceSymbol (std::string symbol) std::string Compiler::lookupReplaceSymbol (std::string symbol)
@ -233,7 +245,12 @@ namespace WallpaperEngine::Render::Shaders
return symbol; return symbol;
} }
std::string Compiler::precompile() std::string& Compiler::getCompiled ()
{
return this->m_compiledContent;
}
void Compiler::precompile()
{ {
#define BREAK_IF_ERROR if (this->m_error == true) { throw std::runtime_error ("ERROR PRE-COMPILING SHADER" + this->m_errorInfo); } #define BREAK_IF_ERROR if (this->m_error == true) { throw std::runtime_error ("ERROR PRE-COMPILING SHADER" + this->m_errorInfo); }
// parse the shader and find #includes and such things and translate them to the correct name // parse the shader and find #includes and such things and translate them to the correct name
@ -475,10 +492,11 @@ namespace WallpaperEngine::Render::Shaders
if (this->m_recursive == false) if (this->m_recursive == false)
{ {
std::cout << "======================== COMPILED SHADER " << this->m_file.c_str () << " ========================" << std::endl; std::cout << "======================== COMPILED SHADER " << this->m_file.c_str () << " ========================" << std::endl;
std::cout << this->m_compiledContent << std::endl; std::cout << finalCode << std::endl;
} }
return finalCode; // store the final final code here
this->m_compiledContent = finalCode;
#undef BREAK_IF_ERROR #undef BREAK_IF_ERROR
} }
@ -526,16 +544,19 @@ namespace WallpaperEngine::Render::Shaders
auto range = data.find ("range"); auto range = data.find ("range");
// this is not a real parameter // this is not a real parameter
if (material == data.end () || defvalue == data.end ()) if (material == data.end ())
return;
auto constant = this->m_constants.find (*material);
if (constant == this->m_constants.end () && defvalue == data.end ())
{ {
if (type != "sampler2D") if (type != "sampler2D")
throw std::runtime_error ("cannot parse parameter info for " + name); throw std::runtime_error ("cannot parse parameter data");
return;
} }
Variables::CShaderVariable* parameter = nullptr; Variables::CShaderVariable* parameter = nullptr;
// TODO: SUPPORT VALUES FOR ALL THESE TYPES
if (type == "vec4") if (type == "vec4")
{ {
parameter = new Variables::CShaderVariableVector4 ( parameter = new Variables::CShaderVariableVector4 (
@ -545,7 +566,9 @@ namespace WallpaperEngine::Render::Shaders
else if (type == "vec3") else if (type == "vec3")
{ {
parameter = new Variables::CShaderVariableVector3 ( parameter = new Variables::CShaderVariableVector3 (
WallpaperEngine::Core::ato3vf (*defvalue) constant == this->m_constants.end ()
? WallpaperEngine::Core::ato3vf (*defvalue)
: *(*constant).second->as <CShaderConstantVector3> ()->getValue ()
); );
} }
else if (type == "vec2") else if (type == "vec2")
@ -556,11 +579,29 @@ namespace WallpaperEngine::Render::Shaders
} }
else if (type == "float") else if (type == "float")
{ {
parameter = new Variables::CShaderVariableFloat ((*defvalue).get <irr::f32> ()); irr::f32 value = 0;
if (constant == this->m_constants.end ())
value = (*defvalue).get <irr::f32> ();
else if ((*constant).second->is <CShaderConstantFloat> () == true)
value = *(*constant).second->as <CShaderConstantFloat> ()->getValue ();
else if ((*constant).second->is <CShaderConstantInteger> () == true)
value = *(*constant).second->as <CShaderConstantInteger> ()->getValue ();
parameter = new Variables::CShaderVariableFloat (value);
} }
else if (type == "int") else if (type == "int")
{ {
parameter = new Variables::CShaderVariableInteger ((*defvalue).get <irr::s32> ()); irr::s32 value = 0;
if (constant == this->m_constants.end ())
value = (*defvalue).get <irr::s32> ();
else if ((*constant).second->is <CShaderConstantFloat> () == true)
value = *(*constant).second->as <CShaderConstantFloat> ()->getValue ();
else if ((*constant).second->is <CShaderConstantInteger> () == true)
value = *(*constant).second->as <CShaderConstantInteger> ()->getValue ();
parameter = new Variables::CShaderVariableInteger (value);
} }
else if (type == "sampler2D") else if (type == "sampler2D")
{ {

View File

@ -16,6 +16,7 @@
namespace WallpaperEngine::Render::Shaders namespace WallpaperEngine::Render::Shaders
{ {
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
/** /**
* A basic shader loader that adds basic function definitions to every loaded shader * A basic shader loader that adds basic function definitions to every loaded shader
@ -50,18 +51,29 @@ namespace WallpaperEngine::Render::Shaders
* @param file The file to load * @param file The file to load
* @param type The type of shader * @param type The type of shader
* @param combos Settings for the shader * @param combos Settings for the shader
* @param constants Default values for shader variables
* @param recursive Whether the compiler should add base definitions or not * @param recursive Whether the compiler should add base definitions or not
*/ */
Compiler (Irrlicht::CContext* context, irr::io::path& file, Type type, std::map<std::string, int> combos, bool recursive = false); Compiler (
Irrlicht::CContext* context,
irr::io::path& file,
Type type,
std::map<std::string, int> combos,
const std::map<std::string, CShaderConstant*>& constants,
bool recursive = false
);
/** /**
* Performs the actual pre-compilation/pre-processing over the shader files * Performs the actual pre-compilation/pre-processing over the shader files
* This step is kinda big, replaces variables names on sVariableReplacement, * This step is kinda big, replaces variables names on sVariableReplacement,
* ensures #include directives are correctly handled * ensures #include directives are correctly handled
* and takes care of attribute comments for the wallpaper engine specifics * and takes care of attribute comments for the wallpaper engine specifics
*
* @return The shader contents ready to be used by OpenGL
*/ */
std::string precompile (); void precompile ();
/**
* @return The compiled shader's text (if available)
*/
std::string& getCompiled ();
/** /**
* Searches the list of parameters available for the parameter with the given value * Searches the list of parameters available for the parameter with the given value
* *
@ -225,6 +237,10 @@ namespace WallpaperEngine::Render::Shaders
* The combos the shader should be generated with * The combos the shader should be generated with
*/ */
std::map <std::string, int> m_combos; std::map <std::string, int> m_combos;
/**
* The shader constants with values for variables inside the shader
*/
const std::map<std::string, CShaderConstant*>& m_constants;
/** /**
* Whether this compilation is a recursive one or not * Whether this compilation is a recursive one or not
*/ */