summaryrefslogtreecommitdiff
path: root/drivers/gles2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2')
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp87
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h5
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp9
-rw-r--r--drivers/gles2/rasterizer_gles2.h4
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp127
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h4
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp254
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h11
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp40
-rw-r--r--drivers/gles2/shader_compiler_gles2.h5
-rw-r--r--drivers/gles2/shader_gles2.cpp6
-rw-r--r--drivers/gles2/shader_gles2.h10
-rw-r--r--drivers/gles2/shaders/canvas.glsl16
-rw-r--r--drivers/gles2/shaders/scene.glsl214
14 files changed, 523 insertions, 269 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index ac54af722c..373d3989ce 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -406,6 +406,66 @@ void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
+void RasterizerCanvasGLES2::_draw_generic_indices(GLuint p_primitive, 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) {
+
+ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
+
+ uint32_t buffer_ofs = 0;
+
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices);
+ glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
+ buffer_ofs += sizeof(Vector2) * p_vertex_count;
+
+ if (p_singlecolor) {
+ glDisableVertexAttribArray(VS::ARRAY_COLOR);
+ 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 {
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
+ glEnableVertexAttribArray(VS::ARRAY_COLOR);
+ glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(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, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
+ buffer_ofs += sizeof(Vector2) * p_vertex_count;
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
+
+ if (storage->config.support_32_bits_indices) { //should check for
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
+ glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0);
+ } else {
+ uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
+ for (int i = 0; i < p_index_count; i++) {
+ index16[i] = uint16_t(p_indices[i]);
+ }
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint16_t) * p_index_count, index16);
+ glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_SHORT, 0);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
+
void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) {
static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
@@ -973,7 +1033,11 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
#ifdef GLES_OVER_GL
if (polygon->antialiased) {
glEnable(GL_LINE_SMOOTH);
- _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
+ if (polygon->antialiasing_use_indices) {
+ _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
+ } else {
+ _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
+ }
glDisable(GL_LINE_SMOOTH);
}
#endif
@@ -1830,7 +1894,7 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons
while (instance) {
- RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.get(instance->polygon_buffer);
+ RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.getornull(instance->polygon_buffer);
if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) {
instance = instance->next;
@@ -1838,9 +1902,20 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons
}
state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::WORLD_MATRIX, instance->xform_cache);
- if (cull != instance->cull_cache) {
- cull = instance->cull_cache;
+ VS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache;
+
+ if (transformed_cull_cache != VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED &&
+ (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) {
+ transformed_cull_cache =
+ transformed_cull_cache == VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ?
+ VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE :
+ VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE;
+ }
+
+ if (cull != transformed_cull_cache) {
+
+ cull = transformed_cull_cache;
switch (cull) {
case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: {
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index ba636a9763..f6ae6a60c0 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -118,6 +118,7 @@ public:
_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(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, const float *p_weights = NULL, const int *p_bones = NULL);
_FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
+ _FORCE_INLINE_ void _draw_generic_indices(GLuint p_primitive, 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, RasterizerStorageGLES2::Material *p_material);
void _copy_screen(const Rect2 &p_rect);
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index cbd0e4a5d5..140617246c 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -130,7 +130,7 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
String output = String() + "GL ERROR: Source: " + debSource + "\tType: " + debType + "\tID: " + itos(id) + "\tSeverity: " + debSev + "\tMessage: " + message;
- ERR_PRINTS(output);
+ ERR_PRINT(output);
}
#endif // CAN_DEBUG
@@ -263,8 +263,7 @@ void RasterizerGLES2::initialize() {
#endif // GLES_OVER_GL
#endif // CAN_DEBUG
- const GLubyte *renderer = glGetString(GL_RENDERER);
- print_line("OpenGL ES 2.0 Renderer: " + String((const char *)renderer));
+ print_line("OpenGL ES 2.0 Renderer: " + VisualServer::get_singleton()->get_video_adapter_name());
storage->initialize();
canvas->initialize();
scene->initialize();
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 4d0d961ae4..9a5501f13d 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index bc47fb46f5..bb6a45e240 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,6 +53,11 @@
#endif
#endif
+#if !defined(GLES_OVER_GL)
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_3D 0x806F
+#endif
+
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -557,15 +562,16 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glGenTextures(1, &rpi->cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
-#if 1
- //Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game
+
+ // Mobile hardware (PowerVR specially) prefers this approach,
+ // the previous approach with manual lod levels kills the game.
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- //Generate framebuffers for rendering
+ // Generate framebuffers for rendering
for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
glBindTexture(GL_TEXTURE_2D, rpi->color[i]);
@@ -576,34 +582,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
}
-#else
- int lod = 0;
-
- //the approach below is fatal for powervr
-
- // Set the initial (empty) mipmaps, all need to be set for this to work in GLES2, even if they won't be used later.
- while (size >= 1) {
-
- for (int i = 0; i < 6; i++) {
- glTexImage2D(_cube_side_enum[i], lod, internal_format, size, size, 0, format, type, NULL);
- if (size == rpi->current_resolution) {
- //adjust framebuffer
- glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
-
-#ifdef DEBUG_ENABLED
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
-#endif
- }
- }
-
- lod++;
-
- size >>= 1;
- }
-#endif
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -1169,7 +1147,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
LightInstance *li = light_instance_owner.getornull(e->instance->light_instances[i]);
- if (li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) {
+ if (!li || li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) {
continue; // too many or light_index did not correspond to the light instances to be rendered
}
@@ -1370,6 +1348,7 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
const Pair<StringName, RID> *textures = p_material->textures.ptr();
const ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptr();
+ const ShaderLanguage::DataType *texture_types = p_material->shader->texture_types.ptr();
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
@@ -1383,22 +1362,66 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
if (!t) {
- switch (texture_hints[i]) {
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+ GLenum target = GL_TEXTURE_2D;
+ GLuint tex = 0;
+ switch (texture_types[i]) {
+ case ShaderLanguage::TYPE_ISAMPLER2D:
+ case ShaderLanguage::TYPE_USAMPLER2D:
+ case ShaderLanguage::TYPE_SAMPLER2D: {
+
+ switch (texture_hints[i]) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ tex = storage->resources.black_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
+ tex = storage->resources.aniso_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ tex = storage->resources.normal_tex;
+ } break;
+ default: {
+ tex = storage->resources.white_tex;
+ } break;
+ }
+
} break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex);
+
+ case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ // TODO
} break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER3D:
+ case ShaderLanguage::TYPE_SAMPLER3D: {
+
+ target = GL_TEXTURE_3D;
+ tex = storage->resources.white_tex_3d;
+
+ //switch (texture_hints[i]) {
+ // TODO
+ //}
+
} break;
- default: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+
+ case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY: {
+
+ target = GL_TEXTURE_2D_ARRAY;
+ tex = storage->resources.white_tex_array;
+
+ //switch (texture_hints[i]) {
+ // TODO
+ //}
+
} break;
+
+ default: {
+ }
}
+ glBindTexture(target, tex);
continue;
}
@@ -1869,7 +1892,6 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false);
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, false);
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, false);
- state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, false);
if (!p_light) { //no light, return off
return;
@@ -1955,8 +1977,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
Color color = light_ptr->color * sign * energy * Math_PI;
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_COLOR, color);
- Color shadow_color = light_ptr->shadow_color.to_linear();
- state.scene_shader.set_uniform(SceneShaderGLES2::SHADOW_COLOR, shadow_color);
+ state.scene_shader.set_uniform(SceneShaderGLES2::SHADOW_COLOR, light_ptr->shadow_color);
//specific parameters
@@ -2687,14 +2708,14 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
};
if (!asymmetrical) {
- float vw, vh, zn;
- camera.get_viewport_size(vw, vh);
+ Vector2 vp_he = camera.get_viewport_half_extents();
+ float zn;
zn = p_projection.get_z_near();
for (int i = 0; i < 4; i++) {
Vector3 uv = vertices[i * 2 + 1];
- uv.x = (uv.x * 2.0 - 1.0) * vw;
- uv.y = -(uv.y * 2.0 - 1.0) * vh;
+ uv.x = (uv.x * 2.0 - 1.0) * vp_he.x;
+ uv.y = -(uv.y * 2.0 - 1.0) * vp_he.y;
uv.z = -zn;
vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
@@ -3327,6 +3348,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glDepthMask(GL_TRUE);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
+ glClear(GL_DEPTH_BUFFER_BIT);
// clear color
@@ -3353,13 +3375,12 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (!env || env->bg_mode != VS::ENV_BG_KEEP) {
glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_color.a);
+ glClear(GL_COLOR_BUFFER_BIT);
}
state.default_ambient = Color(clear_color.r, clear_color.g, clear_color.b, 1.0);
state.default_bg = Color(clear_color.r, clear_color.g, clear_color.b, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
glDisable(GL_SCISSOR_TEST);
}
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 7babcfeed1..74adae05aa 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 40e7f0c441..a1c5d20a14 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -103,15 +103,28 @@ PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
#define glFramebufferTexture2DMultisample glFramebufferTexture2DMultisampleEXT
+PFNGLTEXIMAGE3DOESPROC glTexImage3DOES;
+PFNGLTEXSUBIMAGE3DOESPROC glTexSubImage3DOES;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC glCompressedTexSubImage3DOES;
+#define glTexImage3D glTexImage3DOES
+#define glTexSubImage3D glTexSubImage3DOES
+#define glCompressedTexSubImage3D glCompressedTexSubImage3DOES
+
#elif defined(UWP_ENABLED)
#include <GLES2/gl2ext.h>
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleANGLE
#define glFramebufferTexture2DMultisample glFramebufferTexture2DMultisampleANGLE
#endif
+#define GL_TEXTURE_3D 0x806F
#define GL_MAX_SAMPLES 0x8D57
#endif //!GLES_OVER_GL
+#if !defined(GLES_OVER_GL)
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_3D 0x806F
+#endif
+
void RasterizerStorageGLES2::bind_quad_array() const {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
@@ -566,10 +579,22 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
texture->images.resize(6);
} break;
case VS::TEXTURE_TYPE_2D_ARRAY: {
- texture->images.resize(p_depth_3d);
+ if (config.texture_array_supported) {
+ texture->target = GL_TEXTURE_2D_ARRAY;
+ texture->images.resize(p_depth_3d);
+ } else {
+ WARN_PRINT_ONCE("Texture Arrays not supported on this hardware.");
+ return;
+ }
} break;
case VS::TEXTURE_TYPE_3D: {
- texture->images.resize(p_depth_3d);
+ if (config.texture_3d_supported) {
+ texture->target = GL_TEXTURE_3D;
+ texture->images.resize(p_depth_3d);
+ } else {
+ WARN_PRINT_ONCE("3D textures not supported on this hardware.");
+ return;
+ }
} break;
default: {
ERR_PRINT("Unknown texture type!");
@@ -590,7 +615,7 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
//not supported
- ERR_PRINTS("Streaming texture for non power of 2 or has mipmaps on this hardware: " + texture->path + "'. Mipmaps and repeat disabled.");
+ ERR_PRINT("Streaming texture for non power of 2 or has mipmaps on this hardware: " + texture->path + "'. Mipmaps and repeat disabled.");
texture->flags &= ~(VS::TEXTURE_FLAG_REPEAT | VS::TEXTURE_FLAG_MIPMAPS);
} else {
texture->alloc_height = po2_height;
@@ -614,7 +639,42 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
- if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
+#if defined(GLES_OVER_GL) || defined(ANDROID_ENABLED)
+ if ((p_type == VS::TEXTURE_TYPE_3D && config.texture_3d_supported) || (p_type == VS::TEXTURE_TYPE_2D_ARRAY && config.texture_array_supported)) {
+
+ int width = p_width;
+ int height = p_height;
+ int depth = p_depth_3d;
+
+ int mipmaps = 0;
+
+ while (width > 0 || height > 0 || (p_type == VS::TEXTURE_TYPE_3D && depth > 0)) {
+ width = MAX(1, width);
+ height = MAX(1, height);
+ depth = MAX(1, depth);
+
+ glTexImage3D(texture->target, mipmaps, internal_format, width, height, depth, 0, format, type, NULL);
+
+ width /= 2;
+ height /= 2;
+
+ if (p_type == VS::TEXTURE_TYPE_3D) {
+ depth /= 2;
+ }
+
+ mipmaps++;
+
+ if (!(p_flags & VS::TEXTURE_FLAG_MIPMAPS))
+ break;
+ }
+#ifdef GLES_OVER_GL
+ glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1);
+#endif
+
+ } else
+#endif
+ if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
//prealloc if video
glTexImage2D(texture->target, 0, internal_format, texture->alloc_width, texture->alloc_height, 0, format, type, NULL);
}
@@ -626,6 +686,9 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!texture);
+ if ((texture->type == VS::TEXTURE_TYPE_2D_ARRAY && !config.texture_array_supported) || (texture->type == VS::TEXTURE_TYPE_3D && !config.texture_3d_supported)) {
+ return;
+ }
ERR_FAIL_COND(!texture->active);
ERR_FAIL_COND(texture->render_target);
ERR_FAIL_COND(texture->format != p_image->get_format());
@@ -645,7 +708,7 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
if (texture->resize_to_po2) {
if (p_image->is_compressed()) {
- ERR_PRINTS("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage.");
+ ERR_PRINT("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage.");
}
if (img == p_image) {
@@ -668,7 +731,23 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
}
}
- GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : GL_TEXTURE_2D;
+ GLenum blit_target = GL_TEXTURE_2D;
+
+ switch (texture->type) {
+ case VS::TEXTURE_TYPE_2D: {
+ blit_target = GL_TEXTURE_2D;
+ } break;
+ case VS::TEXTURE_TYPE_CUBEMAP: {
+ ERR_FAIL_INDEX(p_layer, 6);
+ blit_target = _cube_side_enum[p_layer];
+ } break;
+ case VS::TEXTURE_TYPE_2D_ARRAY: {
+ blit_target = GL_TEXTURE_2D_ARRAY;
+ } break;
+ case VS::TEXTURE_TYPE_3D: {
+ blit_target = GL_TEXTURE_3D;
+ } break;
+ }
texture->data_size = img->get_data().size();
PoolVector<uint8_t>::Read read = img->get_data().read();
@@ -725,23 +804,41 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
int size, ofs;
img->get_mipmap_offset_and_size(i, ofs, size);
+ if (texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) {
- if (compressed) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ if (compressed) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- int bw = w;
- int bh = h;
+ int bw = w;
+ int bh = h;
- glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
- } else {
+ glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
+ } else {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
- glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
+ glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]);
+ } else {
+ glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
+ }
+ }
+ }
+#if defined(GLES_OVER_GL) || defined(ANDROID_ENABLED)
+ else {
+ if (texture->compressed) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ int bw = w;
+ int bh = h;
+
+ glCompressedTexSubImage3D(blit_target, i, 0, 0, p_layer, bw, bh, 1, internal_format, size, &read[ofs]);
} else {
- glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexSubImage3D(blit_target, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]);
}
}
+#endif
tsize += size;
@@ -1201,32 +1298,21 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
GLenum type = GL_UNSIGNED_BYTE;
// Set the initial (empty) mipmaps
-#if 1
- //Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game
+ // Mobile hardware (PowerVR specially) prefers this approach,
+ // the previous approach with manual lod levels kills the game.
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- //no filters for now
+
+ // No filters for now
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#else
- while (size >= 1) {
-
- for (int i = 0; i < 6; i++) {
- glTexImage2D(_cube_side_enum[i], lod, internal_format, size, size, 0, format, type, NULL);
- }
-
- lod++;
-
- size >>= 1;
- }
-#endif
- //framebuffer
+ // Framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, resources.mipmap_blur_fbo);
@@ -1498,6 +1584,7 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
p_shader->texture_count = gen_code.texture_uniforms.size();
p_shader->texture_hints = gen_code.texture_hints;
+ p_shader->texture_types = gen_code.texture_types;
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
@@ -1645,11 +1732,19 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
- case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
+
+ pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "TextureArray";
+ } break;
+
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D: {
- // Not implemented in GLES2
+ pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "Texture3D";
} break;
}
@@ -2435,22 +2530,10 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
if (surface->blend_shape_data.size()) {
ERR_PRINT_ONCE("Blend shapes are not supported in OpenGL ES 2.0");
}
- surface->data = array;
- surface->index_data = p_index_array;
-#else
- // Even on non-tools builds, a copy of the surface->data is needed in certain circumstances.
- // Rigged meshes using the USE_SKELETON_SOFTWARE path need to read bone data
- // from surface->data.
-
- // if USE_SKELETON_SOFTWARE is active
- if (config.use_skeleton_software) {
- // if this geometry is used specifically for skinning
- if (p_format & (VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS))
- surface->data = array;
- }
- // An alternative is to always make a copy of surface->data.
#endif
+ surface->data = array;
+ surface->index_data = p_index_array;
surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size;
for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
@@ -2710,6 +2793,7 @@ void RasterizerStorageGLES2::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb
ERR_FAIL_COND(!mesh);
mesh->custom_aabb = p_aabb;
+ mesh->instance_change_notify(true, false);
}
AABB RasterizerStorageGLES2::mesh_get_custom_aabb(RID p_mesh) const {
@@ -2874,20 +2958,20 @@ void RasterizerStorageGLES2::multimesh_allocate(RID p_multimesh, int p_instances
multimesh->xform_floats = 12;
}
- if (multimesh->color_format == VS::MULTIMESH_COLOR_NONE) {
- multimesh->color_floats = 0;
- } else if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
+ if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
multimesh->color_floats = 1;
} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
multimesh->color_floats = 4;
+ } else {
+ multimesh->color_floats = 0;
}
- if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE) {
- multimesh->custom_data_floats = 0;
- } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
+ if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
multimesh->custom_data_floats = 1;
} else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) {
multimesh->custom_data_floats = 4;
+ } else {
+ multimesh->custom_data_floats = 0;
}
int format_floats = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
@@ -3063,6 +3147,7 @@ void RasterizerStorageGLES2::multimesh_instance_set_color(RID p_multimesh, int p
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->size);
ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE);
+ ERR_FAIL_INDEX(multimesh->color_format, VS::MULTIMESH_COLOR_MAX);
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
@@ -3095,6 +3180,7 @@ void RasterizerStorageGLES2::multimesh_instance_set_custom_data(RID p_multimesh,
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->size);
ERR_FAIL_COND(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE);
+ ERR_FAIL_INDEX(multimesh->custom_data_format, VS::MULTIMESH_CUSTOM_DATA_MAX);
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
@@ -3182,6 +3268,7 @@ Color RasterizerStorageGLES2::multimesh_instance_get_color(RID p_multimesh, int
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->size, Color());
ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color());
+ ERR_FAIL_INDEX_V(multimesh->color_format, VS::MULTIMESH_COLOR_MAX, Color());
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
@@ -3214,6 +3301,7 @@ Color RasterizerStorageGLES2::multimesh_instance_get_custom_data(RID p_multimesh
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->size, Color());
ERR_FAIL_COND_V(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE, Color());
+ ERR_FAIL_INDEX_V(multimesh->custom_data_format, VS::MULTIMESH_CUSTOM_DATA_MAX, Color());
int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats;
float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
@@ -4722,7 +4810,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
int max_samples = 0;
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
if (msaa > max_samples) {
- WARN_PRINTS("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples));
+ WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples));
msaa = max_samples;
}
@@ -4914,7 +5002,11 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
bool used_depth = false;
if (j == 0 && i == 0) { //use always
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+ if (config.support_depth_texture) {
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+ } else {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+ }
used_depth = true;
}
@@ -5774,6 +5866,16 @@ int RasterizerStorageGLES2::get_render_info(VS::RenderInfo p_info) {
}
}
+String RasterizerStorageGLES2::get_video_adapter_name() const {
+
+ return (const char *)glGetString(GL_RENDERER);
+}
+
+String RasterizerStorageGLES2::get_video_adapter_vendor() const {
+
+ return (const char *)glGetString(GL_VENDOR);
+}
+
void RasterizerStorageGLES2::initialize() {
RasterizerStorageGLES2::system_fbo = 0;
@@ -5794,6 +5896,8 @@ void RasterizerStorageGLES2::initialize() {
config.depth_type = GL_UNSIGNED_INT;
#ifdef GLES_OVER_GL
+ config.texture_3d_supported = true;
+ config.texture_array_supported = config.extensions.has("GL_EXT_texture_array");
config.float_texture_supported = true;
config.s3tc_supported = true;
config.pvrtc_supported = false;
@@ -5801,12 +5905,22 @@ void RasterizerStorageGLES2::initialize() {
config.support_npot_repeat_mipmap = true;
config.depth_buffer_internalformat = GL_DEPTH_COMPONENT24;
#else
+ config.texture_3d_supported = config.extensions.has("GL_OES_texture_3D");
+ config.texture_array_supported = false;
config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float");
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1");
config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc") || config.extensions.has("WEBGL_compressed_texture_pvrtc");
config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot");
+#ifdef JAVASCRIPT_ENABLED
+ // RenderBuffer internal format must be 16 bits in WebGL,
+ // but depth_texture should default to 32 always
+ // if the implementation doesn't support 32, it should just quietly use 16 instead
+ // https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/
+ config.depth_buffer_internalformat = GL_DEPTH_COMPONENT16;
+ config.depth_type = GL_UNSIGNED_INT;
+#else
// on mobile check for 24 bit depth support for RenderBufferStorage
if (config.extensions.has("GL_OES_depth24")) {
config.depth_buffer_internalformat = _DEPTH_COMPONENT24_OES;
@@ -5816,6 +5930,7 @@ void RasterizerStorageGLES2::initialize() {
config.depth_type = GL_UNSIGNED_SHORT;
}
#endif
+#endif
#ifndef GLES_OVER_GL
//Manually load extensions for android and ios
@@ -5830,6 +5945,9 @@ void RasterizerStorageGLES2::initialize() {
void *gles2_lib = dlopen("libGLESv2.so", RTLD_LAZY);
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glRenderbufferStorageMultisampleEXT");
glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glFramebufferTexture2DMultisampleEXT");
+ glTexImage3DOES = (PFNGLTEXIMAGE3DOESPROC)dlsym(gles2_lib, "glTexImage3DOES");
+ glTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOESPROC)dlsym(gles2_lib, "glTexSubImage3DOES");
+ glCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC)dlsym(gles2_lib, "glCompressedTexSubImage3DOES");
#endif
#endif
@@ -6052,6 +6170,26 @@ void RasterizerStorageGLES2::initialize() {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, anisotexdata);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
+
+#if defined(GLES_OVER_GL) || defined(ANDROID_ENABLED)
+ glGenTextures(1, &resources.white_tex_3d);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_3D, resources.white_tex_3d);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 2, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata);
+
+#ifdef GLES_OVER_GL
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
+#endif
+
+ glGenTextures(1, &resources.white_tex_array);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, resources.white_tex_array);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 8, 8, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata);
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+ glBindTexture(GL_TEXTURE_2D, 0);
+#endif
}
// skeleton buffer
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index daf6b93afc..d006d2e7f4 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,6 +71,8 @@ public:
Set<String> extensions;
+ bool texture_3d_supported;
+ bool texture_array_supported;
bool float_texture_supported;
bool s3tc_supported;
bool etc1_supported;
@@ -109,6 +111,8 @@ public:
GLuint black_tex;
GLuint normal_tex;
GLuint aniso_tex;
+ GLuint white_tex_3d;
+ GLuint white_tex_array;
GLuint mipmap_blur_fbo;
GLuint mipmap_blur_color;
@@ -414,6 +418,7 @@ public:
Map<StringName, RID> default_textures;
+ Vector<ShaderLanguage::DataType> texture_types;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
bool valid;
@@ -1307,6 +1312,8 @@ public:
virtual int get_captured_render_info(VS::RenderInfo p_info);
virtual int get_render_info(VS::RenderInfo p_info);
+ virtual String get_video_adapter_name() const;
+ virtual String get_video_adapter_vendor() const;
RasterizerStorageGLES2();
};
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 7e9b6fdb82..b4b9b70abc 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,7 +80,7 @@ static String _opstr(SL::Operator p_op) {
static String _mkid(const String &p_id) {
- String id = "m_" + p_id;
+ String id = "m_" + p_id.replace("__", "_dus_");
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
@@ -305,6 +305,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
r_gen_code.texture_uniforms.resize(max_texture_uniforms);
r_gen_code.texture_hints.resize(max_texture_uniforms);
+ r_gen_code.texture_types.resize(max_texture_uniforms);
r_gen_code.uniforms.resize(max_uniforms + max_texture_uniforms);
@@ -332,6 +333,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
if (SL::is_sampler_type(E->get().type)) {
r_gen_code.texture_uniforms.write[E->get().texture_order] = E->key();
r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
+ r_gen_code.texture_types.write[E->get().texture_order] = E->get().type;
} else {
r_gen_code.uniforms.write[E->get().order] = E->key();
}
@@ -522,9 +524,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node;
StringBuffer<> declaration;
- if (arr_dec_node->is_const) {
- declaration += "const ";
- }
declaration += _prestr(arr_dec_node->precision);
declaration += _typestr(arr_dec_node->datatype);
@@ -540,22 +539,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
declaration += "[";
declaration += itos(arr_dec_node->declarations[i].size);
declaration += "]";
- int sz = arr_dec_node->declarations[i].initializer.size();
- if (sz > 0) {
- declaration += "=";
- declaration += _typestr(arr_dec_node->datatype);
- declaration += "[";
- declaration += itos(sz);
- declaration += "]";
- declaration += "(";
- for (int j = 0; j < sz; j++) {
- declaration += _dump_node_code(arr_dec_node->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- if (j != sz - 1) {
- declaration += ", ";
- }
- }
- declaration += ")";
- }
}
code += declaration.as_string();
@@ -679,6 +662,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "texture2D";
} else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) {
code += "textureCube";
+ } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER3D) {
+ code += "texture3D";
+ } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2DARRAY) {
+ code += "texture2DArray";
}
} else if (var_node->name == "textureLod") {
@@ -688,6 +675,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "texture2DLod";
} else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) {
code += "textureCubeLod";
+ } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER3D) {
+ code += "texture3DLod";
+ } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2DARRAY) {
+ code += "texture2DArrayLod";
}
} else if (var_node->name == "mix") {
@@ -888,6 +879,7 @@ Error ShaderCompilerGLES2::compile(VS::ShaderMode p_mode, const String &p_code,
r_gen_code.uniforms.clear();
r_gen_code.texture_uniforms.clear();
r_gen_code.texture_hints.clear();
+ r_gen_code.texture_types.clear();
r_gen_code.vertex = String();
r_gen_code.vertex_global = String();
r_gen_code.fragment = String();
@@ -911,7 +903,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv";
- actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize";
+ actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "point_size";
actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix";
@@ -986,7 +978,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].renames["UV"] = "uv_interp";
actions[VS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp";
actions[VS::SHADER_SPATIAL].renames["COLOR"] = "color_interp";
- actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize";
+ actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "point_size";
// gl_InstanceID is not available in OpenGL ES 2.0
actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0";
diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h
index b8f50d6d1f..15cfac9f03 100644
--- a/drivers/gles2/shader_compiler_gles2.h
+++ b/drivers/gles2/shader_compiler_gles2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,6 +54,7 @@ public:
Vector<CharString> custom_defines;
Vector<StringName> uniforms;
Vector<StringName> texture_uniforms;
+ Vector<ShaderLanguage::DataType> texture_types;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
String vertex_global;
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp
index 58eff791ca..f03f1ffa4f 100644
--- a/drivers/gles2/shader_gles2.cpp
+++ b/drivers/gles2/shader_gles2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -126,7 +126,7 @@ static void _display_error_with_code(const String &p_error, const Vector<const c
line++;
}
- ERR_PRINTS(p_error);
+ ERR_PRINT(p_error);
}
static String _mkid(const String &p_id) {
diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h
index c7a6465194..f2953c9ae8 100644
--- a/drivers/gles2/shader_gles2.h
+++ b/drivers/gles2/shader_gles2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -118,10 +118,12 @@ private:
uint32_t code_version;
bool ok;
Version() {
- code_version = 0;
+ id = 0;
+ vert_id = 0;
frag_id = 0;
- ok = false;
uniform_location = NULL;
+ code_version = 0;
+ ok = false;
}
};
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 08548ded17..3b685b3f0b 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -10,6 +10,12 @@ precision highp float;
precision highp int;
#endif
+#ifndef USE_GLES_OVER_GL
+#extension GL_OES_texture_3D : enable
+#else
+#extension GL_EXT_texture_array : enable
+#endif
+
uniform highp mat4 projection_matrix;
/* clang-format on */
@@ -149,6 +155,8 @@ void main() {
uv = uv_attrib;
#endif
+ float point_size = 1.0;
+
{
vec2 src_vtx = outvec.xy;
/* clang-format off */
@@ -158,6 +166,8 @@ VERTEX_SHADER_CODE
/* clang-format on */
}
+ gl_PointSize = point_size;
+
#if !defined(SKIP_TRANSFORM_USED)
outvec = extra_matrix_instance * outvec;
outvec = modelview_matrix * outvec;
@@ -225,6 +235,12 @@ VERTEX_SHADER_CODE
/* clang-format off */
[fragment]
+#ifndef USE_GLES_OVER_GL
+#extension GL_OES_texture_3D : enable
+#else
+#extension GL_EXT_texture_array : enable
+#endif
+
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
// Do not copy these defines in the vertex section.
#ifndef USE_GLES_OVER_GL
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 25dbbf3c90..84aadcbbc3 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -10,6 +10,12 @@ precision highp float;
precision highp int;
#endif
+#ifndef USE_GLES_OVER_GL
+#extension GL_OES_texture_3D : enable
+#else
+#extension GL_EXT_texture_array : enable
+#endif
+
/* clang-format on */
#include "stdlib.glsl"
/* clang-format off */
@@ -251,12 +257,10 @@ void light_compute(
//normalized blinn always unless disabled
vec3 H = normalize(V + L);
float cNdotH = max(dot(N, H), 0.0);
- float cVdotH = max(dot(V, H), 0.0);
- float cLdotH = max(dot(L, H), 0.0);
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
- float blinn = pow(cNdotH, shininess);
+ float blinn = pow(cNdotH, shininess) * cNdotL;
blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
- specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);
+ specular_brdf_NL = blinn;
#endif
SRGB_APPROX(specular_brdf_NL)
@@ -425,6 +429,8 @@ void main() {
#define projection_matrix local_projection_matrix
#define world_transform world_matrix
+ float point_size = 1.0;
+
{
/* clang-format off */
@@ -433,6 +439,7 @@ VERTEX_SHADER_CODE
/* clang-format on */
}
+ gl_PointSize = point_size;
vec4 outvec = vertex;
// use local coordinates
@@ -671,6 +678,12 @@ VERTEX_SHADER_CODE
/* clang-format off */
[fragment]
+#ifndef USE_GLES_OVER_GL
+#extension GL_OES_texture_3D : enable
+#else
+#extension GL_EXT_texture_array : enable
+#endif
+
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
// Do not copy these defines in the vertex section.
#ifndef USE_GLES_OVER_GL
@@ -1270,9 +1283,9 @@ LIGHT_SHADER_CODE
//normalized blinn
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
- float blinn = pow(cNdotH, shininess);
+ float blinn = pow(cNdotH, shininess) * cNdotL;
blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
- specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);
+ specular_brdf_NL = blinn;
#elif defined(SPECULAR_PHONG)
@@ -1547,157 +1560,157 @@ FRAGMENT_SHADER_CODE
#endif // !USE_SHADOW_TO_OPACITY
#ifdef BASE_PASS
- {
- // IBL precalculations
- float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
- vec3 f0 = F0(metallic, specular, albedo);
- vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0);
+
+ // IBL precalculations
+ float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
+ vec3 f0 = F0(metallic, specular, albedo);
+ vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0);
#ifdef AMBIENT_LIGHT_DISABLED
- ambient_light = vec3(0.0, 0.0, 0.0);
+ ambient_light = vec3(0.0, 0.0, 0.0);
#else
#ifdef USE_RADIANCE_MAP
- vec3 ref_vec = reflect(-eye_position, N);
- ref_vec = normalize((radiance_inverse_xform * vec4(ref_vec, 0.0)).xyz);
+ vec3 ref_vec = reflect(-eye_position, N);
+ ref_vec = normalize((radiance_inverse_xform * vec4(ref_vec, 0.0)).xyz);
- ref_vec.z *= -1.0;
+ ref_vec.z *= -1.0;
- specular_light = textureCubeLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).xyz * bg_energy;
+ specular_light = textureCubeLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).xyz * bg_energy;
#ifndef USE_LIGHTMAP
- {
- vec3 ambient_dir = normalize((radiance_inverse_xform * vec4(normal, 0.0)).xyz);
- vec3 env_ambient = textureCubeLod(radiance_map, ambient_dir, 4.0).xyz * bg_energy;
- env_ambient *= 1.0 - F;
+ {
+ vec3 ambient_dir = normalize((radiance_inverse_xform * vec4(normal, 0.0)).xyz);
+ vec3 env_ambient = textureCubeLod(radiance_map, ambient_dir, 4.0).xyz * bg_energy;
+ env_ambient *= 1.0 - F;
- ambient_light = mix(ambient_color.rgb, env_ambient, ambient_sky_contribution);
- }
+ ambient_light = mix(ambient_color.rgb, env_ambient, ambient_sky_contribution);
+ }
#endif
#else
- ambient_light = ambient_color.rgb;
- specular_light = bg_color.rgb * bg_energy;
+ ambient_light = ambient_color.rgb;
+ specular_light = bg_color.rgb * bg_energy;
#endif
#endif // AMBIENT_LIGHT_DISABLED
- ambient_light *= ambient_energy;
+ ambient_light *= ambient_energy;
#if defined(USE_REFLECTION_PROBE1) || defined(USE_REFLECTION_PROBE2)
- vec4 ambient_accum = vec4(0.0);
- vec4 reflection_accum = vec4(0.0);
+ vec4 ambient_accum = vec4(0.0);
+ vec4 reflection_accum = vec4(0.0);
#ifdef USE_REFLECTION_PROBE1
- reflection_process(reflection_probe1,
+ reflection_process(reflection_probe1,
#ifdef USE_VERTEX_LIGHTING
- refprobe1_reflection_normal_blend.rgb,
+ refprobe1_reflection_normal_blend.rgb,
#ifndef USE_LIGHTMAP
- refprobe1_ambient_normal,
+ refprobe1_ambient_normal,
#endif
- refprobe1_reflection_normal_blend.a,
+ refprobe1_reflection_normal_blend.a,
#else
- normal_interp, vertex_interp, refprobe1_local_matrix,
- refprobe1_use_box_project, refprobe1_box_extents, refprobe1_box_offset,
+ normal_interp, vertex_interp, refprobe1_local_matrix,
+ refprobe1_use_box_project, refprobe1_box_extents, refprobe1_box_offset,
#endif
- refprobe1_exterior, refprobe1_intensity, refprobe1_ambient, roughness,
- ambient_light, specular_light, reflection_accum, ambient_accum);
+ refprobe1_exterior, refprobe1_intensity, refprobe1_ambient, roughness,
+ ambient_light, specular_light, reflection_accum, ambient_accum);
#endif // USE_REFLECTION_PROBE1
#ifdef USE_REFLECTION_PROBE2
- reflection_process(reflection_probe2,
+ reflection_process(reflection_probe2,
#ifdef USE_VERTEX_LIGHTING
- refprobe2_reflection_normal_blend.rgb,
+ refprobe2_reflection_normal_blend.rgb,
#ifndef USE_LIGHTMAP
- refprobe2_ambient_normal,
+ refprobe2_ambient_normal,
#endif
- refprobe2_reflection_normal_blend.a,
+ refprobe2_reflection_normal_blend.a,
#else
- normal_interp, vertex_interp, refprobe2_local_matrix,
- refprobe2_use_box_project, refprobe2_box_extents, refprobe2_box_offset,
+ normal_interp, vertex_interp, refprobe2_local_matrix,
+ refprobe2_use_box_project, refprobe2_box_extents, refprobe2_box_offset,
#endif
- refprobe2_exterior, refprobe2_intensity, refprobe2_ambient, roughness,
- ambient_light, specular_light, reflection_accum, ambient_accum);
+ refprobe2_exterior, refprobe2_intensity, refprobe2_ambient, roughness,
+ ambient_light, specular_light, reflection_accum, ambient_accum);
#endif // USE_REFLECTION_PROBE2
- if (reflection_accum.a > 0.0) {
- specular_light = reflection_accum.rgb / reflection_accum.a;
- }
+ if (reflection_accum.a > 0.0) {
+ specular_light = reflection_accum.rgb / reflection_accum.a;
+ }
#ifndef USE_LIGHTMAP
- if (ambient_accum.a > 0.0) {
- ambient_light = ambient_accum.rgb / ambient_accum.a;
- }
+ if (ambient_accum.a > 0.0) {
+ ambient_light = ambient_accum.rgb / ambient_accum.a;
+ }
#endif
#endif // defined(USE_REFLECTION_PROBE1) || defined(USE_REFLECTION_PROBE2)
- // environment BRDF approximation
- {
+ // environment BRDF approximation
+ {
#if defined(DIFFUSE_TOON)
- //simplify for toon, as
- specular_light *= specular * metallic * albedo * 2.0;
+ //simplify for toon, as
+ specular_light *= specular * metallic * albedo * 2.0;
#else
- // scales the specular reflections, needs to be be computed before lighting happens,
- // but after environment and reflection probes are added
- //TODO: this curve is not really designed for gammaspace, should be adjusted
- const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
- const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
- vec4 r = roughness * c0 + c1;
- float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
- vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- specular_light *= env.x * F + env.y;
+ // scales the specular reflections, needs to be be computed before lighting happens,
+ // but after environment and reflection probes are added
+ //TODO: this curve is not really designed for gammaspace, should be adjusted
+ const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
+ const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
+ vec4 r = roughness * c0 + c1;
+ float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
+ vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
+ specular_light *= env.x * F + env.y;
#endif
- }
+ }
#ifdef USE_LIGHTMAP
- //ambient light will come entirely from lightmap is lightmap is used
- ambient_light = texture2D(lightmap, uv2_interp).rgb * lightmap_energy;
+ //ambient light will come entirely from lightmap is lightmap is used
+ ambient_light = texture2D(lightmap, uv2_interp).rgb * lightmap_energy;
#endif
#ifdef USE_LIGHTMAP_CAPTURE
- {
- vec3 cone_dirs[12] = vec3[](
- vec3(0.0, 0.0, 1.0),
- vec3(0.866025, 0.0, 0.5),
- vec3(0.267617, 0.823639, 0.5),
- vec3(-0.700629, 0.509037, 0.5),
- vec3(-0.700629, -0.509037, 0.5),
- vec3(0.267617, -0.823639, 0.5),
- vec3(0.0, 0.0, -1.0),
- vec3(0.866025, 0.0, -0.5),
- vec3(0.267617, 0.823639, -0.5),
- vec3(-0.700629, 0.509037, -0.5),
- vec3(-0.700629, -0.509037, -0.5),
- vec3(0.267617, -0.823639, -0.5));
-
- vec3 local_normal = normalize(camera_matrix * vec4(normal, 0.0)).xyz;
- vec4 captured = vec4(0.0);
- float sum = 0.0;
- for (int i = 0; i < 12; i++) {
- float amount = max(0.0, dot(local_normal, cone_dirs[i])); //not correct, but creates a nice wrap around effect
- captured += lightmap_captures[i] * amount;
- sum += amount;
- }
+ {
+ vec3 cone_dirs[12];
+ cone_dirs[0] = vec3(0.0, 0.0, 1.0);
+ cone_dirs[1] = vec3(0.866025, 0.0, 0.5);
+ cone_dirs[2] = vec3(0.267617, 0.823639, 0.5);
+ cone_dirs[3] = vec3(-0.700629, 0.509037, 0.5);
+ cone_dirs[4] = vec3(-0.700629, -0.509037, 0.5);
+ cone_dirs[5] = vec3(0.267617, -0.823639, 0.5);
+ cone_dirs[6] = vec3(0.0, 0.0, -1.0);
+ cone_dirs[7] = vec3(0.866025, 0.0, -0.5);
+ cone_dirs[8] = vec3(0.267617, 0.823639, -0.5);
+ cone_dirs[9] = vec3(-0.700629, 0.509037, -0.5);
+ cone_dirs[10] = vec3(-0.700629, -0.509037, -0.5);
+ cone_dirs[11] = vec3(0.267617, -0.823639, -0.5);
+
+ vec3 local_normal = normalize(camera_matrix * vec4(normal, 0.0)).xyz;
+ vec4 captured = vec4(0.0);
+ float sum = 0.0;
+ for (int i = 0; i < 12; i++) {
+ float amount = max(0.0, dot(local_normal, cone_dirs[i])); //not correct, but creates a nice wrap around effect
+ captured += lightmap_captures[i] * amount;
+ sum += amount;
+ }
- captured /= sum;
+ captured /= sum;
- if (lightmap_capture_sky) {
- ambient_light = mix(ambient_light, captured.rgb, captured.a);
- } else {
- ambient_light = captured.rgb;
- }
+ if (lightmap_capture_sky) {
+ ambient_light = mix(ambient_light, captured.rgb, captured.a);
+ } else {
+ ambient_light = captured.rgb;
}
-#endif
}
+#endif
+
#endif //BASE PASS
//
@@ -2052,17 +2065,6 @@ FRAGMENT_SHADER_CODE
specular_light += specular_interp * specular_blob_intensity * light_att;
diffuse_light += diffuse_interp * albedo * light_att;
- // Same as above, needed for VERTEX_LIGHTING or else lights are too bright
- const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
- const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
- vec4 r = roughness * c0 + c1;
- float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
- float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
- vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
-
- vec3 f0 = F0(metallic, specular, albedo);
- specular_light *= env.x * f0 + env.y;
-
#else
//fragment lighting
light_compute(