summaryrefslogtreecommitdiff
path: root/drivers/gles3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp23
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp6
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp310
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h17
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp214
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h40
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp88
-rw-r--r--drivers/gles3/shader_compiler_gles3.h2
-rw-r--r--drivers/gles3/shaders/copy.glsl27
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl2
-rw-r--r--drivers/gles3/shaders/scene.glsl70
11 files changed, 579 insertions, 220 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index b2228a6cfa..c10c5fee65 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -914,6 +914,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const
}
+
if (shader_ptr && shader_ptr!=shader_cache) {
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);
@@ -925,6 +926,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const
int tc = material_ptr->textures.size();
RID* textures = material_ptr->textures.ptr();
+ ShaderLanguage::ShaderNode::Uniform::Hint* texture_hints = shader_ptr->texture_hints.ptr();
for(int i=0;i<tc;i++) {
@@ -932,11 +934,30 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const
RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull( textures[i] );
if (!t) {
+
+ switch(texture_hints[i]) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ glBindTexture(GL_TEXTURE_2D,storage->resources.black_tex);
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ glBindTexture(GL_TEXTURE_2D,storage->resources.normal_tex);
+ } break;
+ default: {
+ glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex);
+ } break;
+ }
+
//check hints
- glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex);
+
continue;
}
+ if (storage->config.srgb_decode_supported && t->using_srgb) {
+ //no srgb in 2D
+ glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT);
+ t->using_srgb=false;
+ }
+
glBindTexture(t->target,t->tex_id);
}
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 83c40edc1d..e838020c45 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -253,10 +253,8 @@ void RasterizerGLES3::make_current() {
void RasterizerGLES3::register_config() {
- GLOBAL_DEF("rendering/gles3/framebuffer_format",RasterizerStorageGLES3::FBO_FORMAT_FLOAT);
- Globals::get_singleton()->set_custom_property_info("rendering/gles3/framebuffer_format",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"16 Bits,32 Bits,Half Float"));
- GLOBAL_DEF("rendering/gles3/lighting_technique",1);
- Globals::get_singleton()->set_custom_property_info("rendering/gles3/lighting_technique",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"Forward,Deferred"));
+ GLOBAL_DEF("rendering/gles3/render_architecture",0);
+ Globals::get_singleton()->set_custom_property_info("rendering/gles3/render_architecture",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"Desktop,Mobile"));
GLOBAL_DEF("rendering/gles3/use_nearest_mipmap_filter",false);
GLOBAL_DEF("rendering/gles3/anisotropic_filter_level",4.0);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index aadf9e6336..f7baf1a30b 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -150,27 +150,19 @@ void RasterizerSceneGLES3::environment_set_fog(RID p_env,bool p_enable,float p_b
}
-void RasterizerSceneGLES3::environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper){
+void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, bool p_enable, float p_exposure, float p_white, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale, VS::EnvironmentToneMapper p_tone_mapper){
}
-void RasterizerSceneGLES3::environment_set_brightness(RID p_env,bool p_enable,float p_brightness){
-}
-void RasterizerSceneGLES3::environment_set_contrast(RID p_env,bool p_enable,float p_contrast){
+void RasterizerSceneGLES3::environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp) {
-}
-void RasterizerSceneGLES3::environment_set_saturation(RID p_env,bool p_enable,float p_saturation){
}
-void RasterizerSceneGLES3::environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp){
-
-}
-
-
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
+ print_line("hello light");
LightInstance *light_instance = memnew( LightInstance );
light_instance->light=p_light;
@@ -204,6 +196,29 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
glEnable(GL_CULL_FACE);
}
+ if (state.current_line_width!=p_material->line_width) {
+ glLineWidth(p_material->line_width);
+ state.current_line_width=p_material->line_width;
+ }
+
+ if (state.current_depth_draw!=p_material->shader->spatial.depth_draw_mode) {
+ switch(p_material->shader->spatial.depth_draw_mode) {
+ case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
+ case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
+
+ glDepthMask(!p_alpha_pass);
+ } break;
+ case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
+ glDepthMask(GL_TRUE);
+ } break;
+ case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER: {
+ glDepthMask(GL_FALSE);
+ } break;
+ }
+
+ state.current_depth_draw=p_material->shader->spatial.depth_draw_mode;
+ }
+
//glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
/*
@@ -216,7 +231,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
//if (p_material->line_width)
// glLineWidth(p_material->line_width);
-
+#if 0
//blend mode
if (state.current_blend_mode!=p_material->shader->spatial.blend_mode) {
@@ -256,7 +271,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
state.current_blend_mode=p_material->shader->spatial.blend_mode;
}
-
+#endif
//material parameters
@@ -273,6 +288,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
int tc = p_material->textures.size();
RID* textures = p_material->textures.ptr();
+ ShaderLanguage::ShaderNode::Uniform::Hint* texture_hints = p_material->shader->texture_hints.ptr();
for(int i=0;i<tc;i++) {
@@ -281,11 +297,48 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull( textures[i] );
if (!t) {
//check hints
+ switch(texture_hints[i]) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ glBindTexture(GL_TEXTURE_2D,storage->resources.black_tex);
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ glBindTexture(GL_TEXTURE_2D,storage->resources.normal_tex);
+ } break;
+ default: {
+ glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex);
+ } break;
+ }
glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex);
continue;
}
+ if (storage->config.srgb_decode_supported) {
+ //if SRGB decode extension is present, simply switch the texture to whathever is needed
+ bool must_srgb=false;
+
+ if (t->srgb && texture_hints[i]==ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO) {
+ must_srgb=true;
+ }
+
+ if (t->using_srgb!=must_srgb) {
+ if (must_srgb) {
+ glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT);
+#ifdef TOOLS_ENABLED
+ if (!(t->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
+ t->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR;
+ //notify that texture must be set to linear beforehand, so it works in other platforms when exported
+ }
+#endif
+
+ } else {
+ glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT);
+ }
+ t->using_srgb=must_srgb;
+ }
+ }
+
+
glBindTexture(t->target,t->tex_id);
}
@@ -348,7 +401,60 @@ void RasterizerSceneGLES3::_setup_light(LightInstance *p_light) {
glBindBufferBase(GL_UNIFORM_BUFFER,3,p_light->light_ubo); //bind light uniform
}
+void RasterizerSceneGLES3::_setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection) {
+
+ if (p_instance->billboard || p_instance->billboard_y || p_instance->depth_scale) {
+
+ Transform xf=p_instance->transform;
+ if (p_instance->depth_scale) {
+
+ if (p_projection.matrix[3][3]) {
+ //orthogonal matrix, try to do about the same
+ //with viewport size
+ //real_t w = Math::abs( 1.0/(2.0*(p_projection.matrix[0][0])) );
+ real_t h = Math::abs( 1.0/(2.0*p_projection.matrix[1][1]) );
+ float sc = (h*2.0); //consistent with Y-fov
+ xf.basis.scale( Vector3(sc,sc,sc));
+ } else {
+ //just scale by depth
+ real_t sc = Plane(p_view_transform.origin,-p_view_transform.get_basis().get_axis(2)).distance_to(xf.origin);
+ xf.basis.scale( Vector3(sc,sc,sc));
+ }
+ }
+
+ if (p_instance->billboard) {
+
+ Vector3 scale = xf.basis.get_scale();
+
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
+ xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), -p_view_transform.get_basis().get_axis(1));
+ } else {
+ xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), p_view_transform.get_basis().get_axis(1));
+ }
+
+ xf.basis.scale(scale);
+ }
+
+ if (p_instance->billboard_y) {
+
+ Vector3 scale = xf.basis.get_scale();
+ Vector3 look_at = p_view_transform.get_origin();
+ look_at.y = 0.0;
+ Vector3 look_at_norm = look_at.normalized();
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
+ xf.set_look_at(xf.origin,xf.origin + look_at_norm, Vector3(0.0, -1.0, 0.0));
+ } else {
+ xf.set_look_at(xf.origin,xf.origin + look_at_norm, Vector3(0.0, 1.0, 0.0));
+ }
+ xf.basis.scale(scale);
+ }
+ state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, xf);
+
+ } else {
+ state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, p_instance->transform);
+ }
+}
void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_element_count,const Transform& p_view_transform,const CameraMatrix& p_projection,RasterizerStorageGLES3::Texture* p_base_env,bool p_reverse_cull,bool p_alpha_pass) {
@@ -372,12 +478,18 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
glActiveTexture(GL_TEXTURE0+storage->config.max_texture_image_units-2);
glBindTexture(p_base_env->target,p_base_env->tex_id);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_CUBEMAP,true);
+ } else {
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_CUBEMAP,false);
+
}
+
state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON,false);
state.current_blend_mode=-1;
+ state.current_line_width=-1;
+ state.current_depth_draw=-1;
glDisable(GL_BLEND);
@@ -390,6 +502,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
int prev_blend=-1;
int current_blend_mode=-1;
+ bool prev_additive=false;
+
for (int i=0;i<p_element_count;i++) {
RenderList::Element *e = p_elements[i];
@@ -554,10 +668,16 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
_setup_geometry(e);
}
+ if (rebind || prev_additive!=additive) {
+ state.scene_shader.set_uniform(SceneShaderGLES3::NO_AMBIENT_LIGHT, additive);
+
+ }
+
// _set_cull(e->mirror,p_reverse_cull);
state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror?-1.0:1.0);
- state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform);
+
+ _setup_transform(e->instance,p_view_transform,p_projection);
// _render(e->geometry, material, skeleton,e->owner,e->instance->transform);
@@ -567,6 +687,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
prev_material=material;
prev_base_type=e->instance->base_type;
prev_geometry=e->geometry;
+ prev_additive=additive;
+ prev_light_type=light_type;
+ prev_light_index=light_index;
+
}
//print_line("shaderchanges: "+itos(p_alpha_pass)+": "+itos(_rinfo.shader_change_count));
@@ -824,6 +948,19 @@ void RasterizerSceneGLES3::_draw_skybox(RID p_skybox,CameraMatrix& p_projection,
glActiveTexture(GL_TEXTURE0);
glBindTexture(tex->target,tex->tex_id);
+
+ if (storage->config.srgb_decode_supported && tex->srgb && !tex->using_srgb) {
+
+ glTexParameteri(tex->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT);
+ tex->using_srgb=true;
+#ifdef TOOLS_ENABLED
+ if (!(tex->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
+ tex->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR;
+ //notify that texture must be set to linear beforehand, so it works in other platforms when exported
+ }
+#endif
+ }
+
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
@@ -876,6 +1013,7 @@ void RasterizerSceneGLES3::_draw_skybox(RID p_skybox,CameraMatrix& p_projection,
glDrawArrays(GL_TRIANGLE_FAN,0,4);
glBindVertexArray(0);
+ glColorMask(1,1,1,1);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_CUBEMAP,false);
@@ -977,9 +1115,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
ERR_FAIL_COND( directional_light_instance_count >= RenderList::MAX_LIGHTS);
directional_light_instances[directional_light_instance_count++]=li;
- li->light_ubo_data.light_color_energy[0]=li->light_ptr->color.r;
- li->light_ubo_data.light_color_energy[1]=li->light_ptr->color.g;
- li->light_ubo_data.light_color_energy[2]=li->light_ptr->color.b;
+ Color linear_col = li->light_ptr->color.to_linear();
+ li->light_ubo_data.light_color_energy[0]=linear_col.r;
+ li->light_ubo_data.light_color_energy[1]=linear_col.g;
+ li->light_ubo_data.light_color_energy[2]=linear_col.b;
li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
//omni, keep at 0
@@ -1018,9 +1157,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
} break;
case VS::LIGHT_OMNI: {
- li->light_ubo_data.light_color_energy[0]=li->light_ptr->color.r;
- li->light_ubo_data.light_color_energy[1]=li->light_ptr->color.g;
- li->light_ubo_data.light_color_energy[2]=li->light_ptr->color.b;
+ Color linear_col = li->light_ptr->color.to_linear();
+ li->light_ubo_data.light_color_energy[0]=linear_col.r;
+ li->light_ubo_data.light_color_energy[1]=linear_col.g;
+ li->light_ubo_data.light_color_energy[2]=linear_col.b;
li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin);
@@ -1050,9 +1190,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
} break;
case VS::LIGHT_SPOT: {
- li->light_ubo_data.light_color_energy[0]=li->light_ptr->color.r;
- li->light_ubo_data.light_color_energy[1]=li->light_ptr->color.g;
- li->light_ubo_data.light_color_energy[2]=li->light_ptr->color.b;
+ Color linear_col = li->light_ptr->color.to_linear();
+ li->light_ubo_data.light_color_energy[0]=linear_col.r;
+ li->light_ubo_data.light_color_energy[1]=linear_col.g;
+ li->light_ubo_data.light_color_energy[2]=linear_col.b;
li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin);
@@ -1108,6 +1249,51 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
}
+void RasterizerSceneGLES3::_copy_screen() {
+
+ glBindVertexArray(storage->resources.quadie_array);
+ glDrawArrays(GL_TRIANGLE_FAN,0,4);
+ glBindVertexArray(0);
+
+}
+
+void RasterizerSceneGLES3::_copy_to_front_buffer(Environment *env) {
+
+ //copy to front buffer
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
+
+ glDepthMask(GL_FALSE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDepthFunc(GL_LEQUAL);
+ glColorMask(1,1,1,1);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
+
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA,true);
+
+ if (!env) {
+ //no environment, simply convert from linear to srgb
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,true);
+ } else {
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,true);
+
+ }
+
+ storage->shaders.copy.bind();
+
+ _copy_screen();
+
+
+ //turn off everything used
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA,false);
+
+
+}
+
void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_directional_lights,int p_directional_light_count,RID p_environment){
//first of all, make a new render pass
@@ -1125,6 +1311,8 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
current_material_index=0;
+ bool use_mrt=false;
+
//fill list
for(int i=0;i<p_cull_count;i++) {
@@ -1166,43 +1354,58 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
+
+ RasterizerStorageGLES3::Texture* env_radiance_tex=NULL;
+
+ if (use_mrt) {
+
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,true);
+
+ Color black(0,0,0,0);
+ glClearBufferfv(GL_COLOR,1,black.components); // specular
+ glClearBufferfv(GL_COLOR,2,black.components); // normal metal rough
+
+ } else {
+
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false);
+
+ }
+
+
glClearDepth(1.0);
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
+ glClear(GL_DEPTH_BUFFER_BIT);
- RasterizerStorageGLES3::Texture* env_radiance_tex;
+ Color clear_color(0,0,0,0);
if (!env || env->bg_mode==VS::ENV_BG_CLEAR_COLOR) {
if (storage->frame.clear_request) {
- glClearColor( storage->frame.clear_request_color.r, storage->frame.clear_request_color.g, storage->frame.clear_request_color.b, storage->frame.clear_request_color.a );
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ clear_color = storage->frame.clear_request_color.to_linear();
storage->frame.clear_request=false;
}
} else if (env->bg_mode==VS::ENV_BG_COLOR) {
-
- glClearColor( env->bg_color.r, env->bg_color.g, env->bg_color.b, env->bg_color.a );
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ clear_color = env->bg_color.to_linear();
storage->frame.clear_request=false;
} else if (env->bg_mode==VS::ENV_BG_SKYBOX) {
if (env->skybox_radiance.is_valid()) {
env_radiance_tex = storage->texture_owner.getornull(env->skybox_radiance);
}
- glClear(GL_DEPTH_BUFFER_BIT);
storage->frame.clear_request=false;
} else {
- glClear(GL_DEPTH_BUFFER_BIT);
storage->frame.clear_request=false;
-
}
- state.current_depth_test=true;
- state.current_depth_mask=true;
+ glClearBufferfv(GL_COLOR,0,clear_color.components); // specular
+
+
state.texscreen_copied=false;
glBlendEquation(GL_FUNC_ADD);
@@ -1214,43 +1417,33 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
}
glDisable(GL_BLEND);
- //current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
-
render_list.sort_by_key(false);
- //_render_list_forward(&opaque_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting);
-/*
- if (draw_tex_background) {
-
- //most 3D vendors recommend drawing a texture bg or skybox here,
- //after opaque geometry has been drawn
- //so the zbuffer can get rid of most pixels
- _draw_tex_bg();
- }
-*/
if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
} else {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
-// glDisable(GL_BLEND);
-// current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
-// state.scene_shader.set_conditional(SceneShaderGLES3::USE_GLOW,false);
-// if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
-// glColorMask(1,1,1,0); //don't touch alpha
-// }
-
-
_render_list(render_list.elements,render_list.element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false);
+ state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false);
+
if (env && env->bg_mode==VS::ENV_BG_SKYBOX) {
+ if (use_mrt) {
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo); //switch to alpha fbo for skybox, only diffuse/ambient matters
+ }
+
_draw_skybox(env->skybox_color,p_cam_projection,p_cam_transform,storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP],env->skybox_scale);
}
+
+
+
+
//_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
//glColorMask(1,1,1,1);
@@ -1261,12 +1454,14 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
render_list.sort_by_depth(true);
- _render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false);
+ _render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,true);
+
+ _copy_to_front_buffer(env);
#if 0
if (use_fb) {
@@ -1418,6 +1613,7 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
if (light_instance_owner.owns(p_rid)) {
+ print_line("bye light");
LightInstance *light_instance = light_instance_owner.getptr(p_rid);
glDeleteBuffers(1,&light_instance->light_ubo);
light_instance_owner.free(p_rid);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 4b1b77f13c..5457b5cde3 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -18,10 +18,11 @@ public:
struct State {
- bool current_depth_test;
- bool current_depth_mask;
+
bool texscreen_copied;
int current_blend_mode;
+ float current_line_width;
+ int current_depth_draw;
SceneShaderGLES3 scene_shader;
@@ -57,6 +58,8 @@ public:
GLuint skybox_verts;
GLuint skybox_array;
+
+
} state;
@@ -109,11 +112,8 @@ public:
virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode);
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_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper);
- virtual void environment_set_brightness(RID p_env,bool p_enable,float p_brightness);
- virtual void environment_set_contrast(RID p_env,bool p_enable,float p_contrast);
- virtual void environment_set_saturation(RID p_env,bool p_enable,float p_saturation);
- virtual void environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp);
+ virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale,VS::EnvironmentToneMapper p_tone_mapper);
+ virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp);
/* LIGHT INSTANCE */
@@ -314,6 +314,7 @@ public:
RenderList render_list;
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material* p_material,bool p_alpha_pass);
+ _FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection);
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(LightInstance *p_light);
@@ -327,6 +328,8 @@ public:
void _setup_environment(Environment *env,CameraMatrix& p_cam_projection, const Transform& p_cam_transform);
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform);
+ void _copy_screen();
+ void _copy_to_front_buffer(Environment *env);
virtual void render_scene(const Transform& p_cam_transform,CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_directional_lights,int p_directional_light_count,RID p_environment);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 1141a605c5..a678c460f5 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -57,9 +57,6 @@
#define _EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
-#define _TEXTURE_SRGB_DECODE_EXT 0x8A48
-#define _DECODE_EXT 0x8A49
-#define _SKIP_DECODE_EXT 0x8A4A
#define _GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@@ -679,8 +676,10 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture,const Image& p_image
if (texture->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT);
+ texture->using_srgb=true;
} else {
glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT);
+ texture->using_srgb=false;
}
}
@@ -892,8 +891,10 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture,uint32_t p_flags) {
if (texture->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT);
+ texture->using_srgb=true;
} else {
glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT);
+ texture->using_srgb=false;
}
}
@@ -1024,6 +1025,19 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source,int p_r
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
+ if (config.srgb_decode_supported && texture->srgb && !texture->using_srgb) {
+
+ glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT);
+ texture->using_srgb=true;
+#ifdef TOOLS_ENABLED
+ if (!(texture->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
+ texture->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR;
+ //notify that texture must be set to linear beforehand, so it works in other platforms when exported
+ }
+#endif
+ }
+
+
glActiveTexture(GL_TEXTURE1);
GLuint new_cubemap;
glGenTextures(1, &new_cubemap);
@@ -1302,6 +1316,7 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
p_shader->ubo_size=gen_code.uniform_total_size;
p_shader->ubo_offsets=gen_code.uniform_offsets;
p_shader->texture_count=gen_code.texture_uniforms.size();
+ p_shader->texture_hints=gen_code.texture_hints;
//all materials using this shader will have to be invalidated, unfortunately
@@ -1510,7 +1525,17 @@ Variant RasterizerStorageGLES3::material_get_param(RID p_material, const StringN
return Variant();
}
-_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant& value, uint8_t *data) {
+void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_width) {
+
+ Material *material = material_owner.get( p_material );
+ ERR_FAIL_COND(!material);
+
+ material->line_width=p_width;
+
+
+}
+
+_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant& value, uint8_t *data,bool p_linear_color) {
switch(type) {
case ShaderLanguage::TYPE_BOOL: {
@@ -1683,6 +1708,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
if (value.get_type()==Variant::COLOR) {
Color v=value;
+ if (p_linear_color) {
+ v=v.to_linear();
+ }
+
gui[0]=v.r;
gui[1]=v.g;
gui[2]=v.b;
@@ -2019,7 +2048,7 @@ void RasterizerStorageGLES3::_update_material(Material* material) {
if (V) {
//user provided
- _fill_std140_variant_ubo_value(E->get().type,V->get(),data);
+ _fill_std140_variant_ubo_value(E->get().type,V->get(),data,material->shader->mode==VS::SHADER_SPATIAL);
} else if (E->get().default_value.size()){
//default value
_fill_std140_ubo_value(E->get().type,E->get().default_value,data);
@@ -2641,9 +2670,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface){
Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND(surface->index_array_len==0);
-
- glDeleteBuffers(1,&surface->array_id);
+ glDeleteBuffers(1,&surface->vertex_id);
if (surface->index_id) {
glDeleteBuffers(1,&surface->index_id);
}
@@ -3211,14 +3238,14 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
rt->back.fbo=0;
}
- if (rt->deferred.fbo) {
- glDeleteFramebuffers(1,&rt->deferred.fbo);
- glDeleteFramebuffers(1,&rt->deferred.fbo_color);
- glDeleteTextures(1,&rt->deferred.albedo_ao);
- glDeleteTextures(1,&rt->deferred.normal_special);
- glDeleteTextures(1,&rt->deferred.metal_rough_motion);
- rt->deferred.fbo=0;
- rt->deferred.fbo_color=0;
+ if (rt->buffers.fbo) {
+ glDeleteFramebuffers(1,&rt->buffers.fbo);
+ glDeleteFramebuffers(1,&rt->buffers.alpha_fbo);
+ glDeleteTextures(1,&rt->buffers.diffuse);
+ glDeleteTextures(1,&rt->buffers.specular);
+ glDeleteTextures(1,&rt->buffers.normal_sr);
+ rt->buffers.fbo=0;
+ rt->buffers.alpha_fbo=0;
}
if (rt->depth) {
@@ -3239,26 +3266,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
if (rt->width<=0 || rt->height<=0)
return;
- glActiveTexture(GL_TEXTURE0);
-
- glGenFramebuffers(1, &rt->front.fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->front.fbo);
-
-
- glGenRenderbuffers(1, &rt->depth);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
- if (config.fbo_format==FBO_FORMAT_16_BITS) {
- glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT16, rt->width, rt->height);
- } else {
- glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8, rt->width, rt->height);
- }
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
- glBindRenderbuffer(GL_RENDERBUFFER, 0 );
-
-
- glGenTextures(1, &rt->front.color);
- glBindTexture(GL_TEXTURE_2D, rt->front.color);
-
GLuint color_internal_format;
GLuint color_format;
@@ -3266,21 +3273,8 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
Image::Format image_format;
- if (config.fbo_format==FBO_FORMAT_16_BITS) {
- if (rt->flags[RENDER_TARGET_TRANSPARENT]) {
- color_internal_format=GL_RGB5_A1;
- color_format=GL_RGBA;
- color_type=GL_UNSIGNED_SHORT_5_5_5_1;
- image_format=Image::FORMAT_RGBA5551;
- } else {
- color_internal_format=GL_RGB565;
- color_format=GL_RGB;
- color_type=GL_UNSIGNED_SHORT_5_6_5;
- image_format=Image::FORMAT_RGB565;
- }
-
- } else if (config.fbo_format==FBO_FORMAT_32_BITS || (config.fbo_format==FBO_FORMAT_FLOAT && rt->flags[RENDER_TARGET_NO_3D])) {
+ if (config.render_arch==RENDER_ARCH_MOBILE || rt->flags[RENDER_TARGET_NO_3D]) {
if (rt->flags[RENDER_TARGET_TRANSPARENT]) {
color_internal_format=GL_RGBA8;
@@ -3293,53 +3287,75 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
color_type=GL_UNSIGNED_INT_2_10_10_10_REV;
image_format=Image::FORMAT_RGBA8;//todo
}
- } else if (config.fbo_format==FBO_FORMAT_FLOAT) {
-
+ } else {
color_internal_format=GL_RGBA16F;
color_format=GL_RGBA;
color_type=GL_HALF_FLOAT;
image_format=Image::FORMAT_RGBAH;
}
- glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
+ {
+ /* FRONT FBO */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->front.color, 0);
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenFramebuffers(1, &rt->front.fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->front.fbo);
+
+
+ glGenRenderbuffers(1, &rt->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
+
+
+ glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8, rt->width, rt->height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0 );
+
+
+ glGenTextures(1, &rt->front.color);
+ glBindTexture(GL_TEXTURE_2D, rt->front.color);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->front.color, 0);
- {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
- }
- Texture *tex = texture_owner.get(rt->texture);
- tex->format=image_format;
- tex->gl_format_cache=color_format;
- tex->gl_type_cache=color_type;
- tex->gl_internal_format_cache=color_internal_format;
- tex->tex_id=rt->front.color;
- tex->width=rt->width;
- tex->alloc_width=rt->width;
- tex->height=rt->height;
- tex->alloc_height=rt->height;
+ Texture *tex = texture_owner.get(rt->texture);
+ tex->format=image_format;
+ tex->gl_format_cache=color_format;
+ tex->gl_type_cache=color_type;
+ tex->gl_internal_format_cache=color_internal_format;
+ tex->tex_id=rt->front.color;
+ tex->width=rt->width;
+ tex->alloc_width=rt->width;
+ tex->height=rt->height;
+ tex->alloc_height=rt->height;
+
+ texture_set_flags(rt->texture,tex->flags);
+
+ }
- texture_set_flags(rt->texture,tex->flags);
+
+ /* BACK FBO */
if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) {
glGenFramebuffers(1, &rt->back.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, rt->back.fbo);
-
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
glGenTextures(1, &rt->back.color);
glBindTexture(GL_TEXTURE_2D, rt->back.color);
-
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -3357,43 +3373,42 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
}
}
+ if (config.render_arch==RENDER_ARCH_DESKTOP && !rt->flags[RENDER_TARGET_NO_3D]) {
- if (config.fbo_deferred && !rt->flags[RENDER_TARGET_NO_3D]) {
-
//regular fbo
- glGenFramebuffers(1, &rt->deferred.fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->deferred.fbo);
+ glGenFramebuffers(1, &rt->buffers.fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
- glGenTextures(1, &rt->deferred.albedo_ao);
- glBindTexture(GL_TEXTURE_2D, rt->deferred.albedo_ao);
+ glGenTextures(1, &rt->buffers.diffuse);
+ glBindTexture(GL_TEXTURE_2D, rt->buffers.diffuse);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->deferred.albedo_ao, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0);
- glGenTextures(1, &rt->deferred.metal_rough_motion);
- glBindTexture(GL_TEXTURE_2D, rt->deferred.metal_rough_motion);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glGenTextures(1, &rt->buffers.specular);
+ glBindTexture(GL_TEXTURE_2D, rt->buffers.specular);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, rt->width, rt->height, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->deferred.metal_rough_motion, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->buffers.specular, 0);
- glGenTextures(1, &rt->deferred.normal_special);
- glBindTexture(GL_TEXTURE_2D, rt->deferred.normal_special);
+ glGenTextures(1, &rt->buffers.normal_sr);
+ glBindTexture(GL_TEXTURE_2D, rt->buffers.normal_sr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->deferred.normal_special, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->buffers.normal_sr, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -3402,19 +3417,15 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
if (status != GL_FRAMEBUFFER_COMPLETE) {
_render_target_clear(rt);
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
- }
+ }
- //regular fbo with color attachment (needed for emission or objects rendered as forward)
- glGenFramebuffers(1, &rt->deferred.fbo_color);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->deferred.fbo_color);
+ //alpha fbo
+ glGenFramebuffers(1, &rt->buffers.alpha_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.alpha_fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->deferred.albedo_ao, 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->deferred.metal_rough_motion, 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->deferred.normal_special, 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, rt->front.color, 0);
-
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
@@ -3423,6 +3434,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
_render_target_clear(rt);
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
}
+
}
@@ -3797,8 +3809,8 @@ bool RasterizerStorageGLES3::free(RID p_rid){
void RasterizerStorageGLES3::initialize() {
- config.fbo_format=FBOFormat(int(Globals::get_singleton()->get("rendering/gles3/framebuffer_format")));
- config.fbo_deferred=int(Globals::get_singleton()->get("rendering/gles3/lighting_technique"));
+ config.render_arch=RENDER_ARCH_DESKTOP;
+ //config.fbo_deferred=int(Globals::get_singleton()->get("rendering/gles3/lighting_technique"));
config.system_fbo=0;
@@ -3925,10 +3937,10 @@ void RasterizerStorageGLES3::initialize() {
glGenVertexArrays(1,&resources.quadie_array);
glBindVertexArray(resources.quadie_array);
glBindBuffer(GL_ARRAY_BUFFER,resources.quadie);
- glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,0);
+ glVertexAttribPointer(VS::ARRAY_VERTEX,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,0);
glEnableVertexAttribArray(0);
- glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,((uint8_t*)NULL)+8);
- glEnableVertexAttribArray(1);
+ glVertexAttribPointer(VS::ARRAY_TEX_UV,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,((uint8_t*)NULL)+8);
+ glEnableVertexAttribArray(4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index f052aa8019..b12c2d93b6 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -13,6 +13,9 @@
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
+#define _TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define _DECODE_EXT 0x8A49
+#define _SKIP_DECODE_EXT 0x8A4A
class RasterizerStorageGLES3 : public RasterizerStorage {
public:
@@ -20,16 +23,15 @@ public:
RasterizerCanvasGLES3 *canvas;
RasterizerSceneGLES3 *scene;
- enum FBOFormat {
- FBO_FORMAT_16_BITS,
- FBO_FORMAT_32_BITS,
- FBO_FORMAT_FLOAT,
+ enum RenderArchitecture {
+ RENDER_ARCH_MOBILE,
+ RENDER_ARCH_DESKTOP,
};
struct Config {
- FBOFormat fbo_format;
- bool fbo_deferred;
+ RenderArchitecture render_arch;
+
GLuint system_fbo; //on some devices, such as apple, screen is rendered to yet another fbo.
bool shrink_textures_x2;
@@ -135,12 +137,15 @@ public:
bool active;
GLuint tex_id;
+ bool using_srgb;
+
uint16_t stored_cube_sides;
RenderTarget *render_target;
Texture() {
+ using_srgb=false;
stored_cube_sides=0;
ignore_mipmaps=false;
render_target=NULL;
@@ -218,6 +223,8 @@ public:
Map<StringName,RID> default_textures;
+ Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
+
bool valid;
String path;
@@ -319,12 +326,14 @@ public:
SelfList<Material> list;
SelfList<Material> dirty_list;
Vector<RID> textures;
+ float line_width;
uint32_t index;
uint64_t last_pass;
Material() : list(this), dirty_list(this) {
shader=NULL;
+ line_width=1.0;
ubo_id=0;
ubo_size=0;
last_pass=0;
@@ -346,6 +355,8 @@ public:
virtual void material_set_param(RID p_material, const StringName& p_param, const Variant& p_value);
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);
+
void _update_material(Material* material);
void update_dirty_materials();
@@ -655,14 +666,13 @@ public:
GLuint depth;
- struct Deferred {
+ struct Buffers {
GLuint fbo;
- GLuint fbo_color;
-
- GLuint albedo_ao;
- GLuint metal_rough_motion;
- GLuint normal_special;
- } deferred;
+ GLuint alpha_fbo; //single buffer, just diffuse (for alpha pass)
+ GLuint specular;
+ GLuint diffuse;
+ GLuint normal_sr;
+ } buffers;
int width,height;
@@ -679,8 +689,8 @@ public:
depth=0;
front.fbo=0;
back.fbo=0;
- deferred.fbo=0;
- deferred.fbo_color=0;
+ buffers.fbo=0;
+ buffers.alpha_fbo=0;
used_in_frame=false;
flags[RENDER_TARGET_VFLIP]=false;
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index da8f6689d0..0dff53bfb9 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -75,25 +75,81 @@ static String _mkid(const String& p_id) {
return "m_"+p_id;
}
+static String f2sp0(float p_float) {
+
+ if (int(p_float)==p_float)
+ return itos(p_float)+".0";
+ else
+ return rtoss(p_float);
+}
+
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value>& p_values) {
switch(p_type) {
case SL::TYPE_BOOL: return p_values[0].boolean?"true":"false";
- case SL::TYPE_BVEC2: return String()+"bvec2("+(p_values[0].boolean?"true":"false")+(p_values[1].boolean?"true":"false")+")";
- case SL::TYPE_BVEC3: return String()+"bvec3("+(p_values[0].boolean?"true":"false")+","+(p_values[1].boolean?"true":"false")+","+(p_values[2].boolean?"true":"false")+")";
- case SL::TYPE_BVEC4: return String()+"bvec4("+(p_values[0].boolean?"true":"false")+","+(p_values[1].boolean?"true":"false")+","+(p_values[2].boolean?"true":"false")+","+(p_values[3].boolean?"true":"false")+")";
- case SL::TYPE_INT: return rtos(p_values[0].sint);
- case SL::TYPE_IVEC2: return String()+"ivec2("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+")";
- case SL::TYPE_IVEC3: return String()+"ivec3("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+","+rtos(p_values[2].sint)+")";
- case SL::TYPE_IVEC4: return String()+"ivec4("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+","+rtos(p_values[2].sint)+","+rtos(p_values[3].sint)+")";
- case SL::TYPE_UINT: return rtos(p_values[0].real);
- case SL::TYPE_UVEC2: return String()+"uvec2("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+")";
- case SL::TYPE_UVEC3: return String()+"uvec3("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+")";
- case SL::TYPE_UVEC4: return String()+"uvec4("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+","+rtos(p_values[3].real)+")";
- case SL::TYPE_FLOAT: return rtos(p_values[0].real);
- case SL::TYPE_VEC2: return String()+"vec2("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+")";
- case SL::TYPE_VEC3: return String()+"vec3("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+")";
- case SL::TYPE_VEC4: return String()+"vec4("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+","+rtos(p_values[3].real)+")";
+ case SL::TYPE_BVEC2:
+ case SL::TYPE_BVEC3:
+ case SL::TYPE_BVEC4: {
+
+
+ String text="bvec"+itos(p_type-SL::TYPE_BOOL+1)+"(";
+ for(int i=0;i<p_values.size();i++) {
+ if (i>0)
+ text+=",";
+
+ text+=p_values[i].boolean?"true":"false";
+ }
+ text+=")";
+ return text;
+ }
+
+ case SL::TYPE_INT: return itos(p_values[0].sint);
+ case SL::TYPE_IVEC2:
+ case SL::TYPE_IVEC3:
+ case SL::TYPE_IVEC4: {
+
+ String text="ivec"+itos(p_type-SL::TYPE_INT+1)+"(";
+ for(int i=0;i<p_values.size();i++) {
+ if (i>0)
+ text+=",";
+
+ text+=itos(p_values[i].sint);
+ }
+ text+=")";
+ return text;
+
+ } break;
+ case SL::TYPE_UINT: return itos(p_values[0].uint)+"u";
+ case SL::TYPE_UVEC2:
+ case SL::TYPE_UVEC3:
+ case SL::TYPE_UVEC4: {
+
+ String text="uvec"+itos(p_type-SL::TYPE_UINT+1)+"(";
+ for(int i=0;i<p_values.size();i++) {
+ if (i>0)
+ text+=",";
+
+ text+=itos(p_values[i].uint)+"u";
+ }
+ text+=")";
+ return text;
+ } break;
+ case SL::TYPE_FLOAT: return f2sp0(p_values[0].real)+"f";
+ case SL::TYPE_VEC2:
+ case SL::TYPE_VEC3:
+ case SL::TYPE_VEC4: {
+
+ String text="vec"+itos(p_type-SL::TYPE_FLOAT+1)+"(";
+ for(int i=0;i<p_values.size();i++) {
+ if (i>0)
+ text+=",";
+
+ text+=f2sp0(p_values[i].real);
+ }
+ text+=")";
+ return text;
+
+ } break;
default: ERR_FAIL_V(String());
}
}
@@ -189,6 +245,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
r_gen_code.texture_uniforms.resize(max_texture_uniforms);
+ r_gen_code.texture_hints.resize(max_texture_uniforms);
Vector<int> uniform_sizes;
uniform_sizes.resize(max_uniforms);
@@ -209,6 +266,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
r_gen_code.vertex_global+=ucode;
r_gen_code.fragment_global+=ucode;
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()) {
diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h
index ad51b99927..dcea82d773 100644
--- a/drivers/gles3/shader_compiler_gles3.h
+++ b/drivers/gles3/shader_compiler_gles3.h
@@ -21,6 +21,8 @@ public:
Vector<CharString> defines;
Vector<StringName> texture_uniforms;
+ Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
+
Vector<uint32_t> uniform_offsets;
uint32_t uniform_total_size;
String uniforms;
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index eb58d66431..79982ecf25 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -5,9 +5,9 @@ layout(location=0) in highp vec4 vertex_attrib;
#ifdef USE_CUBEMAP
layout(location=4) in vec3 cube_in;
#else
-layout(location=4) in vec2 uv_in; // attrib:4
+layout(location=4) in vec2 uv_in;
#endif
-layout(location=5) in vec2 uv2_in; // attrib:5
+layout(location=5) in vec2 uv2_in;
#ifdef USE_CUBEMAP
out vec3 cube_interp;
@@ -40,6 +40,15 @@ uniform sampler2D source; //texunit:0
#endif
+float sRGB_gamma_correct(float c){
+ float a = 0.055;
+ if(c < 0.0031308)
+ return 12.92*c;
+ else
+ return (1.0+a)*pow(c, 1.0/2.4) - a;
+}
+
+
uniform float stuff;
in vec2 uv2_interp;
@@ -57,6 +66,20 @@ void main() {
vec4 color = texture( source, uv_interp );
#endif
+#ifdef LINEAR_TO_SRGB
+ //regular Linear -> SRGB conversion
+ vec3 a = vec3(0.055);
+ color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
+#endif
+
+#ifdef DEBUG_GRADIENT
+ color.rg=uv_interp;
+ color.b=0.0;
+#endif
+
+#ifdef DISABLE_ALPHA
+ color.a=1.0;
+#endif
frag_color = color;
}
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index d3d4cbd435..998a59833e 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -3,7 +3,7 @@
layout(location=0) in highp vec2 vertex;
-layout(location=1) in highp vec2 uv;
+layout(location=4) in highp vec2 uv;
out highp vec2 uv_interp;
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 3f94252606..60ac015a17 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -269,11 +269,16 @@ in vec3 normal_interp;
/* PBR CHANNELS */
+//used on forward mainly
+uniform bool no_ambient_light;
+
+
#ifdef USE_RADIANCE_CUBEMAP
uniform sampler2D brdf_texture; //texunit:-1
uniform samplerCube radiance_cube; //texunit:-2
+
layout(std140) uniform Radiance { //ubo:2
mat4 radiance_inverse_xform;
@@ -346,8 +351,18 @@ in mediump vec4 forward_shadow_pos4;
#endif
+#ifdef USE_MULTIPLE_RENDER_TARGETS
+
+layout(location=0) out vec4 diffuse_buffer;
+layout(location=1) out vec4 specular_buffer;
+layout(location=2) out vec4 normal_mr_buffer;
+
+#else
+
layout(location=0) out vec4 frag_color;
+#endif
+
// GGX Specular
// Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
@@ -470,39 +485,46 @@ FRAGMENT_SHADER_CODE
/////////////////////// LIGHTING //////////////////////////////
vec3 specular_light = vec3(0.0,0.0,0.0);
- vec3 ambient_light = ambient_light_color.rgb;
+ vec3 ambient_light;
vec3 diffuse_light = vec3(0.0,0.0,0.0);
vec3 eye_vec = -normalize( vertex_interp );
#ifdef USE_RADIANCE_CUBEMAP
- {
+ if (no_ambient_light) {
+ ambient_light=vec3(0.0,0.0,0.0);
+ } else {
+ {
- float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
- vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy;
+ float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
+ vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy;
- float lod = roughness * 5.0;
- vec3 r = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
- r=normalize((radiance_inverse_xform * vec4(r,0.0)).xyz);
- vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y);
+ float lod = roughness * 5.0;
+ vec3 r = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
+ r=normalize((radiance_inverse_xform * vec4(r,0.0)).xyz);
+ vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y);
- specular_light=mix(albedo,radiance,specular);
+ specular_light=mix(albedo,radiance,specular);
- }
+ }
- {
+ {
- vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
- vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz;
+ vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
+ vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz;
- ambient_light=mix(ambient_light,env_ambient,radiance_ambient_contribution);
+ ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);
+ }
}
-
#else
- ambient_light=albedo;
+ if (no_ambient_light){
+ ambient_light=vec3(0.0,0.0,0.0);
+ } else {
+ ambient_light=ambient_light_color.rgb;
+ }
#endif
@@ -538,11 +560,25 @@ LIGHT_SHADER_CODE
}
#endif
-#ifdef SHADELESS
+#ifdef USE_MULTIPLE_RENDER_TARGETS
+
+ //approximate ambient scale for SSAO, since we will lack full ambient
+ float max_ambient=max(ambient_light.r,max(ambient_light.g,ambient_light.b));
+ float max_diffuse=max(diffuse_light.r,max(diffuse_light.g,diffuse_light.b));
+ float total_ambient = max_ambient+max_diffuse;
+ float ambient_scale = (total_ambient>0.0) ? max_ambient/total_ambient : 0.0;
+ diffuse_buffer=vec4(diffuse_light+ambient_light,ambient_scale);
+ specular_buffer=vec4(specular_light,0.0);
+ normal_mr_buffer=vec4(normal.x,normal.y,max(specular.r,max(specular.g,specular.b)),roughness);
+
+#else
+
+#ifdef SHADELESS
frag_color=vec4(albedo,alpha);
#else
frag_color=vec4(ambient_light+diffuse_light+specular_light,alpha);
+#endif
#endif