diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 19 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 263 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.h | 14 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 7 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 483 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 37 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 287 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 70 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 87 | ||||
-rw-r--r-- | drivers/gles3/shaders/particles.glsl | 3 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 24 | ||||
-rw-r--r-- | drivers/gles3/shaders/screen_space_reflection.glsl | 47 | ||||
-rw-r--r-- | drivers/gles3/shaders/ssao.glsl | 16 |
14 files changed, 766 insertions, 592 deletions
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 4bcebbd69d..4b8c553b60 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -30,10 +30,8 @@ uniform highp mat4 light_local_matrix; uniform vec2 light_pos; varying vec4 light_uv_interp; -#if defined(NORMAL_USED) varying vec4 local_rot; uniform vec2 normal_flip; -#endif #ifdef USE_SHADOWS varying highp vec2 pos; @@ -86,10 +84,8 @@ VERTEX_SHADER_CODE pos=outvec.xy; #endif -#if defined(NORMAL_USED) local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy )*normal_flip.x; local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy )*normal_flip.y; -#endif #endif @@ -107,6 +103,7 @@ precision mediump int; uniform sampler2D texture; // texunit:0 +uniform sampler2D normal_texture; // texunit:0 varying vec2 uv_interp; varying vec4 color_interp; @@ -157,9 +154,7 @@ uniform float light_height; varying vec4 light_uv_interp; uniform float light_outside_alpha; -#if defined(NORMAL_USED) varying vec4 local_rot; -#endif #ifdef USE_SHADOWS @@ -189,19 +184,19 @@ FRAGMENT_SHADER_GLOBALS void main() { vec4 color = color_interp; -#if defined(NORMAL_USED) - vec3 normal = vec3(0.0,0.0,1.0); -#endif #ifdef USE_DISTANCE_FIELD const float smoothing = 1.0/32.0; - float distance = texture2D(texture, uv_interp).a; + float distance = textureLod(texture, uv_interp,0.0).a; color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a; #else color *= texture2D( texture, uv_interp ); #endif + vec3 normal; + normal.xy = textureLod( normal_texture, uv_interp, 0.0 ).xy * 2.0 - 1.0; + normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); #if defined(ENABLE_SCREEN_UV) vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult; @@ -236,9 +231,7 @@ FRAGMENT_SHADER_CODE vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping -#if defined(NORMAL_USED) normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; -#endif float att=1.0; @@ -263,10 +256,8 @@ LIGHT_SHADER_CODE #else -#if defined(NORMAL_USED) vec3 light_normal = normalize(vec3(light_vec,-light_height)); light*=max(dot(-light_normal,normal),0.0); -#endif color*=light; /* diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 1121a07347..a8895f7bfc 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "rasterizer_canvas_gles3.h" +#include "global_config.h" #include "os/os.h" - #ifndef GLES_OVER_GL #define glClearDepth glClearDepthf #endif @@ -113,7 +113,7 @@ void RasterizerCanvasGLES3::light_internal_update(RID p_rid, Light *p_light) { li->ubo_data.light_pos[0] = p_light->light_shader_pos.x; li->ubo_data.light_pos[1] = p_light->light_shader_pos.y; - li->ubo_data.shadowpixel_size = 1.0 / p_light->shadow_buffer_size; + li->ubo_data.shadowpixel_size = (1.0 / p_light->shadow_buffer_size) * (1.0 + p_light->shadow_smooth); li->ubo_data.light_outside_alpha = p_light->mode == VS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0; li->ubo_data.light_height = p_light->height; if (p_light->radius_cache == 0) @@ -188,40 +188,74 @@ void RasterizerCanvasGLES3::canvas_end() { state.using_texture_rect = false; } -RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture) { +RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) { - if (p_texture == state.current_tex) { - return state.current_tex_ptr; - } + RasterizerStorageGLES3::Texture *tex_return = NULL; - if (p_texture.is_valid()) { + if (p_texture == state.current_tex) { + tex_return = state.current_tex_ptr; + } else if (p_texture.is_valid()) { RasterizerStorageGLES3::Texture *texture = storage->texture_owner.getornull(p_texture); if (!texture) { state.current_tex = RID(); state.current_tex_ptr = NULL; + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - return NULL; - } - if (texture->render_target) - texture->render_target->used_in_frame = true; + } else { - glBindTexture(GL_TEXTURE_2D, texture->tex_id); - state.current_tex = p_texture; - state.current_tex_ptr = texture; + if (texture->render_target) + texture->render_target->used_in_frame = true; - return texture; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture->tex_id); + state.current_tex = p_texture; + state.current_tex_ptr = texture; + + tex_return = texture; + } } else { + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); state.current_tex = RID(); state.current_tex_ptr = NULL; } - return NULL; + if (p_normal_map == state.current_normal) { + //do none + state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid()); + + } else if (p_normal_map.is_valid()) { + + RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.getornull(p_normal_map); + + if (!normal_map) { + state.current_normal = RID(); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false); + + } else { + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); + state.current_normal = p_normal_map; + state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, true); + } + + } else { + + state.current_normal = RID(); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false); + } + + return tex_return; } void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable) { @@ -247,113 +281,56 @@ void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable) { state.using_texture_rect = p_enable; } -void RasterizerCanvasGLES3::_draw_polygon(int p_vertex_count, const int *p_indices, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, const RID &p_texture, bool p_singlecolor) { - - bool do_colors = false; - Color m; - if (p_singlecolor) { - m = *p_colors; - glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a); - } else if (!p_colors) { +void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { - glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); - } else - do_colors = true; + glBindVertexArray(data.polygon_buffer_pointer_array); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(p_texture); + uint32_t buffer_ofs = 0; -#ifndef GLES_NO_CLIENT_ARRAYS + //vertex + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices); glEnableVertexAttribArray(VS::ARRAY_VERTEX); - glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), p_vertices); - if (do_colors) { + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + //color - glEnableVertexAttribArray(VS::ARRAY_COLOR); - glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), p_colors); - } else { + if (p_singlecolor) { glDisableVertexAttribArray(VS::ARRAY_COLOR); - } - - if (texture && p_uvs) { - - glEnableVertexAttribArray(VS::ARRAY_TEX_UV); - glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), p_uvs); - } else { - glDisableVertexAttribArray(VS::ARRAY_TEX_UV); - } - - if (p_indices) { - glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_INT, p_indices); + Color m = *p_colors; + glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a); + } else if (!p_colors) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } else { - glDrawArrays(GL_TRIANGLES, 0, p_vertex_count); - } - -#else //WebGL specific impl. - glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer); - float *b = GlobalVertexBuffer; - int ofs = 0; - if (p_vertex_count > MAX_POLYGON_VERTICES) { - print_line("Too many vertices to render"); - return; - } - glEnableVertexAttribArray(VS::ARRAY_VERTEX); - glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs); - for (int i = 0; i < p_vertex_count; i++) { - b[ofs++] = p_vertices[i].x; - b[ofs++] = p_vertices[i].y; - } - - if (p_colors && do_colors) { + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); glEnableVertexAttribArray(VS::ARRAY_COLOR); - glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(float) * 4, ((float *)0) + ofs); - for (int i = 0; i < p_vertex_count; i++) { - b[ofs++] = p_colors[i].r; - b[ofs++] = p_colors[i].g; - b[ofs++] = p_colors[i].b; - b[ofs++] = p_colors[i].a; - } - - } else { - glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Color) * p_vertex_count; } if (p_uvs) { + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); - glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs); - for (int i = 0; i < p_vertex_count; i++) { - b[ofs++] = p_uvs[i].x; - b[ofs++] = p_uvs[i].y; - } + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Vector2) * p_vertex_count; } else { glDisableVertexAttribArray(VS::ARRAY_TEX_UV); } - glBufferSubData(GL_ARRAY_BUFFER, 0, ofs * 4, &b[0]); - //bind the indices buffer. - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer); - - static const int _max_draw_poly_indices = 16 * 1024; // change this size if needed!!! - ERR_FAIL_COND(p_vertex_count > _max_draw_poly_indices); - static uint16_t _draw_poly_indices[_max_draw_poly_indices]; - for (int i = 0; i < p_vertex_count; i++) { - _draw_poly_indices[i] = p_indices[i]; - //OS::get_singleton()->print("ind: %d ", p_indices[i]); - }; - - //copy the data to GPU. - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, p_vertex_count * sizeof(uint16_t), &_draw_poly_indices[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices); //draw the triangles. - glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_SHORT, 0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -#endif + glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0); storage->frame.canvas_draw_commands++; + + glBindVertexArray(0); } void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) { @@ -404,9 +381,9 @@ void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_v } } - glBindBuffer(GL_ARRAY_BUFFER, data.primitive_quad_buffer); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4, &b[0]); - glBindVertexArray(data.primitive_quad_buffer_arrays[version]); + glBindVertexArray(data.polygon_buffer_quad_arrays[version]); glDrawArrays(prim[p_points], 0, p_points); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -429,7 +406,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur Item::CommandLine *line = static_cast<Item::CommandLine *>(c); _set_texture_rect_mode(false); - _bind_canvas_texture(RID()); + _bind_canvas_texture(RID(), RID()); glVertexAttrib4f(VS::ARRAY_COLOR, line->color.r, line->color.g, line->color.b, line->color.a); @@ -460,7 +437,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur //set color glVertexAttrib4f(VS::ARRAY_COLOR, rect->modulate.r, rect->modulate.g, rect->modulate.b, rect->modulate.a); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(rect->texture); + RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(rect->texture, rect->normal_map); if (texture) { @@ -489,8 +466,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - glVertexAttrib4f(1, rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y); - glVertexAttrib4f(2, src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y); + state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, (rect->flags & CANVAS_RECT_CLIP_UV) ? true : false); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); if (untile) { @@ -500,8 +479,9 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur } else { - glVertexAttrib4f(1, rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y); - glVertexAttrib4f(2, 0, 0, 1, 1); + state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(0, 0, 1, 1)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -517,7 +497,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur glVertexAttrib4f(VS::ARRAY_COLOR, np->color.r, np->color.g, np->color.b, np->color.a); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(np->texture); + RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(np->texture, np->normal_map); if (!texture) { @@ -530,9 +510,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false); -#define DSTRECT(m_x, m_y, m_w, m_h) glVertexAttrib4f(1, m_x, m_y, m_w, m_h) -#define SRCRECT(m_x, m_y, m_w, m_h) glVertexAttrib4f(2, (m_x)*texpixel_size.x, (m_y)*texpixel_size.y, (m_w)*texpixel_size.x, (m_h)*texpixel_size.y) +#define DSTRECT(m_x, m_y, m_w, m_h) state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(m_x, m_y, m_w, m_h)) +#define SRCRECT(m_x, m_y, m_w, m_h) state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color((m_x)*texpixel_size.x, (m_y)*texpixel_size.y, (m_w)*texpixel_size.x, (m_h)*texpixel_size.y)) //top left DSTRECT(np->rect.position.x, np->rect.position.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]); @@ -595,7 +576,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur ERR_CONTINUE(primitive->points.size() < 1); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture); + RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture, primitive->normal_map); if (texture) { Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); @@ -618,13 +599,13 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(c); _set_texture_rect_mode(false); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture); + RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map); if (texture) { Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); } - //_draw_polygon(polygon->count,polygon->indices.ptr(),polygon->points.ptr(),polygon->uvs.ptr(),polygon->colors.ptr(),polygon->texture,polygon->colors.size()==1); + _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); } break; case Item::Command::TYPE_CIRCLE: { @@ -644,6 +625,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur indices[i * 3 + 1] = (i + 1) % numpoints; indices[i * 3 + 2] = numpoints; } + + _bind_canvas_texture(RID(), RID()); + _draw_polygon(indices, numpoints * 3, numpoints + 1, points, NULL, &circle->color, true); + //_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true); //canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1); } break; @@ -759,6 +744,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons state.current_tex = RID(); state.current_tex_ptr = NULL; + state.current_normal = RID(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); @@ -866,7 +852,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons for (int i = 0; i < tc; i++) { - glActiveTexture(GL_TEXTURE1 + i); + glActiveTexture(GL_TEXTURE2 + i); RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull(textures[i]); if (!t) { @@ -1165,7 +1151,6 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); - glEnableVertexAttribArray(VS::ARRAY_VERTEX); state.canvas_shadow_shader.bind(); glViewport(0, 0, cls->size, cls->height); @@ -1264,18 +1249,14 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons } } */ - glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id); - glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0); + glBindVertexArray(cc->array_id); glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0); instance = instance->next; } } - glDisableVertexAttribArray(VS::ARRAY_VERTEX); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindVertexArray(0); } void RasterizerCanvasGLES3::reset_canvas() { @@ -1299,9 +1280,6 @@ void RasterizerCanvasGLES3::reset_canvas() { //glLineWidth(1.0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - for (int i = 0; i < VS::ARRAY_MAX; i++) { - glDisableVertexAttribArray(i); - } glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); @@ -1327,9 +1305,7 @@ void RasterizerCanvasGLES3::reset_canvas() { state.vp = canvas_transform; store_transform(canvas_transform, state.canvas_item_ubo_data.projection_matrix); - for (int i = 0; i < 4; i++) { - state.canvas_item_ubo_data.time[i] = storage->frame.time[i]; - } + state.canvas_item_ubo_data.time = storage->frame.time[0]; glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data); @@ -1340,8 +1316,10 @@ void RasterizerCanvasGLES3::reset_canvas() { void RasterizerCanvasGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) { - glVertexAttrib4f(1, p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y); - glVertexAttrib4f(2, p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y); + state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -1376,15 +1354,19 @@ void RasterizerCanvasGLES3::initialize() { { - glGenBuffers(1, &data.primitive_quad_buffer); - glBindBuffer(GL_ARRAY_BUFFER, data.primitive_quad_buffer); - glBufferData(GL_ARRAY_BUFFER, (2 + 2 + 4) * 4 * sizeof(float), NULL, GL_DYNAMIC_DRAW); //allocate max size + uint32_t poly_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_buffer_size_kb", 128); + poly_size *= 1024; //kb + poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float)); + glGenBuffers(1, &data.polygon_buffer); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + glBufferData(GL_ARRAY_BUFFER, poly_size, NULL, GL_DYNAMIC_DRAW); //allocate max size glBindBuffer(GL_ARRAY_BUFFER, 0); + //quad arrays for (int i = 0; i < 4; i++) { - glGenVertexArrays(1, &data.primitive_quad_buffer_arrays[i]); - glBindVertexArray(data.primitive_quad_buffer_arrays[i]); - glBindBuffer(GL_ARRAY_BUFFER, data.primitive_quad_buffer); + glGenVertexArrays(1, &data.polygon_buffer_quad_arrays[i]); + glBindVertexArray(data.polygon_buffer_quad_arrays[i]); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); int uv_ofs = 0; int color_ofs = 0; @@ -1415,6 +1397,15 @@ void RasterizerCanvasGLES3::initialize() { glBindVertexArray(0); } + + glGenVertexArrays(1, &data.polygon_buffer_pointer_array); + + uint32_t index_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_index_buffer_size_kb", 128); + index_size *= 1024; //kb + glGenBuffers(1, &data.polygon_index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW); //allocate max size + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } store_transform(Transform(), state.canvas_item_ubo_data.projection_matrix); @@ -1436,6 +1427,8 @@ void RasterizerCanvasGLES3::finalize() { glDeleteBuffers(1, &data.canvas_quad_vertices); glDeleteVertexArrays(1, &data.canvas_quad_array); + + glDeleteVertexArrays(1, &data.polygon_buffer_pointer_array); } RasterizerCanvasGLES3::RasterizerCanvasGLES3() { diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index 95ef9ee443..4996f0a6b2 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -39,7 +39,7 @@ public: struct CanvasItemUBO { float projection_matrix[16]; - float time[4]; + float time; }; struct Data { @@ -47,8 +47,11 @@ public: GLuint canvas_quad_vertices; GLuint canvas_quad_array; - GLuint primitive_quad_buffer; - GLuint primitive_quad_buffer_arrays[4]; + GLuint polygon_buffer; + GLuint polygon_buffer_quad_arrays[4]; + GLuint polygon_buffer_pointer_array; + GLuint polygon_index_buffer; + uint32_t polygon_buffer_size; } data; @@ -62,6 +65,7 @@ public: bool using_texture_rect; RID current_tex; + RID current_normal; RasterizerStorageGLES3::Texture *current_tex_ptr; Transform vp; @@ -104,10 +108,10 @@ public: virtual void canvas_end(); _FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable); - _FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture); + _FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map); _FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs); - _FORCE_INLINE_ void _draw_polygon(int p_vertex_count, const int *p_indices, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, const RID &p_texture, bool p_singlecolor); + _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); _FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip); virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 2262580d9a..53df7e9c3d 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -212,11 +212,8 @@ void RasterizerGLES3::begin_frame() { storage->update_dirty_resources(); - storage->info.render_object_count = 0; - storage->info.render_material_switch_count = 0; - storage->info.render_surface_switch_count = 0; - storage->info.render_shader_rebind_count = 0; - storage->info.render_vertices_count = 0; + storage->info.render_final = storage->info.render; + storage->info.render.reset(); scene->iteration(); } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 7152b49d27..913aa62452 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -887,17 +887,16 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_ void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) { } -void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) { +void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->ssr_enabled = p_enable; env->ssr_max_steps = p_max_steps; - env->ssr_accel = p_accel; - env->ssr_fade = p_fade; + env->ssr_fade_in = p_fade_in; + env->ssr_fade_out = p_fade_out; env->ssr_depth_tolerance = p_depth_tolerance; - env->ssr_smooth = p_smooth; env->ssr_roughness = p_roughness; } @@ -1004,7 +1003,7 @@ void RasterizerSceneGLES3::light_instance_set_transform(RID p_light_instance, co light_instance->transform = p_transform; } -void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass) { +void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -1019,6 +1018,7 @@ void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_insta light_instance->shadow_transform[p_pass].transform = p_transform; light_instance->shadow_transform[p_pass].farplane = p_far; light_instance->shadow_transform[p_pass].split = p_split; + light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale; } void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) { @@ -1207,6 +1207,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m } break; case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { tex = storage->resources.normal_tex; + } break; default: { tex = storage->resources.white_tex; @@ -1220,6 +1221,15 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m t->detect_3d(t->detect_3d_ud); } #endif + +#ifdef TOOLS_ENABLED + if (t->detect_normal && texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) { + t->detect_normal(t->detect_normal_ud); + } +#endif + if (t->render_target) + t->render_target->used_in_frame = true; + if (storage->config.srgb_decode_supported) { //if SRGB decode extension is present, simply switch the texture to whathever is needed bool must_srgb = false; @@ -1290,8 +1300,11 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo storage->mesh_render_blend_shapes(s, e->instance->blend_values.ptr()); //rebind shader state.scene_shader.bind(); +#ifdef DEBUG_ENABLED + } else if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { + glBindVertexArray(s->array_wireframe_id); // everything is so easy nowadays +#endif } else { - glBindVertexArray(s->array_id); // everything is so easy nowadays } @@ -1301,7 +1314,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo RasterizerStorageGLES3::MultiMesh *multi_mesh = static_cast<RasterizerStorageGLES3::MultiMesh *>(e->owner); RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry); - glBindVertexArray(s->instancing_array_id); // use the instancing array ID +#ifdef DEBUG_ENABLED + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) { + + glBindVertexArray(s->instancing_array_wireframe_id); // use the instancing array ID + } else +#endif + { + glBindVertexArray(s->instancing_array_id); // use the instancing array ID + } + glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer int stride = (multi_mesh->xform_floats + multi_mesh->color_floats) * 4; @@ -1366,13 +1388,26 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo sorter.sort(particle_array, particles->amount); glUnmapBuffer(GL_ARRAY_BUFFER); +#ifdef DEBUG_ENABLED + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) { + glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID + } else +#endif + { - glBindVertexArray(s->instancing_array_id); // use the instancing array ID + glBindVertexArray(s->instancing_array_id); // use the instancing array ID + } glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer } else { - - glBindVertexArray(s->instancing_array_id); // use the instancing array ID +#ifdef DEBUG_ENABLED + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) { + glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID + } else +#endif + { + glBindVertexArray(s->instancing_array_id); // use the instancing array ID + } glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //modify the buffer } @@ -1421,17 +1456,25 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry); - if (s->index_array_len > 0) { +#ifdef DEBUG_ENABLED + + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { + + glDrawElements(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0); + storage->info.render.vertices_count += s->index_array_len; + } else +#endif + if (s->index_array_len > 0) { glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); - storage->info.render_vertices_count += s->index_array_len; + storage->info.render.vertices_count += s->index_array_len; } else { glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); - storage->info.render_vertices_count += s->array_len; + storage->info.render.vertices_count += s->array_len; } } break; @@ -1442,17 +1485,25 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { int amount = MAX(multi_mesh->size, multi_mesh->visible_instances); - if (s->index_array_len > 0) { +#ifdef DEBUG_ENABLED + + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { + + glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount); + storage->info.render.vertices_count += s->index_array_len * amount; + } else +#endif + if (s->index_array_len > 0) { glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount); - storage->info.render_vertices_count += s->index_array_len * amount; + storage->info.render.vertices_count += s->index_array_len * amount; } else { glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount); - storage->info.render_vertices_count += s->array_len * amount; + storage->info.render.vertices_count += s->array_len * amount; } } break; @@ -1478,7 +1529,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { int vertices = c.vertices.size(); uint32_t buf_ofs = 0; - storage->info.render_vertices_count += vertices; + storage->info.render.vertices_count += vertices; if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) { @@ -1600,18 +1651,25 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { glEnableVertexAttribArray(12); //custom glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 2); glVertexAttribDivisor(12, 1); +#ifdef DEBUG_ENABLED - if (s->index_array_len > 0) { + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { + + glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount - split); + storage->info.render.vertices_count += s->index_array_len * (amount - split); + } else +#endif + if (s->index_array_len > 0) { glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount - split); - storage->info.render_vertices_count += s->index_array_len * (amount - split); + storage->info.render.vertices_count += s->index_array_len * (amount - split); } else { glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount - split); - storage->info.render_vertices_count += s->array_len * (amount - split); + storage->info.render.vertices_count += s->array_len * (amount - split); } } @@ -1631,34 +1689,49 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { glEnableVertexAttribArray(12); //custom glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2); glVertexAttribDivisor(12, 1); +#ifdef DEBUG_ENABLED - if (s->index_array_len > 0) { + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { + + glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, split); + storage->info.render.vertices_count += s->index_array_len * split; + } else +#endif + if (s->index_array_len > 0) { glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, split); - storage->info.render_vertices_count += s->index_array_len * split; + storage->info.render.vertices_count += s->index_array_len * split; } else { glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, split); - storage->info.render_vertices_count += s->array_len * split; + storage->info.render.vertices_count += s->array_len * split; } } } else { - if (s->index_array_len > 0) { +#ifdef DEBUG_ENABLED + + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) { + + glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount); + storage->info.render.vertices_count += s->index_array_len * amount; + } else +#endif + if (s->index_array_len > 0) { glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount); - storage->info.render_vertices_count += s->index_array_len * amount; + storage->info.render.vertices_count += s->index_array_len * amount; } else { glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount); - storage->info.render_vertices_count += s->array_len * amount; + storage->info.render.vertices_count += s->array_len * amount; } } @@ -1827,7 +1900,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ bool first = true; bool prev_use_instancing = false; - storage->info.render_object_count += p_element_count; + storage->info.render.draw_call_count += p_element_count; for (int i = 0; i < p_element_count; i++) { @@ -1842,7 +1915,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ if (!p_shadow) { if (p_directional_add) { - if (e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG || !(e->instance->layer_mask & directional_light->light_ptr->cull_mask)) { + if (e->sort_key & SORT_KEY_UNSHADED_FLAG || !(e->instance->layer_mask & directional_light->light_ptr->cull_mask)) { continue; } @@ -1851,7 +1924,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ if (shading != prev_shading) { - if (e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) { + if (e->sort_key & SORT_KEY_UNSHADED_FLAG) { state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, true); state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING, false); @@ -1880,7 +1953,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13); - if (p_directional_add || (directional_light && (e->sort_key & RenderList::SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) { + if (p_directional_add || (directional_light && (e->sort_key & SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) { state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, true); if (p_directional_shadows && directional_light->light_ptr->shadow) { @@ -1975,23 +2048,23 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ if (material != prev_material || rebind) { - storage->info.render_material_switch_count++; + storage->info.render.material_switch_count++; rebind = _setup_material(material, p_alpha_pass); if (rebind) { - storage->info.render_shader_rebind_count++; + storage->info.render.shader_rebind_count++; } } - if (!(e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) { + if (!(e->sort_key & SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) { _setup_light(e, p_view_transform); } if (e->owner != prev_owner || prev_base_type != e->instance->base_type || prev_geometry != e->geometry) { _setup_geometry(e, p_view_transform); - storage->info.render_surface_switch_count++; + storage->info.render.surface_switch_count++; } _set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, p_reverse_cull); @@ -2034,6 +2107,10 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo RasterizerStorageGLES3::Material *m = NULL; RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material); + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { + m_src = default_overdraw_material; + } + /* #ifdef DEBUG_ENABLED if (current_debug==VS::SCENARIO_DEBUG_OVERDRAW) { @@ -2046,7 +2123,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo if (m_src.is_valid()) { m = storage->material_owner.getornull(m_src); - if (!m->shader) { + if (!m->shader || !m->shader->valid) { m = NULL; } } @@ -2109,7 +2186,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo } if (!p_shadow && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) { - e->sort_key |= RenderList::SORT_KEY_NO_DIRECTIONAL_FLAG; + e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG; } e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT; @@ -2137,7 +2214,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo } if (e->instance->gi_probe_instances.size()) { - e->sort_key |= RenderList::SORT_KEY_GI_PROBES_FLAG; + e->sort_key |= SORT_KEY_GI_PROBES_FLAG; } } @@ -2152,9 +2229,9 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo //e->light_type=0xFF; // no lights! - if (shadow || m->shader->spatial.unshaded /*|| current_debug==VS::SCENARIO_DEBUG_SHADELESS*/) { + if (shadow || m->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - e->sort_key |= RenderList::SORT_KEY_UNSHADED_FLAG; + e->sort_key |= SORT_KEY_UNSHADED_FLAG; } } @@ -2247,9 +2324,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr store_transform(p_cam_transform.affine_inverse(), state.ubo_data.camera_inverse_matrix); //time global variables - for (int i = 0; i < 4; i++) { - state.ubo_data.time[i] = storage->frame.time[i]; - } + state.ubo_data.time = storage->frame.time[0]; state.ubo_data.z_far = p_cam_projection.get_z_far(); //bg and ambient @@ -3183,8 +3258,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ //perform SSR - state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::SMOOTH_ACCEL, env->ssr_accel > 0 && env->ssr_smooth); - state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS, env->ssr_accel > 0 && env->ssr_roughness); + state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS, env->ssr_roughness); state.ssr_shader.bind(); @@ -3200,9 +3274,9 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ //state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::FRAME_INDEX,int(render_pass)); state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::FILTER_MIPMAP_LEVELS, float(storage->frame.current_rt->effects.mip_maps[0].sizes.size())); state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::NUM_STEPS, env->ssr_max_steps); - state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::ACCELERATION, env->ssr_accel); state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DEPTH_TOLERANCE, env->ssr_depth_tolerance); - state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DISTANCE_FADE, env->ssr_fade); + state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DISTANCE_FADE, env->ssr_fade_out); + state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::CURVE_FADE_IN, env->ssr_fade_in); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); @@ -3745,6 +3819,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const //fill up ubo + storage->info.render.object_count += p_cull_count; + Environment *env = environment_owner.getornull(p_environment); ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_reflection_atlas); @@ -3771,8 +3847,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const state.ubo_data.subsurface_scatter_width = subsurface_scatter_size; - state.ubo_data.shadow_z_offset = 0; - state.ubo_data.shadow_slope_scale = 0; + state.ubo_data.z_offset = 0; + state.ubo_data.z_slope_scale = 0; state.ubo_data.shadow_dual_paraboloid_render_side = 0; state.ubo_data.shadow_dual_paraboloid_render_zfar = 0; @@ -3789,7 +3865,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const state.used_contact_shadows = true; - if (storage->frame.current_rt && true) { //detect with state.used_contact_shadows too + if (storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { //detect with state.used_contact_shadows too //pre z pass glDisable(GL_BLEND); @@ -3880,6 +3956,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const //effects disabled and transparency also prevent using MRTs use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]; use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS]; + use_mrt = use_mrt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW; glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); @@ -3928,8 +4005,13 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const RasterizerStorageGLES3::Sky *sky = NULL; GLuint env_radiance_tex = 0; - if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 0); + storage->frame.clear_request = false; + } else if (!probe && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + clear_color = Color(0, 0, 0, 0); + storage->frame.clear_request = false; + } else if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR) { if (storage->frame.clear_request) { @@ -3992,7 +4074,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glDrawBuffers(1, &gldb); } - if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { /* if (use_mrt) { @@ -4088,151 +4170,6 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glBindTexture(GL_TEXTURE_2D, env_radiance_tex); storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1)); } - -#if 0 - if (use_fb) { - - - - for(int i=0;i<VS::ARRAY_MAX;i++) { - glDisableVertexAttribArray(i); - } - glBindBuffer(GL_ARRAY_BUFFER,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_SCISSOR_TEST); - glDepthMask(false); - - if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) { - - int hdr_tm = current_env->fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER]; - switch(hdr_tm) { - case VS::ENV_FX_HDR_TONE_MAPPER_LINEAR: { - - - } break; - case VS::ENV_FX_HDR_TONE_MAPPER_LOG: { - copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER,true); - - } break; - case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT: { - copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,true); - } break; - case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE: { - - copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,true); - copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE,true); - } break; - } - - - _process_hdr(); - } - if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) { - _process_glow_bloom(); - int glow_transfer_mode=current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE]; - if (glow_transfer_mode==1) - copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,true); - if (glow_transfer_mode==2) - copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,true); - } - - glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer); - - Size2 size; - if (current_rt) { - glBindFramebuffer(GL_FRAMEBUFFER, current_rt->fbo); - glViewport( 0,0,viewport.width,viewport.height); - size=Size2(viewport.width,viewport.height); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer); - glViewport( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height ); - size=Size2(viewport.width,viewport.height); - } - - //time to copy!!! - copy_shader.set_conditional(CopyShaderGLES2::USE_BCS,current_env && current_env->fx_enabled[VS::ENV_FX_BCS]); - copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB,current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]); - copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]); - copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,current_env && current_env->fx_enabled[VS::ENV_FX_HDR]); - copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,true); - copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,current_env && current_env->fx_enabled[VS::ENV_FX_FXAA]); - - copy_shader.bind(); - //copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0); - - if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) { - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, framebuffer.blur[0].color ); - glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::GLOW_SOURCE),1); - - } - - if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) { - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, current_vd->lum_color ); - glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::HDR_SOURCE),2); - copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE])); - copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE])); - - } - - if (current_env && current_env->fx_enabled[VS::ENV_FX_FXAA]) - copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Size2(1.0/size.x,1.0/size.y)); - - - if (current_env && current_env->fx_enabled[VS::ENV_FX_BCS]) { - - Vector3 bcs; - bcs.x=current_env->fx_param[VS::ENV_FX_PARAM_BCS_BRIGHTNESS]; - bcs.y=current_env->fx_param[VS::ENV_FX_PARAM_BCS_CONTRAST]; - bcs.z=current_env->fx_param[VS::ENV_FX_PARAM_BCS_SATURATION]; - copy_shader.set_uniform(CopyShaderGLES2::BCS,bcs); - } - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, framebuffer.color ); - glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0); - - _copy_screen_quad(); - - copy_shader.set_conditional(CopyShaderGLES2::USE_BCS,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER,false); - - state.scene_shader.set_conditional(SceneShaderGLES3::USE_8BIT_HDR,false); - - - if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR] && GLOBAL_DEF("rasterizer/debug_hdr",false)) { - _debug_luminances(); - } - } - - current_env=NULL; - current_debug=VS::SCENARIO_DEBUG_DISABLED; - if (GLOBAL_DEF("rasterizer/debug_shadow_maps",false)) { - _debug_shadows(); - } - //_debug_luminances(); - //_debug_samplers(); - - if (using_canvas_bg) { - using_canvas_bg=false; - glColorMask(1,1,1,1); //don't touch alpha - } -#endif } void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { @@ -4322,8 +4259,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_ } zfar = light->param[VS::LIGHT_PARAM_RANGE]; - bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS]; - normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS]; + bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS] * light_instance->shadow_transform[p_pass].bias_scale; + normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[p_pass].bias_scale; fbo = directional_shadow.fbo; vp_height = directional_shadow.size; @@ -4441,8 +4378,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_ glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); - state.ubo_data.shadow_z_offset = bias; - state.ubo_data.shadow_slope_scale = normal_bias; + state.ubo_data.z_offset = bias; + state.ubo_data.z_slope_scale = normal_bias; state.ubo_data.shadow_dual_paraboloid_render_side = dp_direction; state.ubo_data.shadow_dual_paraboloid_render_zfar = zfar; @@ -4554,136 +4491,39 @@ bool RasterizerSceneGLES3::free(RID p_rid) { return true; } -// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html -static _FORCE_INLINE_ float radicalInverse_VdC(uint32_t bits) { - bits = (bits << 16u) | (bits >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - return float(bits) * 2.3283064365386963e-10f; // / 0x100000000 -} - -static _FORCE_INLINE_ Vector2 Hammersley(uint32_t i, uint32_t N) { - return Vector2(float(i) / float(N), radicalInverse_VdC(i)); -} - -static _FORCE_INLINE_ Vector3 ImportanceSampleGGX(Vector2 Xi, float Roughness, Vector3 N) { - float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph] - - // Compute distribution direction - float Phi = 2.0f * Math_PI * Xi.x; - float CosTheta = Math::sqrt((float)(1.0f - Xi.y) / (1.0f + (a * a - 1.0f) * Xi.y)); - float SinTheta = Math::sqrt((float)Math::abs(1.0f - CosTheta * CosTheta)); - - // Convert to spherical direction - Vector3 H; - H.x = SinTheta * Math::cos(Phi); - H.y = SinTheta * Math::sin(Phi); - H.z = CosTheta; - - Vector3 UpVector = Math::abs(N.z) < 0.999 ? Vector3(0.0, 0.0, 1.0) : Vector3(1.0, 0.0, 0.0); - Vector3 TangentX = UpVector.cross(N); - TangentX.normalize(); - Vector3 TangentY = N.cross(TangentX); - - // Tangent to world space - return TangentX * H.x + TangentY * H.y + N * H.z; -} - -static _FORCE_INLINE_ float GGX(float NdotV, float a) { - float k = a / 2.0; - return NdotV / (NdotV * (1.0 - k) + k); -} +void RasterizerSceneGLES3::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) { -// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float _FORCE_INLINE_ G_Smith(float a, float nDotV, float nDotL) { - return GGX(nDotL, a * a) * GGX(nDotV, a * a); + state.debug_draw = p_debug_draw; } -void RasterizerSceneGLES3::_generate_brdf() { - - int brdf_size = GLOBAL_DEF("rendering/gles3/brdf_texture_size", 64); - - PoolVector<uint8_t> brdf; - brdf.resize(brdf_size * brdf_size * 2); - - PoolVector<uint8_t>::Write w = brdf.write(); - - for (int i = 0; i < brdf_size; i++) { - for (int j = 0; j < brdf_size; j++) { - - float Roughness = float(j) / (brdf_size - 1); - float NoV = float(i + 1) / (brdf_size); //avoid storing nov0 - - Vector3 V; - V.x = Math::sqrt(1.0f - NoV * NoV); - V.y = 0.0; - V.z = NoV; - - Vector3 N = Vector3(0.0, 0.0, 1.0); - - float A = 0; - float B = 0; - - for (int s = 0; s < 512; s++) { - - Vector2 xi = Hammersley(s, 512); - Vector3 H = ImportanceSampleGGX(xi, Roughness, N); - Vector3 L = 2.0 * V.dot(H) * H - V; +void RasterizerSceneGLES3::initialize() { - float NoL = CLAMP(L.z, 0.0, 1.0); - float NoH = CLAMP(H.z, 0.0, 1.0); - float VoH = CLAMP(V.dot(H), 0.0, 1.0); + render_pass = 0; - if (NoL > 0.0) { - float G = G_Smith(Roughness, NoV, NoL); - float G_Vis = G * VoH / (NoH * NoV); - float Fc = pow(1.0 - VoH, 5.0); + state.scene_shader.init(); - A += (1.0 - Fc) * G_Vis; - B += Fc * G_Vis; - } - } + { + //default material and shader - A /= 512.0; - B /= 512.0; + default_shader = storage->shader_create(); + storage->shader_set_code(default_shader, "shader_type spatial;\n"); + default_material = storage->material_create(); + storage->material_set_shader(default_material, default_shader); - int tofs = ((brdf_size - j - 1) * brdf_size + i) * 2; - w[tofs + 0] = CLAMP(A * 255, 0, 255); - w[tofs + 1] = CLAMP(B * 255, 0, 255); - } + default_shader_twosided = storage->shader_create(); + default_material_twosided = storage->material_create(); + storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n"); + storage->material_set_shader(default_material_twosided, default_shader_twosided); } - //set up brdf texture - - glGenTextures(1, &state.brdf_texture); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, state.brdf_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, brdf_size, brdf_size, 0, GL_RG, GL_UNSIGNED_BYTE, w.ptr()); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); -} - -void RasterizerSceneGLES3::initialize() { - - render_pass = 0; - - state.scene_shader.init(); - - default_shader = storage->shader_create(); - storage->shader_set_code(default_shader, "shader_type spatial;\n"); - default_material = storage->material_create(); - storage->material_set_shader(default_material, default_shader); + { + //default material and shader - default_shader_twosided = storage->shader_create(); - default_material_twosided = storage->material_create(); - storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n"); - storage->material_set_shader(default_material_twosided, default_shader_twosided); + default_overdraw_shader = storage->shader_create(); + storage->shader_set_code(default_overdraw_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }"); + default_overdraw_material = storage->material_create(); + storage->material_set_shader(default_overdraw_material, default_overdraw_shader); + } glGenBuffers(1, &state.scene_ubo); glBindBuffer(GL_UNIFORM_BUFFER, state.scene_ubo); @@ -4721,7 +4561,6 @@ void RasterizerSceneGLES3::initialize() { } render_list.init(); state.cube_to_dp_shader.init(); - _generate_brdf(); shadow_atlas_realloc_tolerance_msec = 500; @@ -4770,7 +4609,7 @@ void RasterizerSceneGLES3::initialize() { { //directional light shadow directional_shadow.light_count = 0; - directional_shadow.size = nearest_power_of_2(GLOBAL_DEF("rendering/shadows/directional_shadow_size", 2048)); + directional_shadow.size = nearest_power_of_2(GLOBAL_DEF("rendering/shadows/directional_shadow_size", 4096)); glGenFramebuffers(1, &directional_shadow.fbo); glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo); glGenTextures(1, &directional_shadow.depth); @@ -4968,6 +4807,8 @@ void RasterizerSceneGLES3::initialize() { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE); } + + state.debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED; } void RasterizerSceneGLES3::iteration() { diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 55d314a800..3e15da52ab 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -77,6 +77,9 @@ public: RID default_shader; RID default_shader_twosided; + RID default_overdraw_material; + RID default_overdraw_shader; + RasterizerStorageGLES3 *storage; Vector<RasterizerStorageGLES3::RenderTarget::Exposure> exposure_shrink; @@ -108,7 +111,6 @@ public: float projection_matrix[16]; float camera_inverse_matrix[16]; float camera_matrix[16]; - float time[4]; float ambient_light_color[4]; float bg_color[4]; float fog_color_enabled[4]; @@ -116,14 +118,15 @@ public: float ambient_energy; float bg_energy; - float shadow_z_offset; - float shadow_slope_scale; + float z_offset; + float z_slope_scale; float shadow_dual_paraboloid_render_zfar; float shadow_dual_paraboloid_render_side; float screen_pixel_size[2]; float shadow_atlas_pixel_size[2]; float shadow_directional_pixel_size[2]; + float time; float z_far; float reflection_multiplier; float subsurface_scatter_width; @@ -152,8 +155,6 @@ public: GLuint env_radiance_ubo; - GLuint brdf_texture; - GLuint sky_verts; GLuint sky_array; @@ -187,6 +188,7 @@ public: bool used_sss; bool used_screen_texture; + VS::ViewportDebugDraw debug_draw; } state; /* SHADOW ATLAS API */ @@ -358,10 +360,9 @@ public: bool ssr_enabled; int ssr_max_steps; - float ssr_accel; - float ssr_fade; + float ssr_fade_in; + float ssr_fade_out; float ssr_depth_tolerance; - bool ssr_smooth; bool ssr_roughness; bool ssao_enabled; @@ -437,10 +438,9 @@ public: ssr_enabled = false; ssr_max_steps = 64; - ssr_accel = 0.04; - ssr_fade = 2.0; + ssr_fade_in = 0.15; + ssr_fade_out = 2.0; ssr_depth_tolerance = 0.2; - ssr_smooth = true; ssr_roughness = true; ssao_enabled = false; @@ -525,7 +525,7 @@ public: virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale); virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); - virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness); + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_radius2, float p_intensity2, float p_intensity, float p_bias, float p_light_affect, const Color &p_color, bool p_blur); virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); @@ -561,6 +561,7 @@ public: Transform transform; float farplane; float split; + float bias_scale; }; ShadowTransform shadow_transform[4]; @@ -596,7 +597,7 @@ public: virtual RID light_instance_create(RID p_light); virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform); - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass); + virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0); virtual void light_instance_mark_visible(RID p_light_instance); /* REFLECTION INSTANCE */ @@ -635,9 +636,10 @@ public: MAX_REFLECTIONS = 1024, SORT_KEY_DEPTH_LAYER_SHIFT = 60, - SORT_KEY_UNSHADED_FLAG = uint64_t(1) << 59, - SORT_KEY_NO_DIRECTIONAL_FLAG = uint64_t(1) << 58, - SORT_KEY_GI_PROBES_FLAG = uint64_t(1) << 57, +//64 bits unsupported in MSVC +#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 59) +#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 58) +#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 57) SORT_KEY_SHADING_SHIFT = 57, SORT_KEY_SHADING_MASK = 7, SORT_KEY_MATERIAL_INDEX_SHIFT = 40, @@ -783,9 +785,8 @@ public: virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); virtual bool free(RID p_rid); - void _generate_brdf(); - virtual void set_scene_pass(uint64_t p_pass); + virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw); void iteration(); void initialize(); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 1801260146..85331342e9 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1072,6 +1072,14 @@ void RasterizerStorageGLES3::texture_set_detect_srgb_callback(RID p_texture, Vis texture->detect_srgb_ud = p_userdata; } +void RasterizerStorageGLES3::texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) { + Texture *texture = texture_owner.get(p_texture); + ERR_FAIL_COND(!texture); + + texture->detect_normal = p_callback; + texture->detect_normal_ud = p_userdata; +} + RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_resolution) const { Texture *texture = texture_owner.get(p_source); @@ -1425,6 +1433,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { _shader_dirty_list.remove(&p_shader->dirty_list); p_shader->valid = false; + p_shader->ubo_size = 0; p_shader->uniforms.clear(); @@ -1547,7 +1556,11 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { - order[E->get().order] = E->key(); + if (E->get().texture_order >= 0) { + order[E->get().texture_order + 100000] = E->key(); + } else { + order[E->get().order] = E->key(); + } } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { @@ -2244,6 +2257,10 @@ void RasterizerStorageGLES3::_update_material(Material *material) { if (material->shader && material->shader->dirty_list.in_list()) { _update_shader(material->shader); } + + if (material->shader && !material->shader->valid) + return; + //update caches { @@ -2658,6 +2675,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: surface->skeleton_bone_used.resize(surface->skeleton_bone_aabb.size()); surface->aabb = p_aabb; surface->max_bone = p_bone_aabbs.size(); + surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size; for (int i = 0; i < surface->skeleton_bone_used.size(); i++) { if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) { @@ -2727,6 +2745,112 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + +#ifdef DEBUG_ENABLED + + if (config.generate_wireframes && p_primitive == VS::PRIMITIVE_TRIANGLES) { + //generate wireframes, this is used mostly by editor + PoolVector<uint32_t> wf_indices; + int index_count; + + if (p_format & VS::ARRAY_FORMAT_INDEX) { + + index_count = p_index_count * 2; + wf_indices.resize(index_count); + + PoolVector<uint8_t>::Read ir = p_index_array.read(); + PoolVector<uint32_t>::Write wr = wf_indices.write(); + + if (p_vertex_count < (1 << 16)) { + //read 16 bit indices + const uint16_t *src_idx = (const uint16_t *)ir.ptr(); + for (int i = 0; i < index_count; i += 6) { + + wr[i + 0] = src_idx[i / 2]; + wr[i + 1] = src_idx[i / 2 + 1]; + wr[i + 2] = src_idx[i / 2 + 1]; + wr[i + 3] = src_idx[i / 2 + 2]; + wr[i + 4] = src_idx[i / 2 + 2]; + wr[i + 5] = src_idx[i / 2]; + } + + } else { + + //read 16 bit indices + const uint32_t *src_idx = (const uint32_t *)ir.ptr(); + for (int i = 0; i < index_count; i += 6) { + + wr[i + 0] = src_idx[i / 2]; + wr[i + 1] = src_idx[i / 2 + 1]; + wr[i + 2] = src_idx[i / 2 + 1]; + wr[i + 3] = src_idx[i / 2 + 2]; + wr[i + 4] = src_idx[i / 2 + 2]; + wr[i + 5] = src_idx[i / 2]; + } + } + + } else { + + index_count = p_vertex_count * 2; + wf_indices.resize(index_count); + PoolVector<uint32_t>::Write wr = wf_indices.write(); + for (int i = 0; i < index_count; i += 6) { + + wr[i + 0] = i / 2; + wr[i + 1] = i / 2 + 1; + wr[i + 2] = i / 2 + 1; + wr[i + 3] = i / 2 + 2; + wr[i + 4] = i / 2 + 2; + wr[i + 5] = i / 2; + } + } + { + PoolVector<uint32_t>::Read ir = wf_indices.read(); + + glGenBuffers(1, &surface->index_wireframe_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_wireframe_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count * sizeof(uint32_t), ir.ptr(), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind + + surface->index_wireframe_len = index_count; + } + + for (int ai = 0; ai < 2; ai++) { + + if (ai == 0) { + //for normal draw + glGenVertexArrays(1, &surface->array_wireframe_id); + glBindVertexArray(surface->array_wireframe_id); + glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); + } else if (ai == 1) { + //for instancing draw (can be changed and no one cares) + glGenVertexArrays(1, &surface->instancing_array_wireframe_id); + glBindVertexArray(surface->instancing_array_wireframe_id); + glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); + } + + for (int i = 0; i < VS::ARRAY_MAX - 1; i++) { + + if (!attribs[i].enabled) + continue; + + if (attribs[i].integer) { + glVertexAttribIPointer(attribs[i].index, attribs[i].size, attribs[i].type, attribs[i].stride, ((uint8_t *)0) + attribs[i].offset); + } else { + glVertexAttribPointer(attribs[i].index, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, ((uint8_t *)0) + attribs[i].offset); + } + glEnableVertexAttribArray(attribs[i].index); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_wireframe_id); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + } + +#endif } { @@ -2739,6 +2863,8 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: PoolVector<uint8_t>::Read vr = p_blend_shapes[i].read(); + surface->total_data_size += array_size; + glGenBuffers(1, &mt.vertex_id); glBindBuffer(GL_ARRAY_BUFFER, mt.vertex_id); glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), GL_STATIC_DRAW); @@ -2770,6 +2896,8 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: mesh->surfaces.push_back(surface); mesh->instance_change_notify(); + + info.vertex_mem += surface->total_data_size; } void RasterizerStorageGLES3::mesh_set_blend_shape_count(RID p_mesh, int p_amount) { @@ -2991,6 +3119,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) { } glDeleteVertexArrays(1, &surface->array_id); + glDeleteVertexArrays(1, &surface->instancing_array_id); for (int i = 0; i < surface->blend_shapes.size(); i++) { @@ -2998,6 +3127,14 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) { glDeleteVertexArrays(1, &surface->blend_shapes[i].array_id); } + if (surface->index_wireframe_id) { + glDeleteBuffers(1, &surface->index_wireframe_id); + glDeleteVertexArrays(1, &surface->array_wireframe_id); + glDeleteVertexArrays(1, &surface->instancing_array_wireframe_id); + } + + info.vertex_mem -= surface->total_data_size; + mesh->instance_material_change_notify(); memdelete(surface); @@ -4149,7 +4286,6 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) { light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3; light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6; light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1; - light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1; light->color = Color(1, 1, 1, 1); light->shadow = false; @@ -4186,8 +4322,7 @@ void RasterizerStorageGLES3::light_set_param(RID p_light, VS::LightParam p_param case VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET: case VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET: case VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS: - case VS::LIGHT_PARAM_SHADOW_BIAS: - case VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE: { + case VS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; light->instance_change_notify(); @@ -5127,6 +5262,23 @@ void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, c particles->emission_transform = p_transform; } +int RasterizerStorageGLES3::particles_get_draw_passes(RID p_particles) const { + + const Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, 0); + + return particles->draw_passes.size(); +} + +RID RasterizerStorageGLES3::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { + + const Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, RID()); + ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID()); + + return particles->draw_passes[p_pass]; +} + void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) { float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime) * particles->speed_scale, (float)1.0); @@ -5258,7 +5410,7 @@ void RasterizerStorageGLES3::update_particles() { shaders.particles.bind(); shaders.particles.set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, particles->amount); - shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, Color(frame.time[0], frame.time[1], frame.time[2], frame.time[3])); + shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, frame.time[0]); shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS, particles->explosiveness); shaders.particles.set_uniform(ParticlesShaderGLES3::LIFETIME, particles->lifetime); shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT, 0); @@ -5321,13 +5473,11 @@ void RasterizerStorageGLES3::update_particles() { particles->particle_valid_histories[0] = true; } + + particles->instance_change_notify(); //make sure shadows are updated } glDisable(GL_RASTERIZER_DISCARD); - - for (int i = 0; i < 6; i++) { - glDisableVertexAttribArray(i); - } } //////// @@ -5914,10 +6064,20 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT default: {} } } +bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) { -bool RasterizerStorageGLES3::render_target_renedered_in_frame(RID p_render_target) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND_V(!rt, false); - return false; + return rt->used_in_frame; +} + +void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) { + + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + rt->used_in_frame = false; } void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) { @@ -5986,6 +6146,7 @@ RID RasterizerStorageGLES3::canvas_light_occluder_create() { co->index_id = 0; co->vertex_id = 0; co->len = 0; + glGenVertexArrays(1, &co->array_id); return canvas_occluder_owner.make_rid(co); } @@ -6057,7 +6218,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder, if (!co->vertex_id) { glGenBuffers(1, &co->vertex_id); glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id); - glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_DYNAMIC_DRAW); } else { glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id); @@ -6070,7 +6231,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder, glGenBuffers(1, &co->index_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW); } else { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id); @@ -6080,6 +6241,12 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder, glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind co->len = lc; + glBindVertexArray(co->array_id); + glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id); + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id); + glBindVertexArray(0); } } @@ -6308,6 +6475,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) { if (co->vertex_id) glDeleteBuffers(1, &co->vertex_id); + glDeleteVertexArrays(1, &co->array_id); + canvas_occluder_owner.free(p_rid); memdelete(co); @@ -6345,6 +6514,97 @@ bool RasterizerStorageGLES3::has_os_feature(const String &p_feature) const { //////////////////////////////////////////// +void RasterizerStorageGLES3::set_debug_generate_wireframes(bool p_generate) { + + config.generate_wireframes = p_generate; +} + +void RasterizerStorageGLES3::render_info_begin_capture() { + + info.snap = info.render; +} + +void RasterizerStorageGLES3::render_info_end_capture() { + + info.snap.object_count = info.render.object_count - info.snap.object_count; + info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count; + info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count; + info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count; + info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count; + info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count; +} + +int RasterizerStorageGLES3::get_captured_render_info(VS::RenderInfo p_info) { + + switch (p_info) { + case VS::INFO_OBJECTS_IN_FRAME: { + + return info.snap.object_count; + } break; + case VS::INFO_VERTICES_IN_FRAME: { + + return info.snap.vertices_count; + } break; + case VS::INFO_MATERIAL_CHANGES_IN_FRAME: { + return info.snap.material_switch_count; + } break; + case VS::INFO_SHADER_CHANGES_IN_FRAME: { + return info.snap.shader_rebind_count; + } break; + case VS::INFO_SURFACE_CHANGES_IN_FRAME: { + return info.snap.surface_switch_count; + } break; + case VS::INFO_DRAW_CALLS_IN_FRAME: { + return info.snap.draw_call_count; + } break; + default: { + return get_render_info(p_info); + } + } +} + +int RasterizerStorageGLES3::get_render_info(VS::RenderInfo p_info) { + + switch (p_info) { + case VS::INFO_OBJECTS_IN_FRAME: { + + return info.render_final.object_count; + } break; + case VS::INFO_VERTICES_IN_FRAME: { + + return info.render_final.vertices_count; + } break; + case VS::INFO_MATERIAL_CHANGES_IN_FRAME: { + return info.render_final.material_switch_count; + } break; + case VS::INFO_SHADER_CHANGES_IN_FRAME: { + return info.render_final.shader_rebind_count; + } break; + case VS::INFO_SURFACE_CHANGES_IN_FRAME: { + return info.render_final.surface_switch_count; + } break; + case VS::INFO_DRAW_CALLS_IN_FRAME: { + return info.render_final.draw_call_count; + } break; + case VS::INFO_USAGE_VIDEO_MEM_TOTAL: { + + return 0; //no idea + } break; + case VS::INFO_VIDEO_MEM_USED: { + + return info.vertex_mem + info.texture_mem; + } break; + case VS::INFO_TEXTURE_MEM_USED: { + + return info.texture_mem; + } break; + case VS::INFO_VERTEX_MEM_USED: { + + return info.vertex_mem; + } break; + } +} + void RasterizerStorageGLES3::initialize() { RasterizerStorageGLES3::system_fbo = 0; @@ -6526,6 +6786,7 @@ void RasterizerStorageGLES3::initialize() { frame.delta = 0; frame.current_rt = NULL; config.keep_original_textures = false; + config.generate_wireframes = false; } void RasterizerStorageGLES3::finalize() { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 9af342301c..ca0194bd5e 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -84,6 +84,8 @@ public: int max_texture_image_units; int max_texture_size; + bool generate_wireframes; + Set<String> extensions; bool keep_original_textures; @@ -124,12 +126,33 @@ public: struct Info { uint64_t texture_mem; + uint64_t vertex_mem; + + struct Render { + uint32_t object_count; + uint32_t draw_call_count; + uint32_t material_switch_count; + uint32_t surface_switch_count; + uint32_t shader_rebind_count; + uint32_t vertices_count; + + void reset() { + object_count = 0; + draw_call_count = 0; + material_switch_count = 0; + surface_switch_count = 0; + shader_rebind_count = 0; + vertices_count = 0; + } + } render, render_final, snap; - uint32_t render_object_count; - uint32_t render_material_switch_count; - uint32_t render_surface_switch_count; - uint32_t render_shader_rebind_count; - uint32_t render_vertices_count; + Info() { + + texture_mem = 0; + vertex_mem = 0; + render.reset(); + render_final.reset(); + } } info; @@ -247,6 +270,9 @@ public: VisualServer::TextureDetectCallback detect_srgb; void *detect_srgb_ud; + VisualServer::TextureDetectCallback detect_normal; + void *detect_normal_ud; + Texture() { using_srgb = false; @@ -266,6 +292,8 @@ public: detect_3d_ud = NULL; detect_srgb = NULL; detect_srgb_ud = NULL; + detect_normal = NULL; + detect_normal_ud = NULL; } ~Texture() { @@ -306,6 +334,7 @@ public: virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); + virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); /* SKY API */ @@ -425,6 +454,7 @@ public: : dirty_list(this) { shader = NULL; + ubo_size = 0; valid = false; custom_code_id = 0; version = 1; @@ -537,6 +567,11 @@ public: GLuint vertex_id; GLuint index_id; + GLuint index_wireframe_id; + GLuint array_wireframe_id; + GLuint instancing_array_wireframe_id; + int index_wireframe_len; + Vector<Rect3> skeleton_bone_aabb; Vector<bool> skeleton_bone_used; @@ -567,6 +602,8 @@ public: mesh->update_multimeshes(); } + int total_data_size; + Surface() { array_byte_size = 0; @@ -581,6 +618,13 @@ public: primitive = VS::PRIMITIVE_POINTS; index_array_len = 0; active = false; + + total_data_size = 0; + + index_wireframe_id = 0; + array_wireframe_id = 0; + instancing_array_wireframe_id = 0; + index_wireframe_len = 0; } ~Surface() { @@ -1105,6 +1149,9 @@ public: virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform); void _particles_process(Particles *p_particles, float p_delta); + virtual int particles_get_draw_passes(RID p_particles) const; + virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const; + /* INSTANCE */ virtual void instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); @@ -1226,7 +1273,8 @@ public: virtual RID render_target_get_texture(RID p_render_target) const; virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value); - virtual bool render_target_renedered_in_frame(RID p_render_target); + virtual bool render_target_was_used(RID p_render_target); + virtual void render_target_clear_used(RID p_render_target); virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa); /* CANVAS SHADOW */ @@ -1248,6 +1296,7 @@ public: struct CanvasOccluder : public RID_Data { + GLuint array_id; // 0 means, unconfigured GLuint vertex_id; // 0 means, unconfigured GLuint index_id; // 0 means, unconfigured PoolVector<Vector2> lines; @@ -1274,6 +1323,7 @@ public: float delta; uint64_t prev_tick; uint64_t count; + } frame; void initialize(); @@ -1283,6 +1333,14 @@ public: virtual void update_dirty_resources(); + virtual void set_debug_generate_wireframes(bool p_generate); + + virtual void render_info_begin_capture(); + virtual void render_info_end_capture(); + virtual int get_captured_render_info(VS::RenderInfo p_info); + + virtual int get_render_info(VS::RenderInfo p_info); + RasterizerStorageGLES3(); }; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index b1f7b4c9bd..3376f99112 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -668,6 +668,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix"; actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix"; actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time"; + actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass"; actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal"; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 017009015e..7be6ee857a 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -6,8 +6,8 @@ layout(location=3) in vec4 color_attrib; #ifdef USE_TEXTURE_RECT -layout(location=1) in highp vec4 dst_rect; -layout(location=2) in highp vec4 src_rect; +uniform vec4 dst_rect; +uniform vec4 src_rect; #else @@ -20,7 +20,7 @@ layout(location=4) in highp vec2 uv_attrib; layout(std140) uniform CanvasItemData { //ubo:0 highp mat4 projection_matrix; - highp vec4 time; + highp float time; }; uniform highp mat4 modelview_matrix; @@ -51,17 +51,21 @@ layout(std140) uniform LightData { //ubo:1 out vec4 light_uv_interp; -#if defined(NORMAL_USED) + out vec4 local_rot; -#endif + #ifdef USE_SHADOWS out highp vec2 pos; #endif +const bool at_light_pass = true; +#else +const bool at_light_pass = false; #endif + VERTEX_SHADER_GLOBALS #if defined(USE_MATERIAL) @@ -121,7 +125,7 @@ VERTEX_SHADER_CODE pos=outvec.xy; #endif -#if defined(NORMAL_USED) + local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy ); local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy ); #ifdef USE_TEXTURE_RECT @@ -129,7 +133,7 @@ VERTEX_SHADER_CODE local_rot.zw*=sign(src_rect.w); #endif -#endif + #endif @@ -141,6 +145,7 @@ VERTEX_SHADER_CODE uniform mediump sampler2D color_texture; // texunit:0 uniform highp vec2 color_texpixel_size; +uniform mediump sampler2D normal_texture; // texunit:1 in mediump vec2 uv_interp; in mediump vec4 color_interp; @@ -155,7 +160,7 @@ uniform sampler2D screen_texture; // texunit:-3 layout(std140) uniform CanvasItemData { highp mat4 projection_matrix; - highp vec4 time; + highp float time; }; @@ -180,9 +185,8 @@ uniform lowp sampler2D light_texture; // texunit:-1 in vec4 light_uv_interp; -#if defined(NORMAL_USED) in vec4 local_rot; -#endif + #ifdef USE_SHADOWS @@ -191,6 +195,9 @@ in highp vec2 pos; #endif +const bool at_light_pass = true; +#else +const bool at_light_pass = false; #endif uniform mediump vec4 final_modulate; @@ -222,12 +229,28 @@ LIGHT_SHADER_CODE } +#ifdef USE_TEXTURE_RECT + +uniform vec4 dst_rect; +uniform vec4 src_rect; +uniform bool clip_rect_uv; + +#endif + +uniform bool use_default_normal; void main() { vec4 color = color_interp; -#if defined(NORMAL_USED) - vec3 normal = vec3(0.0,0.0,1.0); + vec2 uv = uv_interp; + +#ifdef USE_TEXTURE_RECT + if (clip_rect_uv) { + + vec2 half_texpixel = color_texpixel_size * 0.5; + uv = clamp(uv,src_rect.xy+half_texpixel,src_rect.xy+abs(src_rect.zw)-color_texpixel_size); + } + #endif #if !defined(COLOR_USED) @@ -235,15 +258,34 @@ void main() { #ifdef USE_DISTANCE_FIELD const float smoothing = 1.0/32.0; - float distance = texture(color_texture, uv_interp).a; + float distance = textureLod(color_texture, uv,0.0).a; color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a; #else - color *= texture( color_texture, uv_interp ); + color *= texture( color_texture, uv ); #endif #endif + vec3 normal; + +#if defined(NORMAL_USED) + + bool normal_used = true; +#else + bool normal_used = false; +#endif + + if (use_default_normal) { + normal.xy = textureLod(normal_texture, uv,0.0).xy * 2.0 - 1.0; + normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); + normal_used=true; + } else { + normal = vec3(0.0,0.0,1.0); + } + + + #if defined(ENABLE_SCREEN_UV) vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult; #endif @@ -278,9 +320,9 @@ FRAGMENT_SHADER_CODE vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping -#if defined(NORMAL_USED) - normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; -#endif + if (normal_used) { + normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; + } float att=1.0; @@ -301,10 +343,11 @@ FRAGMENT_SHADER_CODE #else -#if defined(NORMAL_USED) - vec3 light_normal = normalize(vec3(light_vec,-light_height)); - light*=max(dot(-light_normal,normal),0.0); -#endif + if (normal_used) { + + vec3 light_normal = normalize(vec3(light_vec,-light_height)); + light*=max(dot(-light_normal,normal),0.0); + } color*=light; /* @@ -381,7 +424,7 @@ FRAGMENT_SHADER_CODE #ifdef SHADOW_FILTER_NEAREST - SHADOW_TEST(su+shadowpixel_size); + SHADOW_TEST(su); #endif diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl index 5d8a532f87..7e7b083f73 100644 --- a/drivers/gles3/shaders/particles.glsl +++ b/drivers/gles3/shaders/particles.glsl @@ -28,7 +28,7 @@ uniform float prev_system_phase; uniform int total_particles; uniform float explosiveness; uniform float randomness; -uniform vec4 time; +uniform float time; uniform float delta; uniform int attractor_count; @@ -132,6 +132,7 @@ void main() { } uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID); + int index = int(gl_VertexID); if (restart) { shader_active=emitting; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 60efc953f9..a047e693cb 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -63,7 +63,6 @@ layout(std140) uniform SceneData { //ubo:0 highp mat4 projection_matrix; highp mat4 camera_inverse_matrix; highp mat4 camera_matrix; - highp vec4 time; highp vec4 ambient_light_color; highp vec4 bg_color; @@ -74,8 +73,8 @@ layout(std140) uniform SceneData { //ubo:0 float ambient_energy; float bg_energy; - float shadow_z_offset; - float shadow_z_slope_scale; + float z_offset; + float z_slope_scale; float shadow_dual_paraboloid_render_zfar; float shadow_dual_paraboloid_render_side; @@ -83,6 +82,7 @@ layout(std140) uniform SceneData { //ubo:0 vec2 shadow_atlas_pixel_size; vec2 directional_shadow_pixel_size; + float time; float z_far; float reflection_multiplier; float subsurface_scatter_width; @@ -245,7 +245,7 @@ void main() { normal = vec4(normal,0.0) * m; #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) - tangent.xyz = vec4(tangent.xyz,0.0) * mn; + tangent.xyz = vec4(tangent.xyz,0.0) * m; #endif } #endif @@ -319,7 +319,7 @@ VERTEX_SHADER_CODE //for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges - highp vec3 vtx = vertex_interp+normalize(vertex_interp)*shadow_z_offset; + highp vec3 vtx = vertex_interp+normalize(vertex_interp)*z_offset; highp float distance = length(vtx); vtx = normalize(vtx); vtx.xy/=1.0-vtx.z; @@ -332,8 +332,8 @@ VERTEX_SHADER_CODE #else - float z_ofs = shadow_z_offset; - z_ofs += (1.0-abs(normal_interp.z))*shadow_z_slope_scale; + float z_ofs = z_offset; + z_ofs += (1.0-abs(normal_interp.z))*z_slope_scale; vertex_interp.z-=z_ofs; #endif //RENDER_DEPTH_DUAL_PARABOLOID @@ -368,6 +368,8 @@ VERTEX_SHADER_CODE */ +uniform highp mat4 world_transform; + #define M_PI 3.14159265359 /* Varyings */ @@ -435,7 +437,6 @@ layout(std140) uniform SceneData { highp mat4 projection_matrix; highp mat4 camera_inverse_matrix; highp mat4 camera_matrix; - highp vec4 time; highp vec4 ambient_light_color; highp vec4 bg_color; @@ -446,8 +447,8 @@ layout(std140) uniform SceneData { float ambient_energy; float bg_energy; - float shadow_z_offset; - float shadow_z_slope_scale; + float z_offset; + float z_slope_scale; float shadow_dual_paraboloid_render_zfar; float shadow_dual_paraboloid_render_side; @@ -455,6 +456,7 @@ layout(std140) uniform SceneData { vec2 shadow_atlas_pixel_size; vec2 directional_shadow_pixel_size; + float time; float z_far; float reflection_multiplier; float subsurface_scatter_width; @@ -1543,7 +1545,7 @@ FRAGMENT_SHADER_CODE #if defined(LIGHT_USE_PSSM_BLEND) if (use_blend) { - shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp)); + shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp),pssm_blend); } #endif diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl index 8eec71ecb6..cc41d36c37 100644 --- a/drivers/gles3/shaders/screen_space_reflection.glsl +++ b/drivers/gles3/shaders/screen_space_reflection.glsl @@ -38,7 +38,8 @@ uniform mat4 projection; uniform int num_steps; uniform float depth_tolerance; uniform float distance_fade; -uniform float acceleration; +uniform float curve_fade_in; + layout(location = 0) out vec4 frag_color; @@ -148,8 +149,6 @@ void main() { bool found=false; - //if acceleration > 0, distance between pixels gets larger each step. This allows covering a larger area - float accel=1.0+acceleration; float steps_taken=0.0; for(int i=0;i<num_steps;i++) { @@ -177,9 +176,6 @@ void main() { steps_taken+=1.0; prev_pos=pos; - z_advance*=accel; - w_advance*=accel; - line_advance*=accel; } @@ -207,41 +203,14 @@ void main() { vec2 final_pos; float grad; + grad=steps_taken/float(num_steps); + float initial_fade = curve_fade_in==0.0 ? 1.0 : pow(clamp(grad,0.0,1.0),curve_fade_in); + float fade = pow(clamp(1.0-grad,0.0,1.0),distance_fade)*initial_fade; + final_pos=pos; -#ifdef SMOOTH_ACCEL - //if the distance between point and prev point is >1, then take some samples in the middle for smoothing out the image - vec2 blend_dir = pos - prev_pos; - float steps = min(8.0,length(blend_dir)); - if (steps>2.0) { - vec2 blend_step = blend_dir/steps; - float blend_z = (z_to-z_from)/steps; - vec2 new_pos; - float subgrad=0.0; - for(float i=0.0;i<steps;i++) { - - new_pos = (prev_pos+blend_step*i); - float z = z_from+blend_z*i; - - depth = texture(source_depth, new_pos*pixel_size).r * 2.0 - 1.0; - depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); - depth=-depth; - - subgrad=i/steps; - if (depth>z) - break; - } - final_pos = new_pos; - grad=(steps_taken+subgrad)/float(num_steps); - } else { -#endif - grad=steps_taken/float(num_steps); - final_pos=pos; -#ifdef SMOOTH_ACCEL - } -#endif @@ -327,10 +296,10 @@ void main() { final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0); } - frag_color = vec4(final_color.rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend); + frag_color = vec4(final_color.rgb,fade*margin_blend); #else - frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend); + frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,fade*margin_blend); #endif diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl index ba29ec52c7..d8302bd46e 100644 --- a/drivers/gles3/shaders/ssao.glsl +++ b/drivers/gles3/shaders/ssao.glsl @@ -12,7 +12,7 @@ void main() { [fragment] -#define NUM_SAMPLES (11) +#define NUM_SAMPLES (15) // If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower // miplevel to maintain reasonable spatial locality in the cache @@ -25,8 +25,20 @@ void main() { // This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent // taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9 -#define NUM_SPIRAL_TURNS (7) +const int ROTATIONS[] = int[]( 1, 1, 2, 3, 2, 5, 2, 3, 2, +3, 3, 5, 5, 3, 4, 7, 5, 5, 7, +9, 8, 5, 5, 7, 7, 7, 8, 5, 8, +11, 12, 7, 10, 13, 8, 11, 8, 7, 14, +11, 11, 13, 12, 13, 19, 17, 13, 11, 18, +19, 11, 11, 14, 17, 21, 15, 16, 17, 18, +13, 17, 11, 17, 19, 18, 25, 18, 19, 19, +29, 21, 19, 27, 31, 29, 21, 18, 17, 29, +31, 31, 23, 18, 25, 26, 25, 23, 19, 34, +19, 27, 21, 25, 39, 29, 17, 21, 27 ); + +//#define NUM_SPIRAL_TURNS (7) +const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES-1]; uniform sampler2D source_depth; //texunit:0 uniform highp usampler2D source_depth_mipmaps; //texunit:1 |