Skip to content

Commit

Permalink
Add custom shader attributes to Canvas Item Shaders
Browse files Browse the repository at this point in the history
Add custom attrs to canvas item visual shader editor
  • Loading branch information
Giwayume committed Dec 28, 2023
1 parent 13a0d6e commit 385645f
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 19 deletions.
12 changes: 6 additions & 6 deletions drivers/gles3/rasterizer_canvas_gles3.cpp
Expand Up @@ -1412,7 +1412,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index, Ren
GLuint vertex_array_gl = 0;
GLuint index_array_gl = 0;

uint64_t input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_COLOR | RS::ARRAY_FORMAT_TEX_UV; // 2D meshes always use the same vertex format.
uint64_t input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_COLOR | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_CUSTOM0 | RS::ARRAY_FORMAT_CUSTOM1; // We could inspect materials to figure this out, but is it worth it?
if (mesh_instance.is_valid()) {
mesh_storage->mesh_instance_surface_get_vertex_arrays_and_format(mesh_instance, j, input_mask, vertex_array_gl);
} else {
Expand Down Expand Up @@ -1539,15 +1539,15 @@ void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken) {
}

void RasterizerCanvasGLES3::_enable_attributes(uint32_t p_start, bool p_primitive, uint32_t p_rate) {
uint32_t split = p_primitive ? 11 : 12;
for (uint32_t i = 6; i < split; i++) {
uint32_t split = p_primitive ? 13 : 14;
for (uint32_t i = 8; i < split; i++) {
glEnableVertexAttribArray(i);
glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 6) * 4 * sizeof(float)));
glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 8) * 4 * sizeof(float)));
glVertexAttribDivisor(i, p_rate);
}
for (uint32_t i = split; i <= 13; i++) {
for (uint32_t i = split; i <= 15; i++) {
glEnableVertexAttribArray(i);
glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 6) * 4 * sizeof(float)));
glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 8) * 4 * sizeof(float)));
glVertexAttribDivisor(i, p_rate);
}
}
Expand Down
42 changes: 31 additions & 11 deletions drivers/gles3/shaders/canvas.glsl
Expand Up @@ -32,18 +32,26 @@ layout(location = 5) in highp uvec4 instance_color_custom_data; // Color packed

#include "stdlib_inc.glsl"

layout(location = 6) in highp vec4 attrib_A;
layout(location = 7) in highp vec4 attrib_B;
layout(location = 8) in highp vec4 attrib_C;
layout(location = 9) in highp vec4 attrib_D;
layout(location = 10) in highp vec4 attrib_E;
#if defined(CUSTOM0_USED)
layout(location = 6) in highp vec4 custom0_attrib;
#endif

#if defined(CUSTOM1_USED)
layout(location = 7) in highp vec4 custom1_attrib;
#endif

layout(location = 8) in highp vec4 attrib_A;
layout(location = 9) in highp vec4 attrib_B;
layout(location = 10) in highp vec4 attrib_C;
layout(location = 11) in highp vec4 attrib_D;
layout(location = 12) in highp vec4 attrib_E;
#ifdef USE_PRIMITIVE
layout(location = 11) in highp uvec4 attrib_F;
layout(location = 13) in highp uvec4 attrib_F;
#else
layout(location = 11) in highp vec4 attrib_F;
layout(location = 13) in highp vec4 attrib_F;
#endif
layout(location = 12) in highp uvec4 attrib_G;
layout(location = 13) in highp uvec4 attrib_H;
layout(location = 14) in highp uvec4 attrib_G;
layout(location = 15) in highp uvec4 attrib_H;

