mirror of
https://github.com/minetest/minetest.git
synced 2024-12-22 22:22:23 +01:00
Initial refactoring on shader usage and generation
`IShaderSource` was designed with the idea that if you want a shader, you must want it for a node. So it depends heavily on being given a tile material and the node drawtype. But this doesn't make sense neither in theory nor in practice. This commit takes a small step towards removing the incorrect abstraction.
This commit is contained in:
parent
eb8beb335e
commit
a6293b9861
@ -1,6 +0,0 @@
|
||||
varying lowp vec4 varColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragData[0] = varColor;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
varying lowp vec4 varColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = mWorldViewProj * inVertexPosition;
|
||||
varColor = inVertexColor;
|
||||
}
|
@ -1,7 +1,3 @@
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT)
|
||||
#define MATERIAL_WAVING_LIQUID 1
|
||||
#endif
|
||||
|
||||
uniform sampler2D baseTexture;
|
||||
|
||||
uniform vec3 dayLight;
|
||||
@ -53,7 +49,7 @@ varying highp vec3 eyeVec;
|
||||
varying float nightRatio;
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER)
|
||||
#if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER)
|
||||
vec4 perm(vec4 x)
|
||||
{
|
||||
return mod(((x * 34.0) + 1.0) * x, 289.0);
|
||||
@ -504,7 +500,7 @@ void main(void)
|
||||
vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition);
|
||||
|
||||
// Water reflections
|
||||
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER)
|
||||
#if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER)
|
||||
vec3 wavePos = worldPosition * vec3(2.0, 0.0, 2.0);
|
||||
float off = animationTimer * WATER_WAVE_SPEED * 10.0;
|
||||
wavePos.x /= WATER_WAVE_LENGTH * 3.0;
|
||||
@ -532,7 +528,7 @@ void main(void)
|
||||
col.rgb += water_reflect_color * f_adj_shadow_strength * brightness_factor;
|
||||
#endif
|
||||
|
||||
#if (defined(ENABLE_NODE_SPECULAR) && !defined(MATERIAL_WAVING_LIQUID))
|
||||
#if (defined(ENABLE_NODE_SPECULAR) && !MATERIAL_WAVING_LIQUID)
|
||||
// Apply specular to blocks.
|
||||
if (dot(v_LightDirection, vNormal) < 0.0) {
|
||||
float intensity = 2.0 * (1.0 - (base.r * varColor.r));
|
||||
|
@ -108,8 +108,7 @@ float smoothTriangleWave(float x)
|
||||
return smoothCurve(triangleWave(x)) * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
// OpenGL < 4.3 does not support continued preprocessor lines
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
|
||||
#if MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER
|
||||
|
||||
//
|
||||
// Simple, fast noise function.
|
||||
@ -166,8 +165,7 @@ void main(void)
|
||||
#endif
|
||||
|
||||
vec4 pos = inVertexPosition;
|
||||
// OpenGL < 4.3 does not support continued preprocessor lines
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
|
||||
#if MATERIAL_WAVING_LIQUID && ENABLE_WAVING_WATER
|
||||
// Generate waves with Perlin-type noise.
|
||||
// The constants are calibrated such that they roughly
|
||||
// correspond to the old sine waves.
|
||||
|
@ -38,7 +38,7 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
|
||||
m_material.FogEnable = true;
|
||||
m_material.AntiAliasing = video::EAAM_SIMPLE;
|
||||
{
|
||||
auto sid = ssrc->getShader("cloud_shader", TILE_MATERIAL_ALPHA);
|
||||
auto sid = ssrc->getShaderRaw("cloud_shader", true);
|
||||
m_material.MaterialType = ssrc->getShaderInfo(sid).material;
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,11 @@ Hud::Hud(Client *client, LocalPlayer *player,
|
||||
|
||||
// Initialize m_selection_material
|
||||
IShaderSource *shdrsrc = client->getShaderSource();
|
||||
{
|
||||
auto shader_id = shdrsrc->getShader(
|
||||
m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", TILE_MATERIAL_ALPHA);
|
||||
if (m_mode == HIGHLIGHT_HALO) {
|
||||
auto shader_id = shdrsrc->getShaderRaw("selection_shader", true);
|
||||
m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
|
||||
} else {
|
||||
m_selection_material.MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
|
||||
if (m_mode == HIGHLIGHT_BOX) {
|
||||
@ -103,10 +104,7 @@ Hud::Hud(Client *client, LocalPlayer *player,
|
||||
}
|
||||
|
||||
// Initialize m_block_bounds_material
|
||||
{
|
||||
auto shader_id = shdrsrc->getShader("default_shader", TILE_MATERIAL_ALPHA);
|
||||
m_block_bounds_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
|
||||
}
|
||||
m_block_bounds_material.MaterialType = video::EMT_SOLID;
|
||||
m_block_bounds_material.Thickness =
|
||||
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
|
||||
|
||||
|
@ -599,7 +599,7 @@ void Minimap::drawMinimap(core::rect<s32> rect)
|
||||
material.TextureLayers[1].Texture = data->heightmap_texture;
|
||||
|
||||
if (data->mode.type == MINIMAP_TYPE_SURFACE) {
|
||||
auto sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA);
|
||||
auto sid = m_shdrsrc->getShaderRaw("minimap_shader", true);
|
||||
material.MaterialType = m_shdrsrc->getShaderInfo(sid).material;
|
||||
} else {
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
|
@ -66,10 +66,12 @@ void populateInterlacedPipeline(RenderPipeline *pipeline, Client *client)
|
||||
}
|
||||
|
||||
pipeline->addStep<OffsetCameraStep>(0.0f);
|
||||
|
||||
IShaderSource *s = client->getShaderSource();
|
||||
u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC);
|
||||
auto shader = s->getShaderRaw("3d_interlaced_merge");
|
||||
video::E_MATERIAL_TYPE material = s->getShaderInfo(shader).material;
|
||||
auto texture_map = { TEXTURE_LEFT, TEXTURE_RIGHT, TEXTURE_MASK };
|
||||
|
||||
auto merge = pipeline->addStep<PostProcessingStep>(material, texture_map);
|
||||
merge->setRenderSource(buffer);
|
||||
merge->setRenderTarget(pipeline->createOwned<ScreenTarget>());
|
||||
|
@ -188,7 +188,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
buffer->setTexture(TEXTURE_BLOOM, scale, "bloom", bloom_format);
|
||||
|
||||
// get bright spots
|
||||
u32 shader_id = client->getShaderSource()->getShader("extract_bloom", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||
u32 shader_id = client->getShaderSource()->getShaderRaw("extract_bloom");
|
||||
RenderStep *extract_bloom = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source, TEXTURE_EXPOSURE_1 });
|
||||
extract_bloom->setRenderSource(buffer);
|
||||
extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM));
|
||||
@ -198,7 +198,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
if (enable_volumetric_light) {
|
||||
buffer->setTexture(TEXTURE_VOLUME, scale, "volume", color_format);
|
||||
|
||||
shader_id = client->getShaderSource()->getShader("volumetric_light", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||
shader_id = client->getShaderSource()->getShaderRaw("volumetric_light");
|
||||
auto volume = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source, TEXTURE_DEPTH });
|
||||
volume->setRenderSource(buffer);
|
||||
volume->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_VOLUME));
|
||||
@ -206,7 +206,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
}
|
||||
|
||||
// downsample
|
||||
shader_id = client->getShaderSource()->getShader("bloom_downsample", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||
shader_id = client->getShaderSource()->getShaderRaw("bloom_downsample");
|
||||
for (u8 i = 0; i < MIPMAP_LEVELS; i++) {
|
||||
auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source });
|
||||
step->setRenderSource(buffer);
|
||||
@ -219,7 +219,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
// Bloom pt 2
|
||||
if (enable_bloom) {
|
||||
// upsample
|
||||
shader_id = client->getShaderSource()->getShader("bloom_upsample", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||
shader_id = client->getShaderSource()->getShaderRaw("bloom_upsample");
|
||||
for (u8 i = MIPMAP_LEVELS - 1; i > 0; i--) {
|
||||
auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { u8(TEXTURE_SCALE_DOWN + i - 1), source });
|
||||
step->setRenderSource(buffer);
|
||||
@ -232,7 +232,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
|
||||
// Dynamic Exposure pt2
|
||||
if (enable_auto_exposure) {
|
||||
shader_id = client->getShaderSource()->getShader("update_exposure", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||
shader_id = client->getShaderSource()->getShaderRaw("update_exposure");
|
||||
auto update_exposure = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_EXPOSURE_1, u8(TEXTURE_SCALE_DOWN + MIPMAP_LEVELS - 1) });
|
||||
update_exposure->setBilinearFilter(1, true);
|
||||
update_exposure->setRenderSource(buffer);
|
||||
@ -246,7 +246,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
final_stage_source = TEXTURE_FXAA;
|
||||
|
||||
buffer->setTexture(TEXTURE_FXAA, scale, "fxaa", color_format);
|
||||
shader_id = client->getShaderSource()->getShader("fxaa", TILE_MATERIAL_PLAIN);
|
||||
shader_id = client->getShaderSource()->getShaderRaw("fxaa");
|
||||
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR });
|
||||
pipeline->addStep(effect);
|
||||
effect->setBilinearFilter(0, true);
|
||||
@ -255,7 +255,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep
|
||||
}
|
||||
|
||||
// final merge
|
||||
shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH);
|
||||
shader_id = client->getShaderSource()->getShaderRaw("second_stage");
|
||||
PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { final_stage_source, TEXTURE_SCALE_UP, TEXTURE_EXPOSURE_2 });
|
||||
pipeline->addStep(effect);
|
||||
if (enable_ssaa)
|
||||
|
@ -271,7 +271,7 @@ public:
|
||||
The id 0 points to a null shader. Its material is EMT_SOLID.
|
||||
*/
|
||||
u32 getShaderIdDirect(const std::string &name,
|
||||
MaterialType material_type, NodeDrawType drawtype) override;
|
||||
MaterialType material_type, NodeDrawType drawtype);
|
||||
|
||||
/*
|
||||
If shader specified by the name pointed by the id doesn't
|
||||
@ -281,10 +281,18 @@ public:
|
||||
and not found in cache, the call is queued to the main thread
|
||||
for processing.
|
||||
*/
|
||||
|
||||
u32 getShader(const std::string &name,
|
||||
MaterialType material_type, NodeDrawType drawtype) override;
|
||||
|
||||
u32 getShaderRaw(const std::string &name, bool blendAlpha) override
|
||||
{
|
||||
// TODO: the shader system should be refactored to be much more generic.
|
||||
// Just let callers pass arbitrary constants, this would also deal with
|
||||
// runtime changes cleanly.
|
||||
return getShader(name, blendAlpha ? TILE_MATERIAL_ALPHA : TILE_MATERIAL_BASIC,
|
||||
NodeDrawType_END);
|
||||
}
|
||||
|
||||
ShaderInfo getShaderInfo(u32 id) override;
|
||||
|
||||
// Processes queued shader requests from other threads.
|
||||
@ -607,11 +615,17 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||
#define textureFlags texture2
|
||||
)";
|
||||
|
||||
/* Define constants for node and object shaders */
|
||||
const bool node_shader = drawtype != NodeDrawType_END;
|
||||
if (node_shader) {
|
||||
|
||||
bool use_discard = fully_programmable;
|
||||
// For renderers that should use discard instead of GL_ALPHA_TEST
|
||||
if (!use_discard) {
|
||||
// workaround for a certain OpenGL implementation lacking GL_ALPHA_TEST
|
||||
const char *renderer = reinterpret_cast<const char*>(GL.GetString(GL.RENDERER));
|
||||
if (strstr(renderer, "GC7000"))
|
||||
use_discard = true;
|
||||
}
|
||||
if (use_discard) {
|
||||
if (shaderinfo.base_material == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
|
||||
shaders_header << "#define USE_DISCARD 1\n";
|
||||
@ -664,9 +678,25 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||
shaders_header << "#define WATER_WAVE_LENGTH " << g_settings->getFloat("water_wave_length") << "\n";
|
||||
shaders_header << "#define WATER_WAVE_SPEED " << g_settings->getFloat("water_wave_speed") << "\n";
|
||||
}
|
||||
switch (material_type) {
|
||||
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
|
||||
case TILE_MATERIAL_WAVING_LIQUID_OPAQUE:
|
||||
case TILE_MATERIAL_WAVING_LIQUID_BASIC:
|
||||
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
||||
shaders_header << "#define MATERIAL_WAVING_LIQUID 1\n";
|
||||
break;
|
||||
default:
|
||||
shaders_header << "#define MATERIAL_WAVING_LIQUID 0\n";
|
||||
break;
|
||||
}
|
||||
|
||||
shaders_header << "#define ENABLE_WAVING_LEAVES " << g_settings->getBool("enable_waving_leaves") << "\n";
|
||||
shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n";
|
||||
|
||||
}
|
||||
|
||||
/* Other constants */
|
||||
|
||||
shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n";
|
||||
|
||||
if (g_settings->getBool("enable_dynamic_shadows")) {
|
||||
|
@ -196,18 +196,33 @@ using CachedStructPixelShaderSetting = CachedStructShaderSetting<T, count, cache
|
||||
|
||||
/*
|
||||
ShaderSource creates and caches shaders.
|
||||
*/
|
||||
|
||||
A "shader" could more precisely be called a "shader material" and comprises
|
||||
a vertex, fragment and optional geometry shader.
|
||||
*/
|
||||
class IShaderSource {
|
||||
public:
|
||||
IShaderSource() = default;
|
||||
virtual ~IShaderSource() = default;
|
||||
|
||||
virtual u32 getShaderIdDirect(const std::string &name,
|
||||
MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;}
|
||||
virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
|
||||
/**
|
||||
* @brief returns information about an existing shader
|
||||
*
|
||||
* Use this to get the material ID to plug into `video::SMaterial`.
|
||||
*/
|
||||
virtual ShaderInfo getShaderInfo(u32 id) = 0;
|
||||
|
||||
/// @brief Generates or gets a shader suitable for nodes and entities
|
||||
virtual u32 getShader(const std::string &name,
|
||||
MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;}
|
||||
MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL) = 0;
|
||||
|
||||
/**
|
||||
* Generates or gets a shader for general use.
|
||||
* @param name name of the shader (directory on disk)
|
||||
* @param blendAlpha enable alpha blending for this material?
|
||||
* @return shader ID
|
||||
*/
|
||||
virtual u32 getShaderRaw(const std::string &name, bool blendAlpha = false) = 0;
|
||||
};
|
||||
|
||||
class IWritableShaderSource : public IShaderSource {
|
||||
|
@ -62,7 +62,7 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
|
||||
|
||||
m_materials[0] = baseMaterial();
|
||||
m_materials[0].MaterialType =
|
||||
ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA)).material;
|
||||
ssrc->getShaderInfo(ssrc->getShaderRaw("stars_shader", true)).material;
|
||||
|
||||
m_materials[1] = baseMaterial();
|
||||
m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
|
@ -20,6 +20,7 @@ enum MaterialType{
|
||||
TILE_MATERIAL_WAVING_LIQUID_BASIC,
|
||||
TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT,
|
||||
TILE_MATERIAL_WAVING_LIQUID_OPAQUE,
|
||||
// Note: PLAIN isn't a material actually used by tiles, rather just entities.
|
||||
TILE_MATERIAL_PLAIN,
|
||||
TILE_MATERIAL_PLAIN_ALPHA
|
||||
};
|
||||
|
@ -222,6 +222,7 @@ enum NodeDrawType : u8
|
||||
NDT_MESH,
|
||||
// Combined plantlike-on-solid
|
||||
NDT_PLANTLIKE_ROOTED,
|
||||
|
||||
// Dummy for validity check
|
||||
NodeDrawType_END
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user