Skip to content

Commit 1faef3f

Browse files
Colin O'RourkeColinSORourke
authored andcommitted
[DRAFT] DrawableTextures
Implementing DrawableTextures based on: godotengine/godot-proposals#7379
1 parent 931820d commit 1faef3f

38 files changed

+2040
-4
lines changed

drivers/gles3/rasterizer_gles3.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ void RasterizerGLES3::initialize() {
211211
}
212212

213213
void RasterizerGLES3::finalize() {
214+
// Has to be a separate call due to TextureStorage & MaterialStorage needing to interact for TexBlit Shaders
215+
texture_storage->_tex_blit_shader_free();
214216
memdelete(scene);
215217
memdelete(canvas);
216218
memdelete(gi);
@@ -373,6 +375,8 @@ RasterizerGLES3::RasterizerGLES3() {
373375
fog = memnew(GLES3::Fog);
374376
canvas = memnew(RasterizerCanvasGLES3());
375377
scene = memnew(RasterizerSceneGLES3());
378+
// Has to be a separate call due to TextureStorage & MaterialStorage needing to interact for TexBlit Shaders
379+
texture_storage->_tex_blit_shader_initialize();
376380

377381
// Disable OpenGL linear to sRGB conversion, because Godot will always do this conversion itself.
378382
if (config->srgb_framebuffer_supported) {

drivers/gles3/shaders/SCsub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ if "GLES3_GLSL" in env["BUILDERS"]:
2525
env.GLES3_GLSL("particles.glsl")
2626
env.GLES3_GLSL("particles_copy.glsl")
2727
env.GLES3_GLSL("skeleton.glsl")
28+
env.GLES3_GLSL("tex_blit.glsl")
2829

2930
# once we finish conversion we can introduce this to cover all files:
3031
# for glsl_file in glsl_files:

drivers/gles3/shaders/tex_blit.glsl

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* clang-format off */
2+
3+
#[modes]
4+
5+
mode_default =
6+
7+
#[specializations]
8+
9+
USE_OUTPUT2 = true
10+
USE_OUTPUT3 = true
11+
USE_OUTPUT4 = true
12+
13+
#[vertex]
14+
15+
layout(location = 0) in vec2 vertex_attrib;
16+
17+
uniform vec2 offset;
18+
uniform vec2 size;
19+
20+
out vec2 uv;
21+
22+
void main() {
23+
uv = vertex_attrib * 0.5 + 0.5;
24+
// This math scales the Vertex Attribute Quad to match the Rect the user passed in, based on Offset & Size
25+
gl_Position = vec4( (offset * 2 - 1) + (size * (vertex_attrib + 1)), 1.0, 1.0);
26+
}
27+
28+
#[fragment]
29+
30+
uniform sampler2D source; // texunit:0
31+
32+
uniform sampler2D source2; // texunit:-1
33+
34+
uniform sampler2D source3; // texunit:-2
35+
36+
uniform sampler2D source4; // texunit:-3
37+
38+
uniform bool convert_to_srgb;
39+
uniform vec4 modulate;
40+
41+
in vec2 uv;
42+
43+
layout (location = 0) out vec4 out_color;
44+
45+
#ifdef USE_OUTPUT2
46+
layout (location = 1) out vec4 out_color2;
47+
#endif
48+
49+
#ifdef USE_OUTPUT3
50+
layout (location = 2) out vec4 out_color3;
51+
#endif
52+
53+
#ifdef USE_OUTPUT4
54+
layout (location = 3) out vec4 out_color4;
55+
#endif
56+
57+
// This needs to be outside clang-format so the ubo comment is in the right place
58+
#ifdef MATERIAL_UNIFORMS_USED
59+
layout(std140) uniform MaterialUniforms{ //ubo:0
60+
61+
#MATERIAL_UNIFORMS
62+
63+
};
64+
#endif
65+
66+
#GLOBALS
67+
68+
vec3 linear_to_srgb(vec3 color) {
69+
// If going to srgb, clamp from 0 to 1.
70+
color = clamp(color, vec3(0.0), vec3(1.0));
71+
const vec3 a = vec3(0.055f);
72+
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)));
73+
}
74+
75+
void main() {
76+
// Handles the case where user code uses extra outputs, but extra output targets were not bound
77+
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
78+
vec4 color2 = vec4(0.0, 0.0, 0.0, 1.0);
79+
vec4 color3 = vec4(0.0, 0.0, 0.0, 1.0);
80+
vec4 color4 = vec4(0.0, 0.0, 0.0, 1.0);
81+
82+
#CODE : BLIT
83+
84+
// Discards extra outputs if extra output targets were not bound
85+
out_color = color;
86+
87+
#ifdef USE_OUTPUT2
88+
out_color2 = color2;
89+
#endif
90+
#ifdef USE_OUTPUT3
91+
out_color3 = color3;
92+
#endif
93+
#ifdef USE_OUTPUT4
94+
out_color4 = color4;
95+
#endif
96+
97+
if (convert_to_srgb) {
98+
out_color.rgb = linear_to_srgb(out_color.rgb); // Regular linear -> SRGB conversion.
99+
#ifdef USE_OUTPUT2
100+
out_color2.rgb = linear_to_srgb(out_color2.rgb);
101+
#endif
102+
#ifdef USE_OUTPUT3
103+
out_color3.rgb = linear_to_srgb(out_color3.rgb);
104+
#endif
105+
#ifdef USE_OUTPUT4
106+
out_color4.rgb = linear_to_srgb(out_color4.rgb);
107+
#endif
108+
}
109+
}

