2018-08-29 22:38:13 +02:00
/*************************************************************************/
/* visual_shader.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2018-08-29 22:38:13 +02:00
/* */
/* 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. */
/*************************************************************************/
2018-07-14 23:15:42 +02:00
# include "visual_shader.h"
2019-05-27 17:33:25 +02:00
2020-11-07 23:33:38 +01:00
# include "core/templates/vmap.h"
2020-03-27 19:21:27 +01:00
# include "servers/rendering/shader_types.h"
2020-02-25 15:50:49 +01:00
# include "visual_shader_nodes.h"
2020-09-15 09:57:40 +02:00
# include "visual_shader_particle_nodes.h"
2020-11-27 08:00:23 +01:00
# include "visual_shader_sdf_nodes.h"
2018-07-14 23:15:42 +02:00
2021-11-05 20:57:24 +01:00
String make_unique_id ( VisualShader : : Type p_type , int p_id , const String & p_name ) {
static const char * typepf [ VisualShader : : TYPE_MAX ] = { " vtx " , " frg " , " lgt " , " start " , " process " , " collide " , " start_custom " , " process_custom " , " sky " , " fog " } ;
return p_name + " _ " + String ( typepf [ p_type ] ) + " _ " + itos ( p_id ) ;
}
2020-01-27 10:10:51 +01:00
bool VisualShaderNode : : is_simple_decl ( ) const {
return simple_decl ;
}
2018-07-14 23:15:42 +02:00
void VisualShaderNode : : set_output_port_for_preview ( int p_index ) {
port_preview = p_index ;
}
int VisualShaderNode : : get_output_port_for_preview ( ) const {
return port_preview ;
}
2022-02-01 09:32:01 +01:00
void VisualShaderNode : : set_input_port_default_value ( int p_port , const Variant & p_value , const Variant & p_prev_value ) {
Variant value = p_value ;
if ( p_prev_value . get_type ( ) ! = Variant : : NIL ) {
switch ( p_value . get_type ( ) ) {
case Variant : : FLOAT : {
switch ( p_prev_value . get_type ( ) ) {
case Variant : : INT : {
value = ( float ) p_prev_value ;
} break ;
case Variant : : FLOAT : {
value = p_prev_value ;
} break ;
case Variant : : VECTOR2 : {
Vector2 pv = p_prev_value ;
value = pv . x ;
} break ;
case Variant : : VECTOR3 : {
Vector3 pv = p_prev_value ;
value = pv . x ;
} break ;
2022-04-12 19:09:29 +02:00
case Variant : : QUATERNION : {
Quaternion pv = p_prev_value ;
value = pv . x ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
case Variant : : INT : {
switch ( p_prev_value . get_type ( ) ) {
case Variant : : INT : {
value = p_prev_value ;
} break ;
case Variant : : FLOAT : {
value = ( int ) p_prev_value ;
} break ;
case Variant : : VECTOR2 : {
Vector2 pv = p_prev_value ;
value = ( int ) pv . x ;
} break ;
case Variant : : VECTOR3 : {
Vector3 pv = p_prev_value ;
value = ( int ) pv . x ;
} break ;
2022-04-12 19:09:29 +02:00
case Variant : : QUATERNION : {
Quaternion pv = p_prev_value ;
value = ( int ) pv . x ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
case Variant : : VECTOR2 : {
switch ( p_prev_value . get_type ( ) ) {
case Variant : : INT : {
float pv = ( float ) ( int ) p_prev_value ;
value = Vector2 ( pv , pv ) ;
} break ;
case Variant : : FLOAT : {
float pv = p_prev_value ;
value = Vector2 ( pv , pv ) ;
} break ;
case Variant : : VECTOR2 : {
value = p_prev_value ;
} break ;
case Variant : : VECTOR3 : {
Vector3 pv = p_prev_value ;
value = Vector2 ( pv . x , pv . y ) ;
} break ;
2022-04-12 19:09:29 +02:00
case Variant : : QUATERNION : {
Quaternion pv = p_prev_value ;
value = Vector2 ( pv . x , pv . y ) ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
case Variant : : VECTOR3 : {
switch ( p_prev_value . get_type ( ) ) {
case Variant : : INT : {
float pv = ( float ) ( int ) p_prev_value ;
value = Vector3 ( pv , pv , pv ) ;
} break ;
case Variant : : FLOAT : {
float pv = p_prev_value ;
value = Vector3 ( pv , pv , pv ) ;
} break ;
case Variant : : VECTOR2 : {
Vector2 pv = p_prev_value ;
2022-02-07 06:46:51 +01:00
value = Vector3 ( pv . x , pv . y , pv . y ) ;
2022-02-01 09:32:01 +01:00
} break ;
case Variant : : VECTOR3 : {
value = p_prev_value ;
} break ;
2022-04-12 19:09:29 +02:00
case Variant : : QUATERNION : {
Quaternion pv = p_prev_value ;
value = Vector3 ( pv . x , pv . y , pv . z ) ;
} break ;
default :
break ;
}
} break ;
case Variant : : QUATERNION : {
switch ( p_prev_value . get_type ( ) ) {
case Variant : : INT : {
float pv = ( float ) ( int ) p_prev_value ;
value = Quaternion ( pv , pv , pv , pv ) ;
} break ;
case Variant : : FLOAT : {
float pv = p_prev_value ;
value = Quaternion ( pv , pv , pv , pv ) ;
} break ;
case Variant : : VECTOR2 : {
Vector2 pv = p_prev_value ;
value = Quaternion ( pv . x , pv . y , pv . y , pv . y ) ;
} break ;
case Variant : : VECTOR3 : {
Vector3 pv = p_prev_value ;
value = Quaternion ( pv . x , pv . y , pv . z , pv . z ) ;
} break ;
case Variant : : QUATERNION : {
value = p_prev_value ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
default :
break ;
}
}
default_input_values [ p_port ] = value ;
2018-07-14 23:15:42 +02:00
emit_changed ( ) ;
}
Variant VisualShaderNode : : get_input_port_default_value ( int p_port ) const {
if ( default_input_values . has ( p_port ) ) {
return default_input_values [ p_port ] ;
}
return Variant ( ) ;
}
2021-06-05 14:53:53 +02:00
void VisualShaderNode : : remove_input_port_default_value ( int p_port ) {
if ( default_input_values . has ( p_port ) ) {
default_input_values . erase ( p_port ) ;
emit_changed ( ) ;
}
}
void VisualShaderNode : : clear_default_input_values ( ) {
if ( ! default_input_values . is_empty ( ) ) {
default_input_values . clear ( ) ;
emit_changed ( ) ;
}
}
2018-07-14 23:15:42 +02:00
bool VisualShaderNode : : is_port_separator ( int p_index ) const {
return false ;
}
2020-07-26 03:04:07 +02:00
bool VisualShaderNode : : is_output_port_connected ( int p_port ) const {
if ( connected_output_ports . has ( p_port ) ) {
2020-10-02 08:06:13 +02:00
return connected_output_ports [ p_port ] > 0 ;
2020-07-26 03:04:07 +02:00
}
return false ;
}
void VisualShaderNode : : set_output_port_connected ( int p_port , bool p_connected ) {
2020-07-31 09:40:05 +02:00
if ( p_connected ) {
2020-10-02 08:06:13 +02:00
connected_output_ports [ p_port ] + + ;
2020-07-31 09:40:05 +02:00
} else {
2020-10-02 08:06:13 +02:00
connected_output_ports [ p_port ] - - ;
2020-07-31 09:40:05 +02:00
}
2020-07-26 03:04:07 +02:00
}
2020-07-27 08:18:37 +02:00
bool VisualShaderNode : : is_input_port_connected ( int p_port ) const {
if ( connected_input_ports . has ( p_port ) ) {
return connected_input_ports [ p_port ] ;
}
return false ;
}
void VisualShaderNode : : set_input_port_connected ( int p_port , bool p_connected ) {
connected_input_ports [ p_port ] = p_connected ;
}
bool VisualShaderNode : : is_generate_input_var ( int p_port ) const {
return true ;
}
2020-12-20 16:45:53 +01:00
bool VisualShaderNode : : is_output_port_expandable ( int p_port ) const {
return false ;
}
2021-10-08 21:55:07 +02:00
bool VisualShaderNode : : has_output_port_preview ( int p_port ) const {
return true ;
}
2020-12-20 16:45:53 +01:00
void VisualShaderNode : : _set_output_ports_expanded ( const Array & p_values ) {
for ( int i = 0 ; i < p_values . size ( ) ; i + + ) {
expanded_output_ports [ p_values [ i ] ] = true ;
}
emit_changed ( ) ;
}
Array VisualShaderNode : : _get_output_ports_expanded ( ) const {
Array arr ;
for ( int i = 0 ; i < get_output_port_count ( ) ; i + + ) {
if ( _is_output_port_expanded ( i ) ) {
arr . push_back ( i ) ;
}
}
return arr ;
}
void VisualShaderNode : : _set_output_port_expanded ( int p_port , bool p_expanded ) {
expanded_output_ports [ p_port ] = p_expanded ;
emit_changed ( ) ;
}
bool VisualShaderNode : : _is_output_port_expanded ( int p_port ) const {
if ( expanded_output_ports . has ( p_port ) ) {
return expanded_output_ports [ p_port ] ;
}
return false ;
}
int VisualShaderNode : : get_expanded_output_port_count ( ) const {
int count = get_output_port_count ( ) ;
int count2 = count ;
for ( int i = 0 ; i < count ; i + + ) {
if ( is_output_port_expandable ( i ) & & _is_output_port_expanded ( i ) ) {
2022-02-01 09:32:01 +01:00
switch ( get_output_port_type ( i ) ) {
case PORT_TYPE_VECTOR_2D : {
count2 + = 2 ;
} break ;
2022-02-06 18:15:28 +01:00
case PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
count2 + = 3 ;
} break ;
2022-04-12 19:09:29 +02:00
case PORT_TYPE_VECTOR_4D : {
count2 + = 4 ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2020-12-20 16:45:53 +01:00
}
}
}
return count2 ;
}
2020-07-26 03:04:07 +02:00
bool VisualShaderNode : : is_code_generated ( ) const {
return true ;
}
2020-09-21 13:32:59 +02:00
bool VisualShaderNode : : is_show_prop_names ( ) const {
return false ;
}
bool VisualShaderNode : : is_use_prop_slots ( ) const {
return false ;
}
2021-05-27 21:17:58 +02:00
bool VisualShaderNode : : is_disabled ( ) const {
return disabled ;
}
void VisualShaderNode : : set_disabled ( bool p_disabled ) {
disabled = p_disabled ;
}
2018-07-14 23:15:42 +02:00
Vector < VisualShader : : DefaultTextureParam > VisualShaderNode : : get_default_texture_parameters ( VisualShader : : Type p_type , int p_id ) const {
return Vector < VisualShader : : DefaultTextureParam > ( ) ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
String VisualShaderNode : : generate_global ( Shader : : Mode p_mode , VisualShader : : Type p_type , int p_id ) const {
return String ( ) ;
}
2022-02-07 06:46:51 +01:00
String VisualShaderNode : : generate_global_per_node ( Shader : : Mode p_mode , int p_id ) const {
2019-07-12 11:14:34 +02:00
return String ( ) ;
}
String VisualShaderNode : : generate_global_per_func ( Shader : : Mode p_mode , VisualShader : : Type p_type , int p_id ) const {
return String ( ) ;
}
2018-07-14 23:15:42 +02:00
Vector < StringName > VisualShaderNode : : get_editable_properties ( ) const {
return Vector < StringName > ( ) ;
}
2022-05-13 15:04:37 +02:00
HashMap < StringName , String > VisualShaderNode : : get_editable_properties_names ( ) const {
return HashMap < StringName , String > ( ) ;
2021-11-04 16:42:57 +01:00
}
2020-01-23 08:42:35 +01:00
Array VisualShaderNode : : get_default_input_values ( ) const {
2018-07-14 23:15:42 +02:00
Array ret ;
2021-08-09 22:13:42 +02:00
for ( const KeyValue < int , Variant > & E : default_input_values ) {
ret . push_back ( E . key ) ;
ret . push_back ( E . value ) ;
2018-07-14 23:15:42 +02:00
}
return ret ;
}
2020-05-14 14:29:06 +02:00
2020-01-23 08:42:35 +01:00
void VisualShaderNode : : set_default_input_values ( const Array & p_values ) {
2018-07-14 23:15:42 +02:00
if ( p_values . size ( ) % 2 = = 0 ) {
for ( int i = 0 ; i < p_values . size ( ) ; i + = 2 ) {
default_input_values [ p_values [ i + 0 ] ] = p_values [ i + 1 ] ;
}
}
emit_changed ( ) ;
}
String VisualShaderNode : : get_warning ( Shader : : Mode p_mode , VisualShader : : Type p_type ) const {
return String ( ) ;
}
2022-01-22 09:09:16 +01:00
bool VisualShaderNode : : is_input_port_default ( int p_port , Shader : : Mode p_mode ) const {
return false ;
2019-10-03 09:40:26 +02:00
}
2018-07-14 23:15:42 +02:00
void VisualShaderNode : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_output_port_for_preview " , " port " ) , & VisualShaderNode : : set_output_port_for_preview ) ;
ClassDB : : bind_method ( D_METHOD ( " get_output_port_for_preview " ) , & VisualShaderNode : : get_output_port_for_preview ) ;
2020-12-20 16:45:53 +01:00
ClassDB : : bind_method ( D_METHOD ( " _set_output_port_expanded " , " port " ) , & VisualShaderNode : : _set_output_port_expanded ) ;
ClassDB : : bind_method ( D_METHOD ( " _is_output_port_expanded " ) , & VisualShaderNode : : _is_output_port_expanded ) ;
ClassDB : : bind_method ( D_METHOD ( " _set_output_ports_expanded " , " values " ) , & VisualShaderNode : : _set_output_ports_expanded ) ;
ClassDB : : bind_method ( D_METHOD ( " _get_output_ports_expanded " ) , & VisualShaderNode : : _get_output_ports_expanded ) ;
2022-02-01 09:32:01 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_input_port_default_value " , " port " , " value " , " prev_value " ) , & VisualShaderNode : : set_input_port_default_value , DEFVAL ( Variant ( ) ) ) ;
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_input_port_default_value " , " port " ) , & VisualShaderNode : : get_input_port_default_value ) ;
2021-06-05 14:53:53 +02:00
ClassDB : : bind_method ( D_METHOD ( " remove_input_port_default_value " , " port " ) , & VisualShaderNode : : remove_input_port_default_value ) ;
ClassDB : : bind_method ( D_METHOD ( " clear_default_input_values " ) , & VisualShaderNode : : clear_default_input_values ) ;
2020-01-23 08:42:35 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_default_input_values " , " values " ) , & VisualShaderNode : : set_default_input_values ) ;
ClassDB : : bind_method ( D_METHOD ( " get_default_input_values " ) , & VisualShaderNode : : get_default_input_values ) ;
2018-07-14 23:15:42 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " output_port_for_preview " ) , " set_output_port_for_preview " , " get_output_port_for_preview " ) ;
2021-11-03 23:06:17 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : ARRAY , " default_input_values " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) , " set_default_input_values " , " get_default_input_values " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : ARRAY , " expanded_output_ports " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) , " _set_output_ports_expanded " , " _get_output_ports_expanded " ) ;
2018-07-14 23:15:42 +02:00
ADD_SIGNAL ( MethodInfo ( " editor_refresh_request " ) ) ;
2019-08-09 21:51:48 +02:00
BIND_ENUM_CONSTANT ( PORT_TYPE_SCALAR ) ;
2020-02-25 15:50:49 +01:00
BIND_ENUM_CONSTANT ( PORT_TYPE_SCALAR_INT ) ;
2022-02-01 09:32:01 +01:00
BIND_ENUM_CONSTANT ( PORT_TYPE_VECTOR_2D ) ;
2022-02-06 18:15:28 +01:00
BIND_ENUM_CONSTANT ( PORT_TYPE_VECTOR_3D ) ;
2022-04-12 19:09:29 +02:00
BIND_ENUM_CONSTANT ( PORT_TYPE_VECTOR_4D ) ;
2019-08-09 21:51:48 +02:00
BIND_ENUM_CONSTANT ( PORT_TYPE_BOOLEAN ) ;
BIND_ENUM_CONSTANT ( PORT_TYPE_TRANSFORM ) ;
2019-10-01 10:51:50 +02:00
BIND_ENUM_CONSTANT ( PORT_TYPE_SAMPLER ) ;
BIND_ENUM_CONSTANT ( PORT_TYPE_MAX ) ;
2018-07-14 23:15:42 +02:00
}
VisualShaderNode : : VisualShaderNode ( ) {
}
/////////////////////////////////////////////////////////
2019-08-09 21:51:48 +02:00
void VisualShaderNodeCustom : : update_ports ( ) {
2021-08-22 03:52:44 +02:00
{
input_ports . clear ( ) ;
int input_port_count ;
if ( GDVIRTUAL_CALL ( _get_input_port_count , input_port_count ) ) {
for ( int i = 0 ; i < input_port_count ; i + + ) {
Port port ;
if ( ! GDVIRTUAL_CALL ( _get_input_port_name , i , port . name ) ) {
port . name = " in " + itos ( i ) ;
}
if ( ! GDVIRTUAL_CALL ( _get_input_port_type , i , port . type ) ) {
port . type = ( int ) PortType : : PORT_TYPE_SCALAR ;
}
input_ports . push_back ( port ) ;
2019-08-09 21:51:48 +02:00
}
}
}
2021-08-22 03:52:44 +02:00
{
output_ports . clear ( ) ;
int output_port_count ;
if ( GDVIRTUAL_CALL ( _get_output_port_count , output_port_count ) ) {
for ( int i = 0 ; i < output_port_count ; i + + ) {
Port port ;
if ( ! GDVIRTUAL_CALL ( _get_output_port_name , i , port . name ) ) {
port . name = " out " + itos ( i ) ;
}
if ( ! GDVIRTUAL_CALL ( _get_output_port_type , i , port . type ) ) {
port . type = ( int ) PortType : : PORT_TYPE_SCALAR ;
}
output_ports . push_back ( port ) ;
2019-08-09 21:51:48 +02:00
}
}
}
}
String VisualShaderNodeCustom : : get_caption ( ) const {
2021-08-22 03:52:44 +02:00
String ret ;
if ( GDVIRTUAL_CALL ( _get_name , ret ) ) {
return ret ;
2019-08-09 21:51:48 +02:00
}
return " Unnamed " ;
}
int VisualShaderNodeCustom : : get_input_port_count ( ) const {
return input_ports . size ( ) ;
}
VisualShaderNodeCustom : : PortType VisualShaderNodeCustom : : get_input_port_type ( int p_port ) const {
ERR_FAIL_INDEX_V ( p_port , input_ports . size ( ) , PORT_TYPE_SCALAR ) ;
return ( PortType ) input_ports [ p_port ] . type ;
}
String VisualShaderNodeCustom : : get_input_port_name ( int p_port ) const {
ERR_FAIL_INDEX_V ( p_port , input_ports . size ( ) , " " ) ;
return input_ports [ p_port ] . name ;
}
int VisualShaderNodeCustom : : get_output_port_count ( ) const {
return output_ports . size ( ) ;
}
VisualShaderNodeCustom : : PortType VisualShaderNodeCustom : : get_output_port_type ( int p_port ) const {
ERR_FAIL_INDEX_V ( p_port , output_ports . size ( ) , PORT_TYPE_SCALAR ) ;
return ( PortType ) output_ports [ p_port ] . type ;
}
String VisualShaderNodeCustom : : get_output_port_name ( int p_port ) const {
ERR_FAIL_INDEX_V ( p_port , output_ports . size ( ) , " " ) ;
return output_ports [ p_port ] . name ;
}
String VisualShaderNodeCustom : : 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 ) const {
2021-08-25 19:44:01 +02:00
ERR_FAIL_COND_V ( ! GDVIRTUAL_IS_OVERRIDDEN ( _get_code ) , " " ) ;
2022-01-04 09:30:47 +01:00
TypedArray < String > input_vars ;
2019-08-09 21:51:48 +02:00
for ( int i = 0 ; i < get_input_port_count ( ) ; i + + ) {
input_vars . push_back ( p_input_vars [ i ] ) ;
}
2022-01-04 09:30:47 +01:00
TypedArray < String > output_vars ;
2019-08-09 21:51:48 +02:00
for ( int i = 0 ; i < get_output_port_count ( ) ; i + + ) {
output_vars . push_back ( p_output_vars [ i ] ) ;
}
2022-02-07 20:58:37 +01:00
2021-08-22 03:52:44 +02:00
String _code ;
2021-11-10 13:22:58 +01:00
GDVIRTUAL_CALL ( _get_code , input_vars , output_vars , p_mode , p_type , _code ) ;
2022-02-07 20:58:37 +01:00
if ( _is_valid_code ( _code ) ) {
String code = " { \n " ;
bool nend = _code . ends_with ( " \n " ) ;
_code = _code . insert ( 0 , " " ) ;
_code = _code . replace ( " \n " , " \n " ) ;
code + = _code ;
if ( ! nend ) {
code + = " \n } " ;
} else {
code . remove_at ( code . size ( ) - 1 ) ;
code + = " } " ;
}
code + = " \n " ;
return code ;
2019-08-09 21:51:48 +02:00
}
2022-02-07 20:58:37 +01:00
return String ( ) ;
2019-08-09 21:51:48 +02:00
}
2022-02-07 06:46:51 +01:00
String VisualShaderNodeCustom : : generate_global_per_node ( Shader : : Mode p_mode , int p_id ) const {
2022-02-07 20:58:37 +01:00
String _code ;
if ( GDVIRTUAL_CALL ( _get_global_code , p_mode , _code ) ) {
if ( _is_valid_code ( _code ) ) {
String code = " // " + get_caption ( ) + " \n " ;
code + = _code ;
code + = " \n " ;
return code ;
}
}
return String ( ) ;
}
String VisualShaderNodeCustom : : generate_global_per_func ( Shader : : Mode p_mode , VisualShader : : Type p_type , int p_id ) const {
String _code ;
if ( GDVIRTUAL_CALL ( _get_func_code , p_mode , p_type , _code ) ) {
if ( _is_valid_code ( _code ) ) {
bool nend = _code . ends_with ( " \n " ) ;
String code = " // " + get_caption ( ) + " \n " ;
code + = " { \n " ;
_code = _code . insert ( 0 , " " ) ;
_code = _code . replace ( " \n " , " \n " ) ;
code + = _code ;
if ( ! nend ) {
code + = " \n } " ;
} else {
code . remove_at ( code . size ( ) - 1 ) ;
code + = " } " ;
}
code + = " \n " ;
return code ;
}
}
return String ( ) ;
}
bool VisualShaderNodeCustom : : is_available ( Shader : : Mode p_mode , VisualShader : : Type p_type ) const {
bool ret ;
if ( GDVIRTUAL_CALL ( _is_available , p_mode , p_type , ret ) ) {
return ret ;
2019-08-09 21:51:48 +02:00
}
2022-02-07 20:58:37 +01:00
return true ;
2019-08-09 21:51:48 +02:00
}
2022-02-01 09:32:01 +01:00
void VisualShaderNodeCustom : : set_input_port_default_value ( int p_port , const Variant & p_value , const Variant & p_prev_value ) {
2021-04-12 12:47:37 +02:00
if ( ! is_initialized ) {
2022-02-01 09:32:01 +01:00
VisualShaderNode : : set_input_port_default_value ( p_port , p_value , p_prev_value ) ;
2021-04-12 12:47:37 +02:00
}
}
void VisualShaderNodeCustom : : set_default_input_values ( const Array & p_values ) {
if ( ! is_initialized ) {
VisualShaderNode : : set_default_input_values ( p_values ) ;
}
}
2021-06-05 14:53:53 +02:00
void VisualShaderNodeCustom : : remove_input_port_default_value ( int p_port ) {
if ( ! is_initialized ) {
VisualShaderNode : : remove_input_port_default_value ( p_port ) ;
}
}
void VisualShaderNodeCustom : : clear_default_input_values ( ) {
if ( ! is_initialized ) {
VisualShaderNode : : clear_default_input_values ( ) ;
}
}
2021-04-12 12:47:37 +02:00
void VisualShaderNodeCustom : : _set_input_port_default_value ( int p_port , const Variant & p_value ) {
VisualShaderNode : : set_input_port_default_value ( p_port , p_value ) ;
}
2022-02-07 20:58:37 +01:00
bool VisualShaderNodeCustom : : _is_valid_code ( const String & p_code ) const {
if ( p_code . is_empty ( ) | | p_code = = " null " ) {
return false ;
}
return true ;
}
2021-04-12 12:47:37 +02:00
bool VisualShaderNodeCustom : : _is_initialized ( ) {
return is_initialized ;
}
void VisualShaderNodeCustom : : _set_initialized ( bool p_enabled ) {
is_initialized = p_enabled ;
}
2019-08-09 21:51:48 +02:00
void VisualShaderNodeCustom : : _bind_methods ( ) {
2021-08-22 03:52:44 +02:00
GDVIRTUAL_BIND ( _get_name ) ;
GDVIRTUAL_BIND ( _get_description ) ;
GDVIRTUAL_BIND ( _get_category ) ;
GDVIRTUAL_BIND ( _get_return_icon_type ) ;
GDVIRTUAL_BIND ( _get_input_port_count ) ;
GDVIRTUAL_BIND ( _get_input_port_type , " port " ) ;
GDVIRTUAL_BIND ( _get_input_port_name , " port " ) ;
GDVIRTUAL_BIND ( _get_output_port_count ) ;
GDVIRTUAL_BIND ( _get_output_port_type , " port " ) ;
GDVIRTUAL_BIND ( _get_output_port_name , " port " ) ;
GDVIRTUAL_BIND ( _get_code , " input_vars " , " output_vars " , " mode " , " type " ) ;
2022-02-07 20:58:37 +01:00
GDVIRTUAL_BIND ( _get_func_code , " mode " , " type " ) ;
2021-08-22 03:52:44 +02:00
GDVIRTUAL_BIND ( _get_global_code , " mode " ) ;
GDVIRTUAL_BIND ( _is_highend ) ;
2022-02-07 20:58:37 +01:00
GDVIRTUAL_BIND ( _is_available , " mode " , " type " ) ;
2021-04-12 12:47:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " _set_initialized " , " enabled " ) , & VisualShaderNodeCustom : : _set_initialized ) ;
ClassDB : : bind_method ( D_METHOD ( " _is_initialized " ) , & VisualShaderNodeCustom : : _is_initialized ) ;
ClassDB : : bind_method ( D_METHOD ( " _set_input_port_default_value " , " port " , " value " ) , & VisualShaderNodeCustom : : _set_input_port_default_value ) ;
2021-11-03 23:06:17 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " initialized " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) , " _set_initialized " , " _is_initialized " ) ;
2019-08-09 21:51:48 +02:00
}
VisualShaderNodeCustom : : VisualShaderNodeCustom ( ) {
2020-01-27 10:10:51 +01:00
simple_decl = false ;
2019-08-09 21:51:48 +02:00
}
/////////////////////////////////////////////////////////
2020-09-09 10:21:38 +02:00
void VisualShader : : set_shader_type ( Type p_type ) {
current_type = p_type ;
}
2020-09-09 16:40:27 +02:00
VisualShader : : Type VisualShader : : get_shader_type ( ) const {
return current_type ;
}
2022-01-09 15:02:13 +01:00
void VisualShader : : add_varying ( const String & p_name , VaryingMode p_mode , VaryingType p_type ) {
ERR_FAIL_COND ( ! p_name . is_valid_identifier ( ) ) ;
ERR_FAIL_INDEX ( ( int ) p_mode , ( int ) VARYING_MODE_MAX ) ;
ERR_FAIL_INDEX ( ( int ) p_type , ( int ) VARYING_TYPE_MAX ) ;
ERR_FAIL_COND ( varyings . has ( p_name ) ) ;
Varying var = Varying ( p_name , p_mode , p_type ) ;
varyings [ p_name ] = var ;
varyings_list . push_back ( var ) ;
_queue_update ( ) ;
}
void VisualShader : : remove_varying ( const String & p_name ) {
ERR_FAIL_COND ( ! varyings . has ( p_name ) ) ;
varyings . erase ( p_name ) ;
for ( List < Varying > : : Element * E = varyings_list . front ( ) ; E ; E = E - > next ( ) ) {
if ( E - > get ( ) . name = = p_name ) {
varyings_list . erase ( E ) ;
break ;
}
}
_queue_update ( ) ;
}
bool VisualShader : : has_varying ( const String & p_name ) const {
return varyings . has ( p_name ) ;
}
int VisualShader : : get_varyings_count ( ) const {
return varyings_list . size ( ) ;
}
const VisualShader : : Varying * VisualShader : : get_varying_by_index ( int p_idx ) const {
ERR_FAIL_INDEX_V ( p_idx , varyings_list . size ( ) , nullptr ) ;
return & varyings_list [ p_idx ] ;
}
void VisualShader : : set_varying_mode ( const String & p_name , VaryingMode p_mode ) {
ERR_FAIL_INDEX ( ( int ) p_mode , ( int ) VARYING_MODE_MAX ) ;
ERR_FAIL_COND ( ! varyings . has ( p_name ) ) ;
if ( varyings [ p_name ] . mode = = p_mode ) {
return ;
}
varyings [ p_name ] . mode = p_mode ;
_queue_update ( ) ;
}
VisualShader : : VaryingMode VisualShader : : get_varying_mode ( const String & p_name ) {
ERR_FAIL_COND_V ( ! varyings . has ( p_name ) , VARYING_MODE_MAX ) ;
return varyings [ p_name ] . mode ;
}
void VisualShader : : set_varying_type ( const String & p_name , VaryingType p_type ) {
ERR_FAIL_INDEX ( ( int ) p_type , ( int ) VARYING_TYPE_MAX ) ;
ERR_FAIL_COND ( ! varyings . has ( p_name ) ) ;
if ( varyings [ p_name ] . type = = p_type ) {
return ;
}
varyings [ p_name ] . type = p_type ;
_queue_update ( ) ;
}
VisualShader : : VaryingType VisualShader : : get_varying_type ( const String & p_name ) {
ERR_FAIL_COND_V ( ! varyings . has ( p_name ) , VARYING_TYPE_MAX ) ;
return varyings [ p_name ] . type ;
}
2021-08-01 17:13:51 +02:00
void VisualShader : : set_engine_version ( const Dictionary & p_engine_version ) {
ERR_FAIL_COND ( ! p_engine_version . has ( " major " ) ) ;
ERR_FAIL_COND ( ! p_engine_version . has ( " minor " ) ) ;
engine_version [ " major " ] = p_engine_version [ " major " ] ;
engine_version [ " minor " ] = p_engine_version [ " minor " ] ;
2020-02-25 15:50:49 +01:00
}
2021-08-01 17:13:51 +02:00
Dictionary VisualShader : : get_engine_version ( ) const {
return engine_version ;
2020-02-25 15:50:49 +01:00
}
2021-08-01 17:13:51 +02:00
# ifndef DISABLE_DEPRECATED
void VisualShader : : update_engine_version ( const Dictionary & p_new_version ) {
if ( engine_version . is_empty ( ) ) { // before 4.0
2020-02-25 15:50:49 +01:00
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2021-08-09 22:13:42 +02:00
for ( KeyValue < int , Node > & E : graph [ i ] . nodes ) {
Ref < VisualShaderNodeInput > input = Object : : cast_to < VisualShaderNodeInput > ( E . value . node . ptr ( ) ) ;
2021-07-18 14:05:25 +02:00
if ( input . is_valid ( ) ) {
if ( input - > get_input_name ( ) = = " side " ) {
input - > set_input_name ( " front_facing " ) ;
}
}
2021-08-09 22:13:42 +02:00
Ref < VisualShaderNodeExpression > expression = Object : : cast_to < VisualShaderNodeExpression > ( E . value . node . ptr ( ) ) ;
2020-02-25 15:50:49 +01:00
if ( expression . is_valid ( ) ) {
for ( int j = 0 ; j < expression - > get_input_port_count ( ) ; j + + ) {
int type = expression - > get_input_port_type ( j ) ;
2022-02-01 09:32:01 +01:00
if ( type > 0 ) { // + PORT_TYPE_SCALAR_INT + PORT_TYPE_VECTOR_2D
type + = 2 ;
2020-02-25 15:50:49 +01:00
}
expression - > set_input_port_type ( j , type ) ;
}
for ( int j = 0 ; j < expression - > get_output_port_count ( ) ; j + + ) {
int type = expression - > get_output_port_type ( j ) ;
2022-02-01 09:32:01 +01:00
if ( type > 0 ) { // + PORT_TYPE_SCALAR_INT + PORT_TYPE_VECTOR_2D
type + = 2 ;
2020-02-25 15:50:49 +01:00
}
expression - > set_output_port_type ( j , type ) ;
}
}
2022-02-01 09:32:01 +01:00
Ref < VisualShaderNodeStep > step = Object : : cast_to < VisualShaderNodeStep > ( E . value . node . ptr ( ) ) ;
if ( step . is_valid ( ) ) {
int op_type = int ( step - > get_op_type ( ) ) ;
if ( int ( op_type ) > 0 ) { // + OP_TYPE_VECTOR_2D + OP_TYPE_VECTOR_2D_SCALAR
op_type + = 2 ;
}
step - > set_op_type ( VisualShaderNodeStep : : OpType ( op_type ) ) ;
}
Ref < VisualShaderNodeSmoothStep > sstep = Object : : cast_to < VisualShaderNodeSmoothStep > ( E . value . node . ptr ( ) ) ;
if ( sstep . is_valid ( ) ) {
int op_type = int ( sstep - > get_op_type ( ) ) ;
if ( int ( op_type ) > 0 ) { // + OP_TYPE_VECTOR_2D + OP_TYPE_VECTOR_2D_SCALAR
op_type + = 2 ;
}
sstep - > set_op_type ( VisualShaderNodeSmoothStep : : OpType ( op_type ) ) ;
}
Ref < VisualShaderNodeMix > mix = Object : : cast_to < VisualShaderNodeMix > ( E . value . node . ptr ( ) ) ;
if ( mix . is_valid ( ) ) {
int op_type = int ( mix - > get_op_type ( ) ) ;
if ( int ( op_type ) > 0 ) { // + OP_TYPE_VECTOR_2D + OP_TYPE_VECTOR_2D_SCALAR
op_type + = 2 ;
}
mix - > set_op_type ( VisualShaderNodeMix : : OpType ( op_type ) ) ;
}
2021-08-09 22:13:42 +02:00
Ref < VisualShaderNodeCompare > compare = Object : : cast_to < VisualShaderNodeCompare > ( E . value . node . ptr ( ) ) ;
2020-02-25 15:50:49 +01:00
if ( compare . is_valid ( ) ) {
int ctype = int ( compare - > get_comparison_type ( ) ) ;
2022-02-01 09:32:01 +01:00
if ( int ( ctype ) > 0 ) { // + CTYPE_SCALAR_INT + CTYPE_VECTOR_2D
ctype + = 2 ;
2020-02-25 15:50:49 +01:00
}
compare - > set_comparison_type ( VisualShaderNodeCompare : : ComparisonType ( ctype ) ) ;
}
}
}
}
2021-08-01 17:13:51 +02:00
set_engine_version ( p_new_version ) ;
2020-02-25 15:50:49 +01:00
}
2021-08-01 17:13:51 +02:00
# endif /* DISABLE_DEPRECATED */
2018-07-14 23:15:42 +02:00
void VisualShader : : add_node ( Type p_type , const Ref < VisualShaderNode > & p_node , const Vector2 & p_position , int p_id ) {
ERR_FAIL_COND ( p_node . is_null ( ) ) ;
ERR_FAIL_COND ( p_id < 2 ) ;
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND ( g - > nodes . has ( p_id ) ) ;
Node n ;
n . node = p_node ;
n . position = p_position ;
Ref < VisualShaderNodeUniform > uniform = n . node ;
if ( uniform . is_valid ( ) ) {
String valid_name = validate_uniform_name ( uniform - > get_uniform_name ( ) , uniform ) ;
uniform - > set_uniform_name ( valid_name ) ;
}
Ref < VisualShaderNodeInput > input = n . node ;
if ( input . is_valid ( ) ) {
input - > shader_mode = shader_mode ;
input - > shader_type = p_type ;
}
2020-02-21 18:28:45 +01:00
n . node - > connect ( " changed " , callable_mp ( this , & VisualShader : : _queue_update ) ) ;
2018-07-14 23:15:42 +02:00
2019-08-09 21:51:48 +02:00
Ref < VisualShaderNodeCustom > custom = n . node ;
if ( custom . is_valid ( ) ) {
custom - > update_ports ( ) ;
}
2018-07-14 23:15:42 +02:00
g - > nodes [ p_id ] = n ;
_queue_update ( ) ;
}
void VisualShader : : set_node_position ( Type p_type , int p_id , const Vector2 & p_position ) {
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND ( ! g - > nodes . has ( p_id ) ) ;
g - > nodes [ p_id ] . position = p_position ;
}
Vector2 VisualShader : : get_node_position ( Type p_type , int p_id ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , Vector2 ( ) ) ;
const Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND_V ( ! g - > nodes . has ( p_id ) , Vector2 ( ) ) ;
return g - > nodes [ p_id ] . position ;
}
2019-05-12 14:09:39 +02:00
2018-07-14 23:15:42 +02:00
Ref < VisualShaderNode > VisualShader : : get_node ( Type p_type , int p_id ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , Ref < VisualShaderNode > ( ) ) ;
const Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND_V ( ! g - > nodes . has ( p_id ) , Ref < VisualShaderNode > ( ) ) ;
return g - > nodes [ p_id ] . node ;
}
Vector < int > VisualShader : : get_node_list ( Type p_type ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , Vector < int > ( ) ) ;
const Graph * g = & graph [ p_type ] ;
Vector < int > ret ;
2021-08-09 22:13:42 +02:00
for ( const KeyValue < int , Node > & E : g - > nodes ) {
ret . push_back ( E . key ) ;
2018-07-14 23:15:42 +02:00
}
return ret ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
int VisualShader : : get_valid_node_id ( Type p_type ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , NODE_ID_INVALID ) ;
const Graph * g = & graph [ p_type ] ;
return g - > nodes . size ( ) ? MAX ( 2 , g - > nodes . back ( ) - > key ( ) + 1 ) : 2 ;
}
int VisualShader : : find_node_id ( Type p_type , const Ref < VisualShaderNode > & p_node ) const {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < int , Node > & E : graph [ p_type ] . nodes ) {
if ( E . value . node = = p_node ) {
return E . key ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
}
return NODE_ID_INVALID ;
}
void VisualShader : : remove_node ( Type p_type , int p_id ) {
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
ERR_FAIL_COND ( p_id < 2 ) ;
Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND ( ! g - > nodes . has ( p_id ) ) ;
2020-02-21 18:28:45 +01:00
g - > nodes [ p_id ] . node - > disconnect ( " changed " , callable_mp ( this , & VisualShader : : _queue_update ) ) ;
2018-07-14 23:15:42 +02:00
g - > nodes . erase ( p_id ) ;
for ( List < Connection > : : Element * E = g - > connections . front ( ) ; E ; ) {
List < Connection > : : Element * N = E - > next ( ) ;
if ( E - > get ( ) . from_node = = p_id | | E - > get ( ) . to_node = = p_id ) {
g - > connections . erase ( E ) ;
2020-01-20 15:46:49 +01:00
if ( E - > get ( ) . from_node = = p_id ) {
g - > nodes [ E - > get ( ) . to_node ] . prev_connected_nodes . erase ( p_id ) ;
2020-07-27 08:18:37 +02:00
g - > nodes [ E - > get ( ) . to_node ] . node - > set_input_port_connected ( E - > get ( ) . to_port , false ) ;
2020-01-20 15:46:49 +01:00
}
2018-07-14 23:15:42 +02:00
}
E = N ;
}
_queue_update ( ) ;
}
2020-12-30 09:45:31 +01:00
void VisualShader : : replace_node ( Type p_type , int p_id , const StringName & p_new_class ) {
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
ERR_FAIL_COND ( p_id < 2 ) ;
Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND ( ! g - > nodes . has ( p_id ) ) ;
if ( g - > nodes [ p_id ] . node - > get_class_name ( ) = = p_new_class ) {
return ;
}
2021-06-18 00:03:09 +02:00
VisualShaderNode * vsn = Object : : cast_to < VisualShaderNode > ( ClassDB : : instantiate ( p_new_class ) ) ;
2022-05-23 12:58:57 +02:00
VisualShaderNode * prev_vsn = g - > nodes [ p_id ] . node . ptr ( ) ;
// Update connection data.
for ( int i = 0 ; i < vsn - > get_output_port_count ( ) ; i + + ) {
if ( i < prev_vsn - > get_output_port_count ( ) ) {
if ( prev_vsn - > is_output_port_connected ( i ) ) {
vsn - > set_output_port_connected ( i , true ) ;
}
if ( prev_vsn - > is_output_port_expandable ( i ) & & prev_vsn - > _is_output_port_expanded ( i ) & & vsn - > is_output_port_expandable ( i ) ) {
vsn - > _set_output_port_expanded ( i , true ) ;
int component_count = 0 ;
switch ( prev_vsn - > get_output_port_type ( i ) ) {
case VisualShaderNode : : PORT_TYPE_VECTOR_2D :
component_count = 2 ;
break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_3D :
component_count = 3 ;
break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_4D :
component_count = 4 ;
break ;
default :
break ;
}
for ( int j = 0 ; j < component_count ; j + + ) {
int sub_port = i + 1 + j ;
if ( prev_vsn - > is_output_port_connected ( sub_port ) ) {
vsn - > set_output_port_connected ( sub_port , true ) ;
}
}
i + = component_count ;
}
} else {
break ;
}
}
2021-01-15 19:10:32 +01:00
vsn - > connect ( " changed " , callable_mp ( this , & VisualShader : : _queue_update ) ) ;
2020-12-30 09:45:31 +01:00
g - > nodes [ p_id ] . node = Ref < VisualShaderNode > ( vsn ) ;
_queue_update ( ) ;
}
2018-07-14 23:15:42 +02:00
bool VisualShader : : is_node_connection ( Type p_type , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , false ) ;
const Graph * g = & graph [ p_type ] ;
2021-07-16 05:45:57 +02:00
for ( const Connection & E : g - > connections ) {
if ( E . from_node = = p_from_node & & E . from_port = = p_from_port & & E . to_node = = p_to_node & & E . to_port = = p_to_port ) {
2018-07-14 23:15:42 +02:00
return true ;
}
}
return false ;
}
2020-01-20 15:46:49 +01:00
bool VisualShader : : is_nodes_connected_relatively ( const Graph * p_graph , int p_node , int p_target ) const {
bool result = false ;
const VisualShader : : Node & node = p_graph - > nodes [ p_node ] ;
2021-07-16 05:45:57 +02:00
for ( const int & E : node . prev_connected_nodes ) {
if ( E = = p_target ) {
2020-01-20 15:46:49 +01:00
return true ;
}
2021-07-16 05:45:57 +02:00
result = is_nodes_connected_relatively ( p_graph , E , p_target ) ;
2020-01-20 15:46:49 +01:00
if ( result ) {
break ;
}
}
return result ;
}
2018-07-14 23:15:42 +02:00
bool VisualShader : : can_connect_nodes ( Type p_type , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , false ) ;
const Graph * g = & graph [ p_type ] ;
2020-05-14 16:41:43 +02:00
if ( ! g - > nodes . has ( p_from_node ) ) {
2018-07-14 23:15:42 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
2020-05-14 16:41:43 +02:00
if ( p_from_node = = p_to_node ) {
2019-04-24 07:44:48 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2019-04-24 07:44:48 +02:00
2020-12-20 16:45:53 +01:00
if ( p_from_port < 0 | | p_from_port > = g - > nodes [ p_from_node ] . node - > get_expanded_output_port_count ( ) ) {
2018-07-14 23:15:42 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
2020-05-14 16:41:43 +02:00
if ( ! g - > nodes . has ( p_to_node ) ) {
2018-07-14 23:15:42 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
2020-05-14 16:41:43 +02:00
if ( p_to_port < 0 | | p_to_port > = g - > nodes [ p_to_node ] . node - > get_input_port_count ( ) ) {
2018-07-14 23:15:42 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
VisualShaderNode : : PortType from_port_type = g - > nodes [ p_from_node ] . node - > get_output_port_type ( p_from_port ) ;
VisualShaderNode : : PortType to_port_type = g - > nodes [ p_to_node ] . node - > get_input_port_type ( p_to_port ) ;
2019-06-26 20:50:38 +02:00
if ( ! is_port_types_compatible ( from_port_type , to_port_type ) ) {
2018-07-14 23:15:42 +02:00
return false ;
}
2021-07-16 05:45:57 +02:00
for ( const Connection & E : g - > connections ) {
if ( E . from_node = = p_from_node & & E . from_port = = p_from_port & & E . to_node = = p_to_node & & E . to_port = = p_to_port ) {
2018-07-14 23:15:42 +02:00
return false ;
}
}
2020-05-14 16:41:43 +02:00
if ( is_nodes_connected_relatively ( g , p_from_node , p_to_node ) ) {
2020-01-20 15:46:49 +01:00
return false ;
2020-05-14 16:41:43 +02:00
}
2020-01-20 15:46:49 +01:00
2018-07-14 23:15:42 +02:00
return true ;
}
2019-06-26 20:50:38 +02:00
bool VisualShader : : is_port_types_compatible ( int p_a , int p_b ) const {
2022-02-01 09:32:01 +01:00
return MAX ( 0 , p_a - 4 ) = = ( MAX ( 0 , p_b - 4 ) ) ;
2019-06-26 20:50:38 +02:00
}
2019-05-12 14:09:39 +02:00
void VisualShader : : connect_nodes_forced ( Type p_type , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) {
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
Graph * g = & graph [ p_type ] ;
2021-02-18 22:57:41 +01:00
ERR_FAIL_COND ( ! g - > nodes . has ( p_from_node ) ) ;
2020-12-20 16:45:53 +01:00
ERR_FAIL_INDEX ( p_from_port , g - > nodes [ p_from_node ] . node - > get_expanded_output_port_count ( ) ) ;
2021-02-18 22:57:41 +01:00
ERR_FAIL_COND ( ! g - > nodes . has ( p_to_node ) ) ;
ERR_FAIL_INDEX ( p_to_port , g - > nodes [ p_to_node ] . node - > get_input_port_count ( ) ) ;
2019-05-12 14:09:39 +02:00
Connection c ;
c . from_node = p_from_node ;
c . from_port = p_from_port ;
c . to_node = p_to_node ;
c . to_port = p_to_port ;
g - > connections . push_back ( c ) ;
2020-01-20 15:46:49 +01:00
g - > nodes [ p_to_node ] . prev_connected_nodes . push_back ( p_from_node ) ;
2020-07-26 03:04:07 +02:00
g - > nodes [ p_from_node ] . node - > set_output_port_connected ( p_from_port , true ) ;
2020-07-27 08:18:37 +02:00
g - > nodes [ p_to_node ] . node - > set_input_port_connected ( p_to_port , true ) ;
2020-01-20 15:46:49 +01:00
2019-05-12 14:09:39 +02:00
_queue_update ( ) ;
}
2018-07-14 23:15:42 +02:00
Error VisualShader : : connect_nodes ( Type p_type , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , ERR_CANT_CONNECT ) ;
Graph * g = & graph [ p_type ] ;
ERR_FAIL_COND_V ( ! g - > nodes . has ( p_from_node ) , ERR_INVALID_PARAMETER ) ;
2020-12-20 16:45:53 +01:00
ERR_FAIL_INDEX_V ( p_from_port , g - > nodes [ p_from_node ] . node - > get_expanded_output_port_count ( ) , ERR_INVALID_PARAMETER ) ;
2018-07-14 23:15:42 +02:00
ERR_FAIL_COND_V ( ! g - > nodes . has ( p_to_node ) , ERR_INVALID_PARAMETER ) ;
ERR_FAIL_INDEX_V ( p_to_port , g - > nodes [ p_to_node ] . node - > get_input_port_count ( ) , ERR_INVALID_PARAMETER ) ;
VisualShaderNode : : PortType from_port_type = g - > nodes [ p_from_node ] . node - > get_output_port_type ( p_from_port ) ;
VisualShaderNode : : PortType to_port_type = g - > nodes [ p_to_node ] . node - > get_input_port_type ( p_to_port ) ;
2019-08-08 22:11:48 +02:00
ERR_FAIL_COND_V_MSG ( ! is_port_types_compatible ( from_port_type , to_port_type ) , ERR_INVALID_PARAMETER , " Incompatible port types (scalar/vec/bool) with transform. " ) ;
2018-07-14 23:15:42 +02:00
2021-07-24 15:46:25 +02:00
for ( const Connection & E : g - > connections ) {
2021-07-16 05:45:57 +02:00
if ( E . from_node = = p_from_node & & E . from_port = = p_from_port & & E . to_node = = p_to_node & & E . to_port = = p_to_port ) {
2018-07-14 23:15:42 +02:00
ERR_FAIL_V ( ERR_ALREADY_EXISTS ) ;
}
}
Connection c ;
c . from_node = p_from_node ;
c . from_port = p_from_port ;
c . to_node = p_to_node ;
c . to_port = p_to_port ;
g - > connections . push_back ( c ) ;
2020-01-20 15:46:49 +01:00
g - > nodes [ p_to_node ] . prev_connected_nodes . push_back ( p_from_node ) ;
2020-07-26 03:04:07 +02:00
g - > nodes [ p_from_node ] . node - > set_output_port_connected ( p_from_port , true ) ;
2020-07-27 08:18:37 +02:00
g - > nodes [ p_to_node ] . node - > set_input_port_connected ( p_to_port , true ) ;
2018-07-14 23:15:42 +02:00
_queue_update ( ) ;
return OK ;
}
2019-05-12 14:09:39 +02:00
2018-07-14 23:15:42 +02:00
void VisualShader : : disconnect_nodes ( Type p_type , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) {
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
Graph * g = & graph [ p_type ] ;
2021-07-16 05:45:57 +02:00
for ( const List < Connection > : : Element * E = g - > connections . front ( ) ; E ; E = E - > next ( ) ) {
2018-07-14 23:15:42 +02:00
if ( E - > get ( ) . from_node = = p_from_node & & E - > get ( ) . from_port = = p_from_port & & E - > get ( ) . to_node = = p_to_node & & E - > get ( ) . to_port = = p_to_port ) {
g - > connections . erase ( E ) ;
2020-01-20 15:46:49 +01:00
g - > nodes [ p_to_node ] . prev_connected_nodes . erase ( p_from_node ) ;
2020-07-26 03:04:07 +02:00
g - > nodes [ p_from_node ] . node - > set_output_port_connected ( p_from_port , false ) ;
2020-07-27 08:18:37 +02:00
g - > nodes [ p_to_node ] . node - > set_input_port_connected ( p_to_port , false ) ;
2018-07-14 23:15:42 +02:00
_queue_update ( ) ;
return ;
}
}
}
Array VisualShader : : _get_node_connections ( Type p_type ) const {
ERR_FAIL_INDEX_V ( p_type , TYPE_MAX , Array ( ) ) ;
const Graph * g = & graph [ p_type ] ;
Array ret ;
2021-07-16 05:45:57 +02:00
for ( const Connection & E : g - > connections ) {
2018-07-14 23:15:42 +02:00
Dictionary d ;
2021-07-16 05:45:57 +02:00
d [ " from_node " ] = E . from_node ;
d [ " from_port " ] = E . from_port ;
d [ " to_node " ] = E . to_node ;
d [ " to_port " ] = E . to_port ;
2018-07-14 23:15:42 +02:00
ret . push_back ( d ) ;
}
return ret ;
}
2019-05-12 14:09:39 +02:00
2018-07-14 23:15:42 +02:00
void VisualShader : : get_node_connections ( Type p_type , List < Connection > * r_connections ) const {
ERR_FAIL_INDEX ( p_type , TYPE_MAX ) ;
const Graph * g = & graph [ p_type ] ;
2021-07-16 05:45:57 +02:00
for ( const Connection & E : g - > connections ) {
r_connections - > push_back ( E ) ;
2018-07-14 23:15:42 +02:00
}
}
void VisualShader : : set_mode ( Mode p_mode ) {
2021-02-16 14:46:20 +01:00
ERR_FAIL_INDEX_MSG ( p_mode , Mode : : MODE_MAX , vformat ( " Invalid shader mode: %d. " , p_mode ) ) ;
2018-07-14 23:15:42 +02:00
if ( shader_mode = = p_mode ) {
return ;
}
//erase input/output connections
modes . clear ( ) ;
flags . clear ( ) ;
shader_mode = p_mode ;
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2021-08-09 22:13:42 +02:00
for ( KeyValue < int , Node > & E : graph [ i ] . nodes ) {
Ref < VisualShaderNodeInput > input = E . value . node ;
2018-07-14 23:15:42 +02:00
if ( input . is_valid ( ) ) {
input - > shader_mode = shader_mode ;
//input->input_index = 0;
}
}
Ref < VisualShaderNodeOutput > output = graph [ i ] . nodes [ NODE_ID_OUTPUT ] . node ;
output - > shader_mode = shader_mode ;
// clear connections since they are no longer valid
for ( List < Connection > : : Element * E = graph [ i ] . connections . front ( ) ; E ; ) {
bool keep = true ;
List < Connection > : : Element * N = E - > next ( ) ;
int from = E - > get ( ) . from_node ;
int to = E - > get ( ) . to_node ;
if ( ! graph [ i ] . nodes . has ( from ) ) {
keep = false ;
} else {
Ref < VisualShaderNode > from_node = graph [ i ] . nodes [ from ] . node ;
if ( from_node - > is_class ( " VisualShaderNodeOutput " ) | | from_node - > is_class ( " VisualShaderNodeInput " ) ) {
keep = false ;
}
}
if ( ! graph [ i ] . nodes . has ( to ) ) {
keep = false ;
} else {
Ref < VisualShaderNode > to_node = graph [ i ] . nodes [ to ] . node ;
if ( to_node - > is_class ( " VisualShaderNodeOutput " ) | | to_node - > is_class ( " VisualShaderNodeInput " ) ) {
keep = false ;
}
}
if ( ! keep ) {
graph [ i ] . connections . erase ( E ) ;
}
E = N ;
}
}
_queue_update ( ) ;
2021-02-10 21:18:45 +01:00
notify_property_list_changed ( ) ;
2018-07-14 23:15:42 +02:00
}
void VisualShader : : set_graph_offset ( const Vector2 & p_offset ) {
graph_offset = p_offset ;
}
Vector2 VisualShader : : get_graph_offset ( ) const {
return graph_offset ;
}
Shader : : Mode VisualShader : : get_mode ( ) const {
return shader_mode ;
}
2018-09-15 03:54:59 +02:00
bool VisualShader : : is_text_shader ( ) const {
return false ;
}
2018-07-14 23:15:42 +02:00
String VisualShader : : generate_preview_shader ( Type p_type , int p_node , int p_port , Vector < DefaultTextureParam > & default_tex_params ) const {
Ref < VisualShaderNode > node = get_node ( p_type , p_node ) ;
ERR_FAIL_COND_V ( ! node . is_valid ( ) , String ( ) ) ;
2020-12-20 16:45:53 +01:00
ERR_FAIL_COND_V ( p_port < 0 | | p_port > = node - > get_expanded_output_port_count ( ) , String ( ) ) ;
2018-07-14 23:15:42 +02:00
ERR_FAIL_COND_V ( node - > get_output_port_type ( p_port ) = = VisualShaderNode : : PORT_TYPE_TRANSFORM , String ( ) ) ;
StringBuilder global_code ;
2019-07-12 11:14:34 +02:00
StringBuilder global_code_per_node ;
2022-05-13 15:04:37 +02:00
HashMap < Type , StringBuilder > global_code_per_func ;
2018-07-14 23:15:42 +02:00
StringBuilder code ;
2022-05-19 17:00:06 +02:00
HashSet < StringName > classes ;
2018-07-14 23:15:42 +02:00
global_code + = String ( ) + " shader_type canvas_item; \n " ;
2019-08-20 18:34:09 +02:00
String global_expressions ;
for ( int i = 0 , index = 0 ; i < TYPE_MAX ; i + + ) {
2022-05-13 15:04:37 +02:00
for ( const KeyValue < int , Node > & E : graph [ i ] . nodes ) {
Ref < VisualShaderNodeGlobalExpression > global_expression = E . value . node ;
2019-08-20 18:34:09 +02:00
if ( global_expression . is_valid ( ) ) {
String expr = " " ;
expr + = " // " + global_expression - > get_caption ( ) + " : " + itos ( index + + ) + " \n " ;
expr + = global_expression - > generate_global ( get_mode ( ) , Type ( i ) , - 1 ) ;
2021-07-19 08:06:51 +02:00
expr = expr . replace ( " \n " , " \n " ) ;
2019-08-20 18:34:09 +02:00
expr + = " \n " ;
global_expressions + = expr ;
}
}
}
global_code + = " \n " ;
global_code + = global_expressions ;
2018-07-14 23:15:42 +02:00
//make it faster to go around through shader
VMap < ConnectionKey , const List < Connection > : : Element * > input_connections ;
VMap < ConnectionKey , const List < Connection > : : Element * > output_connections ;
for ( const List < Connection > : : Element * E = graph [ p_type ] . connections . front ( ) ; E ; E = E - > next ( ) ) {
ConnectionKey from_key ;
from_key . node = E - > get ( ) . from_node ;
from_key . port = E - > get ( ) . from_port ;
output_connections . insert ( from_key , E ) ;
ConnectionKey to_key ;
to_key . node = E - > get ( ) . to_node ;
to_key . port = E - > get ( ) . to_port ;
input_connections . insert ( to_key , E ) ;
}
code + = " \n void fragment() { \n " ;
2022-05-19 17:00:06 +02:00
HashSet < int > processed ;
2022-01-09 15:02:13 +01:00
Error err = _write_node ( p_type , & global_code , & global_code_per_node , & global_code_per_func , code , default_tex_params , input_connections , output_connections , p_node , processed , true , classes ) ;
2018-07-14 23:15:42 +02:00
ERR_FAIL_COND_V ( err ! = OK , String ( ) ) ;
2022-02-01 09:32:01 +01:00
switch ( node - > get_output_port_type ( p_port ) ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
code + = " COLOR.rgb = vec3(n_out " + itos ( p_node ) + " p " + itos ( p_port ) + " ); \n " ;
} break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
code + = " COLOR.rgb = vec3(float(n_out " + itos ( p_node ) + " p " + itos ( p_port ) + " )); \n " ;
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
code + = " COLOR.rgb = vec3(n_out " + itos ( p_node ) + " p " + itos ( p_port ) + " ? 1.0 : 0.0); \n " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
code + = " COLOR.rgb = vec3(n_out " + itos ( p_node ) + " p " + itos ( p_port ) + " , 0.0); \n " ;
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
code + = " COLOR.rgb = n_out " + itos ( p_node ) + " p " + itos ( p_port ) + " ; \n " ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
code + = " COLOR.rgb = n_out " + itos ( p_node ) + " p " + itos ( p_port ) + " .xyz; \n " ;
} break ;
2022-02-01 09:32:01 +01:00
default : {
code + = " COLOR.rgb = vec3(0.0); \n " ;
} break ;
2018-07-14 23:15:42 +02:00
}
2022-02-01 09:32:01 +01:00
2018-07-14 23:15:42 +02:00
code + = " } \n " ;
//set code secretly
global_code + = " \n \n " ;
String final_code = global_code ;
2019-07-12 11:14:34 +02:00
final_code + = global_code_per_node ;
2018-07-14 23:15:42 +02:00
final_code + = code ;
return final_code ;
}
2020-12-02 10:49:46 +01:00
String VisualShader : : validate_port_name ( const String & p_port_name , VisualShaderNode * p_node , int p_port_id , bool p_output ) const {
String name = p_port_name ;
2021-12-09 10:42:46 +01:00
if ( name . is_empty ( ) ) {
2020-12-02 10:49:46 +01:00
return String ( ) ;
}
2019-05-12 14:09:39 +02:00
2022-02-04 09:32:20 +01:00
while ( name . length ( ) & & ! is_ascii_char ( name [ 0 ] ) ) {
2019-05-12 14:09:39 +02:00
name = name . substr ( 1 , name . length ( ) - 1 ) ;
}
2021-12-09 10:42:46 +01:00
if ( ! name . is_empty ( ) ) {
2019-05-12 14:09:39 +02:00
String valid_name ;
for ( int i = 0 ; i < name . length ( ) ; i + + ) {
2022-02-04 09:32:20 +01:00
if ( is_ascii_identifier_char ( name [ i ] ) ) {
2019-05-12 14:09:39 +02:00
valid_name + = String : : chr ( name [ i ] ) ;
} else if ( name [ i ] = = ' ' ) {
valid_name + = " _ " ;
}
}
name = valid_name ;
2020-12-02 10:49:46 +01:00
} else {
return String ( ) ;
2019-05-12 14:09:39 +02:00
}
2020-12-02 10:49:46 +01:00
List < String > input_names ;
List < String > output_names ;
2019-05-12 14:09:39 +02:00
2020-12-02 10:49:46 +01:00
for ( int i = 0 ; i < p_node - > get_input_port_count ( ) ; i + + ) {
if ( ! p_output & & i = = p_port_id ) {
continue ;
2019-05-12 14:09:39 +02:00
}
2020-12-02 10:49:46 +01:00
if ( name = = p_node - > get_input_port_name ( i ) ) {
return String ( ) ;
2019-05-12 14:09:39 +02:00
}
}
2020-12-02 10:49:46 +01:00
for ( int i = 0 ; i < p_node - > get_output_port_count ( ) ; i + + ) {
if ( p_output & & i = = p_port_id ) {
continue ;
}
if ( name = = p_node - > get_output_port_name ( i ) ) {
return String ( ) ;
}
2019-05-12 14:09:39 +02:00
}
return name ;
}
2018-07-14 23:15:42 +02:00
String VisualShader : : validate_uniform_name ( const String & p_name , const Ref < VisualShaderNodeUniform > & p_uniform ) const {
String name = p_name ; //validate name first
2022-02-04 09:32:20 +01:00
while ( name . length ( ) & & ! is_ascii_char ( name [ 0 ] ) ) {
2018-07-14 23:15:42 +02:00
name = name . substr ( 1 , name . length ( ) - 1 ) ;
}
2021-12-09 10:42:46 +01:00
if ( ! name . is_empty ( ) ) {
2018-07-14 23:15:42 +02:00
String valid_name ;
for ( int i = 0 ; i < name . length ( ) ; i + + ) {
2022-02-04 09:32:20 +01:00
if ( is_ascii_identifier_char ( name [ i ] ) ) {
2018-07-14 23:15:42 +02:00
valid_name + = String : : chr ( name [ i ] ) ;
} else if ( name [ i ] = = ' ' ) {
valid_name + = " _ " ;
}
}
name = valid_name ;
}
2021-12-09 10:42:46 +01:00
if ( name . is_empty ( ) ) {
2018-07-14 23:15:42 +02:00
name = p_uniform - > get_caption ( ) ;
}
int attempt = 1 ;
while ( true ) {
bool exists = false ;
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < int , Node > & E : graph [ i ] . nodes ) {
Ref < VisualShaderNodeUniform > node = E . value . node ;
2018-07-14 23:15:42 +02:00
if ( node = = p_uniform ) { //do not test on self
continue ;
}
if ( node . is_valid ( ) & & node - > get_uniform_name ( ) = = name ) {
exists = true ;
break ;
}
}
if ( exists ) {
break ;
}
}
if ( exists ) {
//remove numbers, put new and try again
attempt + + ;
2022-02-04 09:32:20 +01:00
while ( name . length ( ) & & is_digit ( name [ name . length ( ) - 1 ] ) ) {
2018-07-14 23:15:42 +02:00
name = name . substr ( 0 , name . length ( ) - 1 ) ;
}
2021-12-09 10:42:46 +01:00
ERR_FAIL_COND_V ( name . is_empty ( ) , String ( ) ) ;
2018-07-14 23:15:42 +02:00
name + = itos ( attempt ) ;
} else {
break ;
}
}
return name ;
}
static const char * type_string [ VisualShader : : TYPE_MAX ] = {
" vertex " ,
" fragment " ,
2020-09-02 22:25:54 +02:00
" light " ,
2020-09-15 09:57:40 +02:00
" start " ,
2020-09-07 09:28:13 +02:00
" process " ,
2020-09-15 09:57:40 +02:00
" collide " ,
" start_custom " ,
" process_custom " ,
2021-04-17 19:16:03 +02:00
" sky " ,
2021-10-03 13:28:55 +02:00
" fog " ,
2018-07-14 23:15:42 +02:00
} ;
2020-09-07 09:28:13 +02:00
2018-07-14 23:15:42 +02:00
bool VisualShader : : _set ( const StringName & p_name , const Variant & p_value ) {
String name = p_name ;
if ( name = = " mode " ) {
set_mode ( Shader : : Mode ( int ( p_value ) ) ) ;
return true ;
} else if ( name . begins_with ( " flags/ " ) ) {
StringName flag = name . get_slicec ( ' / ' , 1 ) ;
bool enable = p_value ;
if ( enable ) {
flags . insert ( flag ) ;
} else {
flags . erase ( flag ) ;
}
_queue_update ( ) ;
return true ;
} else if ( name . begins_with ( " modes/ " ) ) {
String mode = name . get_slicec ( ' / ' , 1 ) ;
int value = p_value ;
if ( value = = 0 ) {
2019-02-13 09:23:29 +01:00
modes . erase ( mode ) ; //means it's default anyway, so don't store it
2018-07-14 23:15:42 +02:00
} else {
modes [ mode ] = value ;
}
_queue_update ( ) ;
return true ;
2022-01-09 15:02:13 +01:00
} else if ( name . begins_with ( " varyings/ " ) ) {
String var_name = name . get_slicec ( ' / ' , 1 ) ;
Varying value = Varying ( ) ;
value . name = var_name ;
if ( value . from_string ( p_value ) & & ! varyings . has ( var_name ) ) {
varyings [ var_name ] = value ;
varyings_list . push_back ( value ) ;
}
_queue_update ( ) ;
return true ;
2018-07-14 23:15:42 +02:00
} else if ( name . begins_with ( " nodes/ " ) ) {
String typestr = name . get_slicec ( ' / ' , 1 ) ;
Type type = TYPE_VERTEX ;
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
if ( typestr = = type_string [ i ] ) {
type = Type ( i ) ;
break ;
}
}
String index = name . get_slicec ( ' / ' , 2 ) ;
if ( index = = " connections " ) {
Vector < int > conns = p_value ;
if ( conns . size ( ) % 4 = = 0 ) {
for ( int i = 0 ; i < conns . size ( ) ; i + = 4 ) {
2019-05-12 14:09:39 +02:00
connect_nodes_forced ( type , conns [ i + 0 ] , conns [ i + 1 ] , conns [ i + 2 ] , conns [ i + 3 ] ) ;
2018-07-14 23:15:42 +02:00
}
}
return true ;
}
int id = index . to_int ( ) ;
String what = name . get_slicec ( ' / ' , 3 ) ;
if ( what = = " node " ) {
add_node ( type , p_value , Vector2 ( ) , id ) ;
return true ;
} else if ( what = = " position " ) {
set_node_position ( type , id , p_value ) ;
return true ;
2019-05-12 14:09:39 +02:00
} else if ( what = = " size " ) {
2020-10-04 11:11:58 +02:00
( ( VisualShaderNodeResizableBase * ) get_node ( type , id ) . ptr ( ) ) - > set_size ( p_value ) ;
2019-05-12 14:09:39 +02:00
return true ;
} else if ( what = = " input_ports " ) {
( ( VisualShaderNodeGroupBase * ) get_node ( type , id ) . ptr ( ) ) - > set_inputs ( p_value ) ;
return true ;
} else if ( what = = " output_ports " ) {
( ( VisualShaderNodeGroupBase * ) get_node ( type , id ) . ptr ( ) ) - > set_outputs ( p_value ) ;
return true ;
} else if ( what = = " expression " ) {
( ( VisualShaderNodeExpression * ) get_node ( type , id ) . ptr ( ) ) - > set_expression ( p_value ) ;
return true ;
2018-07-14 23:15:42 +02:00
}
}
return false ;
}
bool VisualShader : : _get ( const StringName & p_name , Variant & r_ret ) const {
String name = p_name ;
if ( name = = " mode " ) {
r_ret = get_mode ( ) ;
return true ;
} else if ( name . begins_with ( " flags/ " ) ) {
StringName flag = name . get_slicec ( ' / ' , 1 ) ;
r_ret = flags . has ( flag ) ;
return true ;
} else if ( name . begins_with ( " modes/ " ) ) {
String mode = name . get_slicec ( ' / ' , 1 ) ;
if ( modes . has ( mode ) ) {
r_ret = modes [ mode ] ;
} else {
r_ret = 0 ;
}
return true ;
2022-01-09 15:02:13 +01:00
} else if ( name . begins_with ( " varyings/ " ) ) {
String var_name = name . get_slicec ( ' / ' , 1 ) ;
if ( varyings . has ( var_name ) ) {
r_ret = varyings [ var_name ] . to_string ( ) ;
} else {
r_ret = String ( ) ;
}
return true ;
2018-07-14 23:15:42 +02:00
} else if ( name . begins_with ( " nodes/ " ) ) {
String typestr = name . get_slicec ( ' / ' , 1 ) ;
Type type = TYPE_VERTEX ;
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
if ( typestr = = type_string [ i ] ) {
type = Type ( i ) ;
break ;
}
}
String index = name . get_slicec ( ' / ' , 2 ) ;
if ( index = = " connections " ) {
Vector < int > conns ;
2021-07-16 05:45:57 +02:00
for ( const Connection & E : graph [ type ] . connections ) {
conns . push_back ( E . from_node ) ;
conns . push_back ( E . from_port ) ;
conns . push_back ( E . to_node ) ;
conns . push_back ( E . to_port ) ;
2018-07-14 23:15:42 +02:00
}
r_ret = conns ;
return true ;
}
int id = index . to_int ( ) ;
String what = name . get_slicec ( ' / ' , 3 ) ;
if ( what = = " node " ) {
r_ret = get_node ( type , id ) ;
return true ;
} else if ( what = = " position " ) {
r_ret = get_node_position ( type , id ) ;
return true ;
2019-05-12 14:09:39 +02:00
} else if ( what = = " size " ) {
2020-10-04 11:11:58 +02:00
r_ret = ( ( VisualShaderNodeResizableBase * ) get_node ( type , id ) . ptr ( ) ) - > get_size ( ) ;
2019-05-12 14:09:39 +02:00
return true ;
} else if ( what = = " input_ports " ) {
r_ret = ( ( VisualShaderNodeGroupBase * ) get_node ( type , id ) . ptr ( ) ) - > get_inputs ( ) ;
return true ;
} else if ( what = = " output_ports " ) {
r_ret = ( ( VisualShaderNodeGroupBase * ) get_node ( type , id ) . ptr ( ) ) - > get_outputs ( ) ;
return true ;
} else if ( what = = " expression " ) {
r_ret = ( ( VisualShaderNodeExpression * ) get_node ( type , id ) . ptr ( ) ) - > get_expression ( ) ;
return true ;
2018-07-14 23:15:42 +02:00
}
}
return false ;
}
2021-02-11 18:18:45 +01:00
void VisualShader : : reset_state ( ) {
# ifndef _MSC_VER
# warning everything needs to be cleared here
# endif
emit_changed ( ) ;
}
2020-02-25 15:50:49 +01:00
void VisualShader : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2018-07-14 23:15:42 +02:00
//mode
2022-05-19 08:08:47 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : INT , PNAME ( " mode " ) , PROPERTY_HINT_ENUM , " Node3D,CanvasItem,Particles,Sky,Fog " ) ) ;
2018-07-14 23:15:42 +02:00
//render modes
2022-05-13 15:04:37 +02:00
HashMap < String , String > blend_mode_enums ;
2022-05-19 17:00:06 +02:00
HashSet < String > toggles ;
2018-07-14 23:15:42 +02:00
2021-12-21 15:21:55 +01:00
const Vector < ShaderLanguage : : ModeInfo > & rmodes = ShaderTypes : : get_singleton ( ) - > get_modes ( RenderingServer : : ShaderMode ( shader_mode ) ) ;
for ( int i = 0 ; i < rmodes . size ( ) ; i + + ) {
const ShaderLanguage : : ModeInfo & info = rmodes [ i ] ;
if ( ! info . options . is_empty ( ) ) {
const String begin = String ( info . name ) ;
for ( int j = 0 ; j < info . options . size ( ) ; j + + ) {
2022-05-12 22:03:16 +02:00
const String option = String ( info . options [ j ] ) . capitalize ( ) ;
2021-12-21 15:21:55 +01:00
2018-07-14 23:15:42 +02:00
if ( ! blend_mode_enums . has ( begin ) ) {
blend_mode_enums [ begin ] = option ;
} else {
blend_mode_enums [ begin ] + = " , " + option ;
}
}
2021-12-21 15:21:55 +01:00
} else {
toggles . insert ( String ( info . name ) ) ;
2018-07-14 23:15:42 +02:00
}
}
2021-08-09 22:13:42 +02:00
for ( const KeyValue < String , String > & E : blend_mode_enums ) {
2022-05-19 08:08:47 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : INT , vformat ( " %s/%s " , PNAME ( " modes " ) , E . key ) , PROPERTY_HINT_ENUM , E . value ) ) ;
2018-07-14 23:15:42 +02:00
}
2022-05-19 01:43:40 +02:00
for ( const String & E : toggles ) {
p_list - > push_back ( PropertyInfo ( Variant : : BOOL , vformat ( " %s/%s " , PNAME ( " flags " ) , E ) ) ) ;
2018-07-14 23:15:42 +02:00
}
2022-01-09 15:02:13 +01:00
for ( const KeyValue < String , Varying > & E : varyings ) {
2022-05-19 08:08:47 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING , vformat ( " %s/%s " , PNAME ( " varyings " ) , E . key ) ) ) ;
2022-01-09 15:02:13 +01:00
}
2018-07-14 23:15:42 +02:00
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < int , Node > & E : graph [ i ] . nodes ) {
2018-07-14 23:15:42 +02:00
String prop_name = " nodes/ " ;
prop_name + = type_string [ i ] ;
2021-08-09 22:13:42 +02:00
prop_name + = " / " + itos ( E . key ) ;
2018-07-14 23:15:42 +02:00
2021-08-09 22:13:42 +02:00
if ( E . key ! = NODE_ID_OUTPUT ) {
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : OBJECT , prop_name + " /node " , PROPERTY_HINT_RESOURCE_TYPE , " VisualShaderNode " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE ) ) ;
2018-07-14 23:15:42 +02:00
}
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : VECTOR2 , prop_name + " /position " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
2019-05-12 14:09:39 +02:00
2021-08-09 22:13:42 +02:00
if ( Object : : cast_to < VisualShaderNodeGroupBase > ( E . value . node . ptr ( ) ) ! = nullptr ) {
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : VECTOR2 , prop_name + " /size " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : STRING , prop_name + " /input_ports " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
p_list - > push_back ( PropertyInfo ( Variant : : STRING , prop_name + " /output_ports " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
2019-05-12 14:09:39 +02:00
}
2021-08-09 22:13:42 +02:00
if ( Object : : cast_to < VisualShaderNodeExpression > ( E . value . node . ptr ( ) ) ! = nullptr ) {
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : STRING , prop_name + " /expression " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
2019-05-12 14:09:39 +02:00
}
2018-07-14 23:15:42 +02:00
}
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : PACKED_INT32_ARRAY , " nodes/ " + String ( type_string [ i ] ) + " /connections " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
2018-07-14 23:15:42 +02:00
}
}
2022-05-19 17:00:06 +02:00
Error VisualShader : : _write_node ( Type type , StringBuilder * global_code , StringBuilder * global_code_per_node , HashMap < Type , StringBuilder > * global_code_per_func , StringBuilder & code , Vector < VisualShader : : DefaultTextureParam > & def_tex_params , const VMap < ConnectionKey , const List < Connection > : : Element * > & input_connections , const VMap < ConnectionKey , const List < Connection > : : Element * > & output_connections , int node , HashSet < int > & processed , bool for_preview , HashSet < StringName > & r_classes ) const {
2018-07-14 23:15:42 +02:00
const Ref < VisualShaderNode > vsnode = graph [ type ] . nodes [ node ] . node ;
2021-05-27 21:17:58 +02:00
if ( vsnode - > is_disabled ( ) ) {
code + = " // " + vsnode - > get_caption ( ) + " : " + itos ( node ) + " \n " ;
2021-07-19 08:06:51 +02:00
code + = " // Node is disabled and code is not generated. \n " ;
2021-05-27 21:17:58 +02:00
return OK ;
}
2018-07-14 23:15:42 +02:00
//check inputs recursively first
int input_count = vsnode - > get_input_port_count ( ) ;
for ( int i = 0 ; i < input_count ; i + + ) {
ConnectionKey ck ;
ck . node = node ;
ck . port = i ;
if ( input_connections . has ( ck ) ) {
int from_node = input_connections [ ck ] - > get ( ) . from_node ;
if ( processed . has ( from_node ) ) {
continue ;
}
2019-07-12 11:14:34 +02:00
Error err = _write_node ( type , global_code , global_code_per_node , global_code_per_func , code , def_tex_params , input_connections , output_connections , from_node , processed , for_preview , r_classes ) ;
2020-05-14 16:41:43 +02:00
if ( err ) {
2018-07-14 23:15:42 +02:00
return err ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
}
}
// then this node
2020-07-26 03:04:07 +02:00
Vector < VisualShader : : DefaultTextureParam > params = vsnode - > get_default_texture_parameters ( type , node ) ;
for ( int i = 0 ; i < params . size ( ) ; i + + ) {
def_tex_params . push_back ( params [ i ] ) ;
}
Ref < VisualShaderNodeInput > input = vsnode ;
bool skip_global = input . is_valid ( ) & & for_preview ;
if ( ! skip_global ) {
2020-07-28 10:02:57 +02:00
Ref < VisualShaderNodeUniform > uniform = vsnode ;
if ( ! uniform . is_valid ( ) | | ! uniform - > is_global_code_generated ( ) ) {
2022-01-09 15:02:13 +01:00
if ( global_code ) {
* global_code + = vsnode - > generate_global ( get_mode ( ) , type , node ) ;
}
2020-07-28 10:02:57 +02:00
}
2020-07-26 03:04:07 +02:00
String class_name = vsnode - > get_class_name ( ) ;
if ( class_name = = " VisualShaderNodeCustom " ) {
class_name = vsnode - > get_script_instance ( ) - > get_script ( ) - > get_path ( ) ;
}
if ( ! r_classes . has ( class_name ) ) {
2022-01-09 15:02:13 +01:00
if ( global_code_per_node ) {
* global_code_per_node + = vsnode - > generate_global_per_node ( get_mode ( ) , node ) ;
}
2020-07-26 03:04:07 +02:00
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2022-01-09 15:02:13 +01:00
if ( global_code_per_func ) {
( * global_code_per_func ) [ Type ( i ) ] + = vsnode - > generate_global_per_func ( get_mode ( ) , Type ( i ) , node ) ;
}
2020-07-26 03:04:07 +02:00
}
r_classes . insert ( class_name ) ;
}
}
if ( ! vsnode - > is_code_generated ( ) ) { // just generate globals and ignore locals
processed . insert ( node ) ;
return OK ;
}
2020-09-15 09:57:40 +02:00
String node_name = " // " + vsnode - > get_caption ( ) + " : " + itos ( node ) + " \n " ;
String node_code ;
2018-07-14 23:15:42 +02:00
Vector < String > input_vars ;
input_vars . resize ( vsnode - > get_input_port_count ( ) ) ;
String * inputs = input_vars . ptrw ( ) ;
for ( int i = 0 ; i < input_count ; i + + ) {
ConnectionKey ck ;
ck . node = node ;
ck . port = i ;
if ( input_connections . has ( ck ) ) {
//connected to something, use that output
int from_node = input_connections [ ck ] - > get ( ) . from_node ;
2021-05-27 21:17:58 +02:00
if ( graph [ type ] . nodes [ from_node ] . node - > is_disabled ( ) ) {
continue ;
}
2018-07-14 23:15:42 +02:00
int from_port = input_connections [ ck ] - > get ( ) . from_port ;
VisualShaderNode : : PortType in_type = vsnode - > get_input_port_type ( i ) ;
VisualShaderNode : : PortType out_type = graph [ type ] . nodes [ from_node ] . node - > get_output_port_type ( from_port ) ;
String src_var = " n_out " + itos ( from_node ) + " p " + itos ( from_port ) ;
2019-10-01 10:51:50 +02:00
if ( in_type = = VisualShaderNode : : PORT_TYPE_SAMPLER & & out_type = = VisualShaderNode : : PORT_TYPE_SAMPLER ) {
2019-11-04 16:50:33 +01:00
VisualShaderNode * ptr = const_cast < VisualShaderNode * > ( graph [ type ] . nodes [ from_node ] . node . ptr ( ) ) ;
if ( ptr - > has_method ( " get_input_real_name " ) ) {
inputs [ i ] = ptr - > call ( " get_input_real_name " ) ;
} else if ( ptr - > has_method ( " get_uniform_name " ) ) {
inputs [ i ] = ptr - > call ( " get_uniform_name " ) ;
2019-10-01 10:51:50 +02:00
} else {
2019-11-04 16:50:33 +01:00
inputs [ i ] = " " ;
2019-10-01 10:51:50 +02:00
}
} else if ( in_type = = out_type ) {
2018-07-14 23:15:42 +02:00
inputs [ i ] = src_var ;
2022-02-01 09:32:01 +01:00
} else {
switch ( in_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
switch ( out_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
inputs [ i ] = " float( " + src_var + " ) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
inputs [ i ] = " ( " + src_var + " ? 1.0 : 0.0) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
2022-04-12 19:09:29 +02:00
inputs [ i ] = " dot( " + src_var + " , vec2(0.5, 0.5)) " ;
2022-02-01 09:32:01 +01:00
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
inputs [ i ] = " dot( " + src_var + " , vec3(0.333333, 0.333333, 0.333333)) " ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
inputs [ i ] = " dot( " + src_var + " , vec4(0.25, 0.25, 0.25, 0.25)) " ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
switch ( out_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
inputs [ i ] = " int( " + src_var + " ) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
inputs [ i ] = " ( " + src_var + " ? 1 : 0) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
2022-04-12 19:09:29 +02:00
inputs [ i ] = " dot(float( " + src_var + " ), vec2(0.5, 0.5)) " ;
2022-02-01 09:32:01 +01:00
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
inputs [ i ] = " dot(float( " + src_var + " ), vec3(0.333333, 0.333333, 0.333333)) " ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
inputs [ i ] = " dot(float( " + src_var + " ), vec4(0.25, 0.25, 0.25, 0.25)) " ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
switch ( out_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
inputs [ i ] = src_var + " > 0.0 ? true : false " ;
} break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
inputs [ i ] = src_var + " > 0 ? true : false " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
inputs [ i ] = " all(bvec2( " + src_var + " )) " ;
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
inputs [ i ] = " all(bvec3( " + src_var + " )) " ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
inputs [ i ] = " all(bvec4( " + src_var + " )) " ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
switch ( out_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
inputs [ i ] = " vec2( " + src_var + " ) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
inputs [ i ] = " vec2(float( " + src_var + " )) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
inputs [ i ] = " vec2( " + src_var + " ? 1.0 : 0.0) " ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D :
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
2022-02-01 09:32:01 +01:00
inputs [ i ] = " vec2( " + src_var + " .xy) " ;
} break ;
default :
break ;
}
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
switch ( out_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
inputs [ i ] = " vec3( " + src_var + " ) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
inputs [ i ] = " vec3(float( " + src_var + " )) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
inputs [ i ] = " vec3( " + src_var + " ? 1.0 : 0.0) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
inputs [ i ] = " vec3( " + src_var + " , 0.0) " ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
inputs [ i ] = " vec3( " + src_var + " .xyz) " ;
} break ;
default :
break ;
}
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
switch ( out_type ) {
case VisualShaderNode : : PORT_TYPE_SCALAR : {
inputs [ i ] = " vec4( " + src_var + " ) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT : {
inputs [ i ] = " vec4(float( " + src_var + " )) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_BOOLEAN : {
inputs [ i ] = " vec4( " + src_var + " ? 1.0 : 0.0) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
inputs [ i ] = " vec4( " + src_var + " , 0.0, 0.0) " ;
} break ;
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
inputs [ i ] = " vec4( " + src_var + " , 0.0) " ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
}
} break ;
default :
break ;
}
2018-07-14 23:15:42 +02:00
}
} else {
2020-07-27 08:18:37 +02:00
if ( ! vsnode - > is_generate_input_var ( i ) ) {
continue ;
}
2018-07-14 23:15:42 +02:00
Variant defval = vsnode - > get_input_port_default_value ( i ) ;
2020-02-25 15:50:49 +01:00
if ( defval . get_type ( ) = = Variant : : FLOAT ) {
2018-07-14 23:15:42 +02:00
float val = defval ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
2021-07-19 08:06:51 +02:00
node_code + = " float " + inputs [ i ] + " = " + vformat ( " %.5f " , val ) + " ; \n " ;
2020-02-25 15:50:49 +01:00
} else if ( defval . get_type ( ) = = Variant : : INT ) {
int val = defval ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
2021-07-19 08:06:51 +02:00
node_code + = " int " + inputs [ i ] + " = " + itos ( val ) + " ; \n " ;
2019-02-22 18:38:58 +01:00
} else if ( defval . get_type ( ) = = Variant : : BOOL ) {
bool val = defval ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
2021-07-19 08:06:51 +02:00
node_code + = " bool " + inputs [ i ] + " = " + ( val ? " true " : " false " ) + " ; \n " ;
2022-02-01 09:32:01 +01:00
} else if ( defval . get_type ( ) = = Variant : : VECTOR2 ) {
Vector2 val = defval ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
node_code + = " vec2 " + inputs [ i ] + " = " + vformat ( " vec2(%.5f, %.5f); \n " , val . x , val . y ) ;
2018-07-14 23:15:42 +02:00
} else if ( defval . get_type ( ) = = Variant : : VECTOR3 ) {
Vector3 val = defval ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
2021-07-19 08:06:51 +02:00
node_code + = " vec3 " + inputs [ i ] + " = " + vformat ( " vec3(%.5f, %.5f, %.5f); \n " , val . x , val . y , val . z ) ;
2022-04-12 19:09:29 +02:00
} else if ( defval . get_type ( ) = = Variant : : QUATERNION ) {
Quaternion val = defval ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
node_code + = " vec4 " + inputs [ i ] + " = " + vformat ( " vec4(%.5f, %.5f, %.5f, %.5f); \n " , val . x , val . y , val . z , val . w ) ;
2021-04-28 09:36:08 +02:00
} else if ( defval . get_type ( ) = = Variant : : TRANSFORM3D ) {
2020-10-17 07:08:21 +02:00
Transform3D val = defval ;
2018-07-14 23:15:42 +02:00
val . basis . transpose ( ) ;
inputs [ i ] = " n_in " + itos ( node ) + " p " + itos ( i ) ;
Array values ;
2018-09-27 13:11:41 +02:00
for ( int j = 0 ; j < 3 ; j + + ) {
values . push_back ( val . basis [ j ] . x ) ;
values . push_back ( val . basis [ j ] . y ) ;
values . push_back ( val . basis [ j ] . z ) ;
2018-07-14 23:15:42 +02:00
}
values . push_back ( val . origin . x ) ;
values . push_back ( val . origin . y ) ;
values . push_back ( val . origin . z ) ;
bool err = false ;
2021-07-19 08:06:51 +02:00
node_code + = " mat4 " + 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 ) ;
2018-07-14 23:15:42 +02:00
} else {
//will go empty, node is expected to know what it is doing at this point and handle it
}
}
}
int output_count = vsnode - > get_output_port_count ( ) ;
2020-12-20 16:45:53 +01:00
int initial_output_count = output_count ;
2022-05-13 15:04:37 +02:00
HashMap < int , bool > expanded_output_ports ;
2020-12-20 16:45:53 +01:00
for ( int i = 0 ; i < initial_output_count ; i + + ) {
bool expanded = false ;
if ( vsnode - > is_output_port_expandable ( i ) & & vsnode - > _is_output_port_expanded ( i ) ) {
expanded = true ;
2022-02-01 09:32:01 +01:00
switch ( vsnode - > get_output_port_type ( i ) ) {
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
output_count + = 2 ;
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
output_count + = 3 ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
output_count + = 4 ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2020-12-20 16:45:53 +01:00
}
}
expanded_output_ports . insert ( i , expanded ) ;
}
2018-07-14 23:15:42 +02:00
Vector < String > output_vars ;
2020-12-20 16:45:53 +01:00
output_vars . resize ( output_count ) ;
2018-07-14 23:15:42 +02:00
String * outputs = output_vars . ptrw ( ) ;
2020-01-27 10:10:51 +01:00
if ( vsnode - > is_simple_decl ( ) ) { // less code to generate for some simple_decl nodes
2020-12-20 16:45:53 +01:00
for ( int i = 0 , j = 0 ; i < initial_output_count ; i + + , j + + ) {
String var_name = " n_out " + itos ( node ) + " p " + itos ( j ) ;
2020-01-27 10:10:51 +01:00
switch ( vsnode - > get_output_port_type ( i ) ) {
2020-05-10 13:00:47 +02:00
case VisualShaderNode : : PORT_TYPE_SCALAR :
outputs [ i ] = " float " + var_name ;
break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT :
outputs [ i ] = " int " + var_name ;
break ;
2022-02-01 09:32:01 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_2D :
outputs [ i ] = " vec2 " + var_name ;
break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D :
2020-05-10 13:00:47 +02:00
outputs [ i ] = " vec3 " + var_name ;
break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D :
outputs [ i ] = " vec4 " + var_name ;
break ;
2020-05-10 13:00:47 +02:00
case VisualShaderNode : : PORT_TYPE_BOOLEAN :
outputs [ i ] = " bool " + var_name ;
break ;
case VisualShaderNode : : PORT_TYPE_TRANSFORM :
outputs [ i ] = " mat4 " + var_name ;
break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2020-01-27 10:10:51 +01:00
}
2020-12-20 16:45:53 +01:00
if ( expanded_output_ports [ i ] ) {
2022-02-01 09:32:01 +01:00
switch ( vsnode - > get_output_port_type ( i ) ) {
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
j + = 2 ;
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
j + = 3 ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
j + = 4 ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2020-12-20 16:45:53 +01:00
}
}
2020-01-27 10:10:51 +01:00
}
2018-07-14 23:15:42 +02:00
2020-01-27 10:10:51 +01:00
} else {
2020-12-20 16:45:53 +01:00
for ( int i = 0 , j = 0 ; i < initial_output_count ; i + + , j + + ) {
outputs [ i ] = " n_out " + itos ( node ) + " p " + itos ( j ) ;
2020-01-27 10:10:51 +01:00
switch ( vsnode - > get_output_port_type ( i ) ) {
2020-05-10 13:00:47 +02:00
case VisualShaderNode : : PORT_TYPE_SCALAR :
2021-07-19 08:06:51 +02:00
code + = " float " + outputs [ i ] + " ; \n " ;
2020-05-10 13:00:47 +02:00
break ;
case VisualShaderNode : : PORT_TYPE_SCALAR_INT :
2021-07-19 08:06:51 +02:00
code + = " int " + outputs [ i ] + " ; \n " ;
2020-05-10 13:00:47 +02:00
break ;
2022-02-01 09:32:01 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_2D :
code + = " vec2 " + outputs [ i ] + " ; \n " ;
break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D :
2021-07-19 08:06:51 +02:00
code + = " vec3 " + outputs [ i ] + " ; \n " ;
2020-05-10 13:00:47 +02:00
break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D :
code + = " vec4 " + outputs [ i ] + " ; \n " ;
break ;
2020-05-10 13:00:47 +02:00
case VisualShaderNode : : PORT_TYPE_BOOLEAN :
2021-07-19 08:06:51 +02:00
code + = " bool " + outputs [ i ] + " ; \n " ;
2020-05-10 13:00:47 +02:00
break ;
case VisualShaderNode : : PORT_TYPE_TRANSFORM :
2021-07-19 08:06:51 +02:00
code + = " mat4 " + outputs [ i ] + " ; \n " ;
2020-05-10 13:00:47 +02:00
break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2019-04-09 17:08:36 +02:00
}
2020-12-20 16:45:53 +01:00
if ( expanded_output_ports [ i ] ) {
2022-02-01 09:32:01 +01:00
switch ( vsnode - > get_output_port_type ( i ) ) {
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
j + = 2 ;
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
j + = 3 ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
j + = 4 ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2020-12-20 16:45:53 +01:00
}
}
2018-07-14 23:15:42 +02:00
}
}
2020-09-15 09:57:40 +02:00
node_code + = vsnode - > generate_code ( get_mode ( ) , type , node , inputs , outputs , for_preview ) ;
2021-12-09 10:42:46 +01:00
if ( ! node_code . is_empty ( ) ) {
2020-09-15 09:57:40 +02:00
code + = node_name ;
code + = node_code ;
}
2019-01-21 20:07:53 +01:00
2020-12-20 16:45:53 +01:00
for ( int i = 0 ; i < output_count ; i + + ) {
if ( expanded_output_ports [ i ] ) {
2022-02-01 09:32:01 +01:00
switch ( vsnode - > get_output_port_type ( i ) ) {
case VisualShaderNode : : PORT_TYPE_VECTOR_2D : {
if ( vsnode - > is_output_port_connected ( i + 1 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 1 ) ) ) { // red-component
String r = " n_out " + itos ( node ) + " p " + itos ( i + 1 ) ;
code + = " float " + r + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .r; \n " ;
outputs [ i + 1 ] = r ;
2020-12-20 16:45:53 +01:00
}
2022-02-01 09:32:01 +01:00
if ( vsnode - > is_output_port_connected ( i + 2 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 2 ) ) ) { // green-component
String g = " n_out " + itos ( node ) + " p " + itos ( i + 2 ) ;
code + = " float " + g + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .g; \n " ;
outputs [ i + 2 ] = g ;
}
i + = 2 ;
} break ;
2022-02-06 18:15:28 +01:00
case VisualShaderNode : : PORT_TYPE_VECTOR_3D : {
2022-02-01 09:32:01 +01:00
if ( vsnode - > is_output_port_connected ( i + 1 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 1 ) ) ) { // red-component
String r = " n_out " + itos ( node ) + " p " + itos ( i + 1 ) ;
code + = " float " + r + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .r; \n " ;
outputs [ i + 1 ] = r ;
2020-12-20 16:45:53 +01:00
}
2022-02-01 09:32:01 +01:00
if ( vsnode - > is_output_port_connected ( i + 2 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 2 ) ) ) { // green-component
String g = " n_out " + itos ( node ) + " p " + itos ( i + 2 ) ;
code + = " float " + g + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .g; \n " ;
outputs [ i + 2 ] = g ;
2020-12-20 16:45:53 +01:00
}
2022-02-01 09:32:01 +01:00
if ( vsnode - > is_output_port_connected ( i + 3 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 3 ) ) ) { // blue-component
String b = " n_out " + itos ( node ) + " p " + itos ( i + 3 ) ;
code + = " float " + b + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .b; \n " ;
outputs [ i + 3 ] = b ;
}
i + = 3 ;
} break ;
2022-04-12 19:09:29 +02:00
case VisualShaderNode : : PORT_TYPE_VECTOR_4D : {
if ( vsnode - > is_output_port_connected ( i + 1 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 1 ) ) ) { // red-component
String r = " n_out " + itos ( node ) + " p " + itos ( i + 1 ) ;
code + = " float " + r + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .r; \n " ;
outputs [ i + 1 ] = r ;
}
if ( vsnode - > is_output_port_connected ( i + 2 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 2 ) ) ) { // green-component
String g = " n_out " + itos ( node ) + " p " + itos ( i + 2 ) ;
code + = " float " + g + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .g; \n " ;
outputs [ i + 2 ] = g ;
}
if ( vsnode - > is_output_port_connected ( i + 3 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 3 ) ) ) { // blue-component
String b = " n_out " + itos ( node ) + " p " + itos ( i + 3 ) ;
code + = " float " + b + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .b; \n " ;
outputs [ i + 3 ] = b ;
}
if ( vsnode - > is_output_port_connected ( i + 4 ) | | ( for_preview & & vsnode - > get_output_port_for_preview ( ) = = ( i + 4 ) ) ) { // alpha-component
2022-04-22 19:31:23 +02:00
String a = " n_out " + itos ( node ) + " p " + itos ( i + 4 ) ;
code + = " float " + a + " = n_out " + itos ( node ) + " p " + itos ( i ) + " .a; \n " ;
outputs [ i + 4 ] = a ;
2022-04-12 19:09:29 +02:00
}
i + = 4 ;
} break ;
2022-02-01 09:32:01 +01:00
default :
break ;
2020-12-20 16:45:53 +01:00
}
}
}
2022-04-22 19:31:23 +02:00
if ( ! node_code . is_empty ( ) ) {
code + = " \n " ;
}
2018-07-14 23:15:42 +02:00
code + = " \n " ; //
processed . insert ( node ) ;
return OK ;
}
2020-09-07 09:28:13 +02:00
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 ) {
2020-09-15 09:57:40 +02:00
if ( p_func_name = = " start_custom " | | p_func_name = = " process_custom " | | p_func_name = = " collide " ) {
2020-09-07 09:28:13 +02:00
return true ;
}
}
return false ;
}
return true ;
}
2018-07-14 23:15:42 +02:00
void VisualShader : : _update_shader ( ) const {
2021-02-10 19:22:13 +01:00
if ( ! dirty . is_set ( ) ) {
2018-07-14 23:15:42 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-07-14 23:15:42 +02:00
2021-02-10 19:22:13 +01:00
dirty . clear ( ) ;
2018-07-14 23:15:42 +02:00
StringBuilder global_code ;
2019-07-12 11:14:34 +02:00
StringBuilder global_code_per_node ;
2022-05-13 15:04:37 +02:00
HashMap < Type , StringBuilder > global_code_per_func ;
2018-07-14 23:15:42 +02:00
StringBuilder code ;
Vector < VisualShader : : DefaultTextureParam > default_tex_params ;
2022-05-19 17:00:06 +02:00
HashSet < StringName > classes ;
2022-05-13 15:04:37 +02:00
HashMap < int , int > insertion_pos ;
2021-10-03 13:28:55 +02:00
static const char * shader_mode_str [ Shader : : MODE_MAX ] = { " spatial " , " canvas_item " , " particles " , " sky " , " fog " } ;
2018-07-14 23:15:42 +02:00
global_code + = String ( ) + " shader_type " + shader_mode_str [ shader_mode ] + " ; \n " ;
String render_mode ;
{
2021-12-21 15:21:55 +01:00
const Vector < ShaderLanguage : : ModeInfo > & rmodes = ShaderTypes : : get_singleton ( ) - > get_modes ( RenderingServer : : ShaderMode ( shader_mode ) ) ;
Vector < String > flag_names ;
// Add enum modes first.
for ( int i = 0 ; i < rmodes . size ( ) ; i + + ) {
const ShaderLanguage : : ModeInfo & info = rmodes [ i ] ;
const String temp = String ( info . name ) ;
if ( ! info . options . is_empty ( ) ) {
if ( modes . has ( temp ) & & modes [ temp ] < info . options . size ( ) ) {
if ( ! render_mode . is_empty ( ) ) {
render_mode + = " , " ;
2018-07-14 23:15:42 +02:00
}
2021-12-21 15:21:55 +01:00
render_mode + = temp + " _ " + info . options [ modes [ temp ] ] ;
2018-07-14 23:15:42 +02:00
}
2021-12-21 15:21:55 +01:00
} else if ( flags . has ( temp ) ) {
flag_names . push_back ( temp ) ;
2018-07-14 23:15:42 +02:00
}
}
2021-12-21 15:21:55 +01:00
// Add flags afterward.
for ( int i = 0 ; i < flag_names . size ( ) ; i + + ) {
if ( ! render_mode . is_empty ( ) ) {
render_mode + = " , " ;
2018-07-14 23:15:42 +02:00
}
2021-12-21 15:21:55 +01:00
render_mode + = flag_names [ i ] ;
2018-07-14 23:15:42 +02:00
}
}
2021-12-09 10:42:46 +01:00
if ( ! render_mode . is_empty ( ) ) {
2018-07-14 23:15:42 +02:00
global_code + = " render_mode " + render_mode + " ; \n \n " ;
}
2021-10-03 13:28:55 +02:00
static const char * func_name [ TYPE_MAX ] = { " vertex " , " fragment " , " light " , " start " , " process " , " collide " , " start_custom " , " process_custom " , " sky " , " fog " } ;
2018-07-14 23:15:42 +02:00
2019-08-18 07:09:05 +02:00
String global_expressions ;
2022-05-19 17:00:06 +02:00
HashSet < String > used_uniform_names ;
2020-07-28 10:02:57 +02:00
List < VisualShaderNodeUniform * > uniforms ;
2022-05-13 15:04:37 +02:00
HashMap < int , List < int > > emitters ;
HashMap < int , List < int > > varying_setters ;
2020-07-28 10:02:57 +02:00
2019-08-18 07:09:05 +02:00
for ( int i = 0 , index = 0 ; i < TYPE_MAX ; i + + ) {
2020-09-07 09:28:13 +02:00
if ( ! has_func_name ( RenderingServer : : ShaderMode ( shader_mode ) , func_name [ i ] ) ) {
2020-03-25 10:22:29 +01:00
continue ;
}
2022-05-13 15:04:37 +02:00
for ( const KeyValue < int , Node > & E : graph [ i ] . nodes ) {
Ref < VisualShaderNodeGlobalExpression > global_expression = E . value . node ;
2019-08-18 07:09:05 +02:00
if ( global_expression . is_valid ( ) ) {
String expr = " " ;
expr + = " // " + global_expression - > get_caption ( ) + " : " + itos ( index + + ) + " \n " ;
expr + = global_expression - > generate_global ( get_mode ( ) , Type ( i ) , - 1 ) ;
2021-07-19 08:06:51 +02:00
expr = expr . replace ( " \n " , " \n " ) ;
2019-08-18 07:09:05 +02:00
expr + = " \n " ;
global_expressions + = expr ;
}
2022-05-13 15:04:37 +02:00
Ref < VisualShaderNodeUniformRef > uniform_ref = E . value . node ;
2020-07-28 10:02:57 +02:00
if ( uniform_ref . is_valid ( ) ) {
used_uniform_names . insert ( uniform_ref - > get_uniform_name ( ) ) ;
}
2022-05-13 15:04:37 +02:00
Ref < VisualShaderNodeUniform > uniform = E . value . node ;
2020-07-28 10:02:57 +02:00
if ( uniform . is_valid ( ) ) {
uniforms . push_back ( uniform . ptr ( ) ) ;
}
2022-05-13 15:04:37 +02:00
Ref < VisualShaderNodeVaryingSetter > varying_setter = E . value . node ;
2022-01-09 15:02:13 +01:00
if ( varying_setter . is_valid ( ) & & varying_setter - > is_input_port_connected ( 0 ) ) {
if ( ! varying_setters . has ( i ) ) {
varying_setters . insert ( i , List < int > ( ) ) ;
}
2022-05-13 15:04:37 +02:00
varying_setters [ i ] . push_back ( E . key ) ;
2022-01-09 15:02:13 +01:00
}
2022-05-13 15:04:37 +02:00
Ref < VisualShaderNodeParticleEmit > emit_particle = E . value . node ;
2020-09-15 09:57:40 +02:00
if ( emit_particle . is_valid ( ) ) {
if ( ! emitters . has ( i ) ) {
emitters . insert ( i , List < int > ( ) ) ;
}
2022-05-13 15:04:37 +02:00
emitters [ i ] . push_back ( E . key ) ;
2020-09-15 09:57:40 +02:00
}
2020-07-28 10:02:57 +02:00
}
}
for ( int i = 0 ; i < uniforms . size ( ) ; i + + ) {
VisualShaderNodeUniform * uniform = uniforms [ i ] ;
if ( used_uniform_names . has ( uniform - > get_uniform_name ( ) ) ) {
global_code + = uniform - > generate_global ( get_mode ( ) , Type ( i ) , - 1 ) ;
const_cast < VisualShaderNodeUniform * > ( uniform ) - > set_global_code_generated ( true ) ;
} else {
const_cast < VisualShaderNodeUniform * > ( uniform ) - > set_global_code_generated ( false ) ;
2019-08-18 07:09:05 +02:00
}
}
2022-01-09 15:02:13 +01:00
if ( ! varyings . is_empty ( ) ) {
global_code + = " \n // Varyings \n " ;
for ( const KeyValue < String , Varying > & E : varyings ) {
global_code + = " varying " ;
switch ( E . value . type ) {
case VaryingType : : VARYING_TYPE_FLOAT :
global_code + = " float " ;
break ;
case VaryingType : : VARYING_TYPE_VECTOR_2D :
global_code + = " vec2 " ;
break ;
case VaryingType : : VARYING_TYPE_VECTOR_3D :
global_code + = " vec3 " ;
break ;
2022-04-12 19:09:29 +02:00
case VaryingType : : VARYING_TYPE_VECTOR_4D :
global_code + = " vec4 " ;
break ;
2022-01-09 15:02:13 +01:00
case VaryingType : : VARYING_TYPE_COLOR :
global_code + = " vec4 " ;
break ;
case VaryingType : : VARYING_TYPE_TRANSFORM :
global_code + = " mat4 " ;
break ;
default :
break ;
}
global_code + = E . key + " ; \n " ;
}
global_code + = " \n " ;
}
2022-05-13 15:04:37 +02:00
HashMap < int , String > code_map ;
2022-05-19 17:00:06 +02:00
HashSet < int > empty_funcs ;
2020-09-07 09:28:13 +02:00
2018-07-14 23:15:42 +02:00
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2020-09-07 09:28:13 +02:00
if ( ! has_func_name ( RenderingServer : : ShaderMode ( shader_mode ) , func_name [ i ] ) ) {
2020-03-25 10:22:29 +01:00
continue ;
}
2018-07-14 23:15:42 +02:00
//make it faster to go around through shader
VMap < ConnectionKey , const List < Connection > : : Element * > input_connections ;
VMap < ConnectionKey , const List < Connection > : : Element * > output_connections ;
2020-09-07 09:28:13 +02:00
StringBuilder func_code ;
2022-05-19 17:00:06 +02:00
HashSet < int > processed ;
2020-09-07 09:28:13 +02:00
2021-07-17 21:33:19 +02:00
bool is_empty_func = false ;
2021-10-03 13:28:55 +02:00
if ( shader_mode ! = Shader : : MODE_PARTICLES & & shader_mode ! = Shader : : MODE_SKY & & shader_mode ! = Shader : : MODE_FOG ) {
2021-07-17 21:33:19 +02:00
is_empty_func = true ;
}
2022-01-09 15:02:13 +01:00
String varying_code ;
if ( shader_mode = = Shader : : MODE_SPATIAL | | shader_mode = = Shader : : MODE_CANVAS_ITEM ) {
for ( const KeyValue < String , Varying > & E : varyings ) {
if ( ( E . value . mode = = VARYING_MODE_VERTEX_TO_FRAG_LIGHT & & i = = TYPE_VERTEX ) | | ( E . value . mode = = VARYING_MODE_FRAG_TO_LIGHT & & i = = TYPE_FRAGMENT ) ) {
bool found = false ;
for ( int key : varying_setters [ i ] ) {
Ref < VisualShaderNodeVaryingSetter > setter = Object : : cast_to < VisualShaderNodeVaryingSetter > ( const_cast < VisualShaderNode * > ( graph [ i ] . nodes [ key ] . node . ptr ( ) ) ) ;
if ( setter . is_valid ( ) & & E . value . name = = setter - > get_varying_name ( ) ) {
found = true ;
break ;
}
}
if ( ! found ) {
String code2 ;
switch ( E . value . type ) {
case VaryingType : : VARYING_TYPE_FLOAT :
code2 + = " 0.0 " ;
break ;
case VaryingType : : VARYING_TYPE_VECTOR_2D :
code2 + = " vec2(0.0) " ;
break ;
case VaryingType : : VARYING_TYPE_VECTOR_3D :
code2 + = " vec3(0.0) " ;
break ;
2022-04-12 19:09:29 +02:00
case VaryingType : : VARYING_TYPE_VECTOR_4D :
code2 + = " vec4(0.0) " ;
break ;
2022-01-09 15:02:13 +01:00
case VaryingType : : VARYING_TYPE_COLOR :
code2 + = " vec4(0.0) " ;
break ;
case VaryingType : : VARYING_TYPE_TRANSFORM :
code2 + = " mat4(1.0) " ;
break ;
default :
break ;
}
varying_code + = vformat ( " %s = %s; \n " , E . key , code2 ) ;
}
is_empty_func = false ;
}
}
}
2018-07-14 23:15:42 +02:00
for ( const List < Connection > : : Element * E = graph [ i ] . connections . front ( ) ; E ; E = E - > next ( ) ) {
ConnectionKey from_key ;
from_key . node = E - > get ( ) . from_node ;
from_key . port = E - > get ( ) . from_port ;
output_connections . insert ( from_key , E ) ;
ConnectionKey to_key ;
to_key . node = E - > get ( ) . to_node ;
to_key . port = E - > get ( ) . to_port ;
input_connections . insert ( to_key , E ) ;
2021-07-17 21:33:19 +02:00
if ( is_empty_func & & to_key . node = = NODE_ID_OUTPUT ) {
is_empty_func = false ;
}
2018-07-14 23:15:42 +02:00
}
2021-07-17 21:33:19 +02:00
if ( is_empty_func ) {
2021-07-21 11:57:11 +02:00
empty_funcs . insert ( i ) ;
2021-07-17 21:33:19 +02:00
continue ;
}
2020-09-07 09:28:13 +02:00
if ( shader_mode ! = Shader : : MODE_PARTICLES ) {
func_code + = " \n void " + String ( func_name [ i ] ) + " () { \n " ;
}
2020-09-11 17:06:22 +02:00
insertion_pos . insert ( i , code . get_string_length ( ) + func_code . get_string_length ( ) ) ;
2018-07-14 23:15:42 +02:00
2022-01-09 15:02:13 +01:00
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 ) ;
2018-07-14 23:15:42 +02:00
ERR_FAIL_COND ( err ! = OK ) ;
2022-01-09 15:02:13 +01:00
if ( varying_setters . has ( i ) ) {
for ( int & E : varying_setters [ i ] ) {
err = _write_node ( Type ( i ) , nullptr , nullptr , nullptr , func_code , default_tex_params , input_connections , output_connections , E , processed , false , classes ) ;
ERR_FAIL_COND ( err ! = OK ) ;
}
}
2020-09-15 09:57:40 +02:00
if ( emitters . has ( i ) ) {
2021-07-16 05:45:57 +02:00
for ( int & E : emitters [ i ] ) {
2022-01-09 15:02:13 +01:00
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 , processed , false , classes ) ;
2020-09-15 09:57:40 +02:00
ERR_FAIL_COND ( err ! = OK ) ;
}
}
2020-09-07 09:28:13 +02:00
if ( shader_mode = = Shader : : MODE_PARTICLES ) {
code_map . insert ( i , func_code ) ;
} else {
2022-01-09 15:02:13 +01:00
func_code + = varying_code ;
2020-09-07 09:28:13 +02:00
func_code + = " } \n " ;
code + = func_code ;
}
}
2020-09-15 09:57:40 +02:00
String global_compute_code ;
2020-09-07 09:28:13 +02:00
if ( shader_mode = = Shader : : MODE_PARTICLES ) {
2020-09-15 09:57:40 +02:00
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 ) {
2021-07-19 08:06:51 +02:00
code + = " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED); \n " ;
code + = " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz; \n " ;
code + = " float __radians; \n " ;
code + = " vec3 __vec3_buff1; \n " ;
code + = " vec3 __vec3_buff2; \n " ;
code + = " float __scalar_buff1; \n " ;
code + = " float __scalar_buff2; \n " ;
2021-11-05 20:57:24 +01:00
code + = " int __scalar_ibuff; \n " ;
2021-11-18 11:30:51 +01:00
code + = " vec4 __vec4_buff; \n " ;
2021-07-19 08:06:51 +02:00
code + = " vec3 __ndiff = normalize(__diff); \n \n " ;
2020-09-15 09:57:40 +02:00
}
if ( has_start ) {
2021-07-19 08:06:51 +02:00
code + = " { \n " ;
code + = code_map [ TYPE_START ] . replace ( " \n " , " \n " ) ;
code + = " } \n " ;
2020-09-15 09:57:40 +02:00
if ( has_start_custom ) {
2021-07-19 08:06:51 +02:00
code + = " \n " ;
2020-09-15 09:57:40 +02:00
}
}
if ( has_start_custom ) {
2021-07-19 08:06:51 +02:00
code + = " { \n " ;
code + = code_map [ TYPE_START_CUSTOM ] . replace ( " \n " , " \n " ) ;
code + = " } \n " ;
2020-09-15 09:57:40 +02:00
}
code + = " } \n \n " ;
code + = " void process() { \n " ;
if ( has_process | | has_process_custom | | has_collide ) {
2021-07-19 08:06:51 +02:00
code + = " uint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED); \n " ;
code + = " vec3 __vec3_buff1; \n " ;
code + = " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz; \n " ;
code + = " vec3 __ndiff = normalize(__diff); \n \n " ;
2020-09-15 09:57:40 +02:00
}
2021-07-19 08:06:51 +02:00
code + = " { \n " ;
String tab = " " ;
2020-09-15 09:57:40 +02:00
if ( has_collide ) {
2021-07-19 08:06:51 +02:00
code + = " if (COLLIDED) { \n \n " ;
code + = code_map [ TYPE_COLLIDE ] . replace ( " \n " , " \n " ) ;
2020-09-15 09:57:40 +02:00
if ( has_process ) {
2021-07-19 08:06:51 +02:00
code + = " } else { \n \n " ;
tab + = " " ;
2020-09-15 09:57:40 +02:00
}
}
if ( has_process ) {
2021-07-19 08:06:51 +02:00
code + = code_map [ TYPE_PROCESS ] . replace ( " \n " , " \n " + tab ) ;
2020-09-15 09:57:40 +02:00
}
if ( has_collide ) {
2021-07-19 08:06:51 +02:00
code + = " } \n " ;
2020-09-15 09:57:40 +02:00
}
2021-07-19 08:06:51 +02:00
code + = " } \n " ;
2020-09-15 09:57:40 +02:00
if ( has_process_custom ) {
2021-07-19 08:06:51 +02:00
code + = " { \n \n " ;
code + = code_map [ TYPE_PROCESS_CUSTOM ] . replace ( " \n " , " \n " ) ;
code + = " } \n " ;
2020-09-15 09:57:40 +02:00
}
code + = " } \n \n " ;
global_compute_code + = " float __rand_from_seed(inout uint seed) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " int k; \n " ;
global_compute_code + = " int s = int(seed); \n " ;
global_compute_code + = " if (s == 0) \n " ;
global_compute_code + = " s = 305420679; \n " ;
global_compute_code + = " k = s / 127773; \n " ;
global_compute_code + = " s = 16807 * (s - k * 127773) - 2836 * k; \n " ;
global_compute_code + = " if (s < 0) \n " ;
global_compute_code + = " s += 2147483647; \n " ;
global_compute_code + = " seed = uint(s); \n " ;
global_compute_code + = " return float(seed % uint(65536)) / 65535.0; \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
global_compute_code + = " float __rand_from_seed_m1_p1(inout uint seed) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " return __rand_from_seed(seed) * 2.0 - 1.0; \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
global_compute_code + = " float __randf_range(inout uint seed, float from, float to) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " return __rand_from_seed(seed) * (to - from) + from; \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
2022-02-07 06:46:51 +01:00
global_compute_code + = " vec2 __randv2_range(inout uint seed, vec2 from, vec2 to) { \n " ;
global_compute_code + = " return vec2(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y)); \n " ;
global_compute_code + = " } \n \n " ;
global_compute_code + = " vec3 __randv3_range(inout uint seed, vec3 from, vec3 to) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " return vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z)); \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
global_compute_code + = " uint __hash(uint x) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " x = ((x >> uint(16)) ^ x) * uint(73244475); \n " ;
global_compute_code + = " x = ((x >> uint(16)) ^ x) * uint(73244475); \n " ;
global_compute_code + = " x = (x >> uint(16)) ^ x; \n " ;
global_compute_code + = " return x; \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
global_compute_code + = " mat3 __build_rotation_mat3(vec3 axis, float angle) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " axis = normalize(axis); \n " ;
global_compute_code + = " float s = sin(angle); \n " ;
global_compute_code + = " float c = cos(angle); \n " ;
global_compute_code + = " float oc = 1.0 - c; \n " ;
global_compute_code + = " return 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 " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
global_compute_code + = " mat4 __build_rotation_mat4(vec3 axis, float angle) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " axis = normalize(axis); \n " ;
global_compute_code + = " float s = sin(angle); \n " ;
global_compute_code + = " float c = cos(angle); \n " ;
global_compute_code + = " float oc = 1.0 - c; \n " ;
global_compute_code + = " return 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 " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
2021-11-04 16:42:57 +01:00
global_compute_code + = " vec2 __get_random_unit_vec2(inout uint seed) { \n " ;
global_compute_code + = " return normalize(vec2(__rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed))); \n " ;
global_compute_code + = " } \n \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " vec3 __get_random_unit_vec3(inout uint seed) { \n " ;
2021-07-19 08:06:51 +02:00
global_compute_code + = " return normalize(vec3(__rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed))); \n " ;
2020-09-15 09:57:40 +02:00
global_compute_code + = " } \n \n " ;
2018-07-14 23:15:42 +02:00
}
//set code secretly
global_code + = " \n \n " ;
String final_code = global_code ;
2020-09-15 09:57:40 +02:00
final_code + = global_compute_code ;
2019-07-12 11:14:34 +02:00
final_code + = global_code_per_node ;
2019-08-18 07:09:05 +02:00
final_code + = global_expressions ;
2019-07-12 11:14:34 +02:00
String tcode = code ;
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2020-09-07 09:28:13 +02:00
if ( ! has_func_name ( RenderingServer : : ShaderMode ( shader_mode ) , func_name [ i ] ) ) {
2020-03-25 10:22:29 +01:00
continue ;
}
2021-07-21 11:57:11 +02:00
String func_code = global_code_per_func [ Type ( i ) ] . as_string ( ) ;
if ( empty_funcs . has ( Type ( i ) ) & & ! func_code . is_empty ( ) ) {
func_code = vformat ( " %s%s%s " , String ( " \n void " + String ( func_name [ i ] ) + " () { \n " ) , func_code , " } \n " ) ;
}
tcode = tcode . insert ( insertion_pos [ i ] , func_code ) ;
2019-07-12 11:14:34 +02:00
}
final_code + = tcode ;
2018-07-14 23:15:42 +02:00
const_cast < VisualShader * > ( this ) - > set_code ( final_code ) ;
for ( int i = 0 ; i < default_tex_params . size ( ) ; i + + ) {
2021-10-17 13:38:26 +02:00
for ( int j = 0 ; j < default_tex_params [ i ] . params . size ( ) ; j + + ) {
const_cast < VisualShader * > ( this ) - > set_default_texture_param ( default_tex_params [ i ] . name , default_tex_params [ i ] . params [ j ] , j ) ;
}
2018-07-14 23:15:42 +02:00
}
2019-08-18 11:29:22 +02:00
if ( previous_code ! = final_code ) {
2021-07-17 23:22:52 +02:00
const_cast < VisualShader * > ( this ) - > emit_signal ( SNAME ( " changed " ) ) ;
2019-08-18 11:29:22 +02:00
}
previous_code = final_code ;
2018-07-14 23:15:42 +02:00
}
void VisualShader : : _queue_update ( ) {
2021-02-10 19:22:13 +01:00
if ( dirty . is_set ( ) ) {
2018-07-14 23:15:42 +02:00
return ;
}
2021-02-10 19:22:13 +01:00
dirty . set ( ) ;
2021-07-17 23:22:52 +02:00
call_deferred ( SNAME ( " _update_shader " ) ) ;
2018-07-14 23:15:42 +02:00
}
2019-05-12 14:09:39 +02:00
void VisualShader : : rebuild ( ) {
2021-02-10 19:22:13 +01:00
dirty . set ( ) ;
2019-05-12 14:09:39 +02:00
_update_shader ( ) ;
}
2018-07-14 23:15:42 +02:00
void VisualShader : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_mode " , " mode " ) , & VisualShader : : set_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " add_node " , " type " , " node " , " position " , " id " ) , & VisualShader : : add_node ) ;
2018-07-26 11:56:21 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_node " , " type " , " id " ) , & VisualShader : : get_node ) ;
2019-05-12 14:09:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_node_position " , " type " , " id " , " position " ) , & VisualShader : : set_node_position ) ;
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_node_position " , " type " , " id " ) , & VisualShader : : get_node_position ) ;
ClassDB : : bind_method ( D_METHOD ( " get_node_list " , " type " ) , & VisualShader : : get_node_list ) ;
ClassDB : : bind_method ( D_METHOD ( " get_valid_node_id " , " type " ) , & VisualShader : : get_valid_node_id ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_node " , " type " , " id " ) , & VisualShader : : remove_node ) ;
2020-12-30 09:45:31 +01:00
ClassDB : : bind_method ( D_METHOD ( " replace_node " , " type " , " id " , " new_class " ) , & VisualShader : : replace_node ) ;
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_node_connection " , " type " , " from_node " , " from_port " , " to_node " , " to_port " ) , & VisualShader : : is_node_connection ) ;
2020-04-01 03:49:23 +02:00
ClassDB : : bind_method ( D_METHOD ( " can_connect_nodes " , " type " , " from_node " , " from_port " , " to_node " , " to_port " ) , & VisualShader : : can_connect_nodes ) ;
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " connect_nodes " , " type " , " from_node " , " from_port " , " to_node " , " to_port " ) , & VisualShader : : connect_nodes ) ;
ClassDB : : bind_method ( D_METHOD ( " disconnect_nodes " , " type " , " from_node " , " from_port " , " to_node " , " to_port " ) , & VisualShader : : disconnect_nodes ) ;
2019-05-12 14:09:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " connect_nodes_forced " , " type " , " from_node " , " from_port " , " to_node " , " to_port " ) , & VisualShader : : connect_nodes_forced ) ;
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_node_connections " , " type " ) , & VisualShader : : _get_node_connections ) ;
2021-08-01 17:13:51 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_engine_version " , " version " ) , & VisualShader : : set_engine_version ) ;
ClassDB : : bind_method ( D_METHOD ( " get_engine_version " ) , & VisualShader : : get_engine_version ) ;
2020-02-25 15:50:49 +01:00
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_graph_offset " , " offset " ) , & VisualShader : : set_graph_offset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_graph_offset " ) , & VisualShader : : get_graph_offset ) ;
2022-01-09 15:02:13 +01:00
ClassDB : : bind_method ( D_METHOD ( " add_varying " , " name " , " mode " , " type " ) , & VisualShader : : add_varying ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_varying " , " name " ) , & VisualShader : : remove_varying ) ;
ClassDB : : bind_method ( D_METHOD ( " has_varying " , " name " ) , & VisualShader : : has_varying ) ;
2018-07-14 23:15:42 +02:00
ClassDB : : bind_method ( D_METHOD ( " _update_shader " ) , & VisualShader : : _update_shader ) ;
2021-11-03 23:06:17 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " graph_offset " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) , " set_graph_offset " , " get_graph_offset " ) ;
2022-01-11 05:17:42 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : DICTIONARY , " engine_version " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) , " set_engine_version " , " get_engine_version " ) ;
2018-07-14 23:15:42 +02:00
2020-09-04 10:43:11 +02:00
ADD_PROPERTY_DEFAULT ( " code " , " " ) ; // Inherited from Shader, prevents showing default code as override in docs.
2018-07-14 23:15:42 +02:00
BIND_ENUM_CONSTANT ( TYPE_VERTEX ) ;
BIND_ENUM_CONSTANT ( TYPE_FRAGMENT ) ;
BIND_ENUM_CONSTANT ( TYPE_LIGHT ) ;
2020-09-15 09:57:40 +02:00
BIND_ENUM_CONSTANT ( TYPE_START ) ;
2020-09-11 12:22:10 +02:00
BIND_ENUM_CONSTANT ( TYPE_PROCESS ) ;
2020-09-15 09:57:40 +02:00
BIND_ENUM_CONSTANT ( TYPE_COLLIDE ) ;
BIND_ENUM_CONSTANT ( TYPE_START_CUSTOM ) ;
BIND_ENUM_CONSTANT ( TYPE_PROCESS_CUSTOM ) ;
2021-04-19 12:26:37 +02:00
BIND_ENUM_CONSTANT ( TYPE_SKY ) ;
2021-10-03 13:28:55 +02:00
BIND_ENUM_CONSTANT ( TYPE_FOG ) ;
2018-07-14 23:15:42 +02:00
BIND_ENUM_CONSTANT ( TYPE_MAX ) ;
2022-01-09 15:02:13 +01:00
BIND_ENUM_CONSTANT ( VARYING_MODE_VERTEX_TO_FRAG_LIGHT ) ;
BIND_ENUM_CONSTANT ( VARYING_MODE_FRAG_TO_LIGHT ) ;
BIND_ENUM_CONSTANT ( VARYING_MODE_MAX ) ;
BIND_ENUM_CONSTANT ( VARYING_TYPE_FLOAT ) ;
BIND_ENUM_CONSTANT ( VARYING_TYPE_VECTOR_2D ) ;
BIND_ENUM_CONSTANT ( VARYING_TYPE_VECTOR_3D ) ;
2022-04-12 19:09:29 +02:00
BIND_ENUM_CONSTANT ( VARYING_TYPE_VECTOR_4D ) ;
2022-01-09 15:02:13 +01:00
BIND_ENUM_CONSTANT ( VARYING_TYPE_COLOR ) ;
BIND_ENUM_CONSTANT ( VARYING_TYPE_TRANSFORM ) ;
BIND_ENUM_CONSTANT ( VARYING_TYPE_MAX ) ;
2018-07-14 23:15:42 +02:00
BIND_CONSTANT ( NODE_ID_INVALID ) ;
BIND_CONSTANT ( NODE_ID_OUTPUT ) ;
}
VisualShader : : VisualShader ( ) {
2021-02-10 19:22:13 +01:00
dirty . set ( ) ;
2018-07-14 23:15:42 +02:00
for ( int i = 0 ; i < TYPE_MAX ; i + + ) {
2020-09-15 09:57:40 +02:00
if ( i > ( int ) TYPE_LIGHT & & i < ( int ) TYPE_SKY ) {
Ref < VisualShaderNodeParticleOutput > output ;
2021-06-18 00:03:09 +02:00
output . instantiate ( ) ;
2020-09-15 09:57:40 +02:00
output - > shader_type = Type ( i ) ;
output - > shader_mode = shader_mode ;
graph [ i ] . nodes [ NODE_ID_OUTPUT ] . node = output ;
} else {
Ref < VisualShaderNodeOutput > output ;
2021-06-18 00:03:09 +02:00
output . instantiate ( ) ;
2020-09-15 09:57:40 +02:00
output - > shader_type = Type ( i ) ;
output - > shader_mode = shader_mode ;
graph [ i ] . nodes [ NODE_ID_OUTPUT ] . node = output ;
}
2018-07-14 23:15:42 +02:00
graph [ i ] . nodes [ NODE_ID_OUTPUT ] . position = Vector2 ( 400 , 150 ) ;
}
}
///////////////////////////////////////////////////////////
const VisualShaderNodeInput : : Port VisualShaderNodeInput : : ports [ ] = {
2021-07-18 14:05:25 +02:00
// Node3D
// Node3D, Vertex
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " vertex " , " VERTEX " } ,
2022-03-03 19:08:36 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " vertex_id " , " VERTEX_ID " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " NORMAL " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " tangent " , " TANGENT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " binormal " , " BINORMAL " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv2 " , " UV2 " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " point_size " , " POINT_SIZE " } ,
2021-07-18 14:05:25 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " instance_id " , " INSTANCE_ID " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " instance_custom " , " INSTANCE_CUSTOM " } ,
2021-07-18 14:05:25 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " roughness " , " ROUGHNESS " } ,
2022-03-18 10:10:55 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " model_matrix " , " MODEL_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " modelview_matrix " , " MODELVIEW_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " inv_view_matrix " , " INV_VIEW_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " view_matrix " , " VIEW_MATRIX " } ,
2022-03-28 09:03:52 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " projection_matrix " , " PROJECTION_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " inv_projection_matrix " , " INV_PROJECTION_MATRIX " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " viewport_size " , " VIEWPORT_SIZE " } ,
2019-09-04 17:24:44 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_BOOLEAN , " output_is_srgb " , " OUTPUT_IS_SRGB " } ,
2022-03-03 19:08:36 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " view_index " , " VIEW_INDEX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " view_mono_left " , " VIEW_MONO_LEFT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " view_right " , " VIEW_RIGHT " } ,
2018-07-14 23:15:42 +02:00
2021-07-18 14:05:25 +02:00
// Node3D, Fragment
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " vertex " , " VERTEX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " NORMAL " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " tangent " , " TANGENT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " binormal " , " BINORMAL " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " view " , " VIEW " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv2 " , " UV2 " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " point_coord " , " POINT_COORD " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
2022-03-18 10:10:55 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " model_matrix " , " MODEL_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " view_matrix " , " VIEW_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " inv_view_matrix " , " INV_VIEW_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " projection_matrix " , " PROJECTION_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " inv_projection_matrix " , " INV_PROJECTION_MATRIX " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " viewport_size " , " VIEWPORT_SIZE " } ,
2019-09-04 17:24:44 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_BOOLEAN , " output_is_srgb " , " OUTPUT_IS_SRGB " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_BOOLEAN , " front_facing " , " FRONT_FACING " } ,
2019-11-03 14:38:03 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " screen_texture " , " SCREEN_TEXTURE " } ,
2021-07-18 14:05:25 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " normal_roughness_texture " , " NORMAL_ROUGHNESS_TEXTURE " } ,
2019-11-03 14:38:03 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " depth_texture " , " DEPTH_TEXTURE " } ,
2022-03-03 19:08:36 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " view_index " , " VIEW_INDEX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " view_mono_left " , " VIEW_MONO_LEFT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " view_right " , " VIEW_RIGHT " } ,
2018-07-14 23:15:42 +02:00
2021-07-18 14:05:25 +02:00
// Node3D, Light
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " NORMAL " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv2 " , " UV2 " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " view " , " VIEW " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light " , " LIGHT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light_color " , " LIGHT_COLOR " } ,
2020-11-29 12:16:18 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " attenuation " , " ATTENUATION " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " albedo " , " ALBEDO " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " backlight " , " BACKLIGHT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " diffuse " , " DIFFUSE_LIGHT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " specular " , " SPECULAR_LIGHT " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " roughness " , " ROUGHNESS " } ,
2020-10-10 15:55:36 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " metallic " , " METALLIC " } ,
2022-03-18 10:10:55 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " model_matrix " , " MODEL_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " view_matrix " , " VIEW_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " inv_view_matrix " , " INV_VIEW_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " projection_matrix " , " PROJECTION_MATRIX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_TRANSFORM , " inv_projection_matrix " , " INV_PROJECTION_MATRIX " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " viewport_size " , " VIEWPORT_SIZE " } ,
2019-09-04 17:24:44 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_BOOLEAN , " output_is_srgb " , " OUTPUT_IS_SRGB " } ,
2021-04-17 19:16:03 +02:00
2021-07-18 14:05:25 +02:00
// Canvas Item
2018-07-14 23:15:42 +02:00
// Canvas Item, Vertex
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " vertex " , " VERTEX " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " point_size " , " POINT_SIZE " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " texture_pixel_size " , " TEXTURE_PIXEL_SIZE " } ,
2022-03-18 10:10:55 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " model_matrix " , " MODEL_MATRIX " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " canvas_matrix " , " CANVAS_MATRIX " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " screen_matrix " , " SCREEN_MATRIX " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2020-11-29 12:16:18 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_BOOLEAN , " at_light_pass " , " AT_LIGHT_PASS " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " instance_custom " , " INSTANCE_CUSTOM " } ,
2022-03-03 19:08:36 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " instance_id " , " INSTANCE_ID " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " vertex_id " , " VERTEX_ID " } ,
2021-04-17 19:16:03 +02:00
2018-07-14 23:15:42 +02:00
// Canvas Item, Fragment
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " texture_pixel_size " , " TEXTURE_PIXEL_SIZE " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_pixel_size " , " SCREEN_PIXEL_SIZE " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " point_coord " , " POINT_COORD " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2020-11-29 12:16:18 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_BOOLEAN , " at_light_pass " , " AT_LIGHT_PASS " } ,
2019-11-03 14:38:03 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " texture " , " TEXTURE " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " normal_texture " , " NORMAL_TEXTURE " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " screen_texture " , " SCREEN_TEXTURE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " specular_shininess " , " SPECULAR_SHININESS " } ,
2020-11-29 12:16:18 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SAMPLER , " specular_shininess_texture " , " SPECULAR_SHININESS_TEXTURE " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " vertex " , " VERTEX " } ,
2021-04-17 19:16:03 +02:00
2018-07-14 23:15:42 +02:00
// Canvas Item, Light
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " NORMAL " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " light " , " LIGHT " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " light_color " , " LIGHT_COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light_position " , " LIGHT_POSITION " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light_vertex " , " LIGHT_VERTEX " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " shadow " , " SHADOW_MODULATE " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " texture_pixel_size " , " TEXTURE_PIXEL_SIZE " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " point_coord " , " POINT_COORD " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2019-11-03 14:38:03 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SAMPLER , " texture " , " TEXTURE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " specular_shininess " , " SPECULAR_SHININESS " } ,
2019-01-27 10:16:37 +01:00
2020-09-15 09:57:40 +02:00
// Particles, Start
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " attractor_force " , " ATTRACTOR_FORCE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " velocity " , " VELOCITY " } ,
2020-09-15 09:57:40 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START , VisualShaderNode : : PORT_TYPE_BOOLEAN , " restart " , " RESTART " } ,
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START , VisualShaderNode : : PORT_TYPE_BOOLEAN , " active " , " ACTIVE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " custom " , " CUSTOM " } ,
2020-09-15 09:57:40 +02:00
{ 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)
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " attractor_force " , " ATTRACTOR_FORCE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " velocity " , " VELOCITY " } ,
2020-09-15 09:57:40 +02:00
{ 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 " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_START_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " custom " , " CUSTOM " } ,
2020-09-15 09:57:40 +02:00
{ 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 " } ,
2020-09-07 09:28:13 +02:00
// Particles, Process
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " attractor_force " , " ATTRACTOR_FORCE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " velocity " , " VELOCITY " } ,
2020-09-15 09:57:40 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_BOOLEAN , " restart " , " RESTART " } ,
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_BOOLEAN , " active " , " ACTIVE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " custom " , " CUSTOM " } ,
2020-09-07 09:28:13 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_TRANSFORM , " transform " , " TRANSFORM " } ,
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_SCALAR , " delta " , " DELTA " } ,
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_SCALAR , " lifetime " , " LIFETIME " } ,
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS , VisualShaderNode : : PORT_TYPE_SCALAR_INT , " index " , " INDEX " } ,
{ 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 " } ,
2020-09-15 09:57:40 +02:00
// Particles, Process (Custom)
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " attractor_force " , " ATTRACTOR_FORCE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " velocity " , " VELOCITY " } ,
2020-09-15 09:57:40 +02:00
{ 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 " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_PROCESS_CUSTOM , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " custom " , " CUSTOM " } ,
2020-09-15 09:57:40 +02:00
{ 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
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " attractor_force " , " ATTRACTOR_FORCE " } ,
2020-09-15 09:57:40 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_SCALAR , " collision_depth " , " COLLISION_DEPTH " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " collision_normal " , " COLLISION_NORMAL " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " velocity " , " VELOCITY " } ,
2020-09-15 09:57:40 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_BOOLEAN , " restart " , " RESTART " } ,
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_BOOLEAN , " active " , " ACTIVE " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_PARTICLES , VisualShader : : TYPE_COLLIDE , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " custom " , " CUSTOM " } ,
2020-09-15 09:57:40 +02:00
{ 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 " } ,
2020-03-25 10:22:29 +01:00
2021-04-17 19:16:03 +02:00
// Sky, Sky
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " at_cubemap_pass " , " AT_CUBEMAP_PASS " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " at_half_res_pass " , " AT_HALF_RES_PASS " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " at_quarter_res_pass " , " AT_QUARTER_RES_PASS " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " eyedir " , " EYEDIR " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " half_res_color " , " HALF_RES_COLOR " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light0_color " , " LIGHT0_COLOR " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light0_direction " , " LIGHT0_DIRECTION " } ,
2021-04-17 19:16:03 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " light0_enabled " , " LIGHT0_ENABLED " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " light0_energy " , " LIGHT0_ENERGY " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light1_color " , " LIGHT1_COLOR " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light1_direction " , " LIGHT1_DIRECTION " } ,
2021-04-17 19:16:03 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " light1_enabled " , " LIGHT1_ENABLED " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " light1_energy " , " LIGHT1_ENERGY " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light2_color " , " LIGHT2_COLOR " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light2_direction " , " LIGHT2_DIRECTION " } ,
2021-04-17 19:16:03 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " light2_enabled " , " LIGHT2_ENABLED " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " light2_energy " , " LIGHT2_ENERGY " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light3_color " , " LIGHT3_COLOR " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " light3_direction " , " LIGHT3_DIRECTION " } ,
2021-04-17 19:16:03 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_BOOLEAN , " light3_enabled " , " LIGHT3_ENABLED " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " light3_energy " , " LIGHT3_ENERGY " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " position " , " POSITION " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " quarter_res_color " , " QUARTER_RES_COLOR " } ,
2021-04-17 19:16:03 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SAMPLER , " radiance " , " RADIANCE " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " sky_coords " , " SKY_COORDS " } ,
2021-04-17 19:16:03 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2020-03-25 10:22:29 +01:00
2021-10-03 13:28:55 +02:00
// Fog, Fog
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " world_position " , " WORLD_POSITION " } ,
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " object_position " , " OBJECT_POSITION " } ,
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " uvw " , " UVW " } ,
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " extents " , " EXTENTS " } ,
2021-10-03 13:28:55 +02:00
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_SCALAR , " sdf " , " SDF " } ,
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2020-04-02 01:20:12 +02:00
{ Shader : : MODE_MAX , VisualShader : : TYPE_MAX , VisualShaderNode : : PORT_TYPE_TRANSFORM , nullptr , nullptr } ,
2018-07-14 23:15:42 +02:00
} ;
const VisualShaderNodeInput : : Port VisualShaderNodeInput : : preview_ports [ ] = {
2021-10-08 21:55:07 +02:00
// Spatial, Vertex
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " vec3(0.0, 0.0, 1.0) " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " tangent " , " vec3(0.0, 1.0, 0.0) " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " binormal " , " vec3(1.0, 0.0, 0.0) " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv2 " , " UV " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " vec4(1.0) " } ,
2021-10-08 21:55:07 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " alpha " , " 1.0 " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " viewport_size " , " vec2(1.0) " } ,
2021-10-08 21:55:07 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2018-07-14 23:15:42 +02:00
// Spatial, Fragment
2021-10-08 21:55:07 +02:00
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " vec3(0.0, 0.0, 1.0) " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " tangent " , " vec3(0.0, 1.0, 0.0) " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " binormal " , " vec3(1.0, 0.0, 0.0) " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv2 " , " UV " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " vec4(1.0) " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " alpha " , " 1.0 " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " viewport_size " , " vec2(1.0) " } ,
2021-10-08 21:55:07 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2018-07-14 23:15:42 +02:00
// Spatial, Light
2021-10-08 21:55:07 +02:00
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " vec3(0.0, 0.0, 1.0) " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv2 " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " viewport_size " , " vec2(1.0) " } ,
2021-10-08 21:55:07 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2018-07-14 23:15:42 +02:00
// Canvas Item, Vertex
2021-10-08 21:55:07 +02:00
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " vertex " , " VERTEX " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " vec4(1.0) " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " alpha " , " 1.0 " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2021-10-08 21:55:07 +02:00
2018-07-14 23:15:42 +02:00
// Canvas Item, Fragment
2021-10-08 21:55:07 +02:00
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " vec3(1.0) " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " alpha " , " 1.0 " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2021-10-08 21:55:07 +02:00
2018-07-14 23:15:42 +02:00
// Canvas Item, Light
2021-10-08 21:55:07 +02:00
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " fragcoord " , " FRAGCOORD " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " uv " , " UV " } ,
2022-02-06 18:15:28 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " normal " , " vec3(0.0, 0.0, 1.0) " } ,
2022-04-22 19:31:23 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " color " , " vec4(1.0) " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " alpha " , " 1.0 " } ,
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
2018-07-14 23:15:42 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2020-09-15 09:57:40 +02:00
// Particles
2021-10-08 21:55:07 +02:00
2020-09-15 09:57:40 +02:00
{ 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 " } ,
2021-10-08 21:55:07 +02:00
2021-10-29 15:42:33 +02:00
// Sky
2022-02-01 09:32:01 +01:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " screen_uv " , " SCREEN_UV " } ,
2021-10-29 15:42:33 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
// Fog
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_SCALAR , " time " , " TIME " } ,
2020-04-02 01:20:12 +02:00
{ Shader : : MODE_MAX , VisualShader : : TYPE_MAX , VisualShaderNode : : PORT_TYPE_TRANSFORM , nullptr , nullptr } ,
2018-07-14 23:15:42 +02:00
} ;
int VisualShaderNodeInput : : get_input_port_count ( ) const {
return 0 ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
VisualShaderNodeInput : : PortType VisualShaderNodeInput : : get_input_port_type ( int p_port ) const {
return PORT_TYPE_SCALAR ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
String VisualShaderNodeInput : : get_input_port_name ( int p_port ) const {
return " " ;
}
int VisualShaderNodeInput : : get_output_port_count ( ) const {
return 1 ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
VisualShaderNodeInput : : PortType VisualShaderNodeInput : : get_output_port_type ( int p_port ) const {
2022-04-22 19:31:23 +02:00
return p_port = = 0 ? get_input_type_by_name ( input_name ) : PORT_TYPE_SCALAR ;
2018-07-14 23:15:42 +02:00
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
String VisualShaderNodeInput : : get_output_port_name ( int p_port ) const {
return " " ;
}
String VisualShaderNodeInput : : get_caption ( ) const {
2019-10-29 07:26:05 +01:00
return " Input " ;
2018-07-14 23:15:42 +02:00
}
2022-04-22 19:31:23 +02:00
bool VisualShaderNodeInput : : is_output_port_expandable ( int p_port ) const {
if ( p_port = = 0 ) {
switch ( get_input_type_by_name ( input_name ) ) {
case PORT_TYPE_VECTOR_2D :
return true ;
case PORT_TYPE_VECTOR_3D :
return true ;
case PORT_TYPE_VECTOR_4D :
return true ;
default :
return false ;
}
}
return false ;
}
2019-01-21 20:07:53 +01:00
String VisualShaderNodeInput : : 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 ) const {
2019-11-03 14:38:03 +01:00
if ( get_output_port_type ( 0 ) = = PORT_TYPE_SAMPLER ) {
return " " ;
}
2019-01-21 20:07:53 +01:00
if ( p_for_preview ) {
int idx = 0 ;
2018-07-14 23:15:42 +02:00
2019-01-21 20:07:53 +01:00
String code ;
2018-07-14 23:15:42 +02:00
2019-01-21 20:07:53 +01:00
while ( preview_ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( preview_ports [ idx ] . mode = = shader_mode & & preview_ports [ idx ] . shader_type = = shader_type & & preview_ports [ idx ] . name = = input_name ) {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = " + preview_ports [ idx ] . string + " ; \n " ;
2019-01-21 20:07:53 +01:00
break ;
}
idx + + ;
2018-07-14 23:15:42 +02:00
}
2021-12-09 10:42:46 +01:00
if ( code . is_empty ( ) ) {
2019-01-21 20:07:53 +01:00
switch ( get_output_port_type ( 0 ) ) {
case PORT_TYPE_SCALAR : {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = 0.0; \n " ;
2020-02-25 15:50:49 +01:00
} break ;
case PORT_TYPE_SCALAR_INT : {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = 0; \n " ;
2020-02-25 15:50:49 +01:00
} break ;
2022-02-01 09:32:01 +01:00
case PORT_TYPE_VECTOR_2D : {
code = " " + p_output_vars [ 0 ] + " = vec2(0.0); \n " ;
} break ;
2022-02-06 18:15:28 +01:00
case PORT_TYPE_VECTOR_3D : {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = vec3(0.0); \n " ;
2020-02-25 15:50:49 +01:00
} break ;
2022-04-12 19:09:29 +02:00
case PORT_TYPE_VECTOR_4D : {
code = " " + p_output_vars [ 0 ] + " = vec4(0.0); \n " ;
} break ;
2019-02-22 18:38:58 +01:00
case PORT_TYPE_BOOLEAN : {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = false; \n " ;
2019-02-22 18:38:58 +01:00
} break ;
2021-10-08 21:55:07 +02:00
default :
2019-02-22 18:38:58 +01:00
break ;
2019-01-21 20:07:53 +01:00
}
2018-07-14 23:15:42 +02:00
}
2019-01-21 20:07:53 +01:00
return code ;
2018-07-14 23:15:42 +02:00
2019-01-21 20:07:53 +01:00
} else {
int idx = 0 ;
2018-07-14 23:15:42 +02:00
2019-01-21 20:07:53 +01:00
String code ;
2018-07-14 23:15:42 +02:00
2019-01-21 20:07:53 +01:00
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type & & ports [ idx ] . name = = input_name ) {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = " + ports [ idx ] . string + " ; \n " ;
2019-01-21 20:07:53 +01:00
break ;
}
idx + + ;
}
2018-07-14 23:15:42 +02:00
2021-12-09 10:42:46 +01:00
if ( code . is_empty ( ) ) {
2021-07-19 08:06:51 +02:00
code = " " + p_output_vars [ 0 ] + " = 0.0; \n " ; //default (none found) is scalar
2018-07-14 23:15:42 +02:00
}
2019-01-21 20:07:53 +01:00
return code ;
2018-07-14 23:15:42 +02:00
}
}
void VisualShaderNodeInput : : set_input_name ( String p_name ) {
PortType prev_type = get_input_type_by_name ( input_name ) ;
input_name = p_name ;
emit_changed ( ) ;
if ( get_input_type_by_name ( input_name ) ! = prev_type ) {
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " input_type_changed " ) ) ;
2018-07-14 23:15:42 +02:00
}
}
String VisualShaderNodeInput : : get_input_name ( ) const {
return input_name ;
}
2019-11-03 14:38:03 +01:00
String VisualShaderNodeInput : : get_input_real_name ( ) const {
int idx = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type & & ports [ idx ] . name = = input_name ) {
return String ( ports [ idx ] . string ) ;
}
idx + + ;
}
return " " ;
}
2018-07-14 23:15:42 +02:00
VisualShaderNodeInput : : PortType VisualShaderNodeInput : : get_input_type_by_name ( String p_name ) const {
int idx = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type & & ports [ idx ] . name = = p_name ) {
return ports [ idx ] . type ;
}
idx + + ;
}
return PORT_TYPE_SCALAR ;
}
int VisualShaderNodeInput : : get_input_index_count ( ) const {
int idx = 0 ;
int count = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
count + + ;
}
idx + + ;
}
return count ;
}
VisualShaderNodeInput : : PortType VisualShaderNodeInput : : get_input_index_type ( int p_index ) const {
int idx = 0 ;
int count = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
if ( count = = p_index ) {
return ports [ idx ] . type ;
}
count + + ;
}
idx + + ;
}
return PORT_TYPE_SCALAR ;
}
String VisualShaderNodeInput : : get_input_index_name ( int p_index ) const {
int idx = 0 ;
int count = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
if ( count = = p_index ) {
return ports [ idx ] . name ;
}
count + + ;
}
idx + + ;
}
return " " ;
}
void VisualShaderNodeInput : : _validate_property ( PropertyInfo & property ) const {
if ( property . name = = " input_name " ) {
String port_list ;
int idx = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
2021-12-09 10:42:46 +01:00
if ( ! port_list . is_empty ( ) ) {
2018-07-14 23:15:42 +02:00
port_list + = " , " ;
}
port_list + = ports [ idx ] . name ;
}
idx + + ;
}
2021-12-09 10:42:46 +01:00
if ( port_list . is_empty ( ) ) {
2022-03-28 15:24:14 +02:00
port_list = RTR ( " None " ) ;
2018-07-14 23:15:42 +02:00
}
property . hint_string = port_list ;
}
}
Vector < StringName > VisualShaderNodeInput : : get_editable_properties ( ) const {
Vector < StringName > props ;
props . push_back ( " input_name " ) ;
return props ;
}
2021-06-17 17:03:07 +02:00
void VisualShaderNodeInput : : set_shader_type ( VisualShader : : Type p_shader_type ) {
shader_type = p_shader_type ;
}
void VisualShaderNodeInput : : set_shader_mode ( Shader : : Mode p_shader_mode ) {
shader_mode = p_shader_mode ;
}
2018-07-14 23:15:42 +02:00
void VisualShaderNodeInput : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_input_name " , " name " ) , & VisualShaderNodeInput : : set_input_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_input_name " ) , & VisualShaderNodeInput : : get_input_name ) ;
2019-11-04 16:50:33 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_input_real_name " ) , & VisualShaderNodeInput : : get_input_real_name ) ;
2018-07-14 23:15:42 +02:00
2020-02-20 22:58:05 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING_NAME , " input_name " , PROPERTY_HINT_ENUM , " " ) , " set_input_name " , " get_input_name " ) ;
2018-07-14 23:15:42 +02:00
ADD_SIGNAL ( MethodInfo ( " input_type_changed " ) ) ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
VisualShaderNodeInput : : VisualShaderNodeInput ( ) {
}
2020-07-28 10:02:57 +02:00
////////////// UniformRef
List < VisualShaderNodeUniformRef : : Uniform > uniforms ;
void VisualShaderNodeUniformRef : : add_uniform ( const String & p_name , UniformType p_type ) {
uniforms . push_back ( { p_name , p_type } ) ;
}
void VisualShaderNodeUniformRef : : clear_uniforms ( ) {
uniforms . clear ( ) ;
}
2020-09-21 13:32:59 +02:00
bool VisualShaderNodeUniformRef : : has_uniform ( const String & p_name ) {
2021-07-24 15:46:25 +02:00
for ( const VisualShaderNodeUniformRef : : Uniform & E : uniforms ) {
2021-07-16 05:45:57 +02:00
if ( E . name = = p_name ) {
2020-09-21 13:32:59 +02:00
return true ;
}
}
return false ;
}
2020-07-28 10:02:57 +02:00
String VisualShaderNodeUniformRef : : get_caption ( ) const {
return " UniformRef " ;
}
int VisualShaderNodeUniformRef : : get_input_port_count ( ) const {
return 0 ;
}
VisualShaderNodeUniformRef : : PortType VisualShaderNodeUniformRef : : get_input_port_type ( int p_port ) const {
return PortType : : PORT_TYPE_SCALAR ;
}
String VisualShaderNodeUniformRef : : get_input_port_name ( int p_port ) const {
return " " ;
}
int VisualShaderNodeUniformRef : : get_output_port_count ( ) const {
switch ( uniform_type ) {
case UniformType : : UNIFORM_TYPE_FLOAT :
return 1 ;
case UniformType : : UNIFORM_TYPE_INT :
return 1 ;
case UniformType : : UNIFORM_TYPE_BOOLEAN :
return 1 ;
2022-02-01 09:32:01 +01:00
case UniformType : : UNIFORM_TYPE_VECTOR2 :
return 1 ;
case UniformType : : UNIFORM_TYPE_VECTOR3 :
2020-07-28 10:02:57 +02:00
return 1 ;
2022-04-12 19:09:29 +02:00
case UniformType : : UNIFORM_TYPE_VECTOR4 :
return 1 ;
2020-07-28 10:02:57 +02:00
case UniformType : : UNIFORM_TYPE_TRANSFORM :
return 1 ;
case UniformType : : UNIFORM_TYPE_COLOR :
return 2 ;
case UniformType : : UNIFORM_TYPE_SAMPLER :
return 1 ;
default :
break ;
}
2020-09-21 13:32:59 +02:00
return 1 ;
2020-07-28 10:02:57 +02:00
}
VisualShaderNodeUniformRef : : PortType VisualShaderNodeUniformRef : : get_output_port_type ( int p_port ) const {
switch ( uniform_type ) {
case UniformType : : UNIFORM_TYPE_FLOAT :
return PortType : : PORT_TYPE_SCALAR ;
case UniformType : : UNIFORM_TYPE_INT :
return PortType : : PORT_TYPE_SCALAR_INT ;
case UniformType : : UNIFORM_TYPE_BOOLEAN :
return PortType : : PORT_TYPE_BOOLEAN ;
2022-02-01 09:32:01 +01:00
case UniformType : : UNIFORM_TYPE_VECTOR2 :
return PortType : : PORT_TYPE_VECTOR_2D ;
case UniformType : : UNIFORM_TYPE_VECTOR3 :
2022-02-06 18:15:28 +01:00
return PortType : : PORT_TYPE_VECTOR_3D ;
2022-04-12 19:09:29 +02:00
case UniformType : : UNIFORM_TYPE_VECTOR4 :
return PortType : : PORT_TYPE_VECTOR_4D ;
2020-07-28 10:02:57 +02:00
case UniformType : : UNIFORM_TYPE_TRANSFORM :
return PortType : : PORT_TYPE_TRANSFORM ;
case UniformType : : UNIFORM_TYPE_COLOR :
if ( p_port = = 0 ) {
2022-02-06 18:15:28 +01:00
return PortType : : PORT_TYPE_VECTOR_3D ;
2020-07-28 10:02:57 +02:00
} else if ( p_port = = 1 ) {
return PORT_TYPE_SCALAR ;
}
break ;
case UniformType : : UNIFORM_TYPE_SAMPLER :
return PortType : : PORT_TYPE_SAMPLER ;
default :
break ;
}
return PORT_TYPE_SCALAR ;
}
String VisualShaderNodeUniformRef : : get_output_port_name ( int p_port ) const {
switch ( uniform_type ) {
case UniformType : : UNIFORM_TYPE_FLOAT :
return " " ;
case UniformType : : UNIFORM_TYPE_INT :
return " " ;
case UniformType : : UNIFORM_TYPE_BOOLEAN :
return " " ;
2022-02-01 09:32:01 +01:00
case UniformType : : UNIFORM_TYPE_VECTOR2 :
return " " ;
case UniformType : : UNIFORM_TYPE_VECTOR3 :
2020-07-28 10:02:57 +02:00
return " " ;
2022-04-12 19:09:29 +02:00
case UniformType : : UNIFORM_TYPE_VECTOR4 :
return " " ;
2020-07-28 10:02:57 +02:00
case UniformType : : UNIFORM_TYPE_TRANSFORM :
return " " ;
case UniformType : : UNIFORM_TYPE_COLOR :
if ( p_port = = 0 ) {
return " rgb " ;
} else if ( p_port = = 1 ) {
return " alpha " ;
}
break ;
case UniformType : : UNIFORM_TYPE_SAMPLER :
return " " ;
break ;
default :
break ;
}
return " " ;
}
void VisualShaderNodeUniformRef : : set_uniform_name ( const String & p_name ) {
uniform_name = p_name ;
2020-09-21 13:32:59 +02:00
if ( uniform_name ! = " [None] " ) {
uniform_type = get_uniform_type_by_name ( uniform_name ) ;
2020-07-28 10:02:57 +02:00
} else {
uniform_type = UniformType : : UNIFORM_TYPE_FLOAT ;
}
emit_changed ( ) ;
}
String VisualShaderNodeUniformRef : : get_uniform_name ( ) const {
return uniform_name ;
}
int VisualShaderNodeUniformRef : : get_uniforms_count ( ) const {
return uniforms . size ( ) ;
}
String VisualShaderNodeUniformRef : : get_uniform_name_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < uniforms . size ( ) ) {
return uniforms [ p_idx ] . name ;
}
return " " ;
}
VisualShaderNodeUniformRef : : UniformType VisualShaderNodeUniformRef : : get_uniform_type_by_name ( const String & p_name ) const {
for ( int i = 0 ; i < uniforms . size ( ) ; i + + ) {
if ( uniforms [ i ] . name = = p_name ) {
return uniforms [ i ] . type ;
}
}
return UniformType : : UNIFORM_TYPE_FLOAT ;
}
VisualShaderNodeUniformRef : : UniformType VisualShaderNodeUniformRef : : get_uniform_type_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < uniforms . size ( ) ) {
return uniforms [ p_idx ] . type ;
}
return UniformType : : UNIFORM_TYPE_FLOAT ;
}
2021-07-12 09:34:40 +02:00
VisualShaderNodeUniformRef : : PortType VisualShaderNodeUniformRef : : get_port_type_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < uniforms . size ( ) ) {
switch ( uniforms [ p_idx ] . type ) {
case UniformType : : UNIFORM_TYPE_FLOAT :
return PORT_TYPE_SCALAR ;
case UniformType : : UNIFORM_TYPE_INT :
return PORT_TYPE_SCALAR_INT ;
case UniformType : : UNIFORM_TYPE_SAMPLER :
return PORT_TYPE_SAMPLER ;
2022-02-01 09:32:01 +01:00
case UniformType : : UNIFORM_TYPE_VECTOR2 :
return PORT_TYPE_VECTOR_2D ;
case UniformType : : UNIFORM_TYPE_VECTOR3 :
2022-02-06 18:15:28 +01:00
return PORT_TYPE_VECTOR_3D ;
2022-04-12 19:09:29 +02:00
case UniformType : : UNIFORM_TYPE_VECTOR4 :
return PORT_TYPE_VECTOR_4D ;
2021-07-12 09:34:40 +02:00
case UniformType : : UNIFORM_TYPE_TRANSFORM :
return PORT_TYPE_TRANSFORM ;
case UniformType : : UNIFORM_TYPE_COLOR :
2022-02-06 18:15:28 +01:00
return PORT_TYPE_VECTOR_3D ;
2021-07-12 09:34:40 +02:00
default :
break ;
}
}
return PORT_TYPE_SCALAR ;
}
2020-07-28 10:02:57 +02:00
String VisualShaderNodeUniformRef : : 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 ) const {
switch ( uniform_type ) {
case UniformType : : UNIFORM_TYPE_FLOAT :
2020-09-21 13:32:59 +02:00
if ( uniform_name = = " [None] " ) {
2021-07-19 08:06:51 +02:00
return " " + p_output_vars [ 0 ] + " = 0.0; \n " ;
2020-09-21 13:32:59 +02:00
}
2022-02-01 09:32:01 +01:00
break ;
2020-07-28 10:02:57 +02:00
case UniformType : : UNIFORM_TYPE_COLOR : {
2021-07-19 08:06:51 +02:00
String code = " " + p_output_vars [ 0 ] + " = " + get_uniform_name ( ) + " .rgb; \n " ;
code + = " " + p_output_vars [ 1 ] + " = " + get_uniform_name ( ) + " .a; \n " ;
2020-07-28 10:02:57 +02:00
return code ;
} break ;
case UniformType : : UNIFORM_TYPE_SAMPLER :
2022-02-01 09:32:01 +01:00
return String ( ) ;
2020-07-28 10:02:57 +02:00
default :
break ;
}
2022-02-01 09:32:01 +01:00
return " " + p_output_vars [ 0 ] + " = " + get_uniform_name ( ) + " ; \n " ;
2020-07-28 10:02:57 +02:00
}
2020-09-21 13:32:59 +02:00
void VisualShaderNodeUniformRef : : _set_uniform_type ( int p_uniform_type ) {
uniform_type = ( UniformType ) p_uniform_type ;
}
int VisualShaderNodeUniformRef : : _get_uniform_type ( ) const {
return ( int ) uniform_type ;
}
2020-07-28 10:02:57 +02:00
void VisualShaderNodeUniformRef : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_uniform_name " , " name " ) , & VisualShaderNodeUniformRef : : set_uniform_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_uniform_name " ) , & VisualShaderNodeUniformRef : : get_uniform_name ) ;
2020-09-21 13:32:59 +02:00
ClassDB : : bind_method ( D_METHOD ( " _set_uniform_type " , " type " ) , & VisualShaderNodeUniformRef : : _set_uniform_type ) ;
ClassDB : : bind_method ( D_METHOD ( " _get_uniform_type " ) , & VisualShaderNodeUniformRef : : _get_uniform_type ) ;
2020-07-28 10:02:57 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING_NAME , " uniform_name " , PROPERTY_HINT_ENUM , " " ) , " set_uniform_name " , " get_uniform_name " ) ;
2021-11-03 23:06:17 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " uniform_type " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) , " _set_uniform_type " , " _get_uniform_type " ) ;
2020-07-28 10:02:57 +02:00
}
Vector < StringName > VisualShaderNodeUniformRef : : get_editable_properties ( ) const {
Vector < StringName > props ;
props . push_back ( " uniform_name " ) ;
2020-09-21 13:32:59 +02:00
props . push_back ( " uniform_type " ) ;
2020-07-28 10:02:57 +02:00
return props ;
}
VisualShaderNodeUniformRef : : VisualShaderNodeUniformRef ( ) {
}
2018-07-14 23:15:42 +02:00
////////////////////////////////////////////
const VisualShaderNodeOutput : : Port VisualShaderNodeOutput : : ports [ ] = {
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Node3D.
////////////////////////////////////////////////////////////////////////
// Node3D, Vertex.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Vertex " , " VERTEX " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Normal " , " NORMAL " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Tangent " , " TANGENT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Binormal " , " BINORMAL " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " UV " , " UV " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " UV2 " , " UV2 " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " Color " , " COLOR " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " Roughness " , " ROUGHNESS " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " Point Size " , " POINT_SIZE " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_TRANSFORM , " Model View Matrix " , " MODELVIEW_MATRIX " } ,
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Node3D, Fragment.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Albedo " , " ALBEDO " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Alpha " , " ALPHA " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Metallic " , " METALLIC " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Roughness " , " ROUGHNESS " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Specular " , " SPECULAR " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Emission " , " EMISSION " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " AO " , " AO " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " AO Light Affect " , " AO_LIGHT_AFFECT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Normal " , " NORMAL " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Normal Map " , " NORMAL_MAP " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Normal Map Depth " , " NORMAL_MAP_DEPTH " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Rim " , " RIM " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Rim Tint " , " RIM_TINT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Clearcoat " , " CLEARCOAT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Clearcoat Roughness " , " CLEARCOAT_ROUGHNESS " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Anisotropy " , " ANISOTROPY " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " Anisotropy Flow " , " ANISOTROPY_FLOW " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Subsurf Scatter " , " SSS_STRENGTH " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Backlight " , " BACKLIGHT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Alpha Scissor Threshold " , " ALPHA_SCISSOR_THRESHOLD " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Alpha Hash Scale " , " ALPHA_HASH_SCALE " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Alpha AA Edge " , " ALPHA_ANTIALIASING_EDGE " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " Alpha UV " , " ALPHA_TEXTURE_COORDINATE " } ,
2022-03-03 19:08:36 +01:00
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Node3D, Light.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Diffuse " , " DIFFUSE_LIGHT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Specular " , " SPECULAR_LIGHT " } ,
{ Shader : : MODE_SPATIAL , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_SCALAR , " Alpha " , " ALPHA " } ,
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Canvas Item.
////////////////////////////////////////////////////////////////////////
// Canvas Item, Vertex.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " Vertex " , " VERTEX " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " UV " , " UV " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " Color " , " COLOR " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_VERTEX , VisualShaderNode : : PORT_TYPE_SCALAR , " Point Size " , " POINT_SIZE " } ,
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Canvas Item, Fragment.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " Color " , " COLOR " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Normal " , " NORMAL " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Normal Map " , " NORMAL_MAP " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_SCALAR , " Normal Map Depth " , " NORMAL_MAP_DEPTH " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Light Vertex " , " LIGHT_VERTEX " } ,
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_FRAGMENT , VisualShaderNode : : PORT_TYPE_VECTOR_2D , " Shadow Vertex " , " SHADOW_VERTEX " } ,
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Canvas Item, Light.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_CANVAS_ITEM , VisualShader : : TYPE_LIGHT , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " Light " , " LIGHT " } ,
2020-09-15 09:57:40 +02:00
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
// Sky, Sky.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Color " , " COLOR " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_SCALAR , " Alpha " , " ALPHA " } ,
{ Shader : : MODE_SKY , VisualShader : : TYPE_SKY , VisualShaderNode : : PORT_TYPE_VECTOR_4D , " Fog " , " FOG " } ,
2020-03-25 10:22:29 +01:00
2021-10-03 13:28:55 +02:00
////////////////////////////////////////////////////////////////////////
// Fog, Fog.
////////////////////////////////////////////////////////////////////////
2022-04-24 18:22:29 +02:00
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_SCALAR , " Density " , " DENSITY " } ,
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Albedo " , " ALBEDO " } ,
{ Shader : : MODE_FOG , VisualShader : : TYPE_FOG , VisualShaderNode : : PORT_TYPE_VECTOR_3D , " Emission " , " EMISSION " } ,
2021-10-03 13:28:55 +02:00
2021-07-18 14:05:25 +02:00
////////////////////////////////////////////////////////////////////////
2020-04-02 01:20:12 +02:00
{ Shader : : MODE_MAX , VisualShader : : TYPE_MAX , VisualShaderNode : : PORT_TYPE_TRANSFORM , nullptr , nullptr } ,
2018-07-14 23:15:42 +02:00
} ;
int VisualShaderNodeOutput : : get_input_port_count ( ) const {
int idx = 0 ;
int count = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
count + + ;
}
idx + + ;
}
return count ;
}
VisualShaderNodeOutput : : PortType VisualShaderNodeOutput : : get_input_port_type ( int p_port ) const {
int idx = 0 ;
int count = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
if ( count = = p_port ) {
return ports [ idx ] . type ;
}
count + + ;
}
idx + + ;
}
return PORT_TYPE_SCALAR ;
}
String VisualShaderNodeOutput : : get_input_port_name ( int p_port ) const {
int idx = 0 ;
int count = 0 ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
if ( count = = p_port ) {
2022-04-24 18:22:29 +02:00
return String ( ports [ idx ] . name ) ;
2018-07-14 23:15:42 +02:00
}
count + + ;
}
idx + + ;
}
return String ( ) ;
}
Variant VisualShaderNodeOutput : : get_input_port_default_value ( int p_port ) const {
return Variant ( ) ;
}
int VisualShaderNodeOutput : : get_output_port_count ( ) const {
return 0 ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
VisualShaderNodeOutput : : PortType VisualShaderNodeOutput : : get_output_port_type ( int p_port ) const {
return PORT_TYPE_SCALAR ;
}
2020-05-14 14:29:06 +02:00
2018-07-14 23:15:42 +02:00
String VisualShaderNodeOutput : : get_output_port_name ( int p_port ) const {
return String ( ) ;
}
bool VisualShaderNodeOutput : : is_port_separator ( int p_index ) const {
2021-05-27 21:17:58 +02:00
if ( shader_mode = = Shader : : MODE_SPATIAL & & shader_type = = VisualShader : : TYPE_VERTEX ) {
String name = get_input_port_name ( p_index ) ;
return bool ( name = = " Model View Matrix " ) ;
}
2018-07-14 23:15:42 +02:00
if ( shader_mode = = Shader : : MODE_SPATIAL & & shader_type = = VisualShader : : TYPE_FRAGMENT ) {
String name = get_input_port_name ( p_index ) ;
2022-04-24 18:22:29 +02:00
return bool ( name = = " AO " | | name = = " Normal " | | name = = " Rim " | | name = = " Clearcoat " | | name = = " Anisotropy " | | name = = " Subsurf Scatter " | | name = = " Alpha Scissor Threshold " ) ;
2018-07-14 23:15:42 +02:00
}
return false ;
}
String VisualShaderNodeOutput : : get_caption ( ) const {
2019-10-29 07:26:05 +01:00
return " Output " ;
2018-07-14 23:15:42 +02:00
}
2019-01-21 20:07:53 +01:00
String VisualShaderNodeOutput : : 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 ) const {
2018-07-14 23:15:42 +02:00
int idx = 0 ;
int count = 0 ;
String code ;
while ( ports [ idx ] . mode ! = Shader : : MODE_MAX ) {
if ( ports [ idx ] . mode = = shader_mode & & ports [ idx ] . shader_type = = shader_type ) {
2021-12-09 10:42:46 +01:00
if ( ! p_input_vars [ count ] . is_empty ( ) ) {
2018-07-14 23:15:42 +02:00
String s = ports [ idx ] . string ;
2022-02-03 17:03:38 +01:00
if ( s . contains ( " : " ) ) {
2021-07-19 08:06:51 +02:00
code + = " " + s . get_slicec ( ' : ' , 0 ) + " = " + p_input_vars [ count ] + " . " + s . get_slicec ( ' : ' , 1 ) + " ; \n " ;
2018-07-14 23:15:42 +02:00
} else {
2021-07-19 08:06:51 +02:00
code + = " " + s + " = " + p_input_vars [ count ] + " ; \n " ;
2018-07-14 23:15:42 +02:00
}
}
count + + ;
}
idx + + ;
}
return code ;
}
VisualShaderNodeOutput : : VisualShaderNodeOutput ( ) {
}
///////////////////////////
void VisualShaderNodeUniform : : set_uniform_name ( const String & p_name ) {
uniform_name = p_name ;
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " name_changed " ) ) ;
2018-07-14 23:15:42 +02:00
emit_changed ( ) ;
}
String VisualShaderNodeUniform : : get_uniform_name ( ) const {
return uniform_name ;
}
2020-05-05 10:25:48 +02:00
void VisualShaderNodeUniform : : set_qualifier ( VisualShaderNodeUniform : : Qualifier p_qual ) {
2021-08-14 12:38:22 +02:00
ERR_FAIL_INDEX ( int ( p_qual ) , int ( QUAL_MAX ) ) ;
if ( qualifier = = p_qual ) {
return ;
}
2020-05-05 10:25:48 +02:00
qualifier = p_qual ;
emit_changed ( ) ;
}
VisualShaderNodeUniform : : Qualifier VisualShaderNodeUniform : : get_qualifier ( ) const {
return qualifier ;
}
2020-07-28 10:02:57 +02:00
void VisualShaderNodeUniform : : set_global_code_generated ( bool p_enabled ) {
global_code_generated = p_enabled ;
}
bool VisualShaderNodeUniform : : is_global_code_generated ( ) const {
return global_code_generated ;
}
2018-07-14 23:15:42 +02:00
void VisualShaderNodeUniform : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_uniform_name " , " name " ) , & VisualShaderNodeUniform : : set_uniform_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_uniform_name " ) , & VisualShaderNodeUniform : : get_uniform_name ) ;
2020-05-05 10:25:48 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_qualifier " , " qualifier " ) , & VisualShaderNodeUniform : : set_qualifier ) ;
ClassDB : : bind_method ( D_METHOD ( " get_qualifier " ) , & VisualShaderNodeUniform : : get_qualifier ) ;
2020-02-20 22:58:05 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING_NAME , " uniform_name " ) , " set_uniform_name " , " get_uniform_name " ) ;
2020-05-05 10:25:48 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " qualifier " , PROPERTY_HINT_ENUM , " None,Global,Instance " ) , " set_qualifier " , " get_qualifier " ) ;
BIND_ENUM_CONSTANT ( QUAL_NONE ) ;
BIND_ENUM_CONSTANT ( QUAL_GLOBAL ) ;
BIND_ENUM_CONSTANT ( QUAL_INSTANCE ) ;
2021-08-14 12:38:22 +02:00
BIND_ENUM_CONSTANT ( QUAL_MAX ) ;
2020-05-05 10:25:48 +02:00
}
String VisualShaderNodeUniform : : _get_qual_str ( ) const {
if ( is_qualifier_supported ( qualifier ) ) {
switch ( qualifier ) {
case QUAL_NONE :
break ;
case QUAL_GLOBAL :
return " global " ;
case QUAL_INSTANCE :
return " instance " ;
2021-08-14 12:38:22 +02:00
default :
break ;
2020-05-05 10:25:48 +02:00
}
}
return String ( ) ;
2018-07-14 23:15:42 +02:00
}
2020-04-06 09:25:05 +02:00
String VisualShaderNodeUniform : : get_warning ( Shader : : Mode p_mode , VisualShader : : Type p_type ) const {
List < String > keyword_list ;
ShaderLanguage : : get_keyword_list ( & keyword_list ) ;
if ( keyword_list . find ( uniform_name ) ) {
2022-03-28 15:24:14 +02:00
return RTR ( " Shader keywords cannot be used as uniform names. \n Choose another name. " ) ;
2020-04-06 09:25:05 +02:00
}
2020-05-05 10:25:48 +02:00
if ( ! is_qualifier_supported ( qualifier ) ) {
2021-08-12 15:55:14 +02:00
String qualifier_str ;
switch ( qualifier ) {
case QUAL_NONE :
break ;
case QUAL_GLOBAL :
qualifier_str = " global " ;
break ;
case QUAL_INSTANCE :
qualifier_str = " instance " ;
break ;
2021-08-14 12:38:22 +02:00
default :
break ;
2021-08-12 15:55:14 +02:00
}
2022-03-28 15:24:14 +02:00
return vformat ( RTR ( " This uniform type does not support the '%s' qualifier. " ) , qualifier_str ) ;
2021-08-12 15:55:14 +02:00
} else if ( qualifier = = Qualifier : : QUAL_GLOBAL ) {
RS : : GlobalVariableType gvt = RS : : get_singleton ( ) - > global_variable_get_type ( uniform_name ) ;
if ( gvt = = RS : : GLOBAL_VAR_TYPE_MAX ) {
2022-03-28 15:24:14 +02:00
return vformat ( RTR ( " Global uniform '%s' does not exist. \n Create it in the Project Settings. " ) , uniform_name ) ;
2021-08-12 15:55:14 +02:00
}
bool incompatible_type = false ;
switch ( gvt ) {
case RS : : GLOBAL_VAR_TYPE_FLOAT : {
if ( ! Object : : cast_to < VisualShaderNodeFloatUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_INT : {
if ( ! Object : : cast_to < VisualShaderNodeIntUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_BOOL : {
if ( ! Object : : cast_to < VisualShaderNodeBooleanUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_COLOR : {
if ( ! Object : : cast_to < VisualShaderNodeColorUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_VEC3 : {
if ( ! Object : : cast_to < VisualShaderNodeVec3Uniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
2022-04-12 19:09:29 +02:00
case RS : : GLOBAL_VAR_TYPE_VEC4 : {
if ( ! Object : : cast_to < VisualShaderNodeVec4Uniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
2021-08-12 15:55:14 +02:00
case RS : : GLOBAL_VAR_TYPE_TRANSFORM : {
if ( ! Object : : cast_to < VisualShaderNodeTransformUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_SAMPLER2D : {
if ( ! Object : : cast_to < VisualShaderNodeTextureUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_SAMPLER3D : {
if ( ! Object : : cast_to < VisualShaderNodeTexture3DUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_SAMPLER2DARRAY : {
if ( ! Object : : cast_to < VisualShaderNodeTexture2DArrayUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
case RS : : GLOBAL_VAR_TYPE_SAMPLERCUBE : {
if ( ! Object : : cast_to < VisualShaderNodeCubemapUniform > ( this ) ) {
incompatible_type = true ;
}
} break ;
default :
break ;
}
if ( incompatible_type ) {
2022-03-28 15:24:14 +02:00
return vformat ( RTR ( " Global uniform '%s' has an incompatible type for this kind of node. \n Change it in the Project Settings. " ) , uniform_name ) ;
2021-08-12 15:55:14 +02:00
}
2020-05-05 10:25:48 +02:00
}
2020-04-06 09:25:05 +02:00
return String ( ) ;
}
2020-05-05 10:25:48 +02:00
Vector < StringName > VisualShaderNodeUniform : : get_editable_properties ( ) const {
Vector < StringName > props ;
props . push_back ( " qualifier " ) ;
return props ;
}
2018-07-14 23:15:42 +02:00
VisualShaderNodeUniform : : VisualShaderNodeUniform ( ) {
}
2019-05-12 14:09:39 +02:00
2020-10-04 11:11:58 +02:00
////////////// ResizeableBase
2019-05-12 14:09:39 +02:00
2020-10-04 11:11:58 +02:00
void VisualShaderNodeResizableBase : : set_size ( const Vector2 & p_size ) {
2019-05-12 14:09:39 +02:00
size = p_size ;
}
2020-10-04 11:11:58 +02:00
Vector2 VisualShaderNodeResizableBase : : get_size ( ) const {
2019-05-12 14:09:39 +02:00
return size ;
}
2020-10-04 11:11:58 +02:00
void VisualShaderNodeResizableBase : : set_allow_v_resize ( bool p_enabled ) {
allow_v_resize = p_enabled ;
}
bool VisualShaderNodeResizableBase : : is_allow_v_resize ( ) const {
return allow_v_resize ;
}
void VisualShaderNodeResizableBase : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_size " , " size " ) , & VisualShaderNodeResizableBase : : set_size ) ;
ClassDB : : bind_method ( D_METHOD ( " get_size " ) , & VisualShaderNodeResizableBase : : get_size ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " size " ) , " set_size " , " get_size " ) ;
}
VisualShaderNodeResizableBase : : VisualShaderNodeResizableBase ( ) {
set_allow_v_resize ( true ) ;
}
2021-02-21 09:33:55 +01:00
////////////// Comment
String VisualShaderNodeComment : : get_caption ( ) const {
return title ;
}
int VisualShaderNodeComment : : get_input_port_count ( ) const {
return 0 ;
}
VisualShaderNodeComment : : PortType VisualShaderNodeComment : : get_input_port_type ( int p_port ) const {
return PortType : : PORT_TYPE_SCALAR ;
}
String VisualShaderNodeComment : : get_input_port_name ( int p_port ) const {
return String ( ) ;
}
int VisualShaderNodeComment : : get_output_port_count ( ) const {
return 0 ;
}
VisualShaderNodeComment : : PortType VisualShaderNodeComment : : get_output_port_type ( int p_port ) const {
return PortType : : PORT_TYPE_SCALAR ;
}
String VisualShaderNodeComment : : get_output_port_name ( int p_port ) const {
return String ( ) ;
}
void VisualShaderNodeComment : : set_title ( const String & p_title ) {
title = p_title ;
}
String VisualShaderNodeComment : : get_title ( ) const {
return title ;
}
void VisualShaderNodeComment : : set_description ( const String & p_description ) {
description = p_description ;
}
String VisualShaderNodeComment : : get_description ( ) const {
return description ;
}
String VisualShaderNodeComment : : 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 ) const {
return String ( ) ;
}
void VisualShaderNodeComment : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_title " , " title " ) , & VisualShaderNodeComment : : set_title ) ;
ClassDB : : bind_method ( D_METHOD ( " get_title " ) , & VisualShaderNodeComment : : get_title ) ;
ClassDB : : bind_method ( D_METHOD ( " set_description " , " description " ) , & VisualShaderNodeComment : : set_description ) ;
ClassDB : : bind_method ( D_METHOD ( " get_description " ) , & VisualShaderNodeComment : : get_description ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " title " ) , " set_title " , " get_title " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " description " ) , " set_description " , " get_description " ) ;
}
VisualShaderNodeComment : : VisualShaderNodeComment ( ) {
}
2020-10-04 11:11:58 +02:00
////////////// GroupBase
2019-05-12 14:09:39 +02:00
void VisualShaderNodeGroupBase : : set_inputs ( const String & p_inputs ) {
2020-05-14 16:41:43 +02:00
if ( inputs = = p_inputs ) {
2019-05-12 14:09:39 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-12 14:09:39 +02:00
clear_input_ports ( ) ;
inputs = p_inputs ;
Vector < String > input_strings = inputs . split ( " ; " , false ) ;
int input_port_count = input_strings . size ( ) ;
for ( int i = 0 ; i < input_port_count ; i + + ) {
Vector < String > arr = input_strings [ i ] . split ( " , " ) ;
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
int port_idx = arr [ 0 ] . to_int ( ) ;
int port_type = arr [ 1 ] . to_int ( ) ;
String port_name = arr [ 2 ] ;
Port port ;
port . type = ( PortType ) port_type ;
port . name = port_name ;
input_ports [ port_idx ] = port ;
}
}
String VisualShaderNodeGroupBase : : get_inputs ( ) const {
return inputs ;
}
void VisualShaderNodeGroupBase : : set_outputs ( const String & p_outputs ) {
2020-05-14 16:41:43 +02:00
if ( outputs = = p_outputs ) {
2019-05-12 14:09:39 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-12 14:09:39 +02:00
clear_output_ports ( ) ;
outputs = p_outputs ;
Vector < String > output_strings = outputs . split ( " ; " , false ) ;
int output_port_count = output_strings . size ( ) ;
for ( int i = 0 ; i < output_port_count ; i + + ) {
Vector < String > arr = output_strings [ i ] . split ( " , " ) ;
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
int port_idx = arr [ 0 ] . to_int ( ) ;
int port_type = arr [ 1 ] . to_int ( ) ;
String port_name = arr [ 2 ] ;
Port port ;
port . type = ( PortType ) port_type ;
port . name = port_name ;
output_ports [ port_idx ] = port ;
}
}
String VisualShaderNodeGroupBase : : get_outputs ( ) const {
return outputs ;
}
2019-06-22 16:41:51 +02:00
bool VisualShaderNodeGroupBase : : is_valid_port_name ( const String & p_name ) const {
if ( ! p_name . is_valid_identifier ( ) ) {
return false ;
}
for ( int i = 0 ; i < get_input_port_count ( ) ; i + + ) {
if ( get_input_port_name ( i ) = = p_name ) {
return false ;
}
}
for ( int i = 0 ; i < get_output_port_count ( ) ; i + + ) {
if ( get_output_port_name ( i ) = = p_name ) {
return false ;
}
}
return true ;
}
2019-05-12 14:09:39 +02:00
void VisualShaderNodeGroupBase : : add_input_port ( int p_id , int p_type , const String & p_name ) {
2021-08-14 12:38:22 +02:00
ERR_FAIL_INDEX ( p_type , int ( PORT_TYPE_MAX ) ) ;
ERR_FAIL_COND ( ! is_valid_port_name ( p_name ) ) ;
2019-05-12 14:09:39 +02:00
String str = itos ( p_id ) + " , " + itos ( p_type ) + " , " + p_name + " ; " ;
Vector < String > inputs_strings = inputs . split ( " ; " , false ) ;
int index = 0 ;
if ( p_id < inputs_strings . size ( ) ) {
for ( int i = 0 ; i < inputs_strings . size ( ) ; i + + ) {
if ( i = = p_id ) {
inputs = inputs . insert ( index , str ) ;
break ;
}
index + = inputs_strings [ i ] . size ( ) ;
}
} else {
inputs + = str ;
}
inputs_strings = inputs . split ( " ; " , false ) ;
index = 0 ;
for ( int i = 0 ; i < inputs_strings . size ( ) ; i + + ) {
int count = 0 ;
for ( int j = 0 ; j < inputs_strings [ i ] . size ( ) ; j + + ) {
if ( inputs_strings [ i ] [ j ] = = ' , ' ) {
break ;
}
count + + ;
}
2021-11-11 09:08:08 +01:00
inputs = inputs . left ( index ) + inputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
inputs = inputs . insert ( index , itos ( i ) ) ;
index + = inputs_strings [ i ] . size ( ) ;
}
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
void VisualShaderNodeGroupBase : : remove_input_port ( int p_id ) {
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( ! has_input_port ( p_id ) ) ;
2019-05-12 14:09:39 +02:00
Vector < String > inputs_strings = inputs . split ( " ; " , false ) ;
int count = 0 ;
int index = 0 ;
for ( int i = 0 ; i < inputs_strings . size ( ) ; i + + ) {
Vector < String > arr = inputs_strings [ i ] . split ( " , " ) ;
if ( arr [ 0 ] . to_int ( ) = = p_id ) {
count = inputs_strings [ i ] . size ( ) ;
break ;
}
index + = inputs_strings [ i ] . size ( ) ;
}
2021-11-11 09:08:08 +01:00
inputs = inputs . left ( index ) + inputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
inputs_strings = inputs . split ( " ; " , false ) ;
2020-12-01 14:24:06 +01:00
inputs = inputs . substr ( 0 , index ) ;
2019-05-12 14:09:39 +02:00
for ( int i = p_id ; i < inputs_strings . size ( ) ; i + + ) {
2020-12-01 14:24:06 +01:00
inputs + = inputs_strings [ i ] . replace_first ( inputs_strings [ i ] . split ( " , " ) [ 0 ] , itos ( i ) ) + " ; " ;
2019-05-12 14:09:39 +02:00
}
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
int VisualShaderNodeGroupBase : : get_input_port_count ( ) const {
return input_ports . size ( ) ;
}
bool VisualShaderNodeGroupBase : : has_input_port ( int p_id ) const {
return input_ports . has ( p_id ) ;
}
void VisualShaderNodeGroupBase : : add_output_port ( int p_id , int p_type , const String & p_name ) {
2021-08-14 12:38:22 +02:00
ERR_FAIL_INDEX ( p_type , int ( PORT_TYPE_MAX ) ) ;
ERR_FAIL_COND ( ! is_valid_port_name ( p_name ) ) ;
2019-05-12 14:09:39 +02:00
String str = itos ( p_id ) + " , " + itos ( p_type ) + " , " + p_name + " ; " ;
Vector < String > outputs_strings = outputs . split ( " ; " , false ) ;
int index = 0 ;
if ( p_id < outputs_strings . size ( ) ) {
for ( int i = 0 ; i < outputs_strings . size ( ) ; i + + ) {
if ( i = = p_id ) {
outputs = outputs . insert ( index , str ) ;
break ;
}
index + = outputs_strings [ i ] . size ( ) ;
}
} else {
outputs + = str ;
}
outputs_strings = outputs . split ( " ; " , false ) ;
index = 0 ;
for ( int i = 0 ; i < outputs_strings . size ( ) ; i + + ) {
int count = 0 ;
for ( int j = 0 ; j < outputs_strings [ i ] . size ( ) ; j + + ) {
if ( outputs_strings [ i ] [ j ] = = ' , ' ) {
break ;
}
count + + ;
}
2021-11-11 09:08:08 +01:00
outputs = outputs . left ( index ) + outputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
outputs = outputs . insert ( index , itos ( i ) ) ;
index + = outputs_strings [ i ] . size ( ) ;
}
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
void VisualShaderNodeGroupBase : : remove_output_port ( int p_id ) {
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( ! has_output_port ( p_id ) ) ;
2019-05-12 14:09:39 +02:00
Vector < String > outputs_strings = outputs . split ( " ; " , false ) ;
int count = 0 ;
int index = 0 ;
for ( int i = 0 ; i < outputs_strings . size ( ) ; i + + ) {
Vector < String > arr = outputs_strings [ i ] . split ( " , " ) ;
if ( arr [ 0 ] . to_int ( ) = = p_id ) {
count = outputs_strings [ i ] . size ( ) ;
break ;
}
index + = outputs_strings [ i ] . size ( ) ;
}
2021-11-11 09:08:08 +01:00
outputs = outputs . left ( index ) + outputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
outputs_strings = outputs . split ( " ; " , false ) ;
2020-12-01 14:24:06 +01:00
outputs = outputs . substr ( 0 , index ) ;
2019-05-12 14:09:39 +02:00
for ( int i = p_id ; i < outputs_strings . size ( ) ; i + + ) {
2020-12-01 14:24:06 +01:00
outputs + = outputs_strings [ i ] . replace_first ( outputs_strings [ i ] . split ( " , " ) [ 0 ] , itos ( i ) ) + " ; " ;
2019-05-12 14:09:39 +02:00
}
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
int VisualShaderNodeGroupBase : : get_output_port_count ( ) const {
return output_ports . size ( ) ;
}
bool VisualShaderNodeGroupBase : : has_output_port ( int p_id ) const {
return output_ports . has ( p_id ) ;
}
void VisualShaderNodeGroupBase : : clear_input_ports ( ) {
input_ports . clear ( ) ;
}
void VisualShaderNodeGroupBase : : clear_output_ports ( ) {
output_ports . clear ( ) ;
}
void VisualShaderNodeGroupBase : : set_input_port_type ( int p_id , int p_type ) {
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( ! has_input_port ( p_id ) ) ;
2021-08-14 12:38:22 +02:00
ERR_FAIL_INDEX ( p_type , int ( PORT_TYPE_MAX ) ) ;
2019-06-22 16:41:51 +02:00
2020-05-14 16:41:43 +02:00
if ( input_ports [ p_id ] . type = = p_type ) {
2019-05-12 14:09:39 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-12 14:09:39 +02:00
Vector < String > inputs_strings = inputs . split ( " ; " , false ) ;
int count = 0 ;
int index = 0 ;
for ( int i = 0 ; i < inputs_strings . size ( ) ; i + + ) {
Vector < String > arr = inputs_strings [ i ] . split ( " , " ) ;
2019-12-10 10:03:27 +01:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
if ( arr [ 0 ] . to_int ( ) = = p_id ) {
index + = arr [ 0 ] . size ( ) ;
count = arr [ 1 ] . size ( ) - 1 ;
break ;
}
index + = inputs_strings [ i ] . size ( ) ;
}
2021-11-11 09:08:08 +01:00
inputs = inputs . left ( index ) + inputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
inputs = inputs . insert ( index , itos ( p_type ) ) ;
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
VisualShaderNodeGroupBase : : PortType VisualShaderNodeGroupBase : : get_input_port_type ( int p_id ) const {
ERR_FAIL_COND_V ( ! input_ports . has ( p_id ) , ( PortType ) 0 ) ;
return input_ports [ p_id ] . type ;
}
void VisualShaderNodeGroupBase : : set_input_port_name ( int p_id , const String & p_name ) {
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( ! has_input_port ( p_id ) ) ;
ERR_FAIL_COND ( ! is_valid_port_name ( p_name ) ) ;
2020-05-14 16:41:43 +02:00
if ( input_ports [ p_id ] . name = = p_name ) {
2019-05-12 14:09:39 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-12 14:09:39 +02:00
Vector < String > inputs_strings = inputs . split ( " ; " , false ) ;
int count = 0 ;
int index = 0 ;
for ( int i = 0 ; i < inputs_strings . size ( ) ; i + + ) {
Vector < String > arr = inputs_strings [ i ] . split ( " , " ) ;
2019-12-10 10:03:27 +01:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
if ( arr [ 0 ] . to_int ( ) = = p_id ) {
index + = arr [ 0 ] . size ( ) + arr [ 1 ] . size ( ) ;
count = arr [ 2 ] . size ( ) - 1 ;
break ;
}
index + = inputs_strings [ i ] . size ( ) ;
}
2021-11-11 09:08:08 +01:00
inputs = inputs . left ( index ) + inputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
inputs = inputs . insert ( index , p_name ) ;
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
String VisualShaderNodeGroupBase : : get_input_port_name ( int p_id ) const {
ERR_FAIL_COND_V ( ! input_ports . has ( p_id ) , " " ) ;
return input_ports [ p_id ] . name ;
}
void VisualShaderNodeGroupBase : : set_output_port_type ( int p_id , int p_type ) {
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( ! has_output_port ( p_id ) ) ;
2021-08-14 12:38:22 +02:00
ERR_FAIL_INDEX ( p_type , int ( PORT_TYPE_MAX ) ) ;
2019-06-22 16:41:51 +02:00
2020-05-14 16:41:43 +02:00
if ( output_ports [ p_id ] . type = = p_type ) {
2019-05-12 14:09:39 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-12 14:09:39 +02:00
Vector < String > output_strings = outputs . split ( " ; " , false ) ;
int count = 0 ;
int index = 0 ;
for ( int i = 0 ; i < output_strings . size ( ) ; i + + ) {
Vector < String > arr = output_strings [ i ] . split ( " , " ) ;
2019-12-10 10:03:27 +01:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
if ( arr [ 0 ] . to_int ( ) = = p_id ) {
index + = arr [ 0 ] . size ( ) ;
count = arr [ 1 ] . size ( ) - 1 ;
break ;
}
index + = output_strings [ i ] . size ( ) ;
}
2021-11-11 09:08:08 +01:00
outputs = outputs . left ( index ) + outputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
outputs = outputs . insert ( index , itos ( p_type ) ) ;
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
VisualShaderNodeGroupBase : : PortType VisualShaderNodeGroupBase : : get_output_port_type ( int p_id ) const {
ERR_FAIL_COND_V ( ! output_ports . has ( p_id ) , ( PortType ) 0 ) ;
return output_ports [ p_id ] . type ;
}
void VisualShaderNodeGroupBase : : set_output_port_name ( int p_id , const String & p_name ) {
2019-06-22 16:41:51 +02:00
ERR_FAIL_COND ( ! has_output_port ( p_id ) ) ;
ERR_FAIL_COND ( ! is_valid_port_name ( p_name ) ) ;
2020-05-14 16:41:43 +02:00
if ( output_ports [ p_id ] . name = = p_name ) {
2019-05-12 14:09:39 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2019-05-12 14:09:39 +02:00
Vector < String > output_strings = outputs . split ( " ; " , false ) ;
int count = 0 ;
int index = 0 ;
for ( int i = 0 ; i < output_strings . size ( ) ; i + + ) {
Vector < String > arr = output_strings [ i ] . split ( " , " ) ;
2019-12-10 10:03:27 +01:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
if ( arr [ 0 ] . to_int ( ) = = p_id ) {
index + = arr [ 0 ] . size ( ) + arr [ 1 ] . size ( ) ;
count = arr [ 2 ] . size ( ) - 1 ;
break ;
}
index + = output_strings [ i ] . size ( ) ;
}
2021-11-11 09:08:08 +01:00
outputs = outputs . left ( index ) + outputs . substr ( index + count ) ;
2019-05-12 14:09:39 +02:00
outputs = outputs . insert ( index , p_name ) ;
_apply_port_changes ( ) ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
String VisualShaderNodeGroupBase : : get_output_port_name ( int p_id ) const {
ERR_FAIL_COND_V ( ! output_ports . has ( p_id ) , " " ) ;
return output_ports [ p_id ] . name ;
}
int VisualShaderNodeGroupBase : : get_free_input_port_id ( ) const {
return input_ports . size ( ) ;
}
int VisualShaderNodeGroupBase : : get_free_output_port_id ( ) const {
return output_ports . size ( ) ;
}
2021-04-24 22:33:50 +02:00
void VisualShaderNodeGroupBase : : set_ctrl_pressed ( Control * p_control , int p_index ) {
2019-05-12 14:09:39 +02:00
controls [ p_index ] = p_control ;
}
2021-04-24 22:33:50 +02:00
Control * VisualShaderNodeGroupBase : : is_ctrl_pressed ( int p_index ) {
2020-04-02 01:20:12 +02:00
ERR_FAIL_COND_V ( ! controls . has ( p_index ) , nullptr ) ;
2019-05-12 14:09:39 +02:00
return controls [ p_index ] ;
}
void VisualShaderNodeGroupBase : : _apply_port_changes ( ) {
Vector < String > inputs_strings = inputs . split ( " ; " , false ) ;
Vector < String > outputs_strings = outputs . split ( " ; " , false ) ;
clear_input_ports ( ) ;
clear_output_ports ( ) ;
for ( int i = 0 ; i < inputs_strings . size ( ) ; i + + ) {
Vector < String > arr = inputs_strings [ i ] . split ( " , " ) ;
2019-12-10 10:03:27 +01:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
Port port ;
port . type = ( PortType ) arr [ 1 ] . to_int ( ) ;
port . name = arr [ 2 ] ;
input_ports [ i ] = port ;
}
for ( int i = 0 ; i < outputs_strings . size ( ) ; i + + ) {
Vector < String > arr = outputs_strings [ i ] . split ( " , " ) ;
2019-12-10 10:03:27 +01:00
ERR_FAIL_COND ( arr . size ( ) ! = 3 ) ;
2019-05-12 14:09:39 +02:00
Port port ;
port . type = ( PortType ) arr [ 1 ] . to_int ( ) ;
port . name = arr [ 2 ] ;
output_ports [ i ] = port ;
}
}
2019-08-18 07:09:05 +02:00
void VisualShaderNodeGroupBase : : set_editable ( bool p_enabled ) {
editable = p_enabled ;
}
bool VisualShaderNodeGroupBase : : is_editable ( ) const {
return editable ;
}
2019-05-12 14:09:39 +02:00
void VisualShaderNodeGroupBase : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_inputs " , " inputs " ) , & VisualShaderNodeGroupBase : : set_inputs ) ;
ClassDB : : bind_method ( D_METHOD ( " get_inputs " ) , & VisualShaderNodeGroupBase : : get_inputs ) ;
ClassDB : : bind_method ( D_METHOD ( " set_outputs " , " outputs " ) , & VisualShaderNodeGroupBase : : set_outputs ) ;
ClassDB : : bind_method ( D_METHOD ( " get_outputs " ) , & VisualShaderNodeGroupBase : : get_outputs ) ;
2019-06-22 16:41:51 +02:00
ClassDB : : bind_method ( D_METHOD ( " is_valid_port_name " , " name " ) , & VisualShaderNodeGroupBase : : is_valid_port_name ) ;
2019-05-12 14:09:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_input_port " , " id " , " type " , " name " ) , & VisualShaderNodeGroupBase : : add_input_port ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_input_port " , " id " ) , & VisualShaderNodeGroupBase : : remove_input_port ) ;
ClassDB : : bind_method ( D_METHOD ( " get_input_port_count " ) , & VisualShaderNodeGroupBase : : get_input_port_count ) ;
ClassDB : : bind_method ( D_METHOD ( " has_input_port " , " id " ) , & VisualShaderNodeGroupBase : : has_input_port ) ;
ClassDB : : bind_method ( D_METHOD ( " clear_input_ports " ) , & VisualShaderNodeGroupBase : : clear_input_ports ) ;
ClassDB : : bind_method ( D_METHOD ( " add_output_port " , " id " , " type " , " name " ) , & VisualShaderNodeGroupBase : : add_output_port ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_output_port " , " id " ) , & VisualShaderNodeGroupBase : : remove_output_port ) ;
ClassDB : : bind_method ( D_METHOD ( " get_output_port_count " ) , & VisualShaderNodeGroupBase : : get_output_port_count ) ;
ClassDB : : bind_method ( D_METHOD ( " has_output_port " , " id " ) , & VisualShaderNodeGroupBase : : has_output_port ) ;
ClassDB : : bind_method ( D_METHOD ( " clear_output_ports " ) , & VisualShaderNodeGroupBase : : clear_output_ports ) ;
2019-09-24 11:44:48 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_input_port_name " , " id " , " name " ) , & VisualShaderNodeGroupBase : : set_input_port_name ) ;
ClassDB : : bind_method ( D_METHOD ( " set_input_port_type " , " id " , " type " ) , & VisualShaderNodeGroupBase : : set_input_port_type ) ;
ClassDB : : bind_method ( D_METHOD ( " set_output_port_name " , " id " , " name " ) , & VisualShaderNodeGroupBase : : set_output_port_name ) ;
ClassDB : : bind_method ( D_METHOD ( " set_output_port_type " , " id " , " type " ) , & VisualShaderNodeGroupBase : : set_output_port_type ) ;
2019-05-12 14:09:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_free_input_port_id " ) , & VisualShaderNodeGroupBase : : get_free_input_port_id ) ;
ClassDB : : bind_method ( D_METHOD ( " get_free_output_port_id " ) , & VisualShaderNodeGroupBase : : get_free_output_port_id ) ;
}
String VisualShaderNodeGroupBase : : 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 ) const {
return " " ;
}
VisualShaderNodeGroupBase : : VisualShaderNodeGroupBase ( ) {
2020-09-07 11:29:44 +02:00
simple_decl = false ;
2019-05-12 14:09:39 +02:00
}
////////////// Expression
String VisualShaderNodeExpression : : get_caption ( ) const {
return " Expression " ;
}
void VisualShaderNodeExpression : : set_expression ( const String & p_expression ) {
expression = p_expression ;
2020-09-22 21:54:30 +02:00
emit_changed ( ) ;
2019-05-12 14:09:39 +02:00
}
String VisualShaderNodeExpression : : get_expression ( ) const {
return expression ;
}
String VisualShaderNodeExpression : : 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 ) const {
String _expression = expression ;
_expression = _expression . insert ( 0 , " \n " ) ;
2021-07-19 08:06:51 +02:00
_expression = _expression . replace ( " \n " , " \n " ) ;
2019-05-12 14:09:39 +02:00
static Vector < String > pre_symbols ;
2020-12-15 13:04:21 +01:00
if ( pre_symbols . is_empty ( ) ) {
2021-07-19 08:06:51 +02:00
pre_symbols . push_back ( " " ) ;
2019-08-07 12:48:36 +02:00
pre_symbols . push_back ( " , " ) ;
2019-09-01 12:12:33 +02:00
pre_symbols . push_back ( " ; " ) ;
2019-05-12 14:09:39 +02:00
pre_symbols . push_back ( " { " ) ;
pre_symbols . push_back ( " [ " ) ;
2019-09-04 15:00:18 +02:00
pre_symbols . push_back ( " ] " ) ;
2019-05-12 14:09:39 +02:00
pre_symbols . push_back ( " ( " ) ;
pre_symbols . push_back ( " " ) ;
pre_symbols . push_back ( " - " ) ;
pre_symbols . push_back ( " * " ) ;
pre_symbols . push_back ( " / " ) ;
pre_symbols . push_back ( " + " ) ;
pre_symbols . push_back ( " = " ) ;
pre_symbols . push_back ( " & " ) ;
pre_symbols . push_back ( " | " ) ;
pre_symbols . push_back ( " ! " ) ;
}
static Vector < String > post_symbols ;
2020-12-15 13:04:21 +01:00
if ( post_symbols . is_empty ( ) ) {
2021-07-19 08:06:51 +02:00
post_symbols . push_back ( " " ) ;
2019-05-12 14:09:39 +02:00
post_symbols . push_back ( " \n " ) ;
2019-09-01 10:18:29 +02:00
post_symbols . push_back ( " , " ) ;
2019-05-21 17:37:31 +02:00
post_symbols . push_back ( " ; " ) ;
2019-05-12 14:09:39 +02:00
post_symbols . push_back ( " } " ) ;
2019-09-04 15:00:18 +02:00
post_symbols . push_back ( " [ " ) ;
2019-05-12 14:09:39 +02:00
post_symbols . push_back ( " ] " ) ;
post_symbols . push_back ( " ) " ) ;
post_symbols . push_back ( " " ) ;
post_symbols . push_back ( " . " ) ;
post_symbols . push_back ( " - " ) ;
post_symbols . push_back ( " * " ) ;
post_symbols . push_back ( " / " ) ;
post_symbols . push_back ( " + " ) ;
post_symbols . push_back ( " = " ) ;
post_symbols . push_back ( " & " ) ;
post_symbols . push_back ( " | " ) ;
post_symbols . push_back ( " ! " ) ;
}
for ( int i = 0 ; i < get_input_port_count ( ) ; i + + ) {
for ( int j = 0 ; j < pre_symbols . size ( ) ; j + + ) {
for ( int k = 0 ; k < post_symbols . size ( ) ; k + + ) {
_expression = _expression . replace ( pre_symbols [ j ] + get_input_port_name ( i ) + post_symbols [ k ] , pre_symbols [ j ] + p_input_vars [ i ] + post_symbols [ k ] ) ;
}
}
}
for ( int i = 0 ; i < get_output_port_count ( ) ; i + + ) {
for ( int j = 0 ; j < pre_symbols . size ( ) ; j + + ) {
for ( int k = 0 ; k < post_symbols . size ( ) ; k + + ) {
_expression = _expression . replace ( pre_symbols [ j ] + get_output_port_name ( i ) + post_symbols [ k ] , pre_symbols [ j ] + p_output_vars [ i ] + post_symbols [ k ] ) ;
}
}
}
String output_initializer ;
for ( int i = 0 ; i < get_output_port_count ( ) ; i + + ) {
int port_type = get_output_port_type ( i ) ;
String tk = " " ;
switch ( port_type ) {
case PORT_TYPE_SCALAR :
tk = " 0.0 " ;
break ;
2020-02-25 15:50:49 +01:00
case PORT_TYPE_SCALAR_INT :
tk = " 0 " ;
break ;
2022-02-01 09:32:01 +01:00
case PORT_TYPE_VECTOR_2D :
tk = " vec2(0.0, 0.0) " ;
break ;
2022-02-06 18:15:28 +01:00
case PORT_TYPE_VECTOR_3D :
2019-05-12 14:09:39 +02:00
tk = " vec3(0.0, 0.0, 0.0) " ;
break ;
2022-04-12 19:09:29 +02:00
case PORT_TYPE_VECTOR_4D :
tk = " vec4(0.0, 0.0, 0.0, 0.0) " ;
break ;
2019-05-12 14:09:39 +02:00
case PORT_TYPE_BOOLEAN :
tk = " false " ;
break ;
case PORT_TYPE_TRANSFORM :
tk = " mat4(1.0) " ;
break ;
default :
continue ;
}
2021-07-19 08:06:51 +02:00
output_initializer + = " " + p_output_vars [ i ] + " = " + tk + " ; \n " ;
2019-05-12 14:09:39 +02:00
}
String code ;
code + = output_initializer ;
2021-07-19 08:06:51 +02:00
code + = " { " ;
2019-05-12 14:09:39 +02:00
code + = _expression ;
2021-07-19 08:06:51 +02:00
code + = " \n } \n " ;
2019-05-12 14:09:39 +02:00
return code ;
}
void VisualShaderNodeExpression : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_expression " , " expression " ) , & VisualShaderNodeExpression : : set_expression ) ;
ClassDB : : bind_method ( D_METHOD ( " get_expression " ) , & VisualShaderNodeExpression : : get_expression ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " expression " ) , " set_expression " , " get_expression " ) ;
}
VisualShaderNodeExpression : : VisualShaderNodeExpression ( ) {
2019-08-18 07:09:05 +02:00
set_editable ( true ) ;
}
////////////// Global Expression
String VisualShaderNodeGlobalExpression : : get_caption ( ) const {
return " GlobalExpression " ;
}
String VisualShaderNodeGlobalExpression : : generate_global ( Shader : : Mode p_mode , VisualShader : : Type p_type , int p_id ) const {
return expression ;
}
VisualShaderNodeGlobalExpression : : VisualShaderNodeGlobalExpression ( ) {
set_editable ( false ) ;
2019-05-12 14:09:39 +02:00
}
2022-01-09 15:02:13 +01:00
////////////// Varying
List < VisualShaderNodeVarying : : Varying > varyings ;
void VisualShaderNodeVarying : : add_varying ( const String & p_name , VisualShader : : VaryingMode p_mode , VisualShader : : VaryingType p_type ) { // static
varyings . push_back ( { p_name , p_mode , p_type } ) ;
}
void VisualShaderNodeVarying : : clear_varyings ( ) { // static
varyings . clear ( ) ;
}
bool VisualShaderNodeVarying : : has_varying ( const String & p_name ) { // static
for ( const VisualShaderNodeVarying : : Varying & E : varyings ) {
if ( E . name = = p_name ) {
return true ;
}
}
return false ;
}
int VisualShaderNodeVarying : : get_varyings_count ( ) const {
return varyings . size ( ) ;
}
String VisualShaderNodeVarying : : get_varying_name_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < varyings . size ( ) ) {
return varyings [ p_idx ] . name ;
}
return " " ;
}
VisualShader : : VaryingType VisualShaderNodeVarying : : get_varying_type_by_name ( const String & p_name ) const {
for ( int i = 0 ; i < varyings . size ( ) ; i + + ) {
if ( varyings [ i ] . name = = p_name ) {
return varyings [ i ] . type ;
}
}
return VisualShader : : VARYING_TYPE_FLOAT ;
}
VisualShader : : VaryingType VisualShaderNodeVarying : : get_varying_type_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < varyings . size ( ) ) {
return varyings [ p_idx ] . type ;
}
return VisualShader : : VARYING_TYPE_FLOAT ;
}
VisualShader : : VaryingMode VisualShaderNodeVarying : : get_varying_mode_by_name ( const String & p_name ) const {
for ( int i = 0 ; i < varyings . size ( ) ; i + + ) {
if ( varyings [ i ] . name = = p_name ) {
return varyings [ i ] . mode ;
}
}
return VisualShader : : VARYING_MODE_VERTEX_TO_FRAG_LIGHT ;
}
VisualShader : : VaryingMode VisualShaderNodeVarying : : get_varying_mode_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < varyings . size ( ) ) {
return varyings [ p_idx ] . mode ;
}
return VisualShader : : VARYING_MODE_VERTEX_TO_FRAG_LIGHT ;
}
VisualShaderNodeVarying : : PortType VisualShaderNodeVarying : : get_port_type_by_index ( int p_idx ) const {
if ( p_idx > = 0 & & p_idx < varyings . size ( ) ) {
return get_port_type ( varyings [ p_idx ] . type , 0 ) ;
}
return PORT_TYPE_SCALAR ;
}
//////////////
void VisualShaderNodeVarying : : _bind_methods ( ) {
ClassDB : : bind_method ( D_METHOD ( " set_varying_name " , " name " ) , & VisualShaderNodeVarying : : set_varying_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_varying_name " ) , & VisualShaderNodeVarying : : get_varying_name ) ;
ClassDB : : bind_method ( D_METHOD ( " set_varying_type " , " type " ) , & VisualShaderNodeVarying : : set_varying_type ) ;
ClassDB : : bind_method ( D_METHOD ( " get_varying_type " ) , & VisualShaderNodeVarying : : get_varying_type ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING_NAME , " varying_name " ) , " set_varying_name " , " get_varying_name " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " varying_type " , PROPERTY_HINT_ENUM , " Float,Vector,Transform " ) , " set_varying_type " , " get_varying_type " ) ;
}
String VisualShaderNodeVarying : : get_type_str ( ) const {
switch ( varying_type ) {
case VisualShader : : VARYING_TYPE_FLOAT :
return " float " ;
case VisualShader : : VARYING_TYPE_VECTOR_2D :
return " vec2 " ;
case VisualShader : : VARYING_TYPE_VECTOR_3D :
return " vec3 " ;
2022-04-12 19:09:29 +02:00
case VisualShader : : VARYING_TYPE_VECTOR_4D :
return " vec4 " ;
2022-01-09 15:02:13 +01:00
case VisualShader : : VARYING_TYPE_COLOR :
return " vec4 " ;
case VisualShader : : VARYING_TYPE_TRANSFORM :
return " mat4 " ;
default :
break ;
}
return " " ;
}
VisualShaderNodeVarying : : PortType VisualShaderNodeVarying : : get_port_type ( VisualShader : : VaryingType p_type , int p_port ) const {
switch ( p_type ) {
case VisualShader : : VARYING_TYPE_VECTOR_2D :
return PORT_TYPE_VECTOR_2D ;
case VisualShader : : VARYING_TYPE_VECTOR_3D :
return PORT_TYPE_VECTOR_3D ;
2022-04-12 19:09:29 +02:00
case VisualShader : : VARYING_TYPE_VECTOR_4D :
return PORT_TYPE_VECTOR_4D ;
2022-01-09 15:02:13 +01:00
case VisualShader : : VARYING_TYPE_COLOR :
if ( p_port = = 1 ) {
break ; // scalar
}
return PORT_TYPE_VECTOR_3D ;
case VisualShader : : VARYING_TYPE_TRANSFORM :
return PORT_TYPE_TRANSFORM ;
default :
break ;
}
return PORT_TYPE_SCALAR ;
}
void VisualShaderNodeVarying : : set_varying_name ( String p_varying_name ) {
if ( varying_name = = p_varying_name ) {
return ;
}
varying_name = p_varying_name ;
emit_changed ( ) ;
}
String VisualShaderNodeVarying : : get_varying_name ( ) const {
return varying_name ;
}
void VisualShaderNodeVarying : : set_varying_type ( VisualShader : : VaryingType p_varying_type ) {
ERR_FAIL_INDEX ( p_varying_type , VisualShader : : VARYING_TYPE_MAX ) ;
if ( varying_type = = p_varying_type ) {
return ;
}
varying_type = p_varying_type ;
emit_changed ( ) ;
}
VisualShader : : VaryingType VisualShaderNodeVarying : : get_varying_type ( ) const {
return varying_type ;
}
VisualShaderNodeVarying : : VisualShaderNodeVarying ( ) {
}
////////////// Varying Setter
String VisualShaderNodeVaryingSetter : : get_caption ( ) const {
return vformat ( " VaryingSetter " ) ;
}
int VisualShaderNodeVaryingSetter : : get_input_port_count ( ) const {
if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
return 2 ;
}
return 1 ;
}
VisualShaderNodeVaryingSetter : : PortType VisualShaderNodeVaryingSetter : : get_input_port_type ( int p_port ) const {
return get_port_type ( varying_type , p_port ) ;
}
String VisualShaderNodeVaryingSetter : : get_input_port_name ( int p_port ) const {
if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
if ( p_port = = 0 ) {
return " color " ;
} else {
return " alpha " ;
}
}
return " " ;
}
int VisualShaderNodeVaryingSetter : : get_output_port_count ( ) const {
return 0 ;
}
VisualShaderNodeVaryingSetter : : PortType VisualShaderNodeVaryingSetter : : get_output_port_type ( int p_port ) const {
return PORT_TYPE_SCALAR ;
}
String VisualShaderNodeVaryingSetter : : get_output_port_name ( int p_port ) const {
return " " ;
}
String VisualShaderNodeVaryingSetter : : generate_global ( Shader : : Mode p_mode , VisualShader : : Type p_type , int p_id ) const {
return vformat ( " varying %s %s; \n " , get_type_str ( ) , varying_name ) ;
}
String VisualShaderNodeVaryingSetter : : 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 ) const {
String code ;
if ( varying_name = = " [None] " ) {
return code ;
}
if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
code + = vformat ( " %s = vec4(%s, %s); \n " , varying_name , p_input_vars [ 0 ] , p_input_vars [ 1 ] ) ;
} else {
code + = vformat ( " %s = %s; \n " , varying_name , p_input_vars [ 0 ] ) ;
}
return code ;
}
VisualShaderNodeVaryingSetter : : VisualShaderNodeVaryingSetter ( ) {
}
////////////// Varying Getter
String VisualShaderNodeVaryingGetter : : get_caption ( ) const {
return vformat ( " VaryingGetter " ) ;
}
int VisualShaderNodeVaryingGetter : : get_input_port_count ( ) const {
return 0 ;
}
VisualShaderNodeVaryingGetter : : PortType VisualShaderNodeVaryingGetter : : get_input_port_type ( int p_port ) const {
return PORT_TYPE_SCALAR ;
}
String VisualShaderNodeVaryingGetter : : get_input_port_name ( int p_port ) const {
return " " ;
}
int VisualShaderNodeVaryingGetter : : get_output_port_count ( ) const {
if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
return 2 ;
}
return 1 ;
}
VisualShaderNodeVaryingGetter : : PortType VisualShaderNodeVaryingGetter : : get_output_port_type ( int p_port ) const {
return get_port_type ( varying_type , p_port ) ;
}
String VisualShaderNodeVaryingGetter : : get_output_port_name ( int p_port ) const {
if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
if ( p_port = = 0 ) {
return " color " ;
} else {
return " alpha " ;
}
}
return " " ;
}
bool VisualShaderNodeVaryingGetter : : has_output_port_preview ( int p_port ) const {
return false ;
}
String VisualShaderNodeVaryingGetter : : 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 ) const {
String from = varying_name ;
String from2 ;
if ( varying_name = = " [None] " ) {
switch ( varying_type ) {
case VisualShader : : VARYING_TYPE_FLOAT :
from = " 0.0 " ;
break ;
case VisualShader : : VARYING_TYPE_VECTOR_2D :
from = " vec2(0.0) " ;
break ;
case VisualShader : : VARYING_TYPE_VECTOR_3D :
from = " vec3(0.0) " ;
break ;
2022-04-12 19:09:29 +02:00
case VisualShader : : VARYING_TYPE_VECTOR_4D :
from = " vec4(0.0) " ;
break ;
2022-01-09 15:02:13 +01:00
case VisualShader : : VARYING_TYPE_COLOR :
from = " vec3(0.0) " ;
from2 = " 0.0 " ;
break ;
case VisualShader : : VARYING_TYPE_TRANSFORM :
from = " mat4(1.0) " ;
break ;
default :
break ;
}
} else if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
from = varying_name + " .rgb " ;
from2 = varying_name + " .a " ;
}
if ( varying_type = = VisualShader : : VARYING_TYPE_COLOR ) {
String code ;
code + = vformat ( " %s = %s; \n " , p_output_vars [ 0 ] , from ) ;
code + = vformat ( " %s = %s; \n " , p_output_vars [ 1 ] , from2 ) ;
return code ;
}
return vformat ( " %s = %s; \n " , p_output_vars [ 0 ] , from ) ;
}
VisualShaderNodeVaryingGetter : : VisualShaderNodeVaryingGetter ( ) {
varying_name = " [None] " ;
}