Godot Engine 3.1.2 这篇文章中提到 Godot Engine的未来版本中粒子系统将支持外力 ,看了一下当前版本中自动生成的ParticlesShader
,其实Gravity
就已经算是外力了,把它简单改一下实现了下面的效果,其实就是实时修改这个外力的方向。
这段Shader代码基本上都是自动生成的
shader_type particles;
uniform float spread;
uniform float flatness;
uniform float initial_linear_velocity;
uniform float initial_angle;
uniform float angular_velocity;
uniform float orbit_velocity;
uniform float linear_accel;
uniform float radial_accel;
uniform float tangent_accel;
uniform float damping;
uniform float scale;
uniform float hue_variation;
uniform float anim_speed;
uniform float anim_offset;
uniform float initial_linear_velocity_random;
uniform float initial_angle_random;
uniform float angular_velocity_random;
uniform float orbit_velocity_random;
uniform float linear_accel_random;
uniform float radial_accel_random;
uniform float tangent_accel_random;
uniform float damping_random;
uniform float scale_random;
uniform float hue_variation_random;
uniform float anim_speed_random;
uniform float anim_offset_random;
uniform vec4 color_value : hint_color;
uniform int trail_divisor;
uniform vec3 external_force;
float rand_from_seed(inout uint seed) {
int k;
int s = int(seed);
if (s == 0)
s = 305420679;
k = s / 127773;
s = 16807 * (s - k * 127773) - 2836 * k;
if (s > uint(16)) ^ x) * uint(73244475);
x = ((x >> uint(16)) ^ x) * uint(73244475);
x = (x >> uint(16)) ^ x;
return x;
}
void vertex() {
uint base_number = NUMBER / uint(trail_divisor);
uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);
float angle_rand = rand_from_seed(alt_seed);
float scale_rand = rand_from_seed(alt_seed);
float hue_rot_rand = rand_from_seed(alt_seed);
float anim_offset_rand = rand_from_seed(alt_seed);
float pi = 3.14159;
float degree_to_rad = pi / 180.0;
if (RESTART) {
float tex_linear_velocity = 0.0;
float tex_angle = 0.0;
float tex_anim_offset = 0.0;
float spread_rad = spread * degree_to_rad;
float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;
float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);
vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));
vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));
direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution
vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);
direction = normalize(direction);
VELOCITY = direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);
float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);
CUSTOM.x = base_angle * degree_to_rad;
CUSTOM.y = 0.0;
CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random);
VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;
TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;
} else {
CUSTOM.y += DELTA / LIFETIME;
float tex_linear_velocity = 0.0;
float tex_angular_velocity = 0.0;
float tex_linear_accel = 0.0;
float tex_radial_accel = 0.0;
float tex_tangent_accel = 0.0;
float tex_damping = 0.0;
float tex_angle = 0.0;
float tex_anim_speed = 0.0;
float tex_anim_offset = 0.0;
vec3 pos = TRANSFORM[3].xyz;
// apply linear acceleration
vec3 force = external_force;
force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel + tex_linear_accel) * mix(1.0, rand_from_seed(alt_seed), linear_accel_random) : vec3(0.0);
// apply radial acceleration
vec3 org = EMISSION_TRANSFORM[3].xyz;
vec3 diff = pos - org;
force += length(diff) > 0.0 ? normalize(diff) * (radial_accel + tex_radial_accel) * mix(1.0, rand_from_seed(alt_seed), radial_accel_random) : vec3(0.0);
// apply tangential acceleration;
vec3 crossDiff = cross(normalize(diff), normalize(external_force));
force += length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);
// apply attractor forces
VELOCITY += force * DELTA;
// orbit velocity
if (damping + tex_damping > 0.0) {
float v = length(VELOCITY);
float damp = (damping + tex_damping) * mix(1.0, rand_from_seed(alt_seed), damping_random);
v -= damp * DELTA;
if (v
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?