drivers/gles3/storage/material_storage.cpp

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,12 +1106,14 @@ MaterialStorage::MaterialStorage() {
11061106
shader_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_shader_func;
11071107
shader_data_request_func[RS::SHADER_PARTICLES] = _create_particles_shader_func;
11081108
shader_data_request_func[RS::SHADER_SKY] = _create_sky_shader_func;
1109+
shader_data_request_func[RS::SHADER_TEXTURE_BLIT] = _create_tex_blit_shader_func;
11091110
shader_data_request_func[RS::SHADER_FOG] = nullptr;
11101111

11111112
material_data_request_func[RS::SHADER_SPATIAL] = _create_scene_material_func;
11121113
material_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_material_func;
11131114
material_data_request_func[RS::SHADER_PARTICLES] = _create_particles_material_func;
11141115
material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func;
1116+
material_data_request_func[RS::SHADER_TEXTURE_BLIT] = _create_tex_blit_material_func;
11151117
material_data_request_func[RS::SHADER_FOG] = nullptr;
11161118

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

15091511
shaders.compiler_sky.initialize(actions);
15101512
}
1513+
1514+
{
1515+
// Setup TextureBlit compiler
1516+
ShaderCompiler::DefaultIdentifierActions actions;
1517+
1518+
actions.renames["PI"] = _MKSTR(Math_PI);
1519+
actions.renames["TAU"] = _MKSTR(Math_TAU);
1520+
actions.renames["E"] = _MKSTR(Math_E);
1521+
1522+
actions.renames["FRAGCOORD"] = "gl_FragCoord";
1523+
1524+
actions.renames["UV"] = "uv";
1525+
actions.renames["MODULATE"] = "modulate";
1526+
1527+
actions.renames["COLOR"] = "color";
1528+
actions.renames["COLOR2"] = "color2";
1529+
actions.renames["COLOR3"] = "color3";
1530+
actions.renames["COLOR4"] = "color4";
1531+
1532+
shaders.compiler_tex_blit.initialize(actions);
1533+
}
15111534
}
15121535

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

3251-
bind_uniforms_generic(texture_cache, shader_data->texture_uniforms, 1); // Start at GL_TEXTURE1 because texture slot 0 is reserved for the heightmap texture.
3276+
bind_uniforms_generic(texture_cache, shader_data->texture_uniforms);
3277+
}
3278+
3279+
/* TextureBlit SHADER */
3280+
3281+
void TexBlitShaderData::set_code(const String &p_code) {
3282+
// Initialize and compile the shader.
3283+
3284+
code = p_code;
3285+
valid = false;
3286+
ubo_size = 0;
3287+
uniforms.clear();
3288+
3289+
if (code.is_empty()) {
3290+
return; // Just invalid, but no error.
3291+
}
3292+
3293+
ShaderCompiler::GeneratedCode gen_code;
3294+
3295+
// Actual enum set further down after compilation.
3296+
int blend_modei = BLEND_MODE_MIX;
3297+
3298+
ShaderCompiler::IdentifierActions actions;
3299+
actions.entry_point_stages["blit"] = ShaderCompiler::STAGE_FRAGMENT;
3300+
3301+
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_modei, BLEND_MODE_ADD);
3302+
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_modei, BLEND_MODE_MIX);
3303+
actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_modei, BLEND_MODE_SUB);
3304+
actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_modei, BLEND_MODE_MUL);
3305+
actions.render_mode_values["blend_disabled"] = Pair<int *, int>(&blend_modei, BLEND_MODE_DISABLED);
3306+
3307+
actions.uniforms = &uniforms;
3308+
Error err = MaterialStorage::get_singleton()->shaders.compiler_tex_blit.compile(RS::SHADER_TEXTURE_BLIT, code, &actions, path, gen_code);
3309+
ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
3310+
3311+
if (version.is_null()) {
3312+
version = MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_create();
3313+
}
3314+
3315+
blend_mode = BlendMode(blend_modei);
3316+
3317+
#if 0
3318+
print_line("**compiling shader:");
3319+
print_line("**defines:\n");
3320+
for (int i = 0; i < gen_code.defines.size(); i++) {
3321+
print_line(gen_code.defines[i]);
3322+
}
3323+
3324+
HashMap<String, String>::Iterator el = gen_code.code.begin();
3325+
while (el) {
3326+
print_line("\n**code " + el->key + ":\n" + el->value);
3327+
++el;
3328+
}
3329+
3330+
print_line("\n**uniforms:\n" + gen_code.uniforms);
3331+
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
3332+
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
3333+
#endif
3334+
3335+
LocalVector<ShaderGLES3::TextureUniformData> texture_uniform_data = get_texture_uniform_data(gen_code.texture_uniforms);
3336+
3337+
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);
3338+
ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_is_valid(version));
3339+
3340+
ubo_size = gen_code.uniform_total_size;
3341+
ubo_offsets = gen_code.uniform_offsets;
3342+
texture_uniforms = gen_code.texture_uniforms;
3343+
3344+
valid = true;
3345+
}
3346+
3347+
bool TexBlitShaderData::is_animated() const {
3348+
return false;
3349+
}
3350+
3351+
bool TexBlitShaderData::casts_shadows() const {
3352+
return false;
3353+
}
3354+
3355+
RS::ShaderNativeSourceCode TexBlitShaderData::get_native_source_code() const {
3356+
return MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_get_native_source_code(version);
3357+
}
3358+
3359+
TexBlitShaderData::TexBlitShaderData() {
3360+
valid = false;
3361+
}
3362+
3363+
TexBlitShaderData::~TexBlitShaderData() {
3364+
if (version.is_valid()) {
3365+
MaterialStorage::get_singleton()->shaders.tex_blit_shader.version_free(version);
3366+
}
3367+
}
3368+
3369+
GLES3::ShaderData *GLES3::_create_tex_blit_shader_func() {
3370+
TexBlitShaderData *shader_data = memnew(TexBlitShaderData);
3371+
return shader_data;
3372+
}
3373+
3374+
void TexBlitMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
3375+
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);
3376+
}
3377+
3378+
void TexBlitMaterialData::bind_uniforms() {
3379+
glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer);
3380+
3381+
bind_uniforms_generic(texture_cache, shader_data->texture_uniforms, 1);
3382+
}
3383+
3384+
TexBlitMaterialData::~TexBlitMaterialData() {
3385+
// Pass for now
3386+
}
3387+
3388+
GLES3::MaterialData *GLES3::_create_tex_blit_material_func(ShaderData *p_shader) {
3389+
TexBlitMaterialData *material_data = memnew(TexBlitMaterialData);
3390+
material_data->shader_data = static_cast<TexBlitShaderData *>(p_shader);
3391+
//update will happen later anyway so do nothing.
3392+
return material_data;
32523393
}
32533394

