WIP particle system

Ability to enable and change MSAA settings
Ability to change VCT quality
Ability to enable/disable HDR rendering
This commit is contained in:
Juan Linietsky 2017-01-01 22:16:52 -03:00
parent a62c99c4e4
commit c2a217c350
22 changed files with 677 additions and 164 deletions

View file

@ -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){

View file

@ -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);
//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(){

View file

@ -53,7 +53,6 @@ public:
Vector<RasterizerStorageGLES3::RenderTarget::Exposure> exposure_shrink;
int exposure_shrink_size;
struct State {

View file

@ -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);
// effect resolver
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);
//alpha fbo
glGenFramebuffers(1, &rt->buffers.alpha_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.alpha_fbo);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("err status: %x\n",status);
_render_target_clear(rt);
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
}
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, rt->depth, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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
}
if (apply_forces) {
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;
}
rel_vec = normalize(rel_vec);
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;
}
{
VERTEX_SHADER_CODE
}
out_velocity_seed.xyz += force * delta;
#if !defined(DISABLE_FORCE)
{
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) {
out_velocity_active.a=0.0;
}
rel_vec = normalize(rel_vec);
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;
}
}
out_velocity_seed.xyz += force * delta;
}
#endif
#if !defined(DISABLE_VELOCITY)
{
out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
}
#endif
}
if (apply_velocity) {
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];
out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
}
}
[fragment]
//any code here is never executed, stuff is filled just so it works
FRAGMENT_SHADER_GLOBALS
#if defined(USE_MATERIAL)
layout(std140) uniform UniformData {
MATERIAL_UNIFORMS
};
#endif
void main() {
{
FRAGMENT_SHADER_CODE
}
}

View file

@ -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

View file

@ -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:

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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");

View file

@ -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 );
}

View file

@ -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

View file

@ -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 */

View file

@ -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");

View file

@ -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 */

View file

@ -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) {

View file

@ -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);

View file

@ -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 */

View file

@ -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) {