Continuation of work on visual particles system

This commit is contained in:
Yuri Roubinsky 2020-09-15 10:57:40 +03:00
parent 3041becc64
commit f632e36ae5
19 changed files with 1870 additions and 162 deletions

View file

@ -222,15 +222,19 @@
<constant name="TYPE_LIGHT" value="2" enum="Type">
A shader for light calculations.
</constant>
<constant name="TYPE_EMIT" value="3" enum="Type">
<constant name="TYPE_START" value="3" enum="Type">
</constant>
<constant name="TYPE_PROCESS" value="4" enum="Type">
</constant>
<constant name="TYPE_END" value="5" enum="Type">
<constant name="TYPE_COLLIDE" value="5" enum="Type">
</constant>
<constant name="TYPE_SKY" value="6" enum="Type">
<constant name="TYPE_START_CUSTOM" value="6" enum="Type">
</constant>
<constant name="TYPE_MAX" value="7" enum="Type">
<constant name="TYPE_PROCESS_CUSTOM" value="7" enum="Type">
</constant>
<constant name="TYPE_SKY" value="8" enum="Type">
</constant>
<constant name="TYPE_MAX" value="9" enum="Type">
Represents the size of the [enum Type] enum.
</constant>
<constant name="NODE_ID_INVALID" value="-1">

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleAccelerator" inherits="VisualShaderNodeOutput" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="VisualShaderNodeParticleAccelerator.Mode" default="0">
</member>
</members>
<constants>
<constant name="MODE_LINEAR" value="0" enum="Mode">
</constant>
<constant name="MODE_RADIAL" value="1" enum="Mode">
</constant>
<constant name="MODE_TANGENTIAL" value="2" enum="Mode">
</constant>
<constant name="MODE_MAX" value="3" enum="Mode">
</constant>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleBoxEmitter" inherits="VisualShaderNodeParticleEmitter" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleConeVelocity" inherits="VisualShaderNode" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleEmit" inherits="VisualShaderNode" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="flags" type="int" setter="set_flags" getter="get_flags" enum="VisualShaderNodeParticleEmit.EmitFlags" default="31">
</member>
</members>
<constants>
<constant name="EMIT_FLAG_POSITION" value="1" enum="EmitFlags">
</constant>
<constant name="EMIT_FLAG_ROT_SCALE" value="2" enum="EmitFlags">
</constant>
<constant name="EMIT_FLAG_VELOCITY" value="4" enum="EmitFlags">
</constant>
<constant name="EMIT_FLAG_COLOR" value="8" enum="EmitFlags">
</constant>
<constant name="EMIT_FLAG_CUSTOM" value="16" enum="EmitFlags">
</constant>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleEmitter" inherits="VisualShaderNode" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleMultiplyByAxisAngle" inherits="VisualShaderNode" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="degrees_mode" type="bool" setter="set_degrees_mode" getter="is_degrees_mode" default="true">
</member>
</members>
<constants>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleOutput" inherits="VisualShaderNodeOutput" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleRandomness" inherits="VisualShaderNode" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeParticleRandomness.OpType" default="0">
</member>
</members>
<constants>
<constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
</constant>
<constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
</constant>
<constant name="OP_TYPE_MAX" value="2" enum="OpType">
</constant>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleRingEmitter" inherits="VisualShaderNodeParticleEmitter" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeParticleSphereEmitter" inherits="VisualShaderNodeParticleEmitter" version="4.0">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -44,6 +44,7 @@
#include "scene/gui/panel.h"
#include "scene/main/window.h"
#include "scene/resources/visual_shader_nodes.h"
#include "scene/resources/visual_shader_particle_nodes.h"
#include "scene/resources/visual_shader_sdf_nodes.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_types.h"
@ -417,6 +418,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
}
}
Ref<VisualShaderNodeParticleEmit> emit = vsnode;
if (emit.is_valid()) {
node->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
}
Ref<VisualShaderNodeUniform> uniform = vsnode;
if (uniform.is_valid()) {
VisualShaderEditor::get_singleton()->graph->add_child(node);
@ -1013,13 +1019,13 @@ bool VisualShaderEditor::_is_available(int p_mode) {
if (p_mode != -1) {
switch (current_mode) {
case 0: // Vertex or Emit
case 0: // Vertex / Emit
current_mode = 1;
break;
case 1: // Fragment or Process
case 1: // Fragment / Process
current_mode = 2;
break;
case 2: // Light or End
case 2: // Light / Collide
current_mode = 4;
break;
default:
@ -1235,22 +1241,29 @@ void VisualShaderEditor::_update_options_menu() {
void VisualShaderEditor::_set_mode(int p_which) {
if (p_which == VisualShader::MODE_SKY) {
edit_type_standart->set_visible(false);
edit_type_standard->set_visible(false);
edit_type_particles->set_visible(false);
edit_type_sky->set_visible(true);
edit_type = edit_type_sky;
custom_mode_box->set_visible(false);
mode = MODE_FLAGS_SKY;
} else if (p_which == VisualShader::MODE_PARTICLES) {
edit_type_standart->set_visible(false);
edit_type_standard->set_visible(false);
edit_type_particles->set_visible(true);
edit_type_sky->set_visible(false);
edit_type = edit_type_particles;
if ((edit_type->get_selected() + 3) > VisualShader::TYPE_PROCESS) {
custom_mode_box->set_visible(false);
} else {
custom_mode_box->set_visible(true);
}
mode = MODE_FLAGS_PARTICLES;
} else {
edit_type_particles->set_visible(false);
edit_type_standart->set_visible(true);
edit_type_standard->set_visible(true);
edit_type_sky->set_visible(false);
edit_type = edit_type_standart;
edit_type = edit_type_standard;
custom_mode_box->set_visible(false);
mode = MODE_FLAGS_SPATIAL_CANVASITEM;
}
visual_shader->set_shader_type(get_current_shader_type());
@ -1403,9 +1416,9 @@ void VisualShaderEditor::_update_graph() {
VisualShader::Type VisualShaderEditor::get_current_shader_type() const {
VisualShader::Type type;
if (mode & MODE_FLAGS_PARTICLES) {
type = VisualShader::Type(edit_type->get_selected() + 3);
type = VisualShader::Type(edit_type->get_selected() + 3 + (custom_mode_enabled ? 3 : 0));
} else if (mode & MODE_FLAGS_SKY) {
type = VisualShader::Type(edit_type->get_selected() + 6);
type = VisualShader::Type(edit_type->get_selected() + 8);
} else {
type = VisualShader::Type(edit_type->get_selected());
}
@ -3224,8 +3237,18 @@ void VisualShaderEditor::_mode_selected(int p_id) {
int offset = 0;
if (mode & MODE_FLAGS_PARTICLES) {
offset = 3;
if (p_id + offset > VisualShader::TYPE_PROCESS) {
custom_mode_box->set_visible(false);
custom_mode_enabled = false;
} else {
custom_mode_box->set_visible(true);
if (custom_mode_box->is_pressed()) {
custom_mode_enabled = true;
offset += 3;
}
}
} else if (mode & MODE_FLAGS_SKY) {
offset = 6;
offset = 8;
}
visual_shader->set_shader_type(VisualShader::Type(p_id + offset));
@ -3233,6 +3256,21 @@ void VisualShaderEditor::_mode_selected(int p_id) {
_update_graph();
}
void VisualShaderEditor::_custom_mode_toggled(bool p_enabled) {
if (!(mode & MODE_FLAGS_PARTICLES)) {
return;
}
custom_mode_enabled = p_enabled;
int id = edit_type->get_selected() + 3;
if (p_enabled) {
visual_shader->set_shader_type(VisualShader::Type(id + 3));
} else {
visual_shader->set_shader_type(VisualShader::Type(id));
}
_update_options_menu();
_update_graph();
}
void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, String p_name) {
String prev_name = p_input->get_input_name();
@ -3731,17 +3769,23 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->add_child(vs);
graph->get_zoom_hbox()->move_child(vs, 0);
edit_type_standart = memnew(OptionButton);
edit_type_standart->add_item(TTR("Vertex"));
edit_type_standart->add_item(TTR("Fragment"));
edit_type_standart->add_item(TTR("Light"));
edit_type_standart->select(1);
edit_type_standart->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
custom_mode_box = memnew(CheckBox);
custom_mode_box->set_text(TTR("Custom"));
custom_mode_box->set_pressed(false);
custom_mode_box->set_visible(false);
custom_mode_box->connect("toggled", callable_mp(this, &VisualShaderEditor::_custom_mode_toggled));
edit_type_standard = memnew(OptionButton);
edit_type_standard->add_item(TTR("Vertex"));
edit_type_standard->add_item(TTR("Fragment"));
edit_type_standard->add_item(TTR("Light"));
edit_type_standard->select(1);
edit_type_standard->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
edit_type_particles = memnew(OptionButton);
edit_type_particles->add_item(TTR("Emit"));
edit_type_particles->add_item(TTR("Start"));
edit_type_particles->add_item(TTR("Process"));
edit_type_particles->add_item(TTR("End"));
edit_type_particles->add_item(TTR("Collide"));
edit_type_particles->select(0);
edit_type_particles->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
@ -3750,14 +3794,16 @@ VisualShaderEditor::VisualShaderEditor() {
edit_type_sky->select(0);
edit_type_sky->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
edit_type = edit_type_standart;
edit_type = edit_type_standard;
graph->get_zoom_hbox()->add_child(custom_mode_box);
graph->get_zoom_hbox()->move_child(custom_mode_box, 0);
graph->get_zoom_hbox()->add_child(edit_type_standard);
graph->get_zoom_hbox()->move_child(edit_type_standard, 0);
graph->get_zoom_hbox()->add_child(edit_type_particles);
graph->get_zoom_hbox()->move_child(edit_type_particles, 0);
graph->get_zoom_hbox()->add_child(edit_type_sky);
graph->get_zoom_hbox()->move_child(edit_type_sky, 0);
graph->get_zoom_hbox()->add_child(edit_type_standart);
graph->get_zoom_hbox()->move_child(edit_type_standart, 0);
add_node = memnew(Button);
add_node->set_flat(true);
@ -3977,9 +4023,10 @@ VisualShaderEditor::VisualShaderEditor() {
// INPUT
const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes.");
// SPATIAL-FOR-ALL
const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes.");
add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
@ -3998,6 +4045,23 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
// PARTICLES-FOR-ALL
add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), "attractor_force", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Index", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("LifeTime", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
/////////////////
add_options.push_back(AddOption("Input", "Input", "Common", "VisualShaderNodeInput", TTR("Input parameter.")));
@ -4010,11 +4074,12 @@ VisualShaderEditor::VisualShaderEditor() {
const String input_param_for_sky_shader_mode = TTR("'%s' input parameter for sky shader mode.");
const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode.");
const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode.");
const String input_param_for_emit_shader_mode = TTR("'%s' input parameter for emit shader mode.");
const String input_param_for_start_shader_mode = TTR("'%s' input parameter for start shader mode.");
const String input_param_for_process_shader_mode = TTR("'%s' input parameter for process shader mode.");
const String input_param_for_end_shader_mode = TTR("'%s' input parameter for end shader mode.");
const String input_param_for_emit_and_process_shader_mode = TTR("'%s' input parameter for emit and process shader mode.");
const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode.");
const String input_param_for_collide_shader_mode = TTR("'%s' input parameter for collide shader mode.");
const String input_param_for_start_and_process_shader_mode = TTR("'%s' input parameter for start and process shader modes.");
const String input_param_for_process_and_collide_shader_mode = TTR("'%s' input parameter for process and collide shader modes.");
const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader modes.");
add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
@ -4091,50 +4156,6 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
// PARTICLES INPUTS
add_options.push_back(AddOption("Active", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Alpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Color", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Custom", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CustomAlpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Delta", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("EmissionTransform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Index", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("LifeTime", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Restart", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Time", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Transform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Velocity", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Active", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Alpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Color", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Custom", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CustomAlpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Delta", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("EmissionTransform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Index", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("LifeTime", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Restart", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Time", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Transform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Velocity", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Active", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Alpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Color", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Custom", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CustomAlpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Delta", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("EmissionTransform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Index", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("LifeTime", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Restart", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Time", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Transform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("Velocity", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
// SKY INPUTS
add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
@ -4167,6 +4188,22 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("SkyCoords", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Time", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
// PARTICLES
add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), "collision_depth", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), "collision_normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", -1, -1, -1, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", "A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters.", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
// SCALAR
add_options.push_back(AddOption("FloatFunc", "Scalar", "Common", "VisualShaderNodeFloatFunc", TTR("Float function."), -1, VisualShaderNode::PORT_TYPE_SCALAR));

View file

@ -142,9 +142,11 @@ class VisualShaderEditor : public VBoxContainer {
Button *preview_shader;
OptionButton *edit_type = nullptr;
OptionButton *edit_type_standart;
OptionButton *edit_type_standard;
OptionButton *edit_type_particles;
OptionButton *edit_type_sky;
CheckBox *custom_mode_box;
bool custom_mode_enabled = false;
bool pending_update_preview;
bool shader_error;
@ -189,7 +191,9 @@ class VisualShaderEditor : public VBoxContainer {
enum ParticlesTypeFlags {
TYPE_FLAGS_EMIT = 1,
TYPE_FLAGS_PROCESS = 2,
TYPE_FLAGS_END = 4
TYPE_FLAGS_COLLIDE = 4,
TYPE_FLAGS_EMIT_CUSTOM = 8,
TYPE_FLAGS_PROCESS_CUSTOM = 16,
};
enum SkyTypeFlags {
@ -385,6 +389,7 @@ class VisualShaderEditor : public VBoxContainer {
Ref<VisualShaderGraphPlugin> graph_plugin;
void _mode_selected(int p_id);
void _custom_mode_toggled(bool p_enabled);
void _input_select_item(Ref<VisualShaderNodeInput> input, String name);
void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name);

View file

@ -183,6 +183,7 @@
#include "scene/resources/video_stream.h"
#include "scene/resources/visual_shader.h"
#include "scene/resources/visual_shader_nodes.h"
#include "scene/resources/visual_shader_particle_nodes.h"
#include "scene/resources/visual_shader_sdf_nodes.h"
#include "scene/resources/world_2d.h"
#include "scene/resources/world_3d.h"
@ -613,6 +614,17 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTextureSDFNormal>();
ClassDB::register_class<VisualShaderNodeSDFRaymarch>();
ClassDB::register_class<VisualShaderNodeParticleOutput>();
ClassDB::register_virtual_class<VisualShaderNodeParticleEmitter>();
ClassDB::register_class<VisualShaderNodeParticleSphereEmitter>();
ClassDB::register_class<VisualShaderNodeParticleBoxEmitter>();
ClassDB::register_class<VisualShaderNodeParticleRingEmitter>();
ClassDB::register_class<VisualShaderNodeParticleMultiplyByAxisAngle>();
ClassDB::register_class<VisualShaderNodeParticleConeVelocity>();
ClassDB::register_class<VisualShaderNodeParticleRandomness>();
ClassDB::register_class<VisualShaderNodeParticleAccelerator>();
ClassDB::register_class<VisualShaderNodeParticleEmit>();
ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
ClassDB::register_class<CanvasTexture>();

View file

@ -33,6 +33,7 @@
#include "core/templates/vmap.h"
#include "servers/rendering/shader_types.h"
#include "visual_shader_nodes.h"
#include "visual_shader_particle_nodes.h"
#include "visual_shader_sdf_nodes.h"
bool VisualShaderNode::is_simple_decl() const {
@ -1079,9 +1080,11 @@ static const char *type_string[VisualShader::TYPE_MAX] = {
"vertex",
"fragment",
"light",
"emit",
"start",
"process",
"end",
"collide",
"start_custom",
"process_custom",
"sky",
};
@ -1357,7 +1360,8 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
return OK;
}
code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n";
String node_name = "// " + vsnode->get_caption() + ":" + itos(node) + "\n";
String node_code;
Vector<String> input_vars;
input_vars.resize(vsnode->get_input_port_count());
@ -1428,19 +1432,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
if (defval.get_type() == Variant::FLOAT) {
float val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
node_code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n";
} else if (defval.get_type() == Variant::INT) {
int val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
code += "\tint " + inputs[i] + " = " + itos(val) + ";\n";
node_code += "\tint " + inputs[i] + " = " + itos(val) + ";\n";
} else if (defval.get_type() == Variant::BOOL) {
bool val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
node_code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
} else if (defval.get_type() == Variant::VECTOR3) {
Vector3 val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z);
node_code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z);
} else if (defval.get_type() == Variant::TRANSFORM3D) {
Transform3D val = defval;
val.basis.transpose();
@ -1455,7 +1459,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
values.push_back(val.origin.y);
values.push_back(val.origin.z);
bool err = false;
code += "\tmat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err);
node_code += "\tmat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err);
} else {
//will go empty, node is expected to know what it is doing at this point and handle it
}
@ -1543,7 +1547,12 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
}
code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
node_code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
if (node_code != String()) {
code += node_name;
code += node_code;
code += "\n";
}
for (int i = 0; i < output_count; i++) {
bool new_line_inserted = false;
@ -1593,7 +1602,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const {
if (!ShaderTypes::get_singleton()->get_functions(p_mode).has(p_func_name)) {
if (p_mode == RenderingServer::ShaderMode::SHADER_PARTICLES) {
if (p_func_name == "emit" || p_func_name == "process" || p_func_name == "end") {
if (p_func_name == "start_custom" || p_func_name == "process_custom" || p_func_name == "collide") {
return true;
}
}
@ -1674,11 +1683,12 @@ void VisualShader::_update_shader() const {
global_code += "render_mode " + render_mode + ";\n\n";
}
static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "emit", "process", "end", "sky" };
static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "start", "process", "collide", "start_custom", "process_custom", "sky" };
String global_expressions;
Set<String> used_uniform_names;
List<VisualShaderNodeUniform *> uniforms;
Map<int, List<int>> emitters;
for (int i = 0, index = 0; i < TYPE_MAX; i++) {
if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
@ -1703,6 +1713,19 @@ void VisualShader::_update_shader() const {
if (uniform.is_valid()) {
uniforms.push_back(uniform.ptr());
}
Ref<VisualShaderNodeParticleEmit> emit_particle = Object::cast_to<VisualShaderNodeParticleEmit>(E->get().node.ptr());
if (emit_particle.is_valid()) {
if (!emitters.has(i)) {
emitters.insert(i, List<int>());
}
for (Map<int, Node>::Element *M = graph[i].nodes.front(); M; M = M->next()) {
if (M->get().node == emit_particle.ptr()) {
emitters[i].push_back(M->key());
break;
}
}
}
}
}
@ -1751,6 +1774,13 @@ void VisualShader::_update_shader() const {
Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
ERR_FAIL_COND(err != OK);
if (emitters.has(i)) {
for (List<int>::Element *E = emitters[i].front(); E; E = E->next()) {
err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E->get(), processed, false, classes);
ERR_FAIL_COND(err != OK);
}
}
if (shader_mode == Shader::MODE_PARTICLES) {
code_map.insert(i, func_code);
} else {
@ -1759,19 +1789,130 @@ void VisualShader::_update_shader() const {
}
}
String global_compute_code;
if (shader_mode == Shader::MODE_PARTICLES) {
code += "\nvoid compute() {\n";
code += "\tif (RESTART) {\n";
code += code_map[TYPE_EMIT];
code += "\t} else {\n";
code += code_map[TYPE_PROCESS];
bool has_start = !code_map[TYPE_START].is_empty();
bool has_start_custom = !code_map[TYPE_START_CUSTOM].is_empty();
bool has_process = !code_map[TYPE_PROCESS].is_empty();
bool has_process_custom = !code_map[TYPE_PROCESS_CUSTOM].is_empty();
bool has_collide = !code_map[TYPE_COLLIDE].is_empty();
code += "void start() {\n";
if (has_start || has_start_custom) {
code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
code += "\tfloat __radians;\n";
code += "\tvec3 __vec3_buff1;\n";
code += "\tvec3 __vec3_buff2;\n";
code += "\tfloat __scalar_buff1;\n";
code += "\tfloat __scalar_buff2;\n";
code += "\tvec3 __ndiff = normalize(__diff);\n\n";
}
if (has_start) {
code += "\t{\n";
code += code_map[TYPE_START].replace("\n\t", "\n\t\t");
code += "\t}\n";
if (has_start_custom) {
code += "\t\n";
}
}
if (has_start_custom) {
code += "\t{\n";
code += code_map[TYPE_START_CUSTOM].replace("\n\t", "\n\t\t");
code += "\t}\n";
}
code += "}\n\n";
code += "void process() {\n";
if (has_process || has_process_custom || has_collide) {
code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n";
code += "\tvec3 __vec3_buff1;\n";
code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
code += "\tvec3 __ndiff = normalize(__diff);\n\n";
}
code += "\t{\n";
String tab = "\t";
if (has_collide) {
code += "\t\tif (COLLIDED) {\n\n";
code += code_map[TYPE_COLLIDE].replace("\n\t", "\n\t\t\t");
if (has_process) {
code += "\t\t} else {\n\n";
tab += "\t";
}
}
if (has_process) {
code += code_map[TYPE_PROCESS].replace("\n\t", "\n\t" + tab);
}
if (has_collide) {
code += "\t\t}\n";
}
code += "\t}\n";
code += "}\n";
if (has_process_custom) {
code += "\t{\n\n";
code += code_map[TYPE_PROCESS_CUSTOM].replace("\n\t", "\n\t\t");
code += "\t}\n";
}
code += "}\n\n";
global_compute_code += "float __rand_from_seed(inout uint seed) {\n";
global_compute_code += "\tint k;\n";
global_compute_code += "\tint s = int(seed);\n";
global_compute_code += "\tif (s == 0)\n";
global_compute_code += "\ts = 305420679;\n";
global_compute_code += "\tk = s / 127773;\n";
global_compute_code += "\ts = 16807 * (s - k * 127773) - 2836 * k;\n";
global_compute_code += "\tif (s < 0)\n";
global_compute_code += "\t\ts += 2147483647;\n";
global_compute_code += "\tseed = uint(s);\n";
global_compute_code += "\treturn float(seed % uint(65536)) / 65535.0;\n";
global_compute_code += "}\n\n";
global_compute_code += "float __rand_from_seed_m1_p1(inout uint seed) {\n";
global_compute_code += "\treturn __rand_from_seed(seed) * 2.0 - 1.0;\n";
global_compute_code += "}\n\n";
global_compute_code += "float __randf_range(inout uint seed, float from, float to) {\n";
global_compute_code += "\treturn __rand_from_seed(seed) * (to - from) + from;\n";
global_compute_code += "}\n\n";
global_compute_code += "vec3 __randv_range(inout uint seed, vec3 from, vec3 to) {\n";
global_compute_code += "\treturn vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n";
global_compute_code += "}\n\n";
global_compute_code += "uint __hash(uint x) {\n";
global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n";
global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n";
global_compute_code += "\tx = (x >> uint(16)) ^ x;\n";
global_compute_code += "\treturn x;\n";
global_compute_code += "}\n\n";
global_compute_code += "mat3 __build_rotation_mat3(vec3 axis, float angle) {\n";
global_compute_code += "\taxis = normalize(axis);\n";
global_compute_code += "\tfloat s = sin(angle);\n";
global_compute_code += "\tfloat c = cos(angle);\n";
global_compute_code += "\tfloat oc = 1.0 - c;\n";
global_compute_code += "\treturn mat3(vec3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s), vec3(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s), vec3(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c));\n";
global_compute_code += "}\n\n";
global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle) {\n";
global_compute_code += "\taxis = normalize(axis);\n";
global_compute_code += "\tfloat s = sin(angle);\n";
global_compute_code += "\tfloat c = cos(angle);\n";
global_compute_code += "\tfloat oc = 1.0 - c;\n";
global_compute_code += "\treturn mat4(vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0), vec4(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0), vec4(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0), vec4(0, 0, 0, 1));\n";
global_compute_code += "}\n\n";
global_compute_code += "vec3 __get_random_unit_vec3(inout uint seed) {\n";
global_compute_code += "\treturn normalize(vec3(__rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed)));\n";
global_compute_code += "}\n\n";
}
//set code secretly
global_code += "\n\n";
String final_code = global_code;
final_code += global_compute_code;
final_code += global_code_per_node;
final_code += global_expressions;
String tcode = code;
@ -1862,9 +2003,11 @@ void VisualShader::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_VERTEX);
BIND_ENUM_CONSTANT(TYPE_FRAGMENT);
BIND_ENUM_CONSTANT(TYPE_LIGHT);
BIND_ENUM_CONSTANT(TYPE_EMIT);
BIND_ENUM_CONSTANT(TYPE_START);
BIND_ENUM_CONSTANT(TYPE_PROCESS);
BIND_ENUM_CONSTANT(TYPE_END);
BIND_ENUM_CONSTANT(TYPE_COLLIDE);
BIND_ENUM_CONSTANT(TYPE_START_CUSTOM);
BIND_ENUM_CONSTANT(TYPE_PROCESS_CUSTOM);
BIND_ENUM_CONSTANT(TYPE_SKY);
BIND_ENUM_CONSTANT(TYPE_MAX);
@ -1875,11 +2018,20 @@ void VisualShader::_bind_methods() {
VisualShader::VisualShader() {
dirty.set();
for (int i = 0; i < TYPE_MAX; i++) {
Ref<VisualShaderNodeOutput> output;
output.instance();
output->shader_type = Type(i);
output->shader_mode = shader_mode;
graph[i].nodes[NODE_ID_OUTPUT].node = output;
if (i > (int)TYPE_LIGHT && i < (int)TYPE_SKY) {
Ref<VisualShaderNodeParticleOutput> output;
output.instance();
output->shader_type = Type(i);
output->shader_mode = shader_mode;
graph[i].nodes[NODE_ID_OUTPUT].node = output;
} else {
Ref<VisualShaderNodeOutput> output;
output.instance();
output->shader_type = Type(i);
output->shader_mode = shader_mode;
graph[i].nodes[NODE_ID_OUTPUT].node = output;
}
graph[i].nodes[NODE_ID_OUTPUT].position = Vector2(400, 150);
}
}
@ -2008,27 +2160,45 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular_shininess", "SPECULAR_SHININESS.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "specular_shininess_alpha", "SPECULAR_SHININESS.a" },
// Particles, Emit
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, Start
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, Start (Custom)
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, Process
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
@ -2038,20 +2208,39 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, End
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, Process (Custom)
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, Collide
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "collision_depth", "COLLISION_DEPTH" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "collision_normal", "COLLISION_NORMAL" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Sky, Sky
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_cubemap_pass", "AT_CUBEMAP_PASS" },
@ -2127,11 +2316,13 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles, Vertex
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "vec3(0.0, 0.0, 1.0)" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, nullptr, nullptr },
};
@ -2624,30 +2815,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" },
// Particles, Emit
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
// Particles, Process
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
// Particles, End
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
{ Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
// Sky, Sky
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR" },
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" },

View file

@ -51,9 +51,11 @@ public:
TYPE_VERTEX,
TYPE_FRAGMENT,
TYPE_LIGHT,
TYPE_EMIT,
TYPE_START,
TYPE_PROCESS,
TYPE_END,
TYPE_COLLIDE,
TYPE_START_CUSTOM,
TYPE_PROCESS_CUSTOM,
TYPE_SKY,
TYPE_MAX
};

View file

@ -860,7 +860,7 @@ String VisualShaderNodeCurveTexture::generate_code(Shader::Mode p_mode, VisualSh
}
String id = make_unique_id(p_type, p_id, "curve");
String code;
code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ", 0.0)).r;\n";
code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ")).r;\n";
return code;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,285 @@
/*************************************************************************/
/* visual_shader_particle_nodes.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef VISUAL_SHADER_PARTICLE_NODES_H
#define VISUAL_SHADER_PARTICLE_NODES_H
#include "scene/resources/visual_shader.h"
// Emit nodes
class VisualShaderNodeParticleEmitter : public VisualShaderNode {
GDCLASS(VisualShaderNodeParticleEmitter, VisualShaderNode);
public:
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
VisualShaderNodeParticleEmitter();
};
class VisualShaderNodeParticleSphereEmitter : public VisualShaderNodeParticleEmitter {
GDCLASS(VisualShaderNodeParticleSphereEmitter, VisualShaderNodeParticleEmitter);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeParticleSphereEmitter();
};
class VisualShaderNodeParticleBoxEmitter : public VisualShaderNodeParticleEmitter {
GDCLASS(VisualShaderNodeParticleBoxEmitter, VisualShaderNodeParticleEmitter);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeParticleBoxEmitter();
};
class VisualShaderNodeParticleRingEmitter : public VisualShaderNodeParticleEmitter {
GDCLASS(VisualShaderNodeParticleRingEmitter, VisualShaderNodeParticleEmitter);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeParticleRingEmitter();
};
class VisualShaderNodeParticleMultiplyByAxisAngle : public VisualShaderNode {
GDCLASS(VisualShaderNodeParticleMultiplyByAxisAngle, VisualShaderNode);
bool degrees_mode = true;
protected:
static void _bind_methods();
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual bool is_show_prop_names() const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
void set_degrees_mode(bool p_enabled);
bool is_degrees_mode() const;
Vector<StringName> get_editable_properties() const override;
VisualShaderNodeParticleMultiplyByAxisAngle();
};
class VisualShaderNodeParticleConeVelocity : public VisualShaderNode {
GDCLASS(VisualShaderNodeParticleConeVelocity, VisualShaderNode);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeParticleConeVelocity();
};
class VisualShaderNodeParticleRandomness : public VisualShaderNode {
GDCLASS(VisualShaderNodeParticleRandomness, VisualShaderNode);
public:
enum OpType {
OP_TYPE_SCALAR,
OP_TYPE_VECTOR,
OP_TYPE_MAX,
};
private:
OpType op_type = OP_TYPE_SCALAR;
protected:
static void _bind_methods();
public:
Vector<StringName> get_editable_properties() const override;
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
void set_op_type(OpType p_type);
OpType get_op_type() const;
VisualShaderNodeParticleRandomness();
};
VARIANT_ENUM_CAST(VisualShaderNodeParticleRandomness::OpType)
// Process nodes
class VisualShaderNodeParticleAccelerator : public VisualShaderNodeOutput {
GDCLASS(VisualShaderNodeParticleAccelerator, VisualShaderNodeOutput);
public:
enum Mode {
MODE_LINEAR,
MODE_RADIAL,
MODE_TANGENTIAL,
MODE_MAX,
};
private:
Mode mode = MODE_LINEAR;
protected:
static void _bind_methods();
public:
Vector<StringName> get_editable_properties() const override;
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
void set_mode(Mode p_mode);
Mode get_mode() const;
VisualShaderNodeParticleAccelerator();
};
VARIANT_ENUM_CAST(VisualShaderNodeParticleAccelerator::Mode)
// Common nodes
class VisualShaderNodeParticleOutput : public VisualShaderNodeOutput {
GDCLASS(VisualShaderNodeParticleOutput, VisualShaderNodeOutput);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual bool is_port_separator(int p_index) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeParticleOutput();
};
class VisualShaderNodeParticleEmit : public VisualShaderNode {
GDCLASS(VisualShaderNodeParticleEmit, VisualShaderNode);
public:
enum EmitFlags {
EMIT_FLAG_POSITION = 1,
EMIT_FLAG_ROT_SCALE = 2,
EMIT_FLAG_VELOCITY = 4,
EMIT_FLAG_COLOR = 8,
EMIT_FLAG_CUSTOM = 16,
};
protected:
int flags = EMIT_FLAG_POSITION | EMIT_FLAG_ROT_SCALE | EMIT_FLAG_VELOCITY | EMIT_FLAG_COLOR | EMIT_FLAG_CUSTOM;
static void _bind_methods();
public:
Vector<StringName> get_editable_properties() const override;
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
void add_flag(EmitFlags p_flag);
bool has_flag(EmitFlags p_flag) const;
void set_flags(EmitFlags p_flags);
EmitFlags get_flags() const;
virtual bool is_show_prop_names() const override;
virtual bool is_generate_input_var(int p_port) const override;
virtual String get_input_port_default_hint(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeParticleEmit();
};
VARIANT_ENUM_CAST(VisualShaderNodeParticleEmit::EmitFlags)
#endif