Skip to content

Commit

Permalink
feat: add particle y-billboard option to standard shader
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnklit committed Feb 8, 2024
1 parent a010660 commit 843a66a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 20 deletions.
4 changes: 2 additions & 2 deletions scene/3d/cpu_particles_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,13 @@ PackedStringArray CPUParticles3D::get_configuration_warnings() const {
for (int j = 0; j < get_mesh()->get_surface_count(); j++) {
anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != nullptr;
StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_mesh()->surface_get_material(j).ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES) || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES_Y);
}
}

anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != nullptr;
StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_material_override().ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES) || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES_Y);

if (!mesh_found) {
warnings.push_back(RTR("Nothing is visible because no mesh has been assigned."));
Expand Down
4 changes: 2 additions & 2 deletions scene/3d/gpu_particles_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ PackedStringArray GPUParticles3D::get_configuration_warnings() const {
for (int j = 0; j < draw_passes[i]->get_surface_count(); j++) {
anim_material_found = Object::cast_to<ShaderMaterial>(draw_passes[i]->surface_get_material(j).ptr()) != nullptr;
BaseMaterial3D *spat = Object::cast_to<BaseMaterial3D>(draw_passes[i]->surface_get_material(j).ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES) || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES_Y);
}
if (anim_material_found) {
break;
Expand All @@ -319,7 +319,7 @@ PackedStringArray GPUParticles3D::get_configuration_warnings() const {
anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != nullptr;
{
BaseMaterial3D *spat = Object::cast_to<BaseMaterial3D>(get_material_override().ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == BaseMaterial3D::BILLBOARD_PARTICLES);
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == BaseMaterial3D::BILLBOARD_PARTICLES) || (spat && spat->get_billboard_mode() == BaseMaterial3D::BILLBOARD_PARTICLES_Y);
}

if (!meshes_found) {
Expand Down
44 changes: 28 additions & 16 deletions scene/resources/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ void BaseMaterial3D::_update_shader() {
code += "uniform sampler2D texture_orm : hint_roughness_g," + texfilter_str + ";\n";
}

if (billboard_mode == BILLBOARD_PARTICLES) {
if (billboard_mode == BILLBOARD_PARTICLES || billboard_mode == BILLBOARD_PARTICLES_Y) {
code += "uniform int particles_anim_h_frames;\n";
code += "uniform int particles_anim_v_frames;\n";
code += "uniform bool particles_anim_loop;\n";
Expand Down Expand Up @@ -1018,24 +1018,36 @@ void BaseMaterial3D::_update_shader() {
}
//set modelview normal
code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n";

//handle animation
code += " float h_frames = float(particles_anim_h_frames);\n";
code += " float v_frames = float(particles_anim_v_frames);\n";
code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n";
code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
code += " if (!particles_anim_loop) {\n";
code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n";
code += " } else {\n";
code += " particle_frame = mod(particle_frame, particle_total_frames);\n";
code += " }\n";
code += " UV /= vec2(h_frames, v_frames);\n";
code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor((particle_frame + 0.5) / h_frames) / v_frames);\n";
} break;
case BILLBOARD_PARTICLES_Y: {
code += " mat4 mat_world = mat4(vec4(normalize(cross(MODEL_MATRIX[1].xyz, INV_VIEW_MATRIX[2].xyz)), 0.0), MODEL_MATRIX[1], vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, MODEL_MATRIX[1].xyz)), 0.0), MODEL_MATRIX[3]);\n";
code += " mat_world = mat_world * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat_world;\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
}
//set modelview normal
code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n";
} break;
case BILLBOARD_MAX:
break; // Internal value, skip.
}

if (billboard_mode == BILLBOARD_PARTICLES || billboard_mode == BILLBOARD_PARTICLES_Y) {
//handle animation
code += " float h_frames = float(particles_anim_h_frames);\n";
code += " float v_frames = float(particles_anim_v_frames);\n";
code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n";
code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n";
code += " if (!particles_anim_loop) {\n";
code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n";
code += " } else {\n";
code += " particle_frame = mod(particle_frame, particle_total_frames);\n";
code += " }\n";
code += " UV /= vec2(h_frames, v_frames);\n";
code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor((particle_frame + 0.5) / h_frames) / v_frames);\n";
}

if (flags[FLAG_FIXED_SIZE]) {
code += " if (PROJECTION_MATRIX[3][3] != 0.0) {\n";
//orthogonal matrix, try to do about the same
Expand Down Expand Up @@ -1989,7 +2001,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &p_property) const {
p_property.usage = PROPERTY_USAGE_NONE;
}

if (p_property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
if (p_property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES && billboard_mode != BILLBOARD_PARTICLES_Y) {
p_property.usage = PROPERTY_USAGE_NONE;
}

Expand Down Expand Up @@ -2872,7 +2884,7 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY);

ADD_GROUP("Billboard", "billboard_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard,Particle Y-Billboard"), "set_billboard_mode", "get_billboard_mode");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE);

ADD_GROUP("Particles Anim", "particles_anim_");
Expand Down
1 change: 1 addition & 0 deletions scene/resources/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class BaseMaterial3D : public Material {
BILLBOARD_ENABLED,
BILLBOARD_FIXED_Y,
BILLBOARD_PARTICLES,
BILLBOARD_PARTICLES_Y,
BILLBOARD_MAX
};

Expand Down

0 comments on commit 843a66a

Please sign in to comment.