summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2017-01-01 22:16:52 -0300
committerJuan Linietsky <reduzio@gmail.com>2017-01-01 22:16:52 -0300
commitc2a217c3501b8006a3d2cdf2c678e33def15f275 (patch)
tree9f0b2d128ef5c97d4632e387041079e59c193fd7
parenta62c99c4e4325ca0c015d731f2bcb9b07410bb65 (diff)
WIP particle system
Ability to enable and change MSAA settings Ability to change VCT quality Ability to enable/disable HDR rendering
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp16
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp124
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h1
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp318
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h53
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp19
-rw-r--r--drivers/gles3/shaders/particles.glsl121
-rw-r--r--drivers/gles3/shaders/scene.glsl6
-rw-r--r--drivers/gles3/shaders/subsurf_scattering.glsl4
-rw-r--r--scene/main/scene_main_loop.cpp5
-rw-r--r--scene/main/viewport.cpp48
-rw-r--r--scene/main/viewport.h22
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/shader.cpp2
-rw-r--r--scene/resources/shader.h10
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/shader_types.cpp20
-rw-r--r--servers/visual/visual_server_raster.h3
-rw-r--r--servers/visual/visual_server_viewport.cpp16
-rw-r--r--servers/visual/visual_server_viewport.h3
-rw-r--r--servers/visual_server.h12
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp11
22 files changed, 665 insertions, 152 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index ccc5c70c97..0998d9c423 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -163,18 +163,30 @@ void RasterizerGLES3::initialize() {
void RasterizerGLES3::begin_frame(){
- double time_total = double(OS::get_singleton()->get_ticks_usec())/1000000.0;
+ uint64_t tick = OS::get_singleton()->get_ticks_usec();
+
+ double time_total = double(tick)/1000000.0;
storage->frame.time[0]=time_total;
storage->frame.time[1]=Math::fmod(time_total,3600);
storage->frame.time[2]=Math::fmod(time_total,900);
storage->frame.time[3]=Math::fmod(time_total,60);
storage->frame.count++;
+ storage->frame.delta = double(tick-storage->frame.prev_tick)/1000000.0;
+ if (storage->frame.prev_tick==0) {
+ //to avoid hiccups
+ storage->frame.delta=0.001;
+ }
+
+ storage->frame.prev_tick=tick;
+
+
storage->update_dirty_multimeshes();
storage->update_dirty_skeletons();
storage->update_dirty_shaders();
storage->update_dirty_materials();
+ storage->update_particles();
storage->info.render_object_count=0;
storage->info.render_material_switch_count=0;
@@ -186,6 +198,8 @@ void RasterizerGLES3::begin_frame(){
scene->iteration();
+
+
}
void RasterizerGLES3::set_current_render_target(RID p_render_target){
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 1b080a1216..17e429657b 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2880,10 +2880,17 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
- bool diffuse_copied=false;
if (env->ssao_enabled) {
- //ssao
+ //copy diffuse to front buffer
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->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);
+
//copy from depth, convert to linear
GLint ss[2];
@@ -2960,7 +2967,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.ssao.linear_depth);
glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.normal_rough);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.effect);
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.ssao.blur_fbo[0]); //copy to front first
Color white(1,1,1,1);
@@ -3001,23 +3008,36 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
state.effect_blur_shader.bind();
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::SSAO_COLOR,env->ssao_color);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse); //previous level, since mipmaps[0] starts one level bigger
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->color); //previous level, since mipmaps[0] starts one level bigger
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.ssao.blur_red[0]); //previous level, since mipmaps[0] starts one level bigger
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
_copy_screen();
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SSAO_MERGE,false);
+ } else {
+ //copy diffuse to effect buffer
+ 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);
- diffuse_copied=true;
}
if (state.used_sss) {//sss enabled
//copy diffuse while performing sss
+ //copy normal and roughness to effect buffer
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT3);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_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_NEAREST);
+
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_11_SAMPLES,subsurface_scatter_quality==SSS_QUALITY_LOW);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES,subsurface_scatter_quality==SSS_QUALITY_MEDIUM);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_25_SAMPLES,subsurface_scatter_quality==SSS_QUALITY_HIGH);
@@ -3030,15 +3050,10 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR,Vector2(1,0));
glActiveTexture(GL_TEXTURE0);
- if (diffuse_copied) {
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
- } else {
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
- diffuse_copied=true;
- }
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.motion_sss);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.effect);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@@ -3056,19 +3071,16 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
}
- if (!diffuse_copied) {
- // just copy diffuse
- storage->shaders.copy.bind();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
- _copy_screen();
- }
+ if (env->ssr_enabled) {
+ //copy normal and roughness to effect buffer
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT2);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_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_NEAREST);
- if (env->ssr_enabled) {
//blur diffuse into effect mipmaps using separatable convolution
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
for(int i=0;i<storage->frame.current_rt->effects.mip_maps[1].sizes.size();i++) {
@@ -3127,14 +3139,12 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.normal_rough);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.effect);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
- glActiveTexture(GL_TEXTURE3);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[1].sizes[0].fbo);
glViewport(0,0,ssr_w,ssr_h);
@@ -3145,11 +3155,22 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
}
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT1);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
+ //glDrawBuffer(GL_COLOR_ATTACHMENT0);
+ 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_NEAREST);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+
//copy reflection over diffuse, resolving SSR if needed
state.resolve_shader.set_conditional(ResolveShaderGLES3::USE_SSR,env->ssr_enabled);
state.resolve_shader.bind();
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.specular);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->color);
if (env->ssr_enabled) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[1].color);
@@ -3169,7 +3190,12 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
state.effect_blur_shader.bind();
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD,float(0));
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
+ {
+ GLuint db = GL_COLOR_ATTACHMENT0;
+ glDrawBuffers(1,&db);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
@@ -3193,11 +3219,23 @@ void RasterizerSceneGLES3::_post_process(Environment *env,const CameraMatrix &p_
//turn off everything used
+ //copy specular to front buffer
+ //copy diffuse to effect buffer
+
+
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ 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_NEAREST);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+
if (!env) {
//no environment, simply return and convert to SRGB
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,true);
storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA,true);
storage->shaders.copy.bind();
@@ -3219,7 +3257,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env,const CameraMatrix &p_
//4) Tonemap
//5) Adjustments
- GLuint composite_from = storage->frame.current_rt->buffers.diffuse;
+ GLuint composite_from = storage->frame.current_rt->effects.mip_maps[0].color;
if (env->dof_blur_far_enabled) {
@@ -3701,11 +3739,15 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
if (storage->frame.current_rt && true) {
//pre z pass
+
+
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo);
+ glDrawBuffers(0,NULL);
+
glViewport(0,0,storage->frame.current_rt->width,storage->frame.current_rt->height);
glColorMask(0,0,0,0);
@@ -3808,10 +3850,15 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
} else {
- current_fbo = storage->frame.current_rt->buffers.alpha_fbo;
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
+
+
+ current_fbo = storage->frame.current_rt->buffers.fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false);
+ Vector<GLenum> draw_buffers;
+ draw_buffers.push_back(GL_COLOR_ATTACHMENT0);
+ glDrawBuffers(draw_buffers.size(),draw_buffers.ptr());
}
}
@@ -3902,9 +3949,9 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
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
- }
+ //if (use_mrt) {
+ // glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for skybox, only diffuse/ambient matters
+ //
_draw_skybox(skybox,p_cam_projection,p_cam_transform,storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP],env->skybox_scale);
}
@@ -4902,6 +4949,10 @@ void RasterizerSceneGLES3::initialize() {
GLOBAL_DEF("rendering/gles3/subsurface_scattering/max_size",1.0);
Globals::get_singleton()->set_custom_property_info("rendering/gles3/subsurface_scattering/max_size",PropertyInfo(Variant::INT,"rendering/gles3/subsurface_scattering/max_size",PROPERTY_HINT_RANGE,"0.01,8,0.01"));
GLOBAL_DEF("rendering/gles3/subsurface_scattering/follow_surface",false);
+
+ GLOBAL_DEF("rendering/gles3/high_quality_vct_gi",true);
+
+
}
exposure_shrink_size=243;
@@ -4940,6 +4991,9 @@ void RasterizerSceneGLES3::iteration() {
subsurface_scatter_follow_surface=Globals::get_singleton()->get("rendering/gles3/subsurface_scattering/follow_surface");
subsurface_scatter_quality=SubSurfaceScatterQuality(int(Globals::get_singleton()->get("rendering/gles3/subsurface_scattering/quality")));
subsurface_scatter_size=Globals::get_singleton()->get("rendering/gles3/subsurface_scattering/max_size");
+
+
+ state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH,Globals::get_singleton()->get("rendering/gles3/high_quality_vct_gi"));
}
void RasterizerSceneGLES3::finalize(){
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 3fdbdb95d0..7838345e59 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -53,7 +53,6 @@ public:
Vector<RasterizerStorageGLES3::RenderTarget::Exposure> exposure_shrink;
int exposure_shrink_size;
-
struct State {
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 2875c1f788..c632d1c2da 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1401,7 +1401,7 @@ void RasterizerStorageGLES3::shader_set_mode(RID p_shader,VS::ShaderMode p_mode)
ShaderGLES3* shaders[VS::SHADER_MAX]={
&scene->state.scene_shader,
&canvas->state.canvas_shader,
- &canvas->state.canvas_shader,
+ &this->shaders.particles,
};
@@ -1510,6 +1510,11 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
}
+ case VS::SHADER_PARTICLES: {
+
+ actions=&shaders.actions_particles;
+ actions->uniforms=&p_shader->uniforms;
+ }
}
@@ -4998,6 +5003,7 @@ void RasterizerStorageGLES3::gi_probe_dynamic_data_update(RID p_gi_probe_data, i
///////
+
RID RasterizerStorageGLES3::particles_create() {
Particles *particles = memnew( Particles );
@@ -5018,7 +5024,30 @@ void RasterizerStorageGLES3::particles_set_amount(RID p_particles,int p_amount)
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
+ int floats = p_amount*24;
+ float * data = memnew_arr(float,floats);
+
+ for(int i=0;i<floats;i++) {
+ data[i]=0;
+ }
+
+
+ glBindBuffer(GL_ARRAY_BUFFER,particles->particle_buffers[0]);
+ glBufferData(GL_ARRAY_BUFFER,floats*sizeof(float),data,GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER,particles->particle_buffers[1]);
+ glBufferData(GL_ARRAY_BUFFER,floats*sizeof(float),data,GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+
+ particles->prev_ticks=0;
+ particles->phase=0;
+ particles->prev_phase=0;
+
+ memdelete_arr(data);
+
}
+
void RasterizerStorageGLES3::particles_set_lifetime(RID p_particles,float p_lifetime){
Particles *particles = particles_owner.getornull(p_particles);
@@ -5125,7 +5154,7 @@ void RasterizerStorageGLES3::particles_set_draw_pass_material(RID p_particles,in
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_INDEX(p_pass,particles->draw_passes.size());
- p_pass,particles->draw_passes[p_pass].material=p_material;
+ particles->draw_passes[p_pass].material=p_material;
}
void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles,int p_pass, RID p_mesh) {
@@ -5133,7 +5162,7 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles,int p_
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_INDEX(p_pass,particles->draw_passes.size());
- p_pass,particles->draw_passes[p_pass].mesh=p_mesh;
+ particles->draw_passes[p_pass].mesh=p_mesh;
}
@@ -5145,6 +5174,124 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
return particles->computed_aabb;
}
+void RasterizerStorageGLES3::update_particles() {
+
+ glEnable(GL_RASTERIZER_DISCARD);
+ glBindVertexArray(0);
+
+
+ while (particle_update_list.first()) {
+
+ //use transform feedback to process particles
+
+ Particles *particles = particle_update_list.first()->self();
+
+
+ Material *material = material_owner.getornull(particles->process_material);
+ if (!material || !material->shader || material->shader->mode!=VS::SHADER_PARTICLES) {
+
+ shaders.particles.set_custom_shader(0);
+ } else {
+ shaders.particles.set_custom_shader( material->shader->custom_code_id );
+
+ if (material->ubo_id) {
+
+ glBindBufferBase(GL_UNIFORM_BUFFER,0,material->ubo_id);
+ }
+
+ int tc = material->textures.size();
+ RID* textures = material->textures.ptr();
+ ShaderLanguage::ShaderNode::Uniform::Hint* texture_hints = material->shader->texture_hints.ptr();
+
+
+ for(int i=0;i<tc;i++) {
+
+ glActiveTexture(GL_TEXTURE0+i);
+
+ GLenum target;
+ GLuint tex;
+
+ RasterizerStorageGLES3::Texture *t = texture_owner.getornull( textures[i] );
+
+ if (!t) {
+ //check hints
+ target=GL_TEXTURE_2D;
+
+ switch(texture_hints[i]) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ tex=resources.black_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
+ tex=resources.aniso_tex;
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ tex=resources.normal_tex;
+ } break;
+ default: {
+ tex=resources.white_tex;
+ } break;
+ }
+
+
+ } else {
+
+ target=t->target;
+ tex = t->tex_id;
+
+ }
+
+ glBindTexture(target,tex);
+ }
+
+ }
+
+ shaders.particles.bind();
+
+ shaders.particles.set_uniform(ParticlesShaderGLES3::ORIGIN,particles->origin);
+
+ float new_phase = Math::fmod(particles->phase+(frame.delta/particles->lifetime),1.0);
+
+ shaders.particles.set_uniform(ParticlesShaderGLES3::SYSTEM_PHASE,new_phase);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::PREV_SYSTEM_PHASE,particles->phase);
+ particles->phase = new_phase;
+
+ shaders.particles.set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES,particles->amount);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::TIME,0.0);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS,particles->explosiveness);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA,frame.delta);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::GRAVITY,particles->gravity);
+ shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT,0);
+
+
+
+
+ glBindBuffer(GL_ARRAY_BUFFER,particles->particle_buffers[0]);
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->particle_buffers[1]);
+
+ for(int i=0;i<6;i++) {
+ glEnableVertexAttribArray(i);
+ glVertexAttribPointer(i,4,GL_FLOAT,GL_FALSE,sizeof(float)*4*6,((uint8_t*)0)+(i*16));
+ }
+
+
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS,0,particles->amount);
+ glEndTransformFeedback();
+
+ particle_update_list.remove(particle_update_list.first());
+
+ SWAP(particles->particle_buffers[0],particles->particle_buffers[1]);
+ }
+
+ glDisable(GL_RASTERIZER_DISCARD);
+
+ for(int i=0;i<6;i++) {
+ glDisableVertexAttribArray(i);
+ }
+
+}
+
////////
void RasterizerStorageGLES3::instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance) {
@@ -5258,13 +5405,15 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
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_rough);
- glDeleteTextures(1,&rt->buffers.motion_sss);
+ glDeleteRenderbuffers(1,&rt->buffers.depth);
+ glDeleteRenderbuffers(1,&rt->buffers.diffuse);
+ glDeleteRenderbuffers(1,&rt->buffers.specular);
+ glDeleteRenderbuffers(1,&rt->buffers.normal_rough);
+ glDeleteRenderbuffers(1,&rt->buffers.motion_sss);
+ glDeleteFramebuffers(1,&rt->buffers.effect_fbo);
+ glDeleteTextures(1,&rt->buffers.effect);
+
rt->buffers.fbo=0;
- rt->buffers.alpha_fbo=0;
}
if (rt->depth) {
@@ -5327,19 +5476,12 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
- if (config.render_arch==RENDER_ARCH_MOBILE || rt->flags[RENDER_TARGET_NO_3D]) {
+ if (!rt->flags[RENDER_TARGET_HDR] || rt->flags[RENDER_TARGET_NO_3D]) {
- if (rt->flags[RENDER_TARGET_TRANSPARENT]) {
- color_internal_format=GL_RGBA8;
- color_format=GL_RGBA;
- color_type=GL_UNSIGNED_BYTE;
- image_format=Image::FORMAT_RGBA8;
- } else {
- color_internal_format=GL_RGB10_A2;
- color_format=GL_RGBA;
- color_type=GL_UNSIGNED_INT_2_10_10_10_REV;
- image_format=Image::FORMAT_RGBA8;//todo
- }
+ color_internal_format=GL_RGBA8;
+ color_format=GL_RGBA;
+ color_type=GL_UNSIGNED_BYTE;
+ image_format=Image::FORMAT_RGBA8;
} else {
color_internal_format=GL_RGBA16F;
color_format=GL_RGBA;
@@ -5347,6 +5489,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
image_format=Image::FORMAT_RGBAH;
}
+
{
/* FRONT FBO */
@@ -5407,69 +5550,99 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
+ static const int msaa_value[]={0,2,4,8,16};
+ int msaa=msaa_value[rt->msaa];
+
//regular fbo
glGenFramebuffers(1, &rt->buffers.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_TEXTURE_2D, rt->depth, 0);
+ glGenRenderbuffers(1, &rt->buffers.depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.depth);
+ if (msaa==0)
+ glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8,rt->width,rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER,msaa,GL_DEPTH24_STENCIL8,rt->width,rt->height);
- glGenTextures(1, &rt->buffers.diffuse);
- glBindTexture(GL_TEXTURE_2D, rt->buffers.diffuse);
- 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_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,rt->buffers.depth);
+
+ glGenRenderbuffers(1, &rt->buffers.diffuse);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.diffuse);
- 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->buffers.specular, 0);
+ if (msaa==0)
+ glRenderbufferStorage(GL_RENDERBUFFER,color_internal_format,rt->width,rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER,msaa,GL_RGBA16F,rt->width,rt->height);
- glGenTextures(1, &rt->buffers.normal_rough);
- glBindTexture(GL_TEXTURE_2D, rt->buffers.normal_rough);
- 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->buffers.normal_rough, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_RENDERBUFFER,rt->buffers.diffuse);
+
+ glGenRenderbuffers(1, &rt->buffers.specular);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.specular);
+
+ if (msaa==0)
+ glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA16F,rt->width,rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER,msaa,color_internal_format,rt->width,rt->height);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT1,GL_RENDERBUFFER,rt->buffers.specular);
+
+ glGenRenderbuffers(1, &rt->buffers.normal_rough);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.normal_rough);
+
+ if (msaa==0)
+ glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA8,rt->width,rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER,msaa,GL_RGBA8,rt->width,rt->height);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT2,GL_RENDERBUFFER,rt->buffers.normal_rough);
+
+
+ glGenRenderbuffers(1, &rt->buffers.motion_sss);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.motion_sss);
+
+ if (msaa==0)
+ glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA8,rt->width,rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER,msaa,GL_RGBA8,rt->width,rt->height);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT3,GL_RENDERBUFFER,rt->buffers.motion_sss);
- glGenTextures(1, &rt->buffers.motion_sss);
- glBindTexture(GL_TEXTURE_2D, rt->buffers.motion_sss);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, rt->width, rt->height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 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_ATTACHMENT3, GL_TEXTURE_2D, rt->buffers.motion_sss, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("err status: %x\n",status);
_render_target_clear(rt);
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
- }
+ }
+ glBindRenderbuffer(GL_RENDERBUFFER,0);
- //alpha fbo
- glGenFramebuffers(1, &rt->buffers.alpha_fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.alpha_fbo);
+ // effect resolver
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_TEXTURE_2D, rt->depth, 0);
+ glGenFramebuffers(1, &rt->buffers.effect_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.effect_fbo);
+
+ glGenTextures(1, &rt->buffers.effect);
+ glBindTexture(GL_TEXTURE_2D, rt->buffers.effect);
+ 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->buffers.effect, 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0);
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("err status: %x\n",status);
+ _render_target_clear(rt);
+ ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
+ }
+
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
if (status != GL_FRAMEBUFFER_COMPLETE) {
@@ -5499,7 +5672,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
RenderTarget::Effects::MipMaps::Size mm;
- glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, level, color_internal_format, w, h, 0, color_format, color_type, NULL);
mm.width=w;
mm.height=h;
rt->effects.mip_maps[i].sizes.push_back(mm);
@@ -5711,6 +5884,20 @@ bool RasterizerStorageGLES3::render_target_renedered_in_frame(RID p_render_targe
return false;
}
+void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target,VS::ViewportMSAA p_msaa) {
+
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ if (rt->msaa==p_msaa)
+ return;
+
+ _render_target_clear(rt);
+ rt->msaa=p_msaa;
+ _render_target_allocate(rt);
+
+}
+
/* CANVAS SHADOW */
@@ -6283,10 +6470,13 @@ void RasterizerStorageGLES3::initialize() {
}
shaders.cubemap_filter.init();
+ shaders.particles.init();
glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);
frame.count=0;
+ frame.prev_tick=0;
+ frame.delta=0;
config.keep_original_textures=false;
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 690a169ca2..357b69183e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -8,6 +8,7 @@
#include "shaders/canvas.glsl.h"
#include "shaders/blend_shape.glsl.h"
#include "shaders/cubemap_filter.glsl.h"
+#include "shaders/particles.glsl.h"
#include "self_list.h"
#include "shader_compiler_gles3.h"
@@ -70,8 +71,11 @@ public:
BlendShapeShaderGLES3 blend_shapes;
+ ParticlesShaderGLES3 particles;
+
ShaderCompilerGLES3::IdentifierActions actions_canvas;
ShaderCompilerGLES3::IdentifierActions actions_scene;
+ ShaderCompilerGLES3::IdentifierActions actions_particles;
} shaders;
struct Resources {
@@ -385,6 +389,12 @@ public:
} spatial;
+ struct Particles {
+
+
+ } particles;
+
+
bool uses_vertex_time;
bool uses_fragment_time;
@@ -988,7 +998,17 @@ public:
AABB computed_aabb;
- Particles() {
+ GLuint particle_buffers[2];
+
+ SelfList<Particles> particle_element;
+
+ float phase;
+ float prev_phase;
+ uint64_t prev_ticks;
+
+ Transform origin;
+
+ Particles() : particle_element(this) {
emitting=false;
amount=0;
lifetime=1.0;;
@@ -1000,13 +1020,29 @@ public:
draw_order=VS::PARTICLES_DRAW_ORDER_INDEX;
emission_shape=VS::PARTICLES_EMSSION_POINT;
emission_sphere_radius=1.0;
- float emission_sphere_radius;
emission_box_extents=Vector3(1,1,1);
emission_point_texture=0;
+ particle_buffers[0]=0;
+ particle_buffers[1]=0;
+
+ prev_ticks=0;
+
+ glGenBuffers(2,particle_buffers);
}
+ ~Particles() {
+
+ glDeleteBuffers(2,particle_buffers);
+ }
+
+
};
+ SelfList<Particles>::List particle_update_list;
+
+ void update_particles();
+
+
mutable RID_Owner<Particles> particles_owner;
virtual RID particles_create();
@@ -1054,11 +1090,15 @@ public:
struct Buffers {
GLuint fbo;
- GLuint alpha_fbo; //single buffer, just diffuse (for alpha pass)
+ GLuint depth;
GLuint specular;
GLuint diffuse;
GLuint normal_rough;
GLuint motion_sss;
+
+ GLuint effect_fbo;
+ GLuint effect;
+
} buffers;
struct Effects {
@@ -1110,22 +1150,24 @@ public:
bool flags[RENDER_TARGET_FLAG_MAX];
bool used_in_frame;
+ VS::ViewportMSAA msaa;
RID texture;
RenderTarget() {
+ msaa=VS::VIEWPORT_MSAA_DISABLED;
width=0;
height=0;
depth=0;
fbo=0;
buffers.fbo=0;
- buffers.alpha_fbo=0;
used_in_frame=false;
flags[RENDER_TARGET_VFLIP]=false;
flags[RENDER_TARGET_TRANSPARENT]=false;
flags[RENDER_TARGET_NO_3D]=false;
+ flags[RENDER_TARGET_HDR]=true;
flags[RENDER_TARGET_NO_SAMPLING]=false;
last_exposure_tick=0;
@@ -1143,6 +1185,7 @@ public:
virtual void render_target_set_flag(RID p_render_target,RenderTargetFlags p_flag,bool p_value);
virtual bool render_target_renedered_in_frame(RID p_render_target);
+ virtual void render_target_set_msaa(RID p_render_target,VS::ViewportMSAA p_msaa);
/* CANVAS SHADOW */
@@ -1187,6 +1230,8 @@ public:
Color clear_request_color;
int canvas_draw_commands;
float time[4];
+ float delta;
+ uint64_t prev_tick;
uint64_t count;
} frame;
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 336cf7b34b..26b9aeada4 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -703,6 +703,24 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
+ /* PARTICLES SHADER */
+
+ actions[VS::SHADER_PARTICLES].renames["COLOR"]="color";
+ actions[VS::SHADER_PARTICLES].renames["VELOCITY"]="out_velocity_active.xyz";
+ actions[VS::SHADER_PARTICLES].renames["MASS"]="mass";
+ actions[VS::SHADER_PARTICLES].renames["ACTIVE"]="active";
+ actions[VS::SHADER_PARTICLES].renames["RESTART"]="restart";
+ actions[VS::SHADER_PARTICLES].renames["CUSTOM"]="out_custom";
+ actions[VS::SHADER_PARTICLES].renames["TRANSFORM"]="xform";
+ actions[VS::SHADER_PARTICLES].renames["TIME"]="time";
+ actions[VS::SHADER_PARTICLES].renames["LIFETIME"]="lifetime";
+ actions[VS::SHADER_PARTICLES].renames["DELTA"]="delta";
+ actions[VS::SHADER_PARTICLES].renames["SEED"]="seed";
+ actions[VS::SHADER_PARTICLES].renames["ORIGIN"]="origin";
+ actions[VS::SHADER_PARTICLES].renames["INDEX"]="index";
+
+ actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"]="#define DISABLE_FORCE\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"]="#define DISABLE_VELOCITY\n";
vertex_name="vertex";
@@ -710,7 +728,6 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
time_name="TIME";
-
List<String> func_list;
ShaderLanguage::get_builtin_funcs(&func_list);
diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl
index fb6060957e..e72f12cc5e 100644
--- a/drivers/gles3/shaders/particles.glsl
+++ b/drivers/gles3/shaders/particles.glsl
@@ -2,10 +2,12 @@
-layout(location=0) in highp vec4 pos_lifetime;
-layout(location=1) in highp vec4 color;
-layout(location=2) in highp vec4 velocity_seed;
-layout(location=3) in highp vec4 rot_active;
+layout(location=0) in highp vec4 color;
+layout(location=1) in highp vec4 velocity_active;
+layout(location=2) in highp vec4 custom;
+layout(location=3) in highp vec4 xform_1;
+layout(location=4) in highp vec4 xform_2;
+layout(location=5) in highp vec4 xform_3;
struct Attractor {
@@ -32,10 +34,24 @@ uniform int attractor_count;
uniform Attractor attractors[MAX_ATTRACTORS];
-out highp vec4 out_pos_lifetime; //tfb:
out highp vec4 out_color; //tfb:
-out highp vec4 out_velocity_seed; //tfb:
-out highp vec4 out_rot_active; //tfb:
+out highp vec4 out_velocity_active; //tfb:
+out highp vec4 out_custom; //tfb:
+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)
+
+layout(std140) uniform UniformData { //ubo:0
+
+MATERIAL_UNIFORMS
+
+};
+
+#endif
void main() {
@@ -47,6 +63,7 @@ void main() {
float restart_phase = float(gl_InstanceID)/total_particles;
restart_phase*= explosiveness;
bool restart=false;
+ bool active = out_velocity_active.a > 0.5;
if (system_phase > prev_system_phase) {
restart = prev_system_phase < restart_phase && system_phase >= restart_phase;
@@ -55,60 +72,96 @@ void main() {
}
if (restart) {
- out_rot_active.a=1.0;
+ active=true;
}
- out_pos_lifetime=pos_lifetime;
out_color=color;
- out_velocity_seed=velocity_seed;
+ out_velocity_active=velocity_active;
+ out_custom=custom;
+
+ mat4 xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0)));
+
+
out_rot_active=rot_active;
- if (out_rot_active.a) {
+ if (active) {
//execute shader
- }
+ {
+ VERTEX_SHADER_CODE
+ }
+#if !defined(DISABLE_FORCE)
- if (apply_forces) {
+ {
- vec3 force = gravity;
- for(int i=0;i<attractor_count;i++) {
+ vec3 force = gravity;
+ for(int i=0;i<attractor_count;i++) {
- vec3 rel_vec = out_pos_lifetime.xyz - attractors[i].pos;
- float dist = rel_vec.length();
- if (attractors[i].radius < dist)
- continue;
- if (attractors[i].eat_radius>0 && attractors[i].eat_radius > dist) {
- rot_active.a=0.0;
- }
+ vec3 rel_vec = out_pos_lifetime.xyz - attractors[i].pos;
+ float dist = rel_vec.length();
+ if (attractors[i].radius < dist)
+ continue;
+ if (attractors[i].eat_radius>0 && attractors[i].eat_radius > dist) {
+ out_velocity_active.a=0.0;
+ }
- rel_vec = normalize(rel_vec);
+ rel_vec = normalize(rel_vec);
- float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation);
+ float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation);
- if (attractors[i].dir==vec3(0.0)) {
- //towards center
- force+=attractors[i].strength * rel_vec * attenuation * mass;
- } else {
- force+=attractors[i].strength * attractors[i].dir * attenuation *mass;
+ if (attractors[i].dir==vec3(0.0)) {
+ //towards center
+ force+=attractors[i].strength * rel_vec * attenuation * mass;
+ } else {
+ force+=attractors[i].strength * attractors[i].dir * attenuation *mass;
+ }
}
+
+ out_velocity_seed.xyz += force * delta;
}
+#endif
- out_velocity_seed.xyz += force * delta;
- }
+#if !defined(DISABLE_VELOCITY)
- if (apply_velocity) {
+ {
- out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
+ out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
+ }
+#endif
}
+ xform = transpose(xform);
+
+ out_velocity_active.a = mix(0.0,1.0,active);
+
+ out_xform_1 = xform[0];
+ out_xform_2 = xform[1];
+ out_xform_3 = xform[2];
+
+
}
[fragment]
+//any code here is never executed, stuff is filled just so it works
-void main() {
+FRAGMENT_SHADER_GLOBALS
+
+#if defined(USE_MATERIAL)
+layout(std140) uniform UniformData {
+MATERIAL_UNIFORMS
+
+};
+
+#endif
+
+void main() {
+
+ {
+ FRAGMENT_SHADER_CODE
+ }
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index c18a356a54..c5af010c96 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -484,7 +484,7 @@ layout(location=0) out vec4 diffuse_buffer;
layout(location=1) out vec4 specular_buffer;
layout(location=2) out vec4 normal_mr_buffer;
#if defined (ENABLE_SSS_MOTION)
-layout(location=3) out uint motion_ssr_buffer;
+layout(location=3) out vec4 motion_ssr_buffer;
#endif
#else
@@ -902,7 +902,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s
float max_distance = length(bounds);
//radiance
-#ifndef VCT_QUALITY_HIGH
+#ifdef VCT_QUALITY_HIGH
#define MAX_CONE_DIRS 6
vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] (
@@ -1407,7 +1407,7 @@ LIGHT_SHADER_CODE
normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);
#if defined (ENABLE_SSS_MOTION)
- motion_ssr_buffer = uint(clamp(sqrt(sss_strength)*255.0,0.0,255))<<24;
+ motion_ssr_buffer = vec4(vec3(0.0),sss_strength);
#endif
#else
diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl
index 89e618b66c..eb329dbaed 100644
--- a/drivers/gles3/shaders/subsurf_scattering.glsl
+++ b/drivers/gles3/shaders/subsurf_scattering.glsl
@@ -107,14 +107,14 @@ uniform vec2 dir;
in vec2 uv_interp;
uniform sampler2D source_diffuse; //texunit:0
-uniform highp usampler2D source_motion_ss; //texunit:1
+uniform sampler2D source_motion_ss; //texunit:1
uniform sampler2D source_depth; //texunit:2
layout(location = 0) out vec4 frag_color;
void main() {
- float strength = float(texture(source_motion_ss,uv_interp).r>>24)*(1.0/255.0);
+ float strength = texture(source_motion_ss,uv_interp).a;
strength*=strength; //stored as sqrt
// Fetch color of current pixel:
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index abc4bf3fe2..3145be1dbf 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -2322,6 +2322,11 @@ SceneTree::SceneTree() {
int ref_atlas_size = GLOBAL_DEF("rendering/reflections/atlas_size",2048);
int ref_atlas_subdiv = GLOBAL_DEF("rendering/reflections/atlas_subdiv",8);
+ int msaa_mode = GLOBAL_DEF("rendering/antialias/msaa",0);
+ Globals::get_singleton()->set_custom_property_info("rendering/antialias/msaa",PropertyInfo(Variant::INT,"rendering/antialias/msaa",PROPERTY_HINT_ENUM,"Disabled,2x,4x,8x,16x"));
+ root->set_msaa(Viewport::MSAA(msaa_mode));
+ bool hdr = GLOBAL_DEF("rendering/dynamic_range/hdr",true);
+ root->set_hdr(hdr);
VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(),ref_atlas_size,ref_atlas_subdiv);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8dec34a4cd..29b18c090b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2593,6 +2593,36 @@ int Viewport::gui_get_canvas_sort_index() {
return gui.canvas_sort_index++;
}
+void Viewport::set_msaa(MSAA p_msaa) {
+
+ ERR_FAIL_INDEX(p_msaa,5);
+ if (msaa==p_msaa)
+ return;
+ msaa=p_msaa;
+ VS::get_singleton()->viewport_set_msaa(viewport,VS::ViewportMSAA(p_msaa));
+}
+
+Viewport::MSAA Viewport::get_msaa() const {
+
+ return msaa;
+}
+
+void Viewport::set_hdr(bool p_hdr) {
+
+ if (hdr==p_hdr)
+ return;
+
+ hdr=p_hdr;
+ VS::get_singleton()->viewport_set_hdr(viewport,p_hdr);
+
+}
+
+bool Viewport::get_hdr() const{
+
+ return hdr;
+}
+
+
void Viewport::_bind_methods() {
@@ -2643,6 +2673,12 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_update_mode","mode"), &Viewport::set_update_mode);
ObjectTypeDB::bind_method(_MD("get_update_mode"), &Viewport::get_update_mode);
+ ObjectTypeDB::bind_method(_MD("set_msaa","msaa"), &Viewport::set_msaa);
+ ObjectTypeDB::bind_method(_MD("get_msaa"), &Viewport::get_msaa);
+
+ ObjectTypeDB::bind_method(_MD("set_hdr","enable"), &Viewport::set_hdr);
+ ObjectTypeDB::bind_method(_MD("get_hdr"), &Viewport::get_hdr);
+
ObjectTypeDB::bind_method(_MD("get_texture:ViewportTexture"), &Viewport::get_texture);
ObjectTypeDB::bind_method(_MD("set_physics_object_picking","enable"), &Viewport::set_physics_object_picking);
@@ -2692,6 +2728,8 @@ void Viewport::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world",PROPERTY_HINT_RESOURCE_TYPE,"World"), _SCS("set_world"), _SCS("get_world") );
// ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"msaa",PROPERTY_HINT_ENUM,"Disabled,2x,4x,8x,16x"), _SCS("set_msaa"), _SCS("get_msaa") );
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"hdr"), _SCS("set_hdr"), _SCS("get_hdr") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_vflip"), _SCS("get_vflip") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/clear_on_new_frame"), _SCS("set_clear_on_new_frame"), _SCS("get_clear_on_new_frame") );
ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_update_mode"), _SCS("get_update_mode") );
@@ -2721,6 +2759,13 @@ void Viewport::_bind_methods() {
BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_256 );
BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_1024 );
BIND_CONSTANT( SHADOW_ATLAS_QUADRANT_SUBDIV_MAX );
+
+ BIND_CONSTANT( MSAA_DISABLED );
+ BIND_CONSTANT( MSAA_2X );
+ BIND_CONSTANT( MSAA_4X );
+ BIND_CONSTANT( MSAA_8X );
+ BIND_CONSTANT( MSAA_16X );
+
}
@@ -2790,7 +2835,8 @@ Viewport::Viewport() {
gui.canvas_sort_index=0;
-
+ msaa=MSAA_DISABLED;
+ hdr=false;
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 462ecff93e..46e88e068e 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -98,6 +98,14 @@ public:
};
+ enum MSAA {
+ MSAA_DISABLED,
+ MSAA_2X,
+ MSAA_4X,
+ MSAA_8X,
+ MSAA_16X,
+ };
+
private:
friend class ViewportTexture;
@@ -188,6 +196,9 @@ friend class ViewportTexture;
int shadow_atlas_size;
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
+ MSAA msaa;
+ bool hdr;
+
struct GUI {
// info used when this is a window
@@ -366,6 +377,12 @@ public:
void set_shadow_atlas_quadrant_subdiv(int p_quadrant,ShadowAtlasQuadrantSubdiv p_subdiv);
ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
+ void set_msaa(MSAA p_msaa);
+ MSAA get_msaa() const;
+
+ void set_hdr(bool p_hdr);
+ bool get_hdr() const;
+
Vector2 get_camera_coords(const Vector2& p_viewport_coords) const;
Vector2 get_camera_rect_size() const;
@@ -410,7 +427,8 @@ public:
};
-VARIANT_ENUM_CAST(Viewport::UpdateMode);
-VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
+VARIANT_ENUM_CAST( Viewport::UpdateMode );
+VARIANT_ENUM_CAST( Viewport::ShadowAtlasQuadrantSubdiv );
+VARIANT_ENUM_CAST( Viewport::MSAA );
#endif
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 1c2620ec9a..26b5def5b5 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -557,6 +557,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<RoomBounds>();
// ObjectTypeDB::register_type<MaterialShaderGraph>();
ObjectTypeDB::register_type<SpatialShader>();
+ ObjectTypeDB::register_type<ParticlesShader>();
ObjectTypeDB::add_compatibility_type("Shader","MaterialShader");
ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedSpatialMaterial");
ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedSpatialMaterial");
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 8889d1b6f8..fd64bfe8fa 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -133,7 +133,7 @@ void Shader::_bind_methods() {
BIND_CONSTANT( MODE_SPATIAL);
BIND_CONSTANT( MODE_CANVAS_ITEM );
- BIND_CONSTANT( MODE_POST_PROCESS );
+ BIND_CONSTANT( MODE_PARTICLES );
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index eddb98333d..4ed50fd61e 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -44,7 +44,7 @@ public:
MODE_SPATIAL,
MODE_CANVAS_ITEM,
- MODE_POST_PROCESS,
+ MODE_PARTICLES,
MODE_MAX
};
private:
@@ -119,6 +119,14 @@ public:
};
+class ParticlesShader : public Shader {
+
+ OBJ_TYPE(ParticlesShader,Shader);
+
+public:
+
+ ParticlesShader() : Shader(MODE_PARTICLES) {};
+};
#endif // SHADER_H
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 7452985522..7c6f6111c2 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -484,6 +484,7 @@ public:
RENDER_TARGET_TRANSPARENT,
RENDER_TARGET_NO_3D,
RENDER_TARGET_NO_SAMPLING,
+ RENDER_TARGET_HDR,
RENDER_TARGET_FLAG_MAX
};
@@ -492,6 +493,7 @@ public:
virtual RID render_target_get_texture(RID p_render_target) const=0;
virtual void render_target_set_flag(RID p_render_target,RenderTargetFlags p_flag,bool p_value)=0;
virtual bool render_target_renedered_in_frame(RID p_render_target)=0;
+ virtual void render_target_set_msaa(RID p_render_target,VS::ViewportMSAA p_msaa)=0;
/* CANVAS SHADOW */
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 4872135e2a..0eb3e0fc5a 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -156,7 +156,25 @@ ShaderTypes::ShaderTypes()
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("light_only");
-
+ /************ PARTICLES **************************/
+
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["COLOR"]=ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["VELOCITY"]=ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["MASS"]=ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["ACTIVE"]=ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RESTART"]=ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["CUSTOM"]=ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TRANSFORM"]=ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"]=ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["LIFETIME"]=ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["DELTA"]=ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["SEED"]=ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["ORIGIN"]=ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["INDEX"]=ShaderLanguage::TYPE_INT;
+
+ shader_modes[VS::SHADER_PARTICLES].modes.insert("billboard");
+ shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_force");
+ shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_velocity");
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index e67c140b2d..300924e3b2 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -919,6 +919,9 @@ public:
BIND3(viewport_set_canvas_layer,RID ,RID ,int )
BIND2(viewport_set_shadow_atlas_size,RID ,int )
BIND3(viewport_set_shadow_atlas_quadrant_subdivision,RID ,int, int )
+ BIND2(viewport_set_msaa,RID ,ViewportMSAA )
+ BIND2(viewport_set_hdr,RID ,bool )
+
/* ENVIRONMENT API */
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index fa2c461f36..558a3e4c23 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -517,6 +517,22 @@ void VisualServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_
}
+void VisualServerViewport::viewport_set_msaa(RID p_viewport,VS::ViewportMSAA p_msaa) {
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ VSG::storage->render_target_set_msaa(viewport->render_target,p_msaa);
+}
+
+void VisualServerViewport::viewport_set_hdr(RID p_viewport,bool p_enabled) {
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ VSG::storage->render_target_set_flag(viewport->render_target,RasterizerStorage::RENDER_TARGET_HDR,p_enabled);
+
+}
bool VisualServerViewport::free(RID p_rid) {
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 2eb0ea4679..3b14ee2b1c 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -137,6 +137,9 @@ public:
void viewport_set_shadow_atlas_size(RID p_viewport,int p_size);
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport,int p_quadrant,int p_subdiv);
+ void viewport_set_msaa(RID p_viewport,VS::ViewportMSAA p_msaa);
+ void viewport_set_hdr(RID p_viewport,bool p_enabled);
+
void draw_viewports();
bool free(RID p_rid);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index f4848ff34e..4f7d0e2ac6 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -152,7 +152,7 @@ public:
SHADER_SPATIAL,
SHADER_CANVAS_ITEM,
- SHADER_LIGHT,
+ SHADER_PARTICLES,
SHADER_MAX
};
@@ -593,6 +593,16 @@ public:
virtual void viewport_set_shadow_atlas_size(RID p_viewport,int p_size)=0;
virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport,int p_quadrant,int p_subdiv)=0;
+ enum ViewportMSAA {
+ VIEWPORT_MSAA_DISABLED,
+ VIEWPORT_MSAA_2X,
+ VIEWPORT_MSAA_4X,
+ VIEWPORT_MSAA_8X,
+ VIEWPORT_MSAA_16X,
+ };
+
+ virtual void viewport_set_msaa(RID p_viewport,ViewportMSAA p_msaa)=0;
+ virtual void viewport_set_hdr(RID p_viewport,bool p_enabled)=0;
/* ENVIRONMENT API */
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index e5e8668df6..282a2748da 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -1823,6 +1823,7 @@ void SpatialEditorViewport::_notification(int p_what) {
surface->update();
}
+ //update shadow atlas if changed
int shadowmap_size = Globals::get_singleton()->get("rendering/shadow_atlas/size");
int atlas_q0 = Globals::get_singleton()->get("rendering/shadow_atlas/quadrant_0_subdiv");
@@ -1830,12 +1831,22 @@ void SpatialEditorViewport::_notification(int p_what) {
int atlas_q2 = Globals::get_singleton()->get("rendering/shadow_atlas/quadrant_2_subdiv");
int atlas_q3 = Globals::get_singleton()->get("rendering/shadow_atlas/quadrant_3_subdiv");
+
viewport->set_shadow_atlas_size(shadowmap_size);
viewport->set_shadow_atlas_quadrant_subdiv(0,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
viewport->set_shadow_atlas_quadrant_subdiv(1,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
viewport->set_shadow_atlas_quadrant_subdiv(2,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
viewport->set_shadow_atlas_quadrant_subdiv(3,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
+ //update msaa if changed
+
+ int msaa_mode = Globals::get_singleton()->get("rendering/antialias/msaa");
+ viewport->set_msaa(Viewport::MSAA(msaa_mode));
+
+ bool hdr = Globals::get_singleton()->get("rendering/dynamic_range/hdr");
+ viewport->set_hdr(hdr);
+
+
}
if (p_what==NOTIFICATION_ENTER_TREE) {