Skip to content

[DRAFT] DrawableTextures #105701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions drivers/gles3/rasterizer_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ void RasterizerGLES3::initialize() {
}

void RasterizerGLES3::finalize() {
// Has to be a separate call due to TextureStorage & MaterialStorage needing to interact for TexBlit Shaders
texture_storage->_tex_blit_shader_free();
memdelete(scene);
memdelete(canvas);
memdelete(gi);
Expand Down Expand Up @@ -373,6 +375,8 @@ RasterizerGLES3::RasterizerGLES3() {
fog = memnew(GLES3::Fog);
canvas = memnew(RasterizerCanvasGLES3());
scene = memnew(RasterizerSceneGLES3());
// Has to be a separate call due to TextureStorage & MaterialStorage needing to interact for TexBlit Shaders
texture_storage->_tex_blit_shader_initialize();

// Disable OpenGL linear to sRGB conversion, because Godot will always do this conversion itself.
if (config->srgb_framebuffer_supported) {
Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/shaders/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ if "GLES3_GLSL" in env["BUILDERS"]:
env.GLES3_GLSL("particles.glsl")
env.GLES3_GLSL("particles_copy.glsl")
env.GLES3_GLSL("skeleton.glsl")
env.GLES3_GLSL("tex_blit.glsl")

# once we finish conversion we can introduce this to cover all files:
# for glsl_file in glsl_files:
Expand Down
109 changes: 109 additions & 0 deletions drivers/gles3/shaders/tex_blit.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/* clang-format off */

#[modes]

mode_default =

#[specializations]

USE_OUTPUT2 = true
USE_OUTPUT3 = true
USE_OUTPUT4 = true

#[vertex]

layout(location = 0) in vec2 vertex_attrib;

uniform vec2 offset;
uniform vec2 size;

out vec2 uv;

void main() {
uv = vertex_attrib * 0.5 + 0.5;
// This math scales the Vertex Attribute Quad to match the Rect the user passed in, based on Offset & Size
gl_Position = vec4( (offset * 2 - 1) + (size * (vertex_attrib + 1)), 1.0, 1.0);
}

#[fragment]

uniform sampler2D source; // texunit:0

uniform sampler2D source2; // texunit:-1

uniform sampler2D source3; // texunit:-2

uniform sampler2D source4; // texunit:-3

uniform bool convert_to_srgb;
uniform vec4 modulate;

in vec2 uv;

layout (location = 0) out vec4 out_color;

#ifdef USE_OUTPUT2
layout (location = 1) out vec4 out_color2;
#endif

#ifdef USE_OUTPUT3
layout (location = 2) out vec4 out_color3;
#endif

#ifdef USE_OUTPUT4
layout (location = 3) out vec4 out_color4;
#endif

// This needs to be outside clang-format so the ubo comment is in the right place
#ifdef MATERIAL_UNIFORMS_USED
layout(std140) uniform MaterialUniforms{ //ubo:0

#MATERIAL_UNIFORMS

};
#endif

#GLOBALS

vec3 linear_to_srgb(vec3 color) {
// If going to srgb, clamp from 0 to 1.
color = clamp(color, vec3(0.0), vec3(1.0));
const vec3 a = vec3(0.055f);
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
}

void main() {
// Handles the case where user code uses extra outputs, but extra output targets were not bound
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
vec4 color2 = vec4(0.0, 0.0, 0.0, 1.0);
vec4 color3 = vec4(0.0, 0.0, 0.0, 1.0);
vec4 color4 = vec4(0.0, 0.0, 0.0, 1.0);

#CODE : BLIT

// Discards extra outputs if extra output targets were not bound
out_color = color;

#ifdef USE_OUTPUT2
out_color2 = color2;
#endif
#ifdef USE_OUTPUT3
out_color3 = color3;
#endif
#ifdef USE_OUTPUT4
out_color4 = color4;
#endif

if (convert_to_srgb) {
out_color.rgb = linear_to_srgb(out_color.rgb); // Regular linear -> SRGB conversion.
#ifdef USE_OUTPUT2
out_color2.rgb = linear_to_srgb(out_color2.rgb);
#endif
#ifdef USE_OUTPUT3
out_color3.rgb = linear_to_srgb(out_color3.rgb);
#endif
#ifdef USE_OUTPUT4
out_color4.rgb = linear_to_srgb(out_color4.rgb);
#endif
}
}
143 changes: 142 additions & 1 deletion drivers/gles3/storage/material_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,12 +1106,14 @@ MaterialStorage::MaterialStorage() {
shader_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_shader_func;
shader_data_request_func[RS::SHADER_PARTICLES] = _create_particles_shader_func;
shader_data_request_func[RS::SHADER_SKY] = _create_sky_shader_func;
shader_data_request_func[RS::SHADER_TEXTURE_BLIT] = _create_tex_blit_shader_func;
shader_data_request_func[RS::SHADER_FOG] = nullptr;

material_data_request_func[RS::SHADER_SPATIAL] = _create_scene_material_func;
material_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_material_func;
material_data_request_func[RS::SHADER_PARTICLES] = _create_particles_material_func;
material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func;
material_data_request_func[RS::SHADER_TEXTURE_BLIT] = _create_tex_blit_material_func;
material_data_request_func[RS::SHADER_FOG] = nullptr;

static_assert(sizeof(GlobalShaderUniforms::Value) == 16);
Expand Down Expand Up @@ -1508,6 +1510,27 @@ MaterialStorage::MaterialStorage() {

shaders.compiler_sky.initialize(actions);
}

{
// Setup TextureBlit compiler
ShaderCompiler::DefaultIdentifierActions actions;

actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);

actions.renames["FRAGCOORD"] = "gl_FragCoord";

actions.renames["UV"] = "uv";
actions.renames["MODULATE"] = "modulate";

actions.renames["COLOR"] = "color";
actions.renames["COLOR2"] = "color2";
actions.renames["COLOR3"] = "color3";
actions.renames["COLOR4"] = "color4";

shaders.compiler_tex_blit.initialize(actions);
}
}

MaterialStorage::~MaterialStorage() {
Expand Down Expand Up @@ -2192,6 +2215,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
new_mode = RS::SHADER_SKY;
//} else if (mode_string == "fog") {
// new_mode = RS::SHADER_FOG;
} else if (mode_string == "texture_blit") {
new_mode = RS::SHADER_TEXTURE_BLIT;
} else {
new_mode = RS::SHADER_MAX;
ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
Expand Down Expand Up @@ -3248,7 +3273,123 @@ void ParticleProcessMaterialData::bind_uniforms() {
// Bind Material Uniforms
glBindBufferBase(GL_UNIFORM_BUFFER, GLES3::PARTICLES_MATERIAL_UNIFORM_LOCATION, uniform_buffer);

bind_uniforms_generic(texture_cache, shader_data->texture_uniforms, 1); // Start at GL_TEXTURE1 because texture slot 0 is reserved for the heightmap texture.
bind_uniforms_generic(texture_cache, shader_data->texture_uniforms);
}

/* TextureBlit SHADER */

void TexBlitShaderData::set_code(const String &p_code) {
// Initialize and compile the shader.

code = p_code;
valid = false;
ubo_size = 0;
uniforms.clear();

if (code.is_empty()) {
return; // Just invalid, but no error.
}

ShaderCompiler::GeneratedCode gen_code;

// Actual enum set further down after compilation.
int blend_modei = BLEND_MODE_MIX;

ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["blit"] = ShaderCompiler::STAGE_FRAGMENT;

actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_modei, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_modei, BLEND_MODE_MIX);
actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_modei, BLEND_MODE_SUB);
actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_modei, BLEND_MODE_MUL);
actions.render_mode_values["blend_disabled"] = Pair<int *, int>(&blend_modei, BLEND_MODE_DISABLED);

actions.uniforms = &uniforms;
Error err = MaterialStorage::get_singleton()->shaders.compiler_tex_blit.compile(RS::SHADER_TEXTURE_BLIT, code, &actions, path, gen_code);
ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");

if (version.is_null()) {
version = MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_create();
}

blend_mode = BlendMode(blend_modei);

#if 0
print_line("**compiling shader:");
print_line("**defines:\n");
for (int i = 0; i < gen_code.defines.size(); i++) {
print_line(gen_code.defines[i]);
}

HashMap<String, String>::Iterator el = gen_code.code.begin();
while (el) {
print_line("\n**code " + el->key + ":\n" + el->value);
++el;
}

print_line("\n**uniforms:\n" + gen_code.uniforms);
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif

LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data = get_texture_uniform_data(gen_code.texture_uniforms);

MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_data);
ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_is_valid(version));