32543395
#endif // !GLES3_ENABLED

drivers/gles3/storage/material_storage.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "drivers/gles3/shaders/particles.glsl.gen.h"
4444
#include "drivers/gles3/shaders/scene.glsl.gen.h"
4545
#include "drivers/gles3/shaders/sky.glsl.gen.h"
46+
#include "drivers/gles3/shaders/tex_blit.glsl.gen.h"
4647

4748
namespace GLES3 {
4849

@@ -399,6 +400,52 @@ struct ParticleProcessMaterialData : public MaterialData {
399400

400401
MaterialData *_create_particles_material_func(ShaderData *p_shader);
401402

403+
/* Texture Blit Shader */
404+
405+
struct TexBlitShaderData : public ShaderData {
406+
enum BlendMode { // Used internally.
407+
BLEND_MODE_MIX,
408+
BLEND_MODE_ADD,
409+
BLEND_MODE_SUB,
410+
BLEND_MODE_MUL,
411+
BLEND_MODE_DISABLED,
412+
};
413+
414+
bool valid;
415+
RID version;
416+
417+
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
418+
419+
Vector<uint32_t> ubo_offsets;
420+
uint32_t ubo_size;
421+
422+
String code;
423+
424+
BlendMode blend_mode;
425+
426+
virtual void set_code(const String &p_Code);
427+
virtual bool is_animated() const;
428+
virtual bool casts_shadows() const;
429+
virtual RS::ShaderNativeSourceCode get_native_source_code() const;
430+
431+
TexBlitShaderData();
432+
virtual ~TexBlitShaderData();
433+
};
434+
435+
ShaderData *_create_tex_blit_shader_func();
436+
437+
struct TexBlitMaterialData : public MaterialData {
438+
TexBlitShaderData *shader_data = nullptr;
439+
440+
virtual void set_render_priority(int p_priority) {}
441+
virtual void set_next_pass(RID p_pass) {}
442+
virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
443+
virtual void bind_uniforms();
444+
virtual ~TexBlitMaterialData();
445+
};
446+
447+
MaterialData *_create_tex_blit_material_func(ShaderData *p_shader);
448+
402449
/* Global shader uniform structs */
403450
struct GlobalShaderUniforms {
404451
enum {
@@ -535,11 +582,13 @@ class MaterialStorage : public RendererMaterialStorage {
535582
SkyShaderGLES3 sky_shader;
536583
SceneShaderGLES3 scene_shader;
537584
ParticlesShaderGLES3 particles_process_shader;
585+
TexBlitShaderGLES3 tex_blit_shader;
538586

539587
ShaderCompiler compiler_canvas;
540588
ShaderCompiler compiler_scene;
541589
ShaderCompiler compiler_particles;
542590
ShaderCompiler compiler_sky;
591+
ShaderCompiler compiler_tex_blit;
543592
} shaders;
544593

545594
/* GLOBAL SHADER UNIFORM API */

0 commit comments

Comments
 (0)