diff options
author | reduz <juan@okamstudio.com> | 2016-12-30 08:35:54 -0300 |
---|---|---|
committer | reduz <juan@okamstudio.com> | 2016-12-30 08:35:54 -0300 |
commit | f4a56e7782526e5e20a4351c4c293a7b4f020acd (patch) | |
tree | 8a08474f43dbd7e2204bc9688619f27532056339 /drivers | |
parent | 289bc881aaec35cc127256137abc7dcf116afd48 (diff) |
begin work on new particle system
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 194 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 86 | ||||
-rw-r--r-- | drivers/gles3/shaders/SCsub | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/particles.glsl | 114 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 10 |
5 files changed, 384 insertions, 21 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 698788316c..3fc0513542 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -4882,37 +4882,45 @@ uint32_t RasterizerStorageGLES3::gi_probe_get_version(RID p_probe) { return gip->version; } -RID RasterizerStorageGLES3::gi_probe_dynamic_data_create(int p_width,int p_height,int p_depth) { +RasterizerStorage::GIProbeCompression RasterizerStorageGLES3::gi_probe_get_dynamic_data_get_preferred_compression() const { + if (config.s3tc_supported) { + return GI_PROBE_S3TC; + } else { + return GI_PROBE_UNCOMPRESSED; + } +} + +RID RasterizerStorageGLES3::gi_probe_dynamic_data_create(int p_width, int p_height, int p_depth, GIProbeCompression p_compression) { GIProbeData *gipd = memnew( GIProbeData ); gipd->width=p_width; gipd->height=p_height; gipd->depth=p_depth; + gipd->compression=p_compression; glActiveTexture(GL_TEXTURE0); glGenTextures(1,&gipd->tex_id); glBindTexture(GL_TEXTURE_3D,gipd->tex_id); int level=0; + int min_size=1; + + if (gipd->compression==GI_PROBE_S3TC) { + min_size=4; + } print_line("dyndata create"); while(true) { - Vector<uint8_t> data; - data.resize(p_width*p_height*p_depth*4); - - - for(int i=0;i<data.size();i+=4) { - - data[i+0]=0xFF; - data[i+1]=0x00; - data[i+2]=0xFF; - data[i+3]=0xFF; + if (gipd->compression==GI_PROBE_S3TC) { + int size = p_width * p_height * p_depth; + glCompressedTexImage3D(GL_TEXTURE_3D,level,_EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT,p_width,p_height,p_depth,0, size,NULL); + } else { + glTexImage3D(GL_TEXTURE_3D,level,GL_RGBA8,p_width,p_height,p_depth,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); } - glTexImage3D(GL_TEXTURE_3D,level,GL_RGBA8,p_width,p_height,p_depth,0,GL_RGBA,GL_UNSIGNED_BYTE,data.ptr()); - if (p_width<=1 || p_height<=1 || p_depth<=1) + if (p_width<=min_size || p_height<=min_size || p_depth<=min_size) break; p_width>>=1; p_height>>=1; @@ -4933,7 +4941,7 @@ RID RasterizerStorageGLES3::gi_probe_dynamic_data_create(int p_width,int p_heigh return gi_probe_data_owner.make_rid(gipd); } -void RasterizerStorageGLES3::gi_probe_dynamic_data_update_rgba8(RID p_gi_probe_data, int p_depth_slice, int p_slice_count, int p_mipmap, const void *p_data) { +void RasterizerStorageGLES3::gi_probe_dynamic_data_update(RID p_gi_probe_data, int p_depth_slice, int p_slice_count, int p_mipmap, const void *p_data) { GIProbeData *gipd = gi_probe_data_owner.getornull(p_gi_probe_data); ERR_FAIL_COND(!gipd); @@ -4957,14 +4965,168 @@ void RasterizerStorageGLES3::gi_probe_dynamic_data_update_rgba8(RID p_gi_probe_d */ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_3D,gipd->tex_id); - glTexSubImage3D(GL_TEXTURE_3D,p_mipmap,0,0,p_depth_slice,gipd->width>>p_mipmap,gipd->height>>p_mipmap,p_slice_count,GL_RGBA,GL_UNSIGNED_BYTE,p_data); + if (gipd->compression==GI_PROBE_S3TC) { + int size = (gipd->width>>p_mipmap) * (gipd->height>>p_mipmap) * p_slice_count; + glCompressedTexSubImage3D(GL_TEXTURE_3D,p_mipmap,0,0,p_depth_slice,gipd->width>>p_mipmap,gipd->height>>p_mipmap,p_slice_count,_EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT,size, p_data); + } else { + glTexSubImage3D(GL_TEXTURE_3D,p_mipmap,0,0,p_depth_slice,gipd->width>>p_mipmap,gipd->height>>p_mipmap,p_slice_count,GL_RGBA,GL_UNSIGNED_BYTE,p_data); + } //glTexImage3D(GL_TEXTURE_3D,p_mipmap,GL_RGBA8,gipd->width>>p_mipmap,gipd->height>>p_mipmap,gipd->depth>>p_mipmap,0,GL_RGBA,GL_UNSIGNED_BYTE,p_data); //glTexImage3D(GL_TEXTURE_3D,p_mipmap,GL_RGBA8,gipd->width>>p_mipmap,gipd->height>>p_mipmap,gipd->depth>>p_mipmap,0,GL_RGBA,GL_UNSIGNED_BYTE,data.ptr()); - print_line("update rgba8 "+itos(p_mipmap)); + +} + +/////// + + +RID RasterizerStorageGLES3::particles_create() { + + Particles *particles = memnew( Particles ); + + + return particles_owner.make_rid(particles); +} + +void RasterizerStorageGLES3::particles_set_emitting(RID p_particles,bool p_emitting) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->emitting=p_emitting; + +} +void RasterizerStorageGLES3::particles_set_amount(RID p_particles,int p_amount) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + +} +void RasterizerStorageGLES3::particles_set_lifetime(RID p_particles,float p_lifetime){ + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->lifetime=p_lifetime; +} +void RasterizerStorageGLES3::particles_set_pre_process_time(RID p_particles,float p_time) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->pre_process_time=p_time; + +} +void RasterizerStorageGLES3::particles_set_explosiveness_ratio(RID p_particles,float p_ratio) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->explosiveness=p_ratio; +} +void RasterizerStorageGLES3::particles_set_randomness_ratio(RID p_particles,float p_ratio) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->randomness=p_ratio; + +} +void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles,const AABB& p_aabb) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->custom_aabb=p_aabb; + } +void RasterizerStorageGLES3::particles_set_gravity(RID p_particles,const Vector3& p_gravity) { + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->gravity=p_gravity; + +} +void RasterizerStorageGLES3::particles_set_use_local_coordinates(RID p_particles,bool p_enable) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->use_local_coords=p_enable; +} +void RasterizerStorageGLES3::particles_set_process_material(RID p_particles,RID p_material) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->process_material=p_material; +} + +void RasterizerStorageGLES3::particles_set_emission_shape(RID p_particles, VS::ParticlesEmissionShape p_shape) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->emission_shape=p_shape; +} +void RasterizerStorageGLES3::particles_set_emission_sphere_radius(RID p_particles,float p_radius) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->emission_sphere_radius=p_radius; +} +void RasterizerStorageGLES3::particles_set_emission_box_extents(RID p_particles,const Vector3& p_extents) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->emission_box_extents=p_extents; +} +void RasterizerStorageGLES3::particles_set_emission_points(RID p_particles,const DVector<Vector3>& p_points) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->emission_points=p_points; +} + + +void RasterizerStorageGLES3::particles_set_draw_order(RID p_particles,VS::ParticlesDrawOrder p_order) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->draw_order=p_order; +} + +void RasterizerStorageGLES3::particles_set_draw_passes(RID p_particles,int p_count) { + + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + + particles->draw_passes.resize(p_count); +} +void RasterizerStorageGLES3::particles_set_draw_pass_material(RID p_particles,int p_pass, RID p_material) { + + 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; + +} +void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles,int p_pass, RID p_mesh) { + + 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; + +} + +AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { + + const Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles,AABB()); + + return particles->computed_aabb; +} +//////// void RasterizerStorageGLES3::instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance) { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 5a8246f030..b0f9800159 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -941,6 +941,7 @@ public: int depth; int levels; GLuint tex_id; + GIProbeCompression compression; GIProbeData() { } @@ -948,9 +949,90 @@ public: mutable RID_Owner<GIProbeData> gi_probe_data_owner; - virtual RID gi_probe_dynamic_data_create(int p_width,int p_height,int p_depth); - virtual void gi_probe_dynamic_data_update_rgba8(RID p_gi_probe_data,int p_depth_slice,int p_slice_count,int p_mipmap,const void* p_data); + virtual GIProbeCompression gi_probe_get_dynamic_data_get_preferred_compression() const; + virtual RID gi_probe_dynamic_data_create(int p_width,int p_height,int p_depth,GIProbeCompression p_compression); + virtual void gi_probe_dynamic_data_update(RID p_gi_probe_data,int p_depth_slice,int p_slice_count,int p_mipmap,const void* p_data); + /* PARTICLES */ + + struct Particles : public Instantiable { + + bool emitting; + int amount; + float lifetime; + float pre_process_time; + float explosiveness; + float randomness; + AABB custom_aabb; + Vector3 gravity; + bool use_local_coords; + RID process_material; + + VS::ParticlesEmissionShape emission_shape; + float emission_sphere_radius; + Vector3 emission_box_extents; + DVector<Vector3> emission_points; + GLuint emission_point_texture; + + VS::ParticlesDrawOrder draw_order; + struct DrawPass { + RID mesh; + RID material; + }; + + Vector<DrawPass> draw_passes; + + AABB computed_aabb; + + Particles() { + emitting=false; + amount=0; + lifetime=1.0;; + pre_process_time=0.0; + explosiveness=0.0; + randomness=0.0; + use_local_coords=true; + + 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; + } + + }; + + mutable RID_Owner<Particles> particles_owner; + + virtual RID particles_create(); + + virtual void particles_set_emitting(RID p_particles,bool p_emitting); + virtual void particles_set_amount(RID p_particles,int p_amount); + virtual void particles_set_lifetime(RID p_particles,float p_lifetime); + virtual void particles_set_pre_process_time(RID p_particles,float p_time); + virtual void particles_set_explosiveness_ratio(RID p_particles,float p_ratio); + virtual void particles_set_randomness_ratio(RID p_particles,float p_ratio); + virtual void particles_set_custom_aabb(RID p_particles,const AABB& p_aabb); + virtual void particles_set_gravity(RID p_particles,const Vector3& p_gravity); + virtual void particles_set_use_local_coordinates(RID p_particles,bool p_enable); + virtual void particles_set_process_material(RID p_particles,RID p_material); + + virtual void particles_set_emission_shape(RID p_particles,VS::ParticlesEmissionShape p_shape); + virtual void particles_set_emission_sphere_radius(RID p_particles,float p_radius); + virtual void particles_set_emission_box_extents(RID p_particles,const Vector3& p_extents); + virtual void particles_set_emission_points(RID p_particles,const DVector<Vector3>& p_points); + + + virtual void particles_set_draw_order(RID p_particles,VS::ParticlesDrawOrder p_order); + + virtual void particles_set_draw_passes(RID p_particles,int p_count); + virtual void particles_set_draw_pass_material(RID p_particles,int p_pass, RID p_material); + virtual void particles_set_draw_pass_mesh(RID p_particles,int p_pass, RID p_mesh); + + virtual AABB particles_get_current_aabb(RID p_particles); + + /* INSTANCE */ virtual void instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance); virtual void instance_remove_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance); diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub index 272f9bb5e1..f9baeae97d 100644 --- a/drivers/gles3/shaders/SCsub +++ b/drivers/gles3/shaders/SCsub @@ -17,5 +17,6 @@ if env['BUILDERS'].has_key('GLES3_GLSL'): env.GLES3_GLSL('ssao_blur.glsl'); env.GLES3_GLSL('exposure.glsl'); env.GLES3_GLSL('tonemap.glsl'); + env.GLES3_GLSL('particles.glsl'); diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl new file mode 100644 index 0000000000..fb6060957e --- /dev/null +++ b/drivers/gles3/shaders/particles.glsl @@ -0,0 +1,114 @@ +[vertex] + + + +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; + + +struct Attractor { + + vec3 pos; + vec3 dir; + float radius; + float eat_radius; + float strength; + float attenuation; +}; + +#define MAX_ATTRACTORS 64 + +uniform mat4 origin; +uniform float system_phase; +uniform float prev_system_phase; +uniform float total_particles; +uniform float explosiveness; +uniform vec4 time; +uniform float delta; +uniform vec3 gravity; +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: + +void main() { + + bool apply_forces=true; + bool apply_velocity=true; + + float mass = 1.0; + + float restart_phase = float(gl_InstanceID)/total_particles; + restart_phase*= explosiveness; + bool restart=false; + + if (system_phase > prev_system_phase) { + restart = prev_system_phase < restart_phase && system_phase >= restart_phase; + } else { + restart = prev_system_phase < restart_phase || system_phase >= restart_phase; + } + + if (restart) { + out_rot_active.a=1.0; + } + + out_pos_lifetime=pos_lifetime; + out_color=color; + out_velocity_seed=velocity_seed; + out_rot_active=rot_active; + + if (out_rot_active.a) { + //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; + + } + } + + out_velocity_seed.xyz += force * delta; + } + + if (apply_velocity) { + + out_pos_lifetime.xyz += out_velocity_seed.xyz * delta; + } + +} + +[fragment] + + +void main() { + + +} diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index b0b2782307..90c501ea32 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -899,8 +899,10 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z)); blend=1.0; + float max_distance = length(bounds); + //radiance -#ifdef VCT_QUALITY_HIGH +#ifndef VCT_QUALITY_HIGH #define MAX_CONE_DIRS 6 vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] ( @@ -914,6 +916,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15); float cone_angle_tan = 0.577; + float min_ref_tan = 0.0; #else #define MAX_CONE_DIRS 4 @@ -927,9 +930,10 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.25, 0.25, 0.25); float cone_angle_tan = 0.98269; + max_distance*=0.5; + float min_ref_tan = 0.2; #endif - float max_distance = length(bounds); vec3 light=vec3(0.0); for(int i=0;i<MAX_CONE_DIRS;i++) { @@ -944,7 +948,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s //irradiance - vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,tan(roughness * 0.5 * M_PI) ,max_distance); + vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,max(min_ref_tan,tan(roughness * 0.5 * M_PI)) ,max_distance); irr_light *= multiplier; //irr_light=vec3(0.0); |