ubo_size = gen_code.uniform_total_size;
ubo_offsets = gen_code.uniform_offsets;
texture_uniforms = gen_code.texture_uniforms;

valid = true;
}

bool TexBlitShaderData::is_animated() const {
return false;
}

bool TexBlitShaderData::casts_shadows() const {
return false;
}

RS::ShaderNativeSourceCode TexBlitShaderData::get_native_source_code() const {
return MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_get_native_source_code(version);
}

TexBlitShaderData::TexBlitShaderData() {
valid = false;
}

TexBlitShaderData::~TexBlitShaderData() {
if (version.is_valid()) {
MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_free(version);
}
}

GLES3::ShaderData *GLES3::_create_tex_blit_shader_func() {
TexBlitShaderData *shader_data = memnew(TexBlitShaderData);
return shader_data;
}

void TexBlitMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
update_parameters_internal(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, false);
}

void TexBlitMaterialData::bind_uniforms() {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer);

bind_uniforms_generic(texture_cache, shader_data->texture_uniforms, 1);
}

TexBlitMaterialData::~TexBlitMaterialData() {
// Pass for now
}

GLES3::MaterialData *GLES3::_create_tex_blit_material_func(ShaderData *p_shader) {
TexBlitMaterialData *material_data = memnew(TexBlitMaterialData);
material_data->shader_data = static_cast<TexBlitShaderData *>(p_shader);
//update will happen later anyway so do nothing.
return material_data;
}

