summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp6
-rw-r--r--drivers/gles2/rasterizer_gles2.h4
-rw-r--r--drivers/gles2/shaders/copy.glsl30
-rw-r--r--drivers/gles3/SCsub2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp265
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h9
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp56
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h30
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp287
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h24
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp27
-rw-r--r--drivers/gles3/shader_gles3.cpp36
-rw-r--r--drivers/gles3/shaders/SCsub38
-rw-r--r--drivers/gles3/shaders/canvas.glsl17
-rw-r--r--drivers/gles3/shaders/copy.glsl13
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl59
-rw-r--r--drivers/gles3/shaders/effect_blur.glsl15
-rw-r--r--drivers/gles3/shaders/particles.glsl7
-rw-r--r--drivers/gles3/shaders/scene.glsl193
-rw-r--r--drivers/unix/SCsub2
21 files changed, 863 insertions, 258 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 3c543365f0..25c0f8925d 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -4199,7 +4199,7 @@ void RasterizerGLES2::set_camera(const Transform &p_world, const CameraMatrix &p
void RasterizerGLES2::add_light(RID p_light_instance) {
-#define LIGHT_FADE_TRESHOLD 0.05
+#define LIGHT_FADE_THRESHOLD 0.05
ERR_FAIL_COND(light_instance_count >= MAX_SCENE_LIGHTS);
@@ -6481,7 +6481,7 @@ void RasterizerGLES2::_process_glow_bloom() {
copy_shader.bind();
copy_shader.set_uniform(CopyShaderGLES2::BLOOM, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM]));
- copy_shader.set_uniform(CopyShaderGLES2::BLOOM_TRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD]));
+ copy_shader.set_uniform(CopyShaderGLES2::BLOOM_THRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_THRESHOLD]));
glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
if (current_vd && current_env->fx_enabled[VS::ENV_FX_HDR]) {
@@ -6491,7 +6491,7 @@ void RasterizerGLES2::_process_glow_bloom() {
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]));
//copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,1.0);
- copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_TRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD]));
+ copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_THRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_THRESHOLD]));
copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_SCALE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE]));
glActiveTexture(GL_TEXTURE0);
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index e6b76a4e92..e86d3ba298 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -689,14 +689,14 @@ class RasterizerGLES2 : public Rasterizer {
fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH] = 1.0;
fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE] = 0;
fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM] = 0.0;
- fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD] = 0.5;
+ fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_THRESHOLD] = 0.5;
fx_param[VS::ENV_FX_PARAM_DOF_BLUR_PASSES] = 1;
fx_param[VS::ENV_FX_PARAM_DOF_BLUR_BEGIN] = 100.0;
fx_param[VS::ENV_FX_PARAM_DOF_BLUR_RANGE] = 10.0;
fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER] = VS::ENV_FX_HDR_TONE_MAPPER_LINEAR;
fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE] = 0.4;
fx_param[VS::ENV_FX_PARAM_HDR_WHITE] = 1.0;
- fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD] = 0.95;
+ fx_param[VS::ENV_FX_PARAM_HDR_GLOW_THRESHOLD] = 0.95;
fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE] = 0.2;
fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE] = 0.4;
fx_param[VS::ENV_FX_PARAM_HDR_MAX_LUMINANCE] = 8.0;
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index cb42970921..23680ffe91 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -16,6 +16,7 @@ attribute vec2 uv_in; // attrib:4
#endif
attribute vec2 uv2_in; // attrib:5
+
#ifdef USE_CUBEMAP
varying vec3 cube_interp;
#else
@@ -58,7 +59,9 @@ float sRGB_gamma_correct(float c){
#define LUM_RANGE 4.0
-#ifdef USE_CUBEMAP
+#ifdef USE_ARRAY
+uniform sampler2DArray source;
+#elif defined(USE_CUBEMAP)
varying vec3 cube_interp;
uniform samplerCube source_cube;
#else
@@ -84,7 +87,7 @@ uniform sampler2D glow_source;
#if defined(USE_HDR) && defined(USE_GLOW_COPY)
-uniform highp float hdr_glow_treshold;
+uniform highp float hdr_glow_threshold;
uniform highp float hdr_glow_scale;
#endif
@@ -104,7 +107,7 @@ uniform vec3 bcs;
#ifdef USE_GLOW_COPY
uniform float bloom;
-uniform float bloom_treshold;
+uniform float bloom_threshold;
#endif
@@ -145,23 +148,17 @@ uniform float custom_alpha;
void main() {
//vec4 color = color_interp;
-#ifdef USE_HIGHP_SOURCE
-#ifdef USE_CUBEMAP
+
+#ifdef USE_ARRAY
+ highp vec4 color = textureLod( source, vec3(uv_interp,0.0),0.0 );
+#elif defined(USE_CUBEMAP)
highp vec4 color = textureCube( source_cube, normalize(cube_interp) );
#else
highp vec4 color = texture2D( source, uv_interp );
#endif
-#else
-
-#ifdef USE_CUBEMAP
- vec4 color = textureCube( source_cube, normalize(cube_interp) );
-
-#else
- vec4 color = texture2D( source, uv_interp );
-#endif
#endif
@@ -377,11 +374,11 @@ void main() {
#ifdef USE_GLOW_COPY
- highp vec3 glowcol = color.rgb*color.a+step(bloom_treshold,dot(vec3(0.3333,0.3333,0.3333),color.rgb))*bloom*color.rgb;
+ highp vec3 glowcol = color.rgb*color.a+step(bloom_threshold,dot(vec3(0.3333,0.3333,0.3333),color.rgb))*bloom*color.rgb;
#ifdef USE_HDR
highp float collum = max(color.r,max(color.g,color.b));
- glowcol+=color.rgb*max(collum-hdr_glow_treshold,0.0)*hdr_glow_scale;
+ glowcol+=color.rgb*max(collum-hdr_glow_threshold,0.0)*hdr_glow_scale;
#endif
color.rgb=glowcol;
color.a=0.0;
@@ -503,7 +500,7 @@ void main() {
//lum_accum=exp(lum_accum);
-#ifdef USE_8BIT_HDR
+#ifdef USE_8BIT_HDR
highp float vd_lum = dot(texture2D( source_vd_lum, vec2(0.0) ), _multcv );
lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance*(1.0/LUM_RANGE),max_luminance*(1.0/LUM_RANGE));
@@ -558,4 +555,3 @@ void main() {
#endif
}
-
diff --git a/drivers/gles3/SCsub b/drivers/gles3/SCsub
index a17335b41b..2471dd3739 100644
--- a/drivers/gles3/SCsub
+++ b/drivers/gles3/SCsub
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
Import('env')
env.add_source_files(env.drivers_sources,"*.cpp")
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index c71bf22965..268d6b44c6 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "rasterizer_canvas_gles3.h"
-#include "servers/visual/visual_server_raster.h"
-
#include "global_config.h"
#include "os/os.h"
+#include "rasterizer_scene_gles3.h"
+#include "servers/visual/visual_server_raster.h"
#ifndef GLES_OVER_GL
#define glClearDepth glClearDepthf
#endif
@@ -172,6 +172,11 @@ void RasterizerCanvasGLES3::canvas_begin() {
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, Color(1, 1, 1, 1));
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, Transform2D());
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, Transform2D());
+ if (storage->frame.current_rt) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+ } else {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0));
+ }
//state.canvas_shader.set_uniform(CanvasShaderGLES3::PROJECTION_MATRIX,state.vp);
//state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX,Transform());
@@ -282,7 +287,11 @@ void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable, bool p_ninepat
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate);
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.extra_matrix);
-
+ if (storage->frame.current_rt) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+ } else {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0));
+ }
state.using_texture_rect = p_enable;
state.using_ninepatch = p_ninepatch;
}
@@ -339,6 +348,53 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
glBindVertexArray(0);
}
+void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
+
+ glBindVertexArray(data.polygon_buffer_pointer_array);
+ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+
+ uint32_t buffer_ofs = 0;
+
+ //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), ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(Vector2) * p_vertex_count;
+ //color
+
+ 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, 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(Vector2), ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(Vector2) * p_vertex_count;
+
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
+ }
+
+ glDrawArrays(p_primitive, 0, p_vertex_count);
+
+ 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) {
static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
@@ -416,22 +472,83 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
glVertexAttrib4f(VS::ARRAY_COLOR, line->color.r, line->color.g, line->color.b, line->color.a);
- Vector2 verts[2] = {
- Vector2(line->from.x, line->from.y),
- Vector2(line->to.x, line->to.y)
- };
+ if (line->width <= 1) {
+ Vector2 verts[2] = {
+ Vector2(line->from.x, line->from.y),
+ Vector2(line->to.x, line->to.y)
+ };
#ifdef GLES_OVER_GL
- if (line->antialiased)
- glEnable(GL_LINE_SMOOTH);
+ if (line->antialiased)
+ glEnable(GL_LINE_SMOOTH);
#endif
- //glLineWidth(line->width);
- _draw_gui_primitive(2, verts, NULL, NULL);
+ //glLineWidth(line->width);
+ _draw_gui_primitive(2, verts, NULL, NULL);
+
+#ifdef GLES_OVER_GL
+ if (line->antialiased)
+ glDisable(GL_LINE_SMOOTH);
+#endif
+ } else {
+ //thicker line
+
+ Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5;
+
+ Vector2 verts[4] = {
+ line->from - t,
+ line->from + t,
+ line->to + t,
+ line->to - t,
+ };
+
+ //glLineWidth(line->width);
+ _draw_gui_primitive(4, verts, NULL, NULL);
+#ifdef GLES_OVER_GL
+ if (line->antialiased) {
+ glEnable(GL_LINE_SMOOTH);
+ for (int i = 0; i < 4; i++) {
+ Vector2 vertsl[2] = {
+ verts[i],
+ verts[(i + 1) % 4],
+ };
+ _draw_gui_primitive(2, vertsl, NULL, NULL);
+ }
+ glDisable(GL_LINE_SMOOTH);
+ }
+#endif
+ }
+
+ } break;
+ case Item::Command::TYPE_POLYLINE: {
+ Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(c);
+ _set_texture_rect_mode(false);
+
+ _bind_canvas_texture(RID(), RID());
+
+ if (pline->triangles.size()) {
+
+ _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1);
#ifdef GLES_OVER_GL
- if (line->antialiased)
+ glEnable(GL_LINE_SMOOTH);
+ if (pline->lines.size()) {
+ _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1);
+ }
glDisable(GL_LINE_SMOOTH);
#endif
+ } else {
+
+#ifdef GLES_OVER_GL
+ if (pline->antialiased)
+ glEnable(GL_LINE_SMOOTH);
+#endif
+ _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1);
+
+#ifdef GLES_OVER_GL
+ if (pline->antialiased)
+ glDisable(GL_LINE_SMOOTH);
+#endif
+ }
} break;
case Item::Command::TYPE_RECT: {
@@ -822,6 +939,78 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material,
#endif
+void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
+
+ state.canvas_texscreen_used = true;
+ //blur diffuse into effect mipmaps using separatable convolution
+ //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
+
+ Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height);
+
+ Color blur_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y);
+
+ if (p_rect != Rect2()) {
+
+ scene_render->state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_BLUR_SECTION, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_COPY_SECTION, true);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
+
+ storage->shaders.copy.bind();
+ storage->shaders.copy.set_uniform(CopyShaderGLES3::COPY_SECTION, blur_section);
+
+ scene_render->_copy_screen();
+
+ for (int i = 0; i < storage->frame.current_rt->effects.mip_maps[1].sizes.size(); i++) {
+
+ int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width;
+ int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height;
+ glViewport(0, 0, vp_w, vp_h);
+ //horizontal pass
+ scene_render->state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, true);
+ scene_render->state.effect_blur_shader.bind();
+ scene_render->state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
+ scene_render->state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
+ scene_render->state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::BLUR_SECTION, blur_section);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
+
+ scene_render->_copy_screen();
+
+ scene_render->state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, false);
+
+ //vertical pass
+ scene_render->state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, true);
+ scene_render->state.effect_blur_shader.bind();
+ scene_render->state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
+ scene_render->state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
+ scene_render->state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::BLUR_SECTION, blur_section);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[1].color);
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[i + 1].fbo); //next level, since mipmaps[0] starts one level bigger
+
+ scene_render->_copy_screen();
+
+ scene_render->state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, false);
+ }
+
+ scene_render->state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_BLUR_SECTION, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_COPY_SECTION, false);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //back to front
+ glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
+ state.canvas_shader.bind(); //back to canvas
+
+ if (state.using_texture_rect) {
+ state.using_texture_rect = false;
+ _set_texture_rect_mode(state.using_texture_rect, state.using_ninepatch);
+ }
+}
+
void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) {
Item *current_clip = NULL;
@@ -875,44 +1064,17 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
glDisable(GL_SCISSOR_TEST);
}
}
-#if 0
- if (ci->copy_back_buffer && framebuffer.active && framebuffer.scale==1) {
- Rect2 rect;
- int x,y;
+ if (ci->copy_back_buffer) {
if (ci->copy_back_buffer->full) {
- x = viewport.x;
- y = window_size.height-(viewport.height+viewport.y);
- } else {
- x = viewport.x+ci->copy_back_buffer->screen_rect.pos.x;
- y = window_size.height-(viewport.y+ci->copy_back_buffer->screen_rect.pos.y+ci->copy_back_buffer->screen_rect.size.y);
- }
- glActiveTexture(GL_TEXTURE0+max_texture_units-1);
- glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
-
-#ifdef GLEW_ENABLED
- if (current_rt) {
- glReadBuffer(GL_COLOR_ATTACHMENT0);
+ _copy_texscreen(Rect2());
} else {
- glReadBuffer(GL_BACK);
+ _copy_texscreen(ci->copy_back_buffer->rect);
}
-#endif
- if (current_rt) {
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,viewport.x,viewport.y,viewport.x,viewport.y,viewport.width,viewport.height);
- //window_size.height-(viewport.height+viewport.y)
- } else {
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
- }
-
- canvas_texscreen_used=true;
- glActiveTexture(GL_TEXTURE0);
-
}
-#endif
-
//begin rect
Item *material_owner = ci->material_owner ? ci->material_owner : ci;
@@ -934,6 +1096,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
if (shader_ptr && shader_ptr != shader_cache) {
+ if (shader_ptr->canvas_item.uses_screen_texture && !state.canvas_texscreen_used) {
+ //copy if not copied before
+ _copy_texscreen(Rect2());
+ }
+
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);
state.canvas_shader.bind();
@@ -1046,7 +1213,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate);
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.extra_matrix);
-
+ if (storage->frame.current_rt) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+ } else {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0));
+ }
if (unshaded || (state.canvas_item_modulate.a > 0.001 && (!shader_cache || shader_cache->canvas_item.light_mode != RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !ci->light_masked))
_canvas_item_render_commands(ci, current_clip, reclip);
@@ -1376,6 +1547,12 @@ void RasterizerCanvasGLES3::reset_canvas() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ //use for reading from screen
+ if (storage->frame.current_rt) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
+ }
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
@@ -1543,7 +1720,7 @@ void RasterizerCanvasGLES3::initialize() {
glBindBuffer(GL_UNIFORM_BUFFER, 0);
state.canvas_shader.init();
- state.canvas_shader.set_base_material_tex_index(1);
+ state.canvas_shader.set_base_material_tex_index(2);
state.canvas_shadow_shader.init();
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 5f435275df..c0af22b5e8 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -32,7 +32,9 @@
#include "rasterizer_storage_gles3.h"
#include "servers/visual/rasterizer.h"
-#include "shaders/canvas_shadow.glsl.h"
+#include "shaders/canvas_shadow.glsl.gen.h"
+
+class RasterizerSceneGLES3;
class RasterizerCanvasGLES3 : public RasterizerCanvas {
public:
@@ -42,6 +44,8 @@ public:
float time;
};
+ RasterizerSceneGLES3 *scene_render;
+
struct Data {
GLuint canvas_quad_vertices;
@@ -117,7 +121,10 @@ 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);
+ _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 _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip);
+ _FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light);
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 53df7e9c3d..0cfa8a7d6e 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -412,6 +412,7 @@ RasterizerGLES3::RasterizerGLES3() {
canvas = memnew(RasterizerCanvasGLES3);
scene = memnew(RasterizerSceneGLES3);
canvas->storage = storage;
+ canvas->scene_render = scene;
storage->canvas = canvas;
scene->storage = storage;
storage->scene = scene;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 96c3da99f0..e8c6502bf4 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -869,7 +869,7 @@ void RasterizerSceneGLES3::environment_set_dof_blur_near(RID p_env, bool p_enabl
env->dof_blur_near_amount = p_amount;
env->dof_blur_near_quality = p_quality;
}
-void RasterizerSceneGLES3::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) {
+void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -878,9 +878,9 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_
env->glow_levels = p_level_flags;
env->glow_intensity = p_intensity;
env->glow_strength = p_strength;
- env->glow_bloom = p_bloom_treshold;
+ env->glow_bloom = p_bloom_threshold;
env->glow_blend_mode = p_blend_mode;
- env->glow_hdr_bleed_treshold = p_hdr_bleed_treshold;
+ env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold;
env->glow_hdr_bleed_scale = p_hdr_bleed_scale;
env->glow_bicubic_upscale = p_bicubic_upscale;
}
@@ -1879,19 +1879,29 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.scene_ubo); //bind globals ubo
+ bool use_radiance_map = false;
if (!p_shadow && !p_directional_add) {
glBindBufferBase(GL_UNIFORM_BUFFER, 2, state.env_radiance_ubo); //bind environment radiance info
if (p_base_env) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
- glBindTexture(GL_TEXTURE_2D, p_base_env);
+ if (storage->config.use_texture_array_environment) {
+ glBindTexture(GL_TEXTURE_2D_ARRAY, p_base_env);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, p_base_env);
+ }
+
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, true);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, storage->config.use_texture_array_environment);
+ use_radiance_map = true;
} else {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, false);
}
} else {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, false);
}
state.cull_front = false;
@@ -1958,6 +1968,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false);
//state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true);
} else {
@@ -1973,6 +1984,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false);
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);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, use_radiance_map);
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);
@@ -2155,7 +2167,19 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
ERR_FAIL_COND(!m);
- bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture);
+ _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow);
+
+ while (m->next_pass.is_valid()) {
+ m = storage->material_owner.getornull(m->next_pass);
+ if (!m)
+ break;
+ _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow);
+ }
+}
+
+void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) {
+
+ bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded);
bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop;
bool has_alpha = has_base_alpha || has_blend_alpha;
bool shadow = false;
@@ -3695,7 +3719,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->exposure.color);
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_BLOOM, env->glow_bloom);
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_TRESHOLD, env->glow_hdr_bleed_treshold);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_THRESHOLD, env->glow_hdr_bleed_threshold);
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_SCALE, env->glow_hdr_bleed_scale);
} else {
@@ -3973,7 +3997,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
} else {
- use_mrt = env && (state.used_screen_texture || state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
+ use_mrt = env && (state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
//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];
@@ -4149,6 +4173,20 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (use_mrt) {
_render_mrts(env, p_cam_projection);
+ } else {
+ //FIXME: check that this is possible to use
+ if (state.used_screen_texture) {
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ _blur_effect_buffer();
+ //restored framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
+ }
}
if (state.used_screen_texture) {
@@ -4226,7 +4264,11 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
storage->canvas->canvas_begin();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, env_radiance_tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index c52a00bf17..37bbd60797 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -33,17 +33,17 @@
/* Must come before shaders or the Windows build fails... */
#include "rasterizer_storage_gles3.h"
-#include "drivers/gles3/shaders/cube_to_dp.glsl.h"
-#include "drivers/gles3/shaders/effect_blur.glsl.h"
-#include "drivers/gles3/shaders/exposure.glsl.h"
-#include "drivers/gles3/shaders/resolve.glsl.h"
-#include "drivers/gles3/shaders/scene.glsl.h"
-#include "drivers/gles3/shaders/screen_space_reflection.glsl.h"
-#include "drivers/gles3/shaders/ssao.glsl.h"
-#include "drivers/gles3/shaders/ssao_blur.glsl.h"
-#include "drivers/gles3/shaders/ssao_minify.glsl.h"
-#include "drivers/gles3/shaders/subsurf_scattering.glsl.h"
-#include "drivers/gles3/shaders/tonemap.glsl.h"
+#include "drivers/gles3/shaders/cube_to_dp.glsl.gen.h"
+#include "drivers/gles3/shaders/effect_blur.glsl.gen.h"
+#include "drivers/gles3/shaders/exposure.glsl.gen.h"
+#include "drivers/gles3/shaders/resolve.glsl.gen.h"
+#include "drivers/gles3/shaders/scene.glsl.gen.h"
+#include "drivers/gles3/shaders/screen_space_reflection.glsl.gen.h"
+#include "drivers/gles3/shaders/ssao.glsl.gen.h"
+#include "drivers/gles3/shaders/ssao_blur.glsl.gen.h"
+#include "drivers/gles3/shaders/ssao_minify.glsl.gen.h"
+#include "drivers/gles3/shaders/subsurf_scattering.glsl.gen.h"
+#include "drivers/gles3/shaders/tonemap.glsl.gen.h"
class RasterizerSceneGLES3 : public RasterizerScene {
public:
@@ -381,7 +381,7 @@ public:
float glow_strength;
float glow_bloom;
VS::EnvironmentGlowBlendMode glow_blend_mode;
- float glow_hdr_bleed_treshold;
+ float glow_hdr_bleed_threshold;
float glow_hdr_bleed_scale;
bool glow_bicubic_upscale;
@@ -467,7 +467,7 @@ public:
glow_strength = 1.0;
glow_bloom = 0.0;
glow_blend_mode = VS::GLOW_BLEND_MODE_SOFTLIGHT;
- glow_hdr_bleed_treshold = 1.0;
+ glow_hdr_bleed_threshold = 1.0;
glow_hdr_bleed_scale = 2.0;
glow_bicubic_upscale = false;
@@ -522,7 +522,7 @@ public:
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality);
- 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_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, 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_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
@@ -769,6 +769,8 @@ public:
_FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow);
+ _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow);
+
void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy);
void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index f7e1fdee9d..14fb36f3b0 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1260,6 +1260,10 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //need this for proper sampling
if (config.srgb_decode_supported && texture->srgb && !texture->using_srgb) {
@@ -1275,87 +1279,200 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &sky->radiance);
- glBindTexture(GL_TEXTURE_2D, sky->radiance);
- GLuint tmp_fb;
+ if (config.use_texture_array_environment) {
- glGenFramebuffers(1, &tmp_fb);
- glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
+ //texture3D
+ glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance);
- int size = p_radiance_size;
+ GLuint tmp_fb;
- int lod = 0;
+ glGenFramebuffers(1, &tmp_fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
- int mipmaps = 6;
+ int size = p_radiance_size;
- int mm_level = mipmaps;
+ int array_level = 6;
- bool use_float = config.hdr_supported;
+ bool use_float = config.hdr_supported;
- GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2;
- GLenum format = GL_RGBA;
- GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV;
+ GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2;
+ GLenum format = GL_RGBA;
+ GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV;
- while (mm_level) {
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internal_format, size, size * 2, array_level, 0, format, type, NULL);
- glTexImage2D(GL_TEXTURE_2D, lod, internal_format, size, size * 2, 0, format, type, NULL);
- lod++;
- mm_level--;
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- if (size > 1)
- size >>= 1;
- }
+ GLuint tmp_fb2;
+ GLuint tmp_tex;
+ {
+ //generate another one for rendering, as can't read and write from a single texarray it seems
+ glGenFramebuffers(1, &tmp_fb2);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
+ glGenTextures(1, &tmp_tex);
+ glBindTexture(GL_TEXTURE_2D, tmp_tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size * 2, 0, format, type, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#ifdef DEBUG_ENABLED
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+#endif
+ }
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1);
+ for (int j = 0; j < array_level; j++) {
- lod = 0;
- mm_level = mipmaps;
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
- size = p_radiance_size;
+ if (j == 0) {
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_PANORAMA, true);
- shaders.cubemap_filter.bind();
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, false);
+ shaders.cubemap_filter.bind();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(texture->target, texture->tex_id);
+ } else {
- while (mm_level) {
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
+ shaders.cubemap_filter.bind();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_ARRAY_INDEX, j - 1); //read from previous to ensure better blur
+ }
+
+ for (int i = 0; i < 2; i++) {
+ glViewport(0, i * size, size, size);
+ glBindVertexArray(resources.quadie_array);
+
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, j / float(array_level - 1));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glBindVertexArray(0);
+ }
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tmp_fb);
+ glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, sky->radiance, 0, j);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, tmp_fb2);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBlitFramebuffer(0, 0, size, size * 2, 0, 0, size, size * 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ }
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
+
+ //restore ranges
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance);
+
+ glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
+
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glDeleteFramebuffers(1, &tmp_fb);
+ glDeleteFramebuffers(1, &tmp_fb2);
+ glDeleteTextures(1, &tmp_tex);
+
+ } else {
+ //regular single texture with mipmaps
+ glBindTexture(GL_TEXTURE_2D, sky->radiance);
+
+ GLuint tmp_fb;
+
+ glGenFramebuffers(1, &tmp_fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
+
+ int size = p_radiance_size;
+
+ int lod = 0;
+
+ int mipmaps = 6;
+
+ int mm_level = mipmaps;
+
+ bool use_float = config.hdr_supported;
+
+ GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2;
+ GLenum format = GL_RGBA;
+ GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV;
+
+ while (mm_level) {
+
+ glTexImage2D(GL_TEXTURE_2D, lod, internal_format, size, size * 2, 0, format, type, NULL);
+ lod++;
+ mm_level--;
+
+ if (size > 1)
+ size >>= 1;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->radiance, lod);
+ lod = 0;
+ mm_level = mipmaps;
+
+ size = p_radiance_size;
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
+ shaders.cubemap_filter.bind();
+
+ while (mm_level) {
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->radiance, lod);
#ifdef DEBUG_ENABLED
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
#endif
- for (int i = 0; i < 2; i++) {
- glViewport(0, i * size, size, size);
- glBindVertexArray(resources.quadie_array);
+ for (int i = 0; i < 2; i++) {
+ glViewport(0, i * size, size, size);
+ glBindVertexArray(resources.quadie_array);
- shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
- shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, lod / float(mipmaps - 1));
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, lod / float(mipmaps - 1));
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glBindVertexArray(0);
- }
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glBindVertexArray(0);
+ }
- if (size > 1)
- size >>= 1;
- lod++;
- mm_level--;
- }
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_PANORAMA, false);
+ if (size > 1)
+ size >>= 1;
+ lod++;
+ mm_level--;
+ }
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
- //restore ranges
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1);
+ //restore ranges
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
- glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
- glDeleteFramebuffers(1, &tmp_fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glDeleteFramebuffers(1, &tmp_fb);
+ }
}
/* SHADER API */
@@ -1445,6 +1562,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
+ p_shader->canvas_item.uses_screen_texture = false;
+ p_shader->canvas_item.uses_screen_uv = false;
shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
@@ -1455,6 +1574,10 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
+ shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
+ shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
+ shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
+
actions = &shaders.actions_canvas;
actions->uniforms = &p_shader->uniforms;
@@ -1747,6 +1870,14 @@ void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_wid
material->line_width = p_width;
}
+void RasterizerStorageGLES3::material_set_next_pass(RID p_material, RID p_next_material) {
+
+ Material *material = material_owner.get(p_material);
+ ERR_FAIL_COND(!material);
+
+ material->next_pass = p_next_material;
+}
+
bool RasterizerStorageGLES3::material_is_animated(RID p_material) {
Material *material = material_owner.get(p_material);
@@ -1755,7 +1886,11 @@ bool RasterizerStorageGLES3::material_is_animated(RID p_material) {
_update_material(material);
}
- return material->is_animated_cache;
+ bool animated = material->is_animated_cache;
+ if (!animated && material->next_pass.is_valid()) {
+ animated = material_is_animated(material->next_pass);
+ }
+ return animated;
}
bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) {
@@ -1765,7 +1900,13 @@ bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) {
_update_material(material);
}
- return material->can_cast_shadow_cache;
+ bool casts_shadows = material->can_cast_shadow_cache;
+
+ if (!casts_shadows && material->next_pass.is_valid()) {
+ casts_shadows = material_casts_shadows(material->next_pass);
+ }
+
+ return casts_shadows;
}
void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) {
@@ -5068,6 +5209,14 @@ void RasterizerStorageGLES3::particles_set_lifetime(RID p_particles, float p_lif
ERR_FAIL_COND(!particles);
particles->lifetime = p_lifetime;
}
+
+void RasterizerStorageGLES3::particles_set_one_shot(RID p_particles, bool p_one_shot) {
+
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->one_shot = p_one_shot;
+}
+
void RasterizerStorageGLES3::particles_set_pre_process_time(RID p_particles, float p_time) {
Particles *particles = particles_owner.getornull(p_particles);
@@ -5199,6 +5348,14 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p
particles->draw_passes[p_pass] = p_mesh;
}
+void RasterizerStorageGLES3::particles_restart(RID p_particles) {
+
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->restart_request = true;
+}
+
void RasterizerStorageGLES3::particles_request_process(RID p_particles) {
Particles *particles = particles_owner.getornull(p_particles);
@@ -5290,6 +5447,10 @@ void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_de
particles->cycle_number = 0;
particles->random_seed = Math::rand();
} else if (new_phase < particles->phase) {
+ if (particles->one_shot) {
+ particles->emitting = false;
+ shaders.particles.set_uniform(ParticlesShaderGLES3::EMITTING, false);
+ }
particles->cycle_number++;
}
@@ -5356,6 +5517,17 @@ void RasterizerStorageGLES3::update_particles() {
Particles *particles = particle_update_list.first()->self();
+ if (particles->restart_request) {
+ particles->emitting = true; //restart from zero
+ particles->prev_ticks = 0;
+ particles->phase = 0;
+ particles->prev_phase = 0;
+ particles->clear = true;
+ particles->particle_valid_histories[0] = false;
+ particles->particle_valid_histories[1] = false;
+ particles->restart_request = false;
+ }
+
if (particles->inactive && !particles->emitting) {
particle_update_list.remove(particle_update_list.first());
@@ -6820,6 +6992,7 @@ void RasterizerStorageGLES3::initialize() {
frame.current_rt = NULL;
config.keep_original_textures = false;
config.generate_wireframes = false;
+ config.use_texture_array_environment = GLOBAL_DEF("rendering/quality/texture_array_environments", true);
}
void RasterizerStorageGLES3::finalize() {
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 65026a16ec..183db534ac 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -35,11 +35,11 @@
#include "servers/visual/shader_language.h"
#include "shader_compiler_gles3.h"
#include "shader_gles3.h"
-#include "shaders/blend_shape.glsl.h"
-#include "shaders/canvas.glsl.h"
-#include "shaders/copy.glsl.h"
-#include "shaders/cubemap_filter.glsl.h"
-#include "shaders/particles.glsl.h"
+#include "shaders/blend_shape.glsl.gen.h"
+#include "shaders/canvas.glsl.gen.h"
+#include "shaders/copy.glsl.gen.h"
+#include "shaders/cubemap_filter.glsl.gen.h"
+#include "shaders/particles.glsl.gen.h"
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
@@ -86,6 +86,8 @@ public:
bool generate_wireframes;
+ bool use_texture_array_environment;
+
Set<String> extensions;
bool keep_original_textures;
@@ -401,6 +403,8 @@ public:
};
int light_mode;
+ bool uses_screen_texture;
+ bool uses_screen_uv;
} canvas_item;
@@ -492,6 +496,8 @@ public:
Vector<RID> textures;
float line_width;
+ RID next_pass;
+
uint32_t index;
uint64_t last_pass;
@@ -529,6 +535,7 @@ public:
virtual Variant material_get_param(RID p_material, const StringName &p_param) const;
virtual void material_set_line_width(RID p_material, float p_width);
+ virtual void material_set_next_pass(RID p_material, RID p_next_material);
virtual bool material_is_animated(RID p_material);
virtual bool material_casts_shadows(RID p_material);
@@ -1036,11 +1043,13 @@ public:
bool inactive;
float inactive_time;
bool emitting;
+ bool one_shot;
int amount;
float lifetime;
float pre_process_time;
float explosiveness;
float randomness;
+ bool restart_request;
Rect3 custom_aabb;
bool use_local_coords;
RID process_material;
@@ -1080,6 +1089,7 @@ public:
: particle_element(this) {
cycle_number = 0;
emitting = false;
+ one_shot = false;
amount = 0;
lifetime = 1.0;
pre_process_time = 0.0;
@@ -1093,6 +1103,8 @@ public:
speed_scale = 1.0;
random_seed = 0;
+ restart_request = false;
+
custom_aabb = Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8));
draw_order = VS::PARTICLES_DRAW_ORDER_INDEX;
@@ -1131,6 +1143,7 @@ public:
virtual void particles_set_emitting(RID p_particles, bool p_emitting);
virtual void particles_set_amount(RID p_particles, int p_amount);
virtual void particles_set_lifetime(RID p_particles, float p_lifetime);
+ virtual void particles_set_one_shot(RID p_particles, bool p_one_shot);
virtual void particles_set_pre_process_time(RID p_particles, float p_time);
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio);
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio);
@@ -1140,6 +1153,7 @@ public:
virtual void particles_set_process_material(RID p_particles, RID p_material);
virtual void particles_set_fixed_fps(RID p_particles, int p_fps);
virtual void particles_set_fractional_delta(RID p_particles, bool p_enable);
+ virtual void particles_restart(RID p_particles);
virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order);
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 41421a3e2f..206f270f68 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -304,6 +304,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
uniform_sizes.resize(max_uniforms);
uniform_alignments.resize(max_uniforms);
uniform_defines.resize(max_uniforms);
+ bool uses_uniforms = false;
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
@@ -323,9 +324,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key());
r_gen_code.texture_hints[E->get().texture_order] = E->get().hint;
} else {
- if (r_gen_code.uniforms.empty()) {
+ if (!uses_uniforms) {
r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
+ uses_uniforms = true;
}
uniform_defines[E->get().order] = ucode;
uniform_sizes[E->get().order] = _get_datatype_size(E->get().type);
@@ -651,6 +653,14 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
_dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode]);
+ if (r_gen_code.uniform_total_size) { //uniforms used?
+ int md = sizeof(float) * 4;
+ if (r_gen_code.uniform_total_size % md) {
+ r_gen_code.uniform_total_size += md - (r_gen_code.uniform_total_size % md);
+ }
+ r_gen_code.uniform_total_size += md; //pad just in case
+ }
+
return OK;
}
@@ -680,7 +690,8 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"] = "screen_texture";
- actions[VS::SHADER_CANVAS_ITEM].renames["POSITION"] = "(gl_FragCoord.xy)";
+ actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size";
+ actions[VS::SHADER_CANVAS_ITEM].renames["FRAGCOORD"] = "gl_FragCoord";
actions[VS::SHADER_CANVAS_ITEM].renames["POINT_COORD"] = "gl_PointCoord";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_VEC"] = "light_vec";
@@ -694,11 +705,12 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n";
- actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
/** SPATIAL SHADER **/
@@ -773,11 +785,18 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
- actions[VS::SHADER_SPATIAL].render_mode_defines["skip_default_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
+
+ actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
/* PARTICLES SHADER */
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index e08ef0ad12..33a7c9a22f 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -289,16 +289,17 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
#endif
strings.push_back(vertex_code0.get_data());
+
if (cc) {
- code_globals = cc->vertex_globals.ascii();
- strings.push_back(code_globals.get_data());
+ material_string = cc->uniforms.ascii();
+ strings.push_back(material_string.get_data());
}
strings.push_back(vertex_code1.get_data());
if (cc) {
- material_string = cc->uniforms.ascii();
- strings.push_back(material_string.get_data());
+ code_globals = cc->vertex_globals.ascii();
+ strings.push_back(code_globals.get_data());
}
strings.push_back(vertex_code2.get_data());
@@ -387,15 +388,15 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
strings.push_back(fragment_code0.get_data());
if (cc) {
- code_globals = cc->fragment_globals.ascii();
- strings.push_back(code_globals.get_data());
+ material_string = cc->uniforms.ascii();
+ strings.push_back(material_string.get_data());
}
strings.push_back(fragment_code1.get_data());
if (cc) {
- material_string = cc->uniforms.ascii();
- strings.push_back(material_string.get_data());
+ code_globals = cc->fragment_globals.ascii();
+ strings.push_back(code_globals.get_data());
}
strings.push_back(fragment_code2.get_data());
@@ -415,7 +416,8 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
strings.push_back(fragment_code4.get_data());
#ifdef DEBUG_SHADER
- DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data()));
+ DEBUG_PRINT("\nFragment Globals:\n\n" + String(code_globals.get_data()));
+ DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string2.get_data()));
for (int i = 0; i < strings.size(); i++) {
//print_line("frag strings "+itos(i)+":"+String(strings[i]));
@@ -617,21 +619,21 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
String material_tag = "\nMATERIAL_UNIFORMS";
String code_tag = "\nVERTEX_SHADER_CODE";
String code = vertex_code;
- int cpos = code.find(globals_tag);
+ int cpos = code.find(material_tag);
if (cpos == -1) {
vertex_code0 = code.ascii();
} else {
vertex_code0 = code.substr(0, cpos).ascii();
- code = code.substr(cpos + globals_tag.length(), code.length());
+ code = code.substr(cpos + material_tag.length(), code.length());
- cpos = code.find(material_tag);
+ cpos = code.find(globals_tag);
if (cpos == -1) {
vertex_code1 = code.ascii();
} else {
vertex_code1 = code.substr(0, cpos).ascii();
- String code2 = code.substr(cpos + material_tag.length(), code.length());
+ String code2 = code.substr(cpos + globals_tag.length(), code.length());
cpos = code2.find(code_tag);
if (cpos == -1) {
@@ -651,14 +653,14 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
String code_tag = "\nFRAGMENT_SHADER_CODE";
String light_code_tag = "\nLIGHT_SHADER_CODE";
String code = fragment_code;
- int cpos = code.find(globals_tag);
+ int cpos = code.find(material_tag);
if (cpos == -1) {
fragment_code0 = code.ascii();
} else {
fragment_code0 = code.substr(0, cpos).ascii();
//print_line("CODE0:\n"+String(fragment_code0.get_data()));
- code = code.substr(cpos + globals_tag.length(), code.length());
- cpos = code.find(material_tag);
+ code = code.substr(cpos + material_tag.length(), code.length());
+ cpos = code.find(globals_tag);
if (cpos == -1) {
fragment_code1 = code.ascii();
@@ -667,7 +669,7 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
fragment_code1 = code.substr(0, cpos).ascii();
//print_line("CODE1:\n"+String(fragment_code1.get_data()));
- String code2 = code.substr(cpos + material_tag.length(), code.length());
+ String code2 = code.substr(cpos + globals_tag.length(), code.length());
cpos = code2.find(light_code_tag);
if (cpos == -1) {
diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub
index f9baeae97d..0c69c8cf74 100644
--- a/drivers/gles3/shaders/SCsub
+++ b/drivers/gles3/shaders/SCsub
@@ -1,22 +1,22 @@
+#!/usr/bin/env python
+
Import('env')
if env['BUILDERS'].has_key('GLES3_GLSL'):
- env.GLES3_GLSL('copy.glsl');
- env.GLES3_GLSL('resolve.glsl');
- env.GLES3_GLSL('canvas.glsl');
- env.GLES3_GLSL('canvas_shadow.glsl');
- env.GLES3_GLSL('scene.glsl');
- env.GLES3_GLSL('cubemap_filter.glsl');
- env.GLES3_GLSL('cube_to_dp.glsl');
- env.GLES3_GLSL('blend_shape.glsl');
- env.GLES3_GLSL('screen_space_reflection.glsl');
- env.GLES3_GLSL('effect_blur.glsl');
- env.GLES3_GLSL('subsurf_scattering.glsl');
- env.GLES3_GLSL('ssao.glsl');
- env.GLES3_GLSL('ssao_minify.glsl');
- env.GLES3_GLSL('ssao_blur.glsl');
- env.GLES3_GLSL('exposure.glsl');
- env.GLES3_GLSL('tonemap.glsl');
- env.GLES3_GLSL('particles.glsl');
-
-
+ env.GLES3_GLSL('copy.glsl');
+ env.GLES3_GLSL('resolve.glsl');
+ env.GLES3_GLSL('canvas.glsl');
+ env.GLES3_GLSL('canvas_shadow.glsl');
+ env.GLES3_GLSL('scene.glsl');
+ env.GLES3_GLSL('cubemap_filter.glsl');
+ env.GLES3_GLSL('cube_to_dp.glsl');
+ env.GLES3_GLSL('blend_shape.glsl');
+ env.GLES3_GLSL('screen_space_reflection.glsl');
+ env.GLES3_GLSL('effect_blur.glsl');
+ env.GLES3_GLSL('subsurf_scattering.glsl');
+ env.GLES3_GLSL('ssao.glsl');
+ env.GLES3_GLSL('ssao_minify.glsl');
+ env.GLES3_GLSL('ssao_blur.glsl');
+ env.GLES3_GLSL('exposure.glsl');
+ env.GLES3_GLSL('tonemap.glsl');
+ env.GLES3_GLSL('particles.glsl');
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index e97ce62daa..1c950c82d9 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -90,7 +90,6 @@ uniform int h_frames;
uniform int v_frames;
#endif
-VERTEX_SHADER_GLOBALS
#if defined(USE_MATERIAL)
@@ -102,6 +101,8 @@ MATERIAL_UNIFORMS
#endif
+VERTEX_SHADER_GLOBALS
+
void main() {
vec4 vertex_color = color_attrib;
@@ -211,6 +212,11 @@ uniform sampler2D screen_texture; // texunit:-3
#endif
+#if defined(SCREEN_UV_USED)
+
+uniform vec2 screen_pixel_size;
+#endif
+
layout(std140) uniform CanvasItemData {
highp mat4 projection_matrix;
@@ -256,7 +262,7 @@ const bool at_light_pass = false;
uniform mediump vec4 final_modulate;
-FRAGMENT_SHADER_GLOBALS
+
layout(location=0) out mediump vec4 frag_color;
@@ -272,6 +278,7 @@ MATERIAL_UNIFORMS
#endif
+FRAGMENT_SHADER_GLOBALS
void light_compute(inout vec3 light,vec3 light_vec,float light_height,vec4 light_color,vec2 light_uv,vec4 shadow,vec3 normal,vec2 uv,vec2 screen_uv,vec4 color) {
@@ -361,7 +368,7 @@ void main() {
);
if (draw_center==0) {
- color.a=0;
+ color.a=0.0;
}
uv = uv*src_rect.zw+src_rect.xy; //apply region if needed
@@ -410,8 +417,8 @@ void main() {
-#if defined(ENABLE_SCREEN_UV)
- vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
+#if defined(SCREEN_UV_USED)
+ vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size;
#endif
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index b0fb525e20..a7c388815d 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -17,6 +17,12 @@ out vec2 uv_interp;
out vec2 uv2_interp;
+#ifdef USE_COPY_SECTION
+
+uniform vec4 copy_section;
+
+#endif
+
void main() {
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
@@ -30,6 +36,13 @@ void main() {
#endif
uv2_interp = uv2_in;
gl_Position = vertex_attrib;
+
+#ifdef USE_COPY_SECTION
+
+ uv_interp = copy_section.xy + uv_interp * copy_section.zw;
+ gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0;
+#endif
+
}
[fragment]
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index 2aec6380f5..393ef2892a 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -19,9 +19,16 @@ void main() {
precision highp float;
precision highp int;
-#ifdef USE_PANORAMA
+#ifdef USE_SOURCE_PANORAMA
uniform sampler2D source_panorama; //texunit:0
-#else
+#endif
+
+#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
+uniform sampler2DArray source_dual_paraboloid_array; //texunit:0
+uniform int source_array_index;
+#endif
+
+#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
uniform samplerCube source_cube; //texunit:0
#endif
@@ -169,7 +176,7 @@ vec2 Hammersley(uint i, uint N) {
uniform bool z_flip;
-#ifdef USE_PANORAMA
+#ifdef USE_SOURCE_PANORAMA
vec4 texturePanorama(vec3 normal,sampler2D pano ) {
@@ -189,6 +196,23 @@ vec4 texturePanorama(vec3 normal,sampler2D pano ) {
#endif
+#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
+
+
+vec4 textureDualParaboloidArray(vec3 normal) {
+
+ vec3 norm = normalize(normal);
+ norm.xy/=1.0+abs(norm.z);
+ norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
+ if (norm.z<0) {
+ norm.y=0.5-norm.y+0.5;
+ }
+ return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0);
+
+}
+
+#endif
+
void main() {
#ifdef USE_DUAL_PARABOLOID
@@ -197,9 +221,8 @@ void main() {
N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y));
N = normalize(N);
- if (!z_flip) {
+ if (z_flip) {
N.y=-N.y; //y is flipped to improve blending between both sides
- } else {
N.z=-N.z;
}
@@ -212,13 +235,24 @@ void main() {
#ifdef USE_DIRECT_WRITE
-#ifdef USE_PANORAMA
+#ifdef USE_SOURCE_PANORAMA
frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0);
-#else
+#endif
+
+#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
+
+ frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0);
+#endif
+
+#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+
frag_color=vec4(texture(N,source_cube).rgb,1.0);
#endif
+
+
+
#else
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
@@ -233,9 +267,16 @@ void main() {
float ndotl = clamp(dot(N, L),0.0,1.0);
if (ndotl>0.0) {
-#ifdef USE_PANORAMA
+#ifdef USE_SOURCE_PANORAMA
sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl;
-#else
+#endif
+
+#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
+
+ sum.rgb += textureDualParaboloidArray(H).rgb *ndotl;
+#endif
+
+#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
#endif
sum.a += ndotl;
diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl
index 89afa12f60..2550335174 100644
--- a/drivers/gles3/shaders/effect_blur.glsl
+++ b/drivers/gles3/shaders/effect_blur.glsl
@@ -6,11 +6,21 @@ layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
+#ifdef USE_BLUR_SECTION
+
+uniform vec4 blur_section;
+
+#endif
void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
+#ifdef USE_BLUR_SECTION
+
+ uv_interp = blur_section.xy + uv_interp * blur_section.zw;
+ gl_Position.xy = (blur_section.xy + (gl_Position.xy * 0.5 + 0.5) * blur_section.zw) * 2.0 - 1.0;
+#endif
}
[fragment]
@@ -89,7 +99,7 @@ uniform highp float auto_exposure_grey;
#endif
uniform float glow_bloom;
-uniform float glow_hdr_treshold;
+uniform float glow_hdr_threshold;
uniform float glow_hdr_scale;
#endif
@@ -252,7 +262,7 @@ void main() {
frag_color*=exposure;
float luminance = max(frag_color.r,max(frag_color.g,frag_color.b));
- float feedback = max( smoothstep(glow_hdr_treshold,glow_hdr_treshold+glow_hdr_scale,luminance), glow_bloom );
+ float feedback = max( smoothstep(glow_hdr_threshold,glow_hdr_threshold+glow_hdr_scale,luminance), glow_bloom );
frag_color *= feedback;
@@ -275,4 +285,3 @@ void main() {
}
-
diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl
index ec2577538c..6a977a201e 100644
--- a/drivers/gles3/shaders/particles.glsl
+++ b/drivers/gles3/shaders/particles.glsl
@@ -47,7 +47,6 @@ out highp vec4 out_xform_1; //tfb:
out highp vec4 out_xform_2; //tfb:
out highp vec4 out_xform_3; //tfb:
-VERTEX_SHADER_GLOBALS
#if defined(USE_MATERIAL)
@@ -59,6 +58,9 @@ MATERIAL_UNIFORMS
#endif
+
+VERTEX_SHADER_GLOBALS
+
uint hash(uint x) {
x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
@@ -233,7 +235,6 @@ VERTEX_SHADER_CODE
//any code here is never executed, stuff is filled just so it works
-FRAGMENT_SHADER_GLOBALS
#if defined(USE_MATERIAL)
@@ -245,6 +246,8 @@ MATERIAL_UNIFORMS
#endif
+FRAGMENT_SHADER_GLOBALS
+
void main() {
{
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index a047e693cb..6fbfeeff6c 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -146,7 +146,7 @@ out vec3 binormal_interp;
#endif
-VERTEX_SHADER_GLOBALS
+
#if defined(USE_MATERIAL)
@@ -159,6 +159,8 @@ MATERIAL_UNIFORMS
#endif
+VERTEX_SHADER_GLOBALS
+
#ifdef RENDER_DEPTH_DUAL_PARABOLOID
out highp float dp_clip;
@@ -273,6 +275,19 @@ void main() {
highp mat4 modelview = camera_inverse_matrix * world_matrix;
highp mat4 local_projection = projection_matrix;
+//using world coordinates
+#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
+
+ vertex = world_matrix * vertex;
+ normal = normalize((world_matrix * vec4(normal,0.0)).xyz);
+
+#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
+
+ tangent = normalize((world_matrix * vec4(tangent,0.0)).xyz);
+ binormal = normalize((world_matrix * vec4(binormal,0.0)).xyz);
+#endif
+#endif
+
//defines that make writing custom shaders easier
#define projection_matrix local_projection
#define world_transform world_matrix
@@ -284,29 +299,42 @@ VERTEX_SHADER_CODE
-
-#if !defined(SKIP_TRANSFORM_USED)
+//using local coordinates (default)
+#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED)
vertex = modelview * vertex;
normal = normalize((modelview * vec4(normal,0.0)).xyz);
+
+#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
+
+ tangent = normalize((modelview * vec4(tangent,0.0)).xyz);
+ binormal = normalize((modelview * vec4(binormal,0.0)).xyz);
+#endif
#endif
+//using world coordinates
+#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
- vertex_interp = vertex.xyz;
- normal_interp = normal;
+ vertex = camera_inverse_matrix * vertex;
+ normal = normalize((camera_inverse_matrix * vec4(normal,0.0)).xyz);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
-#if !defined(SKIP_TRANSFORM_USED)
+ tangent = normalize((camera_inverse_matrix * vec4(tangent,0.0)).xyz);
+ binormal = normalize((camera_inverse_matrix * vec4(binormal,0.0)).xyz);
+#endif
+#endif
- tangent = normalize((modelview * vec4(tangent,0.0)).xyz);
- binormal = normalize((modelview * vec4(binormal,0.0)).xyz);
+ vertex_interp = vertex.xyz;
+ normal_interp = normal;
-#endif
+
+#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
tangent_interp = tangent;
binormal_interp = binormal;
#endif
+
#ifdef RENDER_DEPTH
@@ -403,7 +431,6 @@ uniform bool no_ambient_light;
#ifdef USE_RADIANCE_MAP
-uniform sampler2D radiance_map; //texunit:-2
layout(std140) uniform Radiance { //ubo:2
@@ -413,12 +440,57 @@ layout(std140) uniform Radiance { //ubo:2
};
+#define RADIANCE_MAX_LOD 5.0
+
+#ifdef USE_RADIANCE_MAP_ARRAY
+
+uniform sampler2DArray radiance_map; //texunit:-2
+
+vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) {
+
+ vec3 norm = normalize(p_vec);
+ norm.xy/=1.0+abs(norm.z);
+ norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
+
+ // we need to lie the derivatives (normg) and assume that DP side is always the same
+ // to get proper texure filtering
+ vec2 normg=norm.xy;
+ if (norm.z>0) {
+ norm.y=0.5-norm.y+0.5;
+ }
+
+ // thanks to OpenGL spec using floor(layer + 0.5) for texture arrays,
+ // it's easy to have precision errors using fract() to interpolate layers
+ // as such, using fixed point to ensure it works.
+
+ float index = p_roughness * RADIANCE_MAX_LOD;
+ int indexi = int(index * 256.0);
+ vec3 base = textureGrad(p_tex, vec3(norm.xy, float(indexi/256)),dFdx(normg),dFdy(normg)).xyz;
+ vec3 next = textureGrad(p_tex, vec3(norm.xy, float(indexi/256+1)),dFdx(normg),dFdy(normg)).xyz;
+ return mix(base,next,float(indexi%256)/256.0);
+}
+
+#else
+
+uniform sampler2D radiance_map; //texunit:-2
+
+vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec,float p_roughness) {
+
+ vec3 norm = normalize(p_vec);
+ norm.xy/=1.0+abs(norm.z);
+ norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
+ if (norm.z>0) {
+ norm.y=0.5-norm.y+0.5;
+ }
+ return textureLod(p_tex, norm.xy, p_roughness * RADIANCE_MAX_LOD).xyz;
+}
+
#endif
-/* Material Uniforms */
+#endif
+/* Material Uniforms */
-FRAGMENT_SHADER_GLOBALS
#if defined(USE_MATERIAL)
@@ -431,6 +503,7 @@ MATERIAL_UNIFORMS
#endif
+FRAGMENT_SHADER_GLOBALS
layout(std140) uniform SceneData {
@@ -702,6 +775,10 @@ LIGHT_SHADER_CODE
diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
}
+#elif defined(DIFFUSE_TOON)
+
+ diffuse += smoothstep(-roughness,max(roughness,0.01),dot(N,L)) * light_color * diffuse_color;
+
#elif defined(DIFFUSE_BURLEY)
{
@@ -732,6 +809,37 @@ LIGHT_SHADER_CODE
if (roughness > 0.0) {
+
+ // D
+
+#if defined(SPECULAR_BLINN)
+
+ vec3 H = normalize(V + L);
+ float dotNH = max(dot(N,H), 0.0 );
+ float intensity = pow( dotNH, (1.0-roughness) * 256.0);
+ specular += light_color * intensity * specular_blob_intensity;
+
+#elif defined(SPECULAR_PHONG)
+
+ vec3 R = normalize(-reflect(L,N));
+ float dotNV = max(0.0,dot(R,V));
+ float intensity = pow( dotNV, (1.0-roughness) * 256.0);
+ specular += light_color * intensity * specular_blob_intensity;
+
+#elif defined(SPECULAR_TOON)
+
+ vec3 R = normalize(-reflect(L,N));
+ float dotNV = dot(R,V);
+ float mid = 1.0-roughness;
+ mid*=mid;
+ float intensity = smoothstep(mid-roughness*0.5,mid+roughness*0.5,dotNV) * mid;
+ diffuse += light_color * intensity * specular_blob_intensity; //write to diffuse, as in toon shading you generally want no reflection
+
+#elif defined(SPECULAR_DISABLED)
+ //none..
+
+#else
+ // shlick+ggx as default
float alpha = roughness * roughness;
vec3 H = normalize(V + L);
@@ -739,7 +847,6 @@ LIGHT_SHADER_CODE
float dotNH = max(dot(N,H), 0.0 );
float dotLH = max(dot(L,H), 0.0 );
- // D
#if defined(LIGHT_USE_ANISOTROPY)
float aspect = sqrt(1.0-anisotropy*0.9);
@@ -771,6 +878,7 @@ LIGHT_SHADER_CODE
float speci = dotNL * D * F * vis;
specular += speci * light_color * specular_blob_intensity;
+#endif
#if defined(LIGHT_USE_CLEARCOAT)
float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss));
@@ -861,7 +969,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -912,21 +1020,21 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
-void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
float normalized_distance = light_length*spot_lights[idx].light_pos_inv_radius.w;
- vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), spot_lights[idx].light_direction_attenuation.w ));
+ vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.001), spot_lights[idx].light_direction_attenuation.w ));
vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz;
float spot_cutoff=spot_lights[idx].light_params.y;
float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff);
float spot_rim = (1.0 - scos) / (1.0 - spot_cutoff);
- light_attenuation *= 1.0 - pow( spot_rim, spot_lights[idx].light_params.x);
+ light_attenuation *= 1.0 - pow( max(spot_rim,0.001), spot_lights[idx].light_params.x);
if (spot_lights[idx].light_params.w>0.5) {
//there is a shadowmap
@@ -945,7 +1053,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1230,23 +1338,7 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_sp
#endif
-vec3 textureDualParabolod(sampler2D p_tex, vec3 p_vec,float p_lod) {
- vec3 norm = normalize(p_vec);
- float y_ofs=0.0;
- if (norm.z>=0.0) {
-
- norm.z+=1.0;
- y_ofs+=0.5;
- } else {
- norm.z=1.0 - norm.z;
- norm.y=-norm.y;
- }
-
- norm.xy/=norm.z;
- norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs);
- return textureLod(p_tex, norm.xy, p_lod).xyz;
-}
void main() {
@@ -1386,15 +1478,11 @@ FRAGMENT_SHADER_CODE
} else {
{
-
-#define RADIANCE_MAX_LOD 5.0
- float lod = roughness * RADIANCE_MAX_LOD;
-
{ //read radiance from dual paraboloid
vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);
- vec3 radiance = textureDualParabolod(radiance_map,ref_vec,lod) * bg_energy;
+ vec3 radiance = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy;
specular_light = radiance;
}
@@ -1406,7 +1494,7 @@ FRAGMENT_SHADER_CODE
{
vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
- vec3 env_ambient=textureDualParabolod(radiance_map,ambient_dir,RADIANCE_MAX_LOD) * bg_energy;
+ vec3 env_ambient=textureDualParaboloid(radiance_map,ambient_dir,1.0) * bg_energy;
ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);
//ambient_light=vec3(0.0,0.0,0.0);
@@ -1424,6 +1512,11 @@ FRAGMENT_SHADER_CODE
ambient_light*=ambient_energy;
+ float specular_blob_intensity=1.0;
+#if defined(SPECULAR_TOON)
+ specular_blob_intensity*=specular * 2.0;
+#endif
+
#ifdef USE_LIGHT_DIRECTIONAL
vec3 light_attenuation=vec3(1.0);
@@ -1563,7 +1656,7 @@ FRAGMENT_SHADER_CODE
#endif //LIGHT_DIRECTIONAL_SHADOW
- light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
#endif //#USE_LIGHT_DIRECTIONAL
@@ -1579,8 +1672,6 @@ FRAGMENT_SHADER_CODE
highp vec4 reflection_accum = vec4(0.0,0.0,0.0,0.0);
highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0);
-
-
for(int i=0;i<reflection_count;i++) {
reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,reflection_accum,ambient_accum);
}
@@ -1593,11 +1684,11 @@ FRAGMENT_SHADER_CODE
}
for(int i=0;i<omni_light_count;i++) {
- light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
for(int i=0;i<spot_light_count;i++) {
- light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
@@ -1629,11 +1720,15 @@ FRAGMENT_SHADER_CODE
diffuse_light=mix(diffuse_light,vec3(0.0),metallic);
ambient_light=mix(ambient_light,vec3(0.0),metallic);
{
+
+#if defined(DIFFUSE_TOON)
+ //simplify for toon, as
+ specular_light *= specular * metallic * albedo * 2.0;
+#else
//brdf approximation (Lazarov 2013)
float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
-
+ vec3 dielectric = vec3(0.034) * specular * 2.0;
//energy conservation
- vec3 dielectric = vec3(0.034) * 0.5 * 2.0;
vec3 f0 = mix(dielectric, albedo, metallic);
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);
@@ -1642,6 +1737,8 @@ FRAGMENT_SHADER_CODE
vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw;
specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
+#endif
+
}
if (fog_color_enabled.a > 0.5) {
diff --git a/drivers/unix/SCsub b/drivers/unix/SCsub
index 3766e782e4..96efc91b7a 100644
--- a/drivers/unix/SCsub
+++ b/drivers/unix/SCsub
@@ -8,7 +8,7 @@ g_set_p += 'String OS_Unix::get_global_settings_path() const {\n'
g_set_p += '\treturn "' + env["unix_global_settings_path"] + '";\n'
g_set_p += '}\n'
g_set_p += '#endif'
-f = open("os_unix_global_settings_path.cpp", "wb")
+f = open("os_unix_global_settings_path.gen.cpp", "wb")
f.write(g_set_p)
f.close()