diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 6 | ||||
| -rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 4 | ||||
| -rw-r--r-- | drivers/gles2/shaders/copy.glsl | 30 | ||||
| -rw-r--r-- | drivers/gles3/SCsub | 2 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 265 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.h | 9 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 1 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 56 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 30 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 287 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 24 | ||||
| -rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 27 | ||||
| -rw-r--r-- | drivers/gles3/shader_gles3.cpp | 36 | ||||
| -rw-r--r-- | drivers/gles3/shaders/SCsub | 38 | ||||
| -rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 17 | ||||
| -rw-r--r-- | drivers/gles3/shaders/copy.glsl | 13 | ||||
| -rw-r--r-- | drivers/gles3/shaders/cubemap_filter.glsl | 59 | ||||
| -rw-r--r-- | drivers/gles3/shaders/effect_blur.glsl | 15 | ||||
| -rw-r--r-- | drivers/gles3/shaders/particles.glsl | 7 | ||||
| -rw-r--r-- | drivers/gles3/shaders/scene.glsl | 193 | ||||
| -rw-r--r-- | drivers/unix/SCsub | 2 |
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() |