#endif // !GLES3_ENABLED
49 changes: 49 additions & 0 deletions drivers/gles3/storage/material_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "drivers/gles3/shaders/particles.glsl.gen.h"
#include "drivers/gles3/shaders/scene.glsl.gen.h"
#include "drivers/gles3/shaders/sky.glsl.gen.h"
#include "drivers/gles3/shaders/tex_blit.glsl.gen.h"

namespace GLES3 {

Expand Down Expand Up @@ -399,6 +400,52 @@ struct ParticleProcessMaterialData : public MaterialData {

MaterialData *_create_particles_material_func(ShaderData *p_shader);

/* Texture Blit Shader */

struct TexBlitShaderData : public ShaderData {
enum BlendMode { // Used internally.
BLEND_MODE_MIX,
BLEND_MODE_ADD,
BLEND_MODE_SUB,
BLEND_MODE_MUL,
BLEND_MODE_DISABLED,
};

bool valid;
RID version;

Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;

Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;

String code;

BlendMode blend_mode;

virtual void set_code(const String &p_Code);
virtual bool is_animated() const;
virtual bool casts_shadows() const;
virtual RS::ShaderNativeSourceCode get_native_source_code() const;

TexBlitShaderData();
virtual ~TexBlitShaderData();
};

ShaderData *_create_tex_blit_shader_func();

struct TexBlitMaterialData : public MaterialData {
TexBlitShaderData *shader_data = nullptr;

virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual void bind_uniforms();
virtual ~TexBlitMaterialData();
};

MaterialData *_create_tex_blit_material_func(ShaderData *p_shader);

/* Global shader uniform structs */
struct GlobalShaderUniforms {
enum {
Expand Down Expand Up @@ -535,11 +582,13 @@ class MaterialStorage : public RendererMaterialStorage {
SkyShaderGLES3 sky_shader;
SceneShaderGLES3 scene_shader;
ParticlesShaderGLES3 particles_process_shader;
TexBlitShaderGLES3 tex_blit_shader;

ShaderCompiler compiler_canvas;
ShaderCompiler compiler_scene;
ShaderCompiler compiler_particles;
ShaderCompiler compiler_sky;
ShaderCompiler compiler_tex_blit;
} shaders;

/* GLOBAL SHADER UNIFORM API */
Expand Down
Loading
Loading