#define read_draw_data_world_x attrib_A.xy
#define read_draw_data_world_y attrib_A.zw
Expand Down Expand Up @@ -136,6 +144,10 @@ void main() {
varying_G = read_draw_data_lights;

vec4 instance_custom = vec4(0.0);
vec4 custom0 = vec4(0.0);
vec4 custom1 = vec4(0.0);
vec4 custom2 = vec4(0.0); // These two are unusable in gles3, but leaving the declaration
vec4 custom3 = vec4(0.0); // here makes switching between renderers relatively harmless

#ifdef USE_PRIMITIVE
vec2 vertex;
Expand Down Expand Up @@ -169,17 +181,25 @@ void main() {
if (bool(read_draw_data_flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
}
#endif // !USE_INSTANCING

#if defined(CUSTOM0_USED)
custom0 = custom0_attrib;
#endif

#else
#if defined(CUSTOM1_USED)
custom1 = custom1_attrib;
#endif

#else // !USE_ATTRIBUTES
vec2 vertex_base_arr[6] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(1.0, 1.0));
vec2 vertex_base = vertex_base_arr[gl_VertexID % 6];

vec2 uv = read_draw_data_src_rect.xy + abs(read_draw_data_src_rect.zw) * ((read_draw_data_flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy);
vec4 color = read_draw_data_modulation;
vec2 vertex = read_draw_data_dst_rect.xy + abs(read_draw_data_dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(read_draw_data_src_rect.zw, vec2(0.0, 0.0)));

#endif
#endif // USE_ATTRIBUTES

mat4 model_matrix = mat4(vec4(read_draw_data_world_x, 0.0, 0.0), vec4(read_draw_data_world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(read_draw_data_world_ofs, 0.0, 1.0));

Expand Down
9 changes: 9 additions & 0 deletions drivers/gles3/storage/material_storage.cpp
Expand Up @@ -1160,6 +1160,11 @@ MaterialStorage::MaterialStorage() {
actions.renames["INSTANCE_ID"] = "gl_InstanceID";
actions.renames["VERTEX_ID"] = "gl_VertexID";

actions.renames["CUSTOM0"] = "custom0";
actions.renames["CUSTOM1"] = "custom1";
actions.renames["CUSTOM2"] = "custom2";
actions.renames["CUSTOM3"] = "custom3";

actions.renames["LIGHT_POSITION"] = "light_position";
actions.renames["LIGHT_DIRECTION"] = "light_direction";
actions.renames["LIGHT_IS_DIRECTIONAL"] = "is_directional";
Expand All @@ -1180,6 +1185,10 @@ MaterialStorage::MaterialStorage() {
actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
actions.usage_defines["SPECULAR_SHININESS"] = "#define SPECULAR_SHININESS_USED\n";
actions.usage_defines["CUSTOM0"] = "#define CUSTOM0_USED\n";
actions.usage_defines["CUSTOM1"] = "#define CUSTOM1_USED\n";
actions.usage_defines["CUSTOM2"] = "#define CUSTOM2_USED\n";
actions.usage_defines["CUSTOM3"] = "#define CUSTOM3_USED\n";

actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
Expand Down
4 changes: 4 additions & 0 deletions editor/plugins/visual_shader_editor_plugin.cpp
Expand Up @@ -5786,6 +5786,10 @@ VisualShaderEditor::VisualShaderEditor() {

add_options.push_back(AddOption("AtLightPass", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass", "AT_LIGHT_PASS"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("CanvasMatrix", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas_matrix", "CANVAS_MATRIX"), { "canvas_matrix" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Custom0", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom0", "CUSTOM0"), { "custom0" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Custom1", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom1", "CUSTOM1"), { "custom1" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Custom2", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom2", "CUSTOM2"), { "custom2" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Custom3", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom3", "CUSTOM3"), { "custom3" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("InstanceCustom", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom", "INSTANCE_CUSTOM"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR_4D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("InstanceId", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id", "INSTANCE_ID"), { "instance_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ModelMatrix", "Input/Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "model_matrix", "MODEL_MATRIX"), { "model_matrix" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
Expand Down
4 changes: 4 additions & 0 deletions scene/resources/visual_shader.cpp
Expand Up @@ -2952,6 +2952,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "screen_matrix", "SCREEN_MATRIX" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_4D, "custom0", "CUSTOM0" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_4D, "custom1", "CUSTOM1" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_4D, "custom2", "CUSTOM2" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_4D, "custom3", "CUSTOM3" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_4D, "instance_custom", "INSTANCE_CUSTOM" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "instance_id", "INSTANCE_ID" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "vertex_id", "VERTEX_ID" },
Expand Down
9 changes: 9 additions & 0 deletions servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
Expand Up @@ -2562,6 +2562,11 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
actions.renames["VERTEX_ID"] = "gl_VertexIndex";

actions.renames["CUSTOM0"] = "custom0";
actions.renames["CUSTOM1"] = "custom1";
actions.renames["CUSTOM2"] = "custom2";
actions.renames["CUSTOM3"] = "custom3";

actions.renames["LIGHT_POSITION"] = "light_position";
actions.renames["LIGHT_DIRECTION"] = "light_direction";
actions.renames["LIGHT_IS_DIRECTIONAL"] = "is_directional";
Expand All @@ -2583,6 +2588,10 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
actions.usage_defines["SPECULAR_SHININESS"] = "#define SPECULAR_SHININESS_USED\n";
actions.usage_defines["POINT_SIZE"] = "#define USE_POINT_SIZE\n";
actions.usage_defines["CUSTOM0"] = "#define CUSTOM0_USED\n";
actions.usage_defines["CUSTOM1"] = "#define CUSTOM1_USED\n";
actions.usage_defines["CUSTOM2"] = "#define CUSTOM2_USED\n";
actions.usage_defines["CUSTOM3"] = "#define CUSTOM3_USED\n";

actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
Expand Down
41 changes: 39 additions & 2 deletions servers/rendering/renderer_rd/shaders/canvas.glsl
Expand Up @@ -9,6 +9,22 @@ layout(location = 0) in vec2 vertex_attrib;
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;

#if defined(CUSTOM0_USED)
layout(location = 6) in vec4 custom0_attrib;
#endif

#if defined(CUSTOM1_USED)
layout(location = 7) in vec4 custom1_attrib;
#endif

#if defined(CUSTOM2_USED)
layout(location = 8) in vec4 custom2_attrib;
#endif

#if defined(CUSTOM3_USED)
layout(location = 9) in vec4 custom3_attrib;
#endif

layout(location = 10) in uvec4 bone_attrib;
layout(location = 11) in vec4 weight_attrib;

Expand Down Expand Up @@ -44,6 +60,11 @@ vec3 srgb_to_linear(vec3 color) {

void main() {
vec4 instance_custom = vec4(0.0);
vec4 custom0 = vec4(0.0);
vec4 custom1 = vec4(0.0);
vec4 custom2 = vec4(0.0);
vec4 custom3 = vec4(0.0);

#ifdef USE_PRIMITIVE

//weird bug,
Expand Down Expand Up @@ -78,9 +99,25 @@ void main() {
color *= draw_data.modulation;
vec2 uv = uv_attrib;

#if defined(CUSTOM0_USED)
custom0 = custom0_attrib;
#endif

#if defined(CUSTOM1_USED)
custom1 = custom1_attrib;
#endif

#if defined(CUSTOM2_USED)
custom2 = custom2_attrib;
#endif

#if defined(CUSTOM3_USED)
custom3 = custom3_attrib;
#endif

uvec4 bones = bone_attrib;
vec4 bone_weights = weight_attrib;
#else
#else // !USE_ATTRIBUTES

vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
vec2 vertex_base = vertex_base_arr[gl_VertexIndex];
Expand All @@ -90,7 +127,7 @@ void main() {
vec2 vertex = draw_data.dst_rect.xy + abs(draw_data.dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data.src_rect.zw, vec2(0.0, 0.0)));
uvec4 bones = uvec4(0, 0, 0, 0);

#endif
#endif // USE_ATTRIBUTES

mat4 model_matrix = mat4(vec4(draw_data.world_x, 0.0, 0.0), vec4(draw_data.world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data.world_ofs, 0.0, 1.0));

Expand Down
4 changes: 4 additions & 0 deletions servers/rendering/shader_types.cpp
Expand Up @@ -250,6 +250,10 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX_ID"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["CUSTOM0"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["CUSTOM1"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["CUSTOM2"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["CUSTOM3"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].can_discard = false;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].main_function = true;

Expand Down

0 comments on commit 385645f

Please sign in to comment.