1/**************************************************************************/
2/* visual_shader_nodes.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "visual_shader_nodes.h"
32
33#include "scene/resources/image_texture.h"
34
35////////////// Vector Base
36
37VisualShaderNodeVectorBase::PortType VisualShaderNodeVectorBase::get_input_port_type(int p_port) const {
38 switch (op_type) {
39 case OP_TYPE_VECTOR_2D:
40 return PORT_TYPE_VECTOR_2D;
41 case OP_TYPE_VECTOR_3D:
42 return PORT_TYPE_VECTOR_3D;
43 case OP_TYPE_VECTOR_4D:
44 return PORT_TYPE_VECTOR_4D;
45 default:
46 break;
47 }
48 return PORT_TYPE_SCALAR;
49}
50
51VisualShaderNodeVectorBase::PortType VisualShaderNodeVectorBase::get_output_port_type(int p_port) const {
52 switch (op_type) {
53 case OP_TYPE_VECTOR_2D:
54 return PORT_TYPE_VECTOR_2D;
55 case OP_TYPE_VECTOR_3D:
56 return PORT_TYPE_VECTOR_3D;
57 case OP_TYPE_VECTOR_4D:
58 return PORT_TYPE_VECTOR_4D;
59 default:
60 break;
61 }
62 return PORT_TYPE_SCALAR;
63}
64
65void VisualShaderNodeVectorBase::set_op_type(OpType p_op_type) {
66 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
67 if (op_type == p_op_type) {
68 return;
69 }
70 op_type = p_op_type;
71 emit_changed();
72}
73
74VisualShaderNodeVectorBase::OpType VisualShaderNodeVectorBase::get_op_type() const {
75 return op_type;
76}
77
78void VisualShaderNodeVectorBase::_bind_methods() {
79 ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeVectorBase::set_op_type);
80 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeVectorBase::get_op_type);
81
82 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
83
84 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
85 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
86 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
87 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
88}
89
90Vector<StringName> VisualShaderNodeVectorBase::get_editable_properties() const {
91 Vector<StringName> props;
92 props.push_back("op_type");
93 return props;
94}
95
96VisualShaderNodeVectorBase::VisualShaderNodeVectorBase() {
97}
98
99////////////// Constants Base
100
101VisualShaderNodeConstant::VisualShaderNodeConstant() {
102}
103
104////////////// Scalar(Float)
105
106String VisualShaderNodeFloatConstant::get_caption() const {
107 return "FloatConstant";
108}
109
110int VisualShaderNodeFloatConstant::get_input_port_count() const {
111 return 0;
112}
113
114VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_input_port_type(int p_port) const {
115 return PORT_TYPE_SCALAR;
116}
117
118String VisualShaderNodeFloatConstant::get_input_port_name(int p_port) const {
119 return String();
120}
121
122int VisualShaderNodeFloatConstant::get_output_port_count() const {
123 return 1;
124}
125
126VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_output_port_type(int p_port) const {
127 return PORT_TYPE_SCALAR;
128}
129
130String VisualShaderNodeFloatConstant::get_output_port_name(int p_port) const {
131 return ""; //no output port means the editor will be used as port
132}
133
134String VisualShaderNodeFloatConstant::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 {
135 return " " + p_output_vars[0] + " = " + vformat("%.6f", constant) + ";\n";
136}
137
138void VisualShaderNodeFloatConstant::set_constant(float p_constant) {
139 if (Math::is_equal_approx(constant, p_constant)) {
140 return;
141 }
142 constant = p_constant;
143 emit_changed();
144}
145
146float VisualShaderNodeFloatConstant::get_constant() const {
147 return constant;
148}
149
150Vector<StringName> VisualShaderNodeFloatConstant::get_editable_properties() const {
151 Vector<StringName> props;
152 props.push_back("constant");
153 return props;
154}
155
156void VisualShaderNodeFloatConstant::_bind_methods() {
157 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeFloatConstant::set_constant);
158 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeFloatConstant::get_constant);
159
160 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant"), "set_constant", "get_constant");
161}
162
163VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() {
164}
165
166////////////// Scalar(Int)
167
168String VisualShaderNodeIntConstant::get_caption() const {
169 return "IntConstant";
170}
171
172int VisualShaderNodeIntConstant::get_input_port_count() const {
173 return 0;
174}
175
176VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_input_port_type(int p_port) const {
177 return PORT_TYPE_SCALAR_INT;
178}
179
180String VisualShaderNodeIntConstant::get_input_port_name(int p_port) const {
181 return String();
182}
183
184int VisualShaderNodeIntConstant::get_output_port_count() const {
185 return 1;
186}
187
188VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_output_port_type(int p_port) const {
189 return PORT_TYPE_SCALAR_INT;
190}
191
192String VisualShaderNodeIntConstant::get_output_port_name(int p_port) const {
193 return ""; //no output port means the editor will be used as port
194}
195
196String VisualShaderNodeIntConstant::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 {
197 return " " + p_output_vars[0] + " = " + itos(constant) + ";\n";
198}
199
200void VisualShaderNodeIntConstant::set_constant(int p_constant) {
201 if (constant == p_constant) {
202 return;
203 }
204 constant = p_constant;
205 emit_changed();
206}
207
208int VisualShaderNodeIntConstant::get_constant() const {
209 return constant;
210}
211
212Vector<StringName> VisualShaderNodeIntConstant::get_editable_properties() const {
213 Vector<StringName> props;
214 props.push_back("constant");
215 return props;
216}
217
218void VisualShaderNodeIntConstant::_bind_methods() {
219 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeIntConstant::set_constant);
220 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeIntConstant::get_constant);
221
222 ADD_PROPERTY(PropertyInfo(Variant::INT, "constant"), "set_constant", "get_constant");
223}
224
225VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() {
226}
227
228////////////// Scalar(UInt)
229
230String VisualShaderNodeUIntConstant::get_caption() const {
231 return "UIntConstant";
232}
233
234int VisualShaderNodeUIntConstant::get_input_port_count() const {
235 return 0;
236}
237
238VisualShaderNodeUIntConstant::PortType VisualShaderNodeUIntConstant::get_input_port_type(int p_port) const {
239 return PORT_TYPE_SCALAR_UINT;
240}
241
242String VisualShaderNodeUIntConstant::get_input_port_name(int p_port) const {
243 return String();
244}
245
246int VisualShaderNodeUIntConstant::get_output_port_count() const {
247 return 1;
248}
249
250VisualShaderNodeUIntConstant::PortType VisualShaderNodeUIntConstant::get_output_port_type(int p_port) const {
251 return PORT_TYPE_SCALAR_UINT;
252}
253
254String VisualShaderNodeUIntConstant::get_output_port_name(int p_port) const {
255 return ""; // No output port means the editor will be used as port.
256}
257
258String VisualShaderNodeUIntConstant::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 {
259 return " " + p_output_vars[0] + " = " + itos(constant) + "u;\n";
260}
261
262void VisualShaderNodeUIntConstant::set_constant(int p_constant) {
263 if (constant == p_constant) {
264 return;
265 }
266 constant = p_constant;
267 emit_changed();
268}
269
270int VisualShaderNodeUIntConstant::get_constant() const {
271 return constant;
272}
273
274Vector<StringName> VisualShaderNodeUIntConstant::get_editable_properties() const {
275 Vector<StringName> props;
276 props.push_back("constant");
277 return props;
278}
279
280void VisualShaderNodeUIntConstant::_bind_methods() {
281 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeUIntConstant::set_constant);
282 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeUIntConstant::get_constant);
283
284 ADD_PROPERTY(PropertyInfo(Variant::INT, "constant"), "set_constant", "get_constant");
285}
286
287VisualShaderNodeUIntConstant::VisualShaderNodeUIntConstant() {
288}
289
290////////////// Boolean
291
292String VisualShaderNodeBooleanConstant::get_caption() const {
293 return "BooleanConstant";
294}
295
296int VisualShaderNodeBooleanConstant::get_input_port_count() const {
297 return 0;
298}
299
300VisualShaderNodeBooleanConstant::PortType VisualShaderNodeBooleanConstant::get_input_port_type(int p_port) const {
301 return PORT_TYPE_BOOLEAN;
302}
303
304String VisualShaderNodeBooleanConstant::get_input_port_name(int p_port) const {
305 return String();
306}
307
308int VisualShaderNodeBooleanConstant::get_output_port_count() const {
309 return 1;
310}
311
312VisualShaderNodeBooleanConstant::PortType VisualShaderNodeBooleanConstant::get_output_port_type(int p_port) const {
313 return PORT_TYPE_BOOLEAN;
314}
315
316String VisualShaderNodeBooleanConstant::get_output_port_name(int p_port) const {
317 return ""; //no output port means the editor will be used as port
318}
319
320String VisualShaderNodeBooleanConstant::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 {
321 return " " + p_output_vars[0] + " = " + (constant ? "true" : "false") + ";\n";
322}
323
324void VisualShaderNodeBooleanConstant::set_constant(bool p_constant) {
325 if (constant == p_constant) {
326 return;
327 }
328 constant = p_constant;
329 emit_changed();
330}
331
332bool VisualShaderNodeBooleanConstant::get_constant() const {
333 return constant;
334}
335
336Vector<StringName> VisualShaderNodeBooleanConstant::get_editable_properties() const {
337 Vector<StringName> props;
338 props.push_back("constant");
339 return props;
340}
341
342void VisualShaderNodeBooleanConstant::_bind_methods() {
343 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeBooleanConstant::set_constant);
344 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeBooleanConstant::get_constant);
345
346 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "constant"), "set_constant", "get_constant");
347}
348
349VisualShaderNodeBooleanConstant::VisualShaderNodeBooleanConstant() {
350}
351
352////////////// Color
353
354String VisualShaderNodeColorConstant::get_caption() const {
355 return "ColorConstant";
356}
357
358int VisualShaderNodeColorConstant::get_input_port_count() const {
359 return 0;
360}
361
362VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_input_port_type(int p_port) const {
363 return PORT_TYPE_VECTOR_4D;
364}
365
366String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const {
367 return String();
368}
369
370int VisualShaderNodeColorConstant::get_output_port_count() const {
371 return 1;
372}
373
374VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_output_port_type(int p_port) const {
375 return p_port == 0 ? PORT_TYPE_VECTOR_4D : PORT_TYPE_SCALAR;
376}
377
378String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const {
379 return "";
380}
381
382bool VisualShaderNodeColorConstant::is_output_port_expandable(int p_port) const {
383 if (p_port == 0) {
384 return true;
385 }
386 return false;
387}
388
389String VisualShaderNodeColorConstant::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 {
390 return " " + p_output_vars[0] + " = " + vformat("vec4(%.6f, %.6f, %.6f, %.6f)", constant.r, constant.g, constant.b, constant.a) + ";\n";
391}
392
393void VisualShaderNodeColorConstant::set_constant(const Color &p_constant) {
394 if (constant.is_equal_approx(p_constant)) {
395 return;
396 }
397 constant = p_constant;
398 emit_changed();
399}
400
401Color VisualShaderNodeColorConstant::get_constant() const {
402 return constant;
403}
404
405Vector<StringName> VisualShaderNodeColorConstant::get_editable_properties() const {
406 Vector<StringName> props;
407 props.push_back("constant");
408 return props;
409}
410
411void VisualShaderNodeColorConstant::_bind_methods() {
412 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeColorConstant::set_constant);
413 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeColorConstant::get_constant);
414
415 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "constant"), "set_constant", "get_constant");
416}
417
418VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() {
419}
420
421////////////// Vector2
422
423String VisualShaderNodeVec2Constant::get_caption() const {
424 return "Vector2Constant";
425}
426
427int VisualShaderNodeVec2Constant::get_input_port_count() const {
428 return 0;
429}
430
431VisualShaderNodeVec2Constant::PortType VisualShaderNodeVec2Constant::get_input_port_type(int p_port) const {
432 return PORT_TYPE_VECTOR_2D;
433}
434
435String VisualShaderNodeVec2Constant::get_input_port_name(int p_port) const {
436 return String();
437}
438
439int VisualShaderNodeVec2Constant::get_output_port_count() const {
440 return 1;
441}
442
443VisualShaderNodeVec2Constant::PortType VisualShaderNodeVec2Constant::get_output_port_type(int p_port) const {
444 return PORT_TYPE_VECTOR_2D;
445}
446
447String VisualShaderNodeVec2Constant::get_output_port_name(int p_port) const {
448 return ""; //no output port means the editor will be used as port
449}
450
451String VisualShaderNodeVec2Constant::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 {
452 return " " + p_output_vars[0] + " = " + vformat("vec2(%.6f, %.6f)", constant.x, constant.y) + ";\n";
453}
454
455void VisualShaderNodeVec2Constant::set_constant(const Vector2 &p_constant) {
456 if (constant.is_equal_approx(p_constant)) {
457 return;
458 }
459 constant = p_constant;
460 emit_changed();
461}
462
463Vector2 VisualShaderNodeVec2Constant::get_constant() const {
464 return constant;
465}
466
467Vector<StringName> VisualShaderNodeVec2Constant::get_editable_properties() const {
468 Vector<StringName> props;
469 props.push_back("constant");
470 return props;
471}
472
473void VisualShaderNodeVec2Constant::_bind_methods() {
474 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeVec2Constant::set_constant);
475 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec2Constant::get_constant);
476
477 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant"), "set_constant", "get_constant");
478}
479
480VisualShaderNodeVec2Constant::VisualShaderNodeVec2Constant() {
481}
482
483////////////// Vector3
484
485String VisualShaderNodeVec3Constant::get_caption() const {
486 return "Vector3Constant";
487}
488
489int VisualShaderNodeVec3Constant::get_input_port_count() const {
490 return 0;
491}
492
493VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_input_port_type(int p_port) const {
494 return PORT_TYPE_VECTOR_3D;
495}
496
497String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const {
498 return String();
499}
500
501int VisualShaderNodeVec3Constant::get_output_port_count() const {
502 return 1;
503}
504
505VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_output_port_type(int p_port) const {
506 return PORT_TYPE_VECTOR_3D;
507}
508
509String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const {
510 return ""; //no output port means the editor will be used as port
511}
512
513String VisualShaderNodeVec3Constant::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 {
514 return " " + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.x, constant.y, constant.z) + ";\n";
515}
516
517void VisualShaderNodeVec3Constant::set_constant(const Vector3 &p_constant) {
518 if (constant.is_equal_approx(p_constant)) {
519 return;
520 }
521 constant = p_constant;
522 emit_changed();
523}
524
525Vector3 VisualShaderNodeVec3Constant::get_constant() const {
526 return constant;
527}
528
529Vector<StringName> VisualShaderNodeVec3Constant::get_editable_properties() const {
530 Vector<StringName> props;
531 props.push_back("constant");
532 return props;
533}
534
535void VisualShaderNodeVec3Constant::_bind_methods() {
536 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeVec3Constant::set_constant);
537 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec3Constant::get_constant);
538
539 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant"), "set_constant", "get_constant");
540}
541
542VisualShaderNodeVec3Constant::VisualShaderNodeVec3Constant() {
543}
544
545////////////// Vector4
546
547String VisualShaderNodeVec4Constant::get_caption() const {
548 return "Vector4Constant";
549}
550
551int VisualShaderNodeVec4Constant::get_input_port_count() const {
552 return 0;
553}
554
555VisualShaderNodeVec4Constant::PortType VisualShaderNodeVec4Constant::get_input_port_type(int p_port) const {
556 return PORT_TYPE_VECTOR_4D;
557}
558
559String VisualShaderNodeVec4Constant::get_input_port_name(int p_port) const {
560 return String();
561}
562
563int VisualShaderNodeVec4Constant::get_output_port_count() const {
564 return 1;
565}
566
567VisualShaderNodeVec4Constant::PortType VisualShaderNodeVec4Constant::get_output_port_type(int p_port) const {
568 return PORT_TYPE_VECTOR_4D;
569}
570
571String VisualShaderNodeVec4Constant::get_output_port_name(int p_port) const {
572 return ""; // No output port means the editor will be used as port.
573}
574
575String VisualShaderNodeVec4Constant::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 {
576 return " " + p_output_vars[0] + " = " + vformat("vec4(%.6f, %.6f, %.6f, %.6f)", constant.x, constant.y, constant.z, constant.w) + ";\n";
577}
578
579void VisualShaderNodeVec4Constant::set_constant(const Quaternion &p_constant) {
580 if (constant.is_equal_approx(p_constant)) {
581 return;
582 }
583 constant = p_constant;
584 emit_changed();
585}
586
587Quaternion VisualShaderNodeVec4Constant::get_constant() const {
588 return constant;
589}
590
591Vector<StringName> VisualShaderNodeVec4Constant::get_editable_properties() const {
592 Vector<StringName> props;
593 props.push_back("constant");
594 return props;
595}
596
597void VisualShaderNodeVec4Constant::_bind_methods() {
598 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeVec4Constant::set_constant);
599 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec4Constant::get_constant);
600
601 ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "constant"), "set_constant", "get_constant");
602}
603
604VisualShaderNodeVec4Constant::VisualShaderNodeVec4Constant() {
605}
606
607////////////// Transform3D
608
609String VisualShaderNodeTransformConstant::get_caption() const {
610 return "TransformConstant";
611}
612
613int VisualShaderNodeTransformConstant::get_input_port_count() const {
614 return 0;
615}
616
617VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_input_port_type(int p_port) const {
618 return PORT_TYPE_VECTOR_3D;
619}
620
621String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const {
622 return String();
623}
624
625int VisualShaderNodeTransformConstant::get_output_port_count() const {
626 return 1;
627}
628
629VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_output_port_type(int p_port) const {
630 return PORT_TYPE_TRANSFORM;
631}
632
633String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const {
634 return ""; //no output port means the editor will be used as port
635}
636
637String VisualShaderNodeTransformConstant::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 {
638 Transform3D t = constant;
639 t.basis.transpose();
640
641 String code = " " + p_output_vars[0] + " = mat4(";
642 code += vformat("vec4(%.6f, %.6f, %.6f, 0.0), ", t.basis[0].x, t.basis[0].y, t.basis[0].z);
643 code += vformat("vec4(%.6f, %.6f, %.6f, 0.0), ", t.basis[1].x, t.basis[1].y, t.basis[1].z);
644 code += vformat("vec4(%.6f, %.6f, %.6f, 0.0), ", t.basis[2].x, t.basis[2].y, t.basis[2].z);
645 code += vformat("vec4(%.6f, %.6f, %.6f, 1.0));\n", t.origin.x, t.origin.y, t.origin.z);
646 return code;
647}
648
649void VisualShaderNodeTransformConstant::set_constant(const Transform3D &p_constant) {
650 if (constant.is_equal_approx(p_constant)) {
651 return;
652 }
653 constant = p_constant;
654 emit_changed();
655}
656
657Transform3D VisualShaderNodeTransformConstant::get_constant() const {
658 return constant;
659}
660
661Vector<StringName> VisualShaderNodeTransformConstant::get_editable_properties() const {
662 Vector<StringName> props;
663 props.push_back("constant");
664 return props;
665}
666
667void VisualShaderNodeTransformConstant::_bind_methods() {
668 ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeTransformConstant::set_constant);
669 ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeTransformConstant::get_constant);
670
671 ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "constant"), "set_constant", "get_constant");
672}
673
674VisualShaderNodeTransformConstant::VisualShaderNodeTransformConstant() {
675}
676
677////////////// Texture
678
679String VisualShaderNodeTexture::get_caption() const {
680 return "Texture2D";
681}
682
683int VisualShaderNodeTexture::get_input_port_count() const {
684 return 3;
685}
686
687VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
688 switch (p_port) {
689 case 0:
690 return PORT_TYPE_VECTOR_2D;
691 case 1:
692 return PORT_TYPE_SCALAR;
693 case 2:
694 return PORT_TYPE_SAMPLER;
695 default:
696 return PORT_TYPE_SCALAR;
697 }
698}
699
700String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
701 switch (p_port) {
702 case 0:
703 return "uv";
704 case 1:
705 return "lod";
706 case 2:
707 return "sampler2D";
708 default:
709 return "";
710 }
711}
712
713int VisualShaderNodeTexture::get_output_port_count() const {
714 return 1;
715}
716
717VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const {
718 switch (p_port) {
719 case 0:
720 return PORT_TYPE_VECTOR_4D;
721 default:
722 return PORT_TYPE_SCALAR;
723 }
724}
725
726String VisualShaderNodeTexture::get_output_port_name(int p_port) const {
727 switch (p_port) {
728 case 0:
729 return "color";
730 default:
731 return "";
732 }
733}
734
735bool VisualShaderNodeTexture::is_output_port_expandable(int p_port) const {
736 if (p_port == 0) {
737 return true;
738 }
739 return false;
740}
741
742bool VisualShaderNodeTexture::is_input_port_default(int p_port, Shader::Mode p_mode) const {
743 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
744 if (p_port == 0) {
745 return true;
746 }
747 }
748 return false;
749}
750
751Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
752 VisualShader::DefaultTextureParam dtp;
753 dtp.name = make_unique_id(p_type, p_id, "tex");
754 dtp.params.push_back(texture);
755 Vector<VisualShader::DefaultTextureParam> ret;
756 ret.push_back(dtp);
757 return ret;
758}
759
760String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
761 String code;
762
763 switch (source) {
764 case SOURCE_TEXTURE: {
765 code += "uniform sampler2D " + make_unique_id(p_type, p_id, "tex");
766 switch (texture_type) {
767 case TYPE_DATA: {
768 } break;
769 case TYPE_COLOR: {
770 code += " : source_color";
771 } break;
772 case TYPE_NORMAL_MAP: {
773 code += " : hint_normal";
774 } break;
775 default: {
776 } break;
777 }
778 code += ";\n";
779 } break;
780 case SOURCE_SCREEN: {
781 if ((p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
782 code += "uniform sampler2D " + make_unique_id(p_type, p_id, "screen_tex") + " : hint_screen_texture;\n";
783 }
784 } break;
785 case SOURCE_DEPTH:
786 case SOURCE_3D_NORMAL:
787 case SOURCE_ROUGHNESS: {
788 if (p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
789 String sampler_name = "";
790 String hint = " : ";
791 if (source == SOURCE_DEPTH) {
792 sampler_name = "depth_tex";
793 hint += "hint_depth_texture;\n";
794 } else {
795 sampler_name = source == SOURCE_ROUGHNESS ? "roughness_tex" : "normal_roughness_tex";
796 hint += "hint_normal_roughness_texture;\n";
797 }
798 code += "uniform sampler2D " + make_unique_id(p_type, p_id, sampler_name) + hint;
799 }
800 } break;
801 default: {
802 } break;
803 }
804
805 return code;
806}
807
808String VisualShaderNodeTexture::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 {
809 String default_uv;
810 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
811 if (source == SOURCE_SCREEN) {
812 default_uv = "SCREEN_UV";
813 } else {
814 default_uv = "UV";
815 }
816 } else {
817 default_uv = "vec2(0.0)";
818 }
819
820 String code;
821 String uv = p_input_vars[0].is_empty() ? default_uv : p_input_vars[0];
822
823 switch (source) {
824 case SOURCE_PORT:
825 case SOURCE_TEXTURE: {
826 String id;
827 if (source == SOURCE_PORT) {
828 id = p_input_vars[2];
829 if (id.is_empty()) {
830 break;
831 }
832 } else { // SOURCE_TEXTURE
833 id = make_unique_id(p_type, p_id, "tex");
834 }
835 if (p_input_vars[1].is_empty()) {
836 code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
837 } else {
838 code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
839 }
840 return code;
841 } break;
842 case SOURCE_SCREEN: {
843 if ((p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
844 String id = make_unique_id(p_type, p_id, "screen_tex");
845 if (p_input_vars[1].is_empty()) {
846 code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
847 } else {
848 code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
849 }
850 return code;
851 }
852 } break;
853 case SOURCE_2D_NORMAL:
854 case SOURCE_2D_TEXTURE: {
855 if (p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
856 String id = source == SOURCE_2D_TEXTURE ? "TEXTURE" : "NORMAL_TEXTURE";
857
858 if (p_input_vars[1].is_empty()) {
859 code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
860 } else {
861 code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
862 }
863 return code;
864 }
865 } break;
866 case SOURCE_3D_NORMAL:
867 case SOURCE_ROUGHNESS:
868 case SOURCE_DEPTH: {
869 if (!p_for_preview && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
870 String var_name = "";
871 String sampler_name = "";
872
873 switch (source) {
874 case SOURCE_DEPTH: {
875 var_name = "_depth";
876 sampler_name = "depth_tex";
877 } break;
878 case SOURCE_ROUGHNESS: {
879 var_name = "_roughness";
880 sampler_name = "roughness_tex";
881 } break;
882 case SOURCE_3D_NORMAL: {
883 var_name = "_normal";
884 sampler_name = "normal_roughness_tex";
885 } break;
886 default: {
887 } break;
888 }
889
890 String id = make_unique_id(p_type, p_id, sampler_name);
891 String type = source == SOURCE_3D_NORMAL ? "vec3" : "float";
892 String components = source == SOURCE_3D_NORMAL ? "rgb" : "r";
893
894 code += " {\n";
895 if (p_input_vars[1].is_empty()) {
896 code += " " + type + " " + var_name + " = texture(" + id + ", " + uv + ")." + components + ";\n";
897 } else {
898 code += " " + type + " " + var_name + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ")." + components + ";\n";
899 }
900 if (source == SOURCE_3D_NORMAL) {
901 code += " " + p_output_vars[0] + " = vec4(" + var_name + ", 1.0);\n";
902 } else {
903 code += " " + p_output_vars[0] + " = vec4(" + var_name + ", " + var_name + ", " + var_name + ", 1.0);\n";
904 }
905 code += " }\n";
906
907 return code;
908 }
909 } break;
910 default: {
911 } break;
912 }
913
914 code += " " + p_output_vars[0] + " = vec4(0.0);\n";
915 return code;
916}
917
918void VisualShaderNodeTexture::set_source(Source p_source) {
919 ERR_FAIL_INDEX(int(p_source), int(SOURCE_MAX));
920 if (source == p_source) {
921 return;
922 }
923 switch (p_source) {
924 case SOURCE_TEXTURE:
925 simple_decl = true;
926 break;
927 case SOURCE_SCREEN:
928 simple_decl = false;
929 break;
930 case SOURCE_2D_TEXTURE:
931 simple_decl = false;
932 break;
933 case SOURCE_2D_NORMAL:
934 simple_decl = false;
935 break;
936 case SOURCE_DEPTH:
937 simple_decl = false;
938 break;
939 case SOURCE_PORT:
940 simple_decl = false;
941 break;
942 case SOURCE_3D_NORMAL:
943 simple_decl = false;
944 break;
945 case SOURCE_ROUGHNESS:
946 simple_decl = false;
947 break;
948 default:
949 break;
950 }
951 source = p_source;
952 emit_changed();
953}
954
955VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
956 return source;
957}
958
959void VisualShaderNodeTexture::set_texture(Ref<Texture2D> p_texture) {
960 texture = p_texture;
961 emit_changed();
962}
963
964Ref<Texture2D> VisualShaderNodeTexture::get_texture() const {
965 return texture;
966}
967
968void VisualShaderNodeTexture::set_texture_type(TextureType p_texture_type) {
969 ERR_FAIL_INDEX(int(p_texture_type), int(TYPE_MAX));
970 if (texture_type == p_texture_type) {
971 return;
972 }
973 texture_type = p_texture_type;
974 emit_changed();
975}
976
977VisualShaderNodeTexture::TextureType VisualShaderNodeTexture::get_texture_type() const {
978 return texture_type;
979}
980
981Vector<StringName> VisualShaderNodeTexture::get_editable_properties() const {
982 Vector<StringName> props;
983 props.push_back("source");
984 if (source == SOURCE_TEXTURE) {
985 props.push_back("texture");
986 props.push_back("texture_type");
987 }
988 return props;
989}
990
991String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
992 if (is_input_port_connected(2) && source != SOURCE_PORT) {
993 return RTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'.");
994 }
995
996 switch (source) {
997 case SOURCE_TEXTURE:
998 case SOURCE_PORT: {
999 return String(); // All good.
1000 } break;
1001 case SOURCE_SCREEN: {
1002 if ((p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
1003 return String(); // All good.
1004 }
1005 } break;
1006 case SOURCE_2D_NORMAL:
1007 case SOURCE_2D_TEXTURE: {
1008 if (p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
1009 return String(); // All good.
1010 }
1011 } break;
1012 case SOURCE_3D_NORMAL:
1013 case SOURCE_ROUGHNESS:
1014 case SOURCE_DEPTH: {
1015 if (p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
1016 if (get_output_port_for_preview() == 0) { // Not supported in preview(canvas_item) shader.
1017 return RTR("Invalid source for preview.");
1018 }
1019 return String(); // All good.
1020 }
1021 } break;
1022 default: {
1023 } break;
1024 }
1025
1026 return RTR("Invalid source for shader.");
1027}
1028
1029void VisualShaderNodeTexture::_bind_methods() {
1030 ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeTexture::set_source);
1031 ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeTexture::get_source);
1032
1033 ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture::set_texture);
1034 ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture::get_texture);
1035
1036 ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeTexture::set_texture_type);
1037 ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type);
1038
1039 ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort,Normal3D,Roughness"), "set_source", "get_source");
1040 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
1041 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type");
1042
1043 BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
1044 BIND_ENUM_CONSTANT(SOURCE_SCREEN);
1045 BIND_ENUM_CONSTANT(SOURCE_2D_TEXTURE);
1046 BIND_ENUM_CONSTANT(SOURCE_2D_NORMAL);
1047 BIND_ENUM_CONSTANT(SOURCE_DEPTH);
1048 BIND_ENUM_CONSTANT(SOURCE_PORT);
1049 BIND_ENUM_CONSTANT(SOURCE_3D_NORMAL);
1050 BIND_ENUM_CONSTANT(SOURCE_ROUGHNESS);
1051 BIND_ENUM_CONSTANT(SOURCE_MAX);
1052
1053 BIND_ENUM_CONSTANT(TYPE_DATA);
1054 BIND_ENUM_CONSTANT(TYPE_COLOR);
1055 BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP);
1056 BIND_ENUM_CONSTANT(TYPE_MAX);
1057}
1058
1059VisualShaderNodeTexture::VisualShaderNodeTexture() {
1060}
1061
1062////////////// CurveTexture
1063
1064String VisualShaderNodeCurveTexture::get_caption() const {
1065 return "CurveTexture";
1066}
1067
1068int VisualShaderNodeCurveTexture::get_input_port_count() const {
1069 return 1;
1070}
1071
1072VisualShaderNodeCurveTexture::PortType VisualShaderNodeCurveTexture::get_input_port_type(int p_port) const {
1073 return PORT_TYPE_SCALAR;
1074}
1075
1076String VisualShaderNodeCurveTexture::get_input_port_name(int p_port) const {
1077 return String();
1078}
1079
1080int VisualShaderNodeCurveTexture::get_output_port_count() const {
1081 return 1;
1082}
1083
1084VisualShaderNodeCurveTexture::PortType VisualShaderNodeCurveTexture::get_output_port_type(int p_port) const {
1085 return PORT_TYPE_SCALAR;
1086}
1087
1088String VisualShaderNodeCurveTexture::get_output_port_name(int p_port) const {
1089 return String();
1090}
1091
1092void VisualShaderNodeCurveTexture::set_texture(Ref<CurveTexture> p_texture) {
1093 texture = p_texture;
1094 emit_changed();
1095}
1096
1097Ref<CurveTexture> VisualShaderNodeCurveTexture::get_texture() const {
1098 return texture;
1099}
1100
1101Vector<StringName> VisualShaderNodeCurveTexture::get_editable_properties() const {
1102 Vector<StringName> props;
1103 props.push_back("texture");
1104 return props;
1105}
1106
1107String VisualShaderNodeCurveTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1108 return "uniform sampler2D " + make_unique_id(p_type, p_id, "curve") + " : repeat_disable;\n";
1109}
1110
1111String VisualShaderNodeCurveTexture::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 {
1112 if (p_input_vars[0].is_empty()) {
1113 return " " + p_output_vars[0] + " = 0.0;\n";
1114 }
1115 String id = make_unique_id(p_type, p_id, "curve");
1116 String code;
1117 code += " " + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ")).r;\n";
1118 return code;
1119}
1120
1121Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
1122 VisualShader::DefaultTextureParam dtp;
1123 dtp.name = make_unique_id(p_type, p_id, "curve");
1124 dtp.params.push_back(texture);
1125 Vector<VisualShader::DefaultTextureParam> ret;
1126 ret.push_back(dtp);
1127 return ret;
1128}
1129
1130void VisualShaderNodeCurveTexture::_bind_methods() {
1131 ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurveTexture::set_texture);
1132 ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurveTexture::get_texture);
1133
1134 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_texture", "get_texture");
1135}
1136
1137bool VisualShaderNodeCurveTexture::is_use_prop_slots() const {
1138 return true;
1139}
1140
1141VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() {
1142 set_input_port_default_value(0, 0.0);
1143 simple_decl = true;
1144 allow_v_resize = false;
1145}
1146
1147////////////// CurveXYZTexture
1148
1149String VisualShaderNodeCurveXYZTexture::get_caption() const {
1150 return "CurveXYZTexture";
1151}
1152
1153int VisualShaderNodeCurveXYZTexture::get_input_port_count() const {
1154 return 1;
1155}
1156
1157VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_input_port_type(int p_port) const {
1158 return PORT_TYPE_SCALAR;
1159}
1160
1161String VisualShaderNodeCurveXYZTexture::get_input_port_name(int p_port) const {
1162 return String();
1163}
1164
1165int VisualShaderNodeCurveXYZTexture::get_output_port_count() const {
1166 return 1;
1167}
1168
1169VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_output_port_type(int p_port) const {
1170 return PORT_TYPE_VECTOR_3D;
1171}
1172
1173String VisualShaderNodeCurveXYZTexture::get_output_port_name(int p_port) const {
1174 return String();
1175}
1176
1177void VisualShaderNodeCurveXYZTexture::set_texture(Ref<CurveXYZTexture> p_texture) {
1178 texture = p_texture;
1179 emit_changed();
1180}
1181
1182Ref<CurveXYZTexture> VisualShaderNodeCurveXYZTexture::get_texture() const {
1183 return texture;
1184}
1185
1186Vector<StringName> VisualShaderNodeCurveXYZTexture::get_editable_properties() const {
1187 Vector<StringName> props;
1188 props.push_back("texture");
1189 return props;
1190}
1191
1192String VisualShaderNodeCurveXYZTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1193 return "uniform sampler2D " + make_unique_id(p_type, p_id, "curve3d") + ";\n";
1194}
1195
1196String VisualShaderNodeCurveXYZTexture::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 {
1197 if (p_input_vars[0].is_empty()) {
1198 return " " + p_output_vars[0] + " = vec3(0.0);\n";
1199 }
1200 String id = make_unique_id(p_type, p_id, "curve3d");
1201 String code;
1202 code += " " + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ")).rgb;\n";
1203 return code;
1204}
1205
1206Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveXYZTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
1207 VisualShader::DefaultTextureParam dtp;
1208 dtp.name = make_unique_id(p_type, p_id, "curve3d");
1209 dtp.params.push_back(texture);
1210 Vector<VisualShader::DefaultTextureParam> ret;
1211 ret.push_back(dtp);
1212 return ret;
1213}
1214
1215void VisualShaderNodeCurveXYZTexture::_bind_methods() {
1216 ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurveXYZTexture::set_texture);
1217 ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurveXYZTexture::get_texture);
1218
1219 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_texture", "get_texture");
1220}
1221
1222bool VisualShaderNodeCurveXYZTexture::is_use_prop_slots() const {
1223 return true;
1224}
1225
1226VisualShaderNodeCurveXYZTexture::VisualShaderNodeCurveXYZTexture() {
1227 set_input_port_default_value(0, 0.0);
1228 simple_decl = true;
1229 allow_v_resize = false;
1230}
1231
1232////////////// Sample3D
1233
1234int VisualShaderNodeSample3D::get_input_port_count() const {
1235 return 3;
1236}
1237
1238VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_input_port_type(int p_port) const {
1239 switch (p_port) {
1240 case 0:
1241 return PORT_TYPE_VECTOR_3D;
1242 case 1:
1243 return PORT_TYPE_SCALAR;
1244 case 2:
1245 return PORT_TYPE_SAMPLER;
1246 default:
1247 return PORT_TYPE_SCALAR;
1248 }
1249}
1250
1251String VisualShaderNodeSample3D::get_input_port_name(int p_port) const {
1252 switch (p_port) {
1253 case 0:
1254 return "uvw";
1255 case 1:
1256 return "lod";
1257 default:
1258 return "";
1259 }
1260}
1261
1262int VisualShaderNodeSample3D::get_output_port_count() const {
1263 return 1;
1264}
1265
1266VisualShaderNodeSample3D::PortType VisualShaderNodeSample3D::get_output_port_type(int p_port) const {
1267 return p_port == 0 ? PORT_TYPE_VECTOR_4D : PORT_TYPE_SCALAR;
1268}
1269
1270String VisualShaderNodeSample3D::get_output_port_name(int p_port) const {
1271 return "color";
1272}
1273
1274bool VisualShaderNodeSample3D::is_output_port_expandable(int p_port) const {
1275 if (p_port == 0) {
1276 return true;
1277 }
1278 return false;
1279}
1280
1281bool VisualShaderNodeSample3D::is_input_port_default(int p_port, Shader::Mode p_mode) const {
1282 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
1283 if (p_port == 0) {
1284 return true;
1285 }
1286 }
1287 return false;
1288}
1289
1290String VisualShaderNodeSample3D::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 {
1291 String code;
1292 String id;
1293 if (source == SOURCE_TEXTURE) {
1294 id = make_unique_id(p_type, p_id, "tex3d");
1295 } else { // SOURCE_PORT
1296 id = p_input_vars[2];
1297 if (id.is_empty()) {
1298 code += " " + p_output_vars[0] + " = vec4(0.0);\n";
1299 return code;
1300 }
1301 }
1302 String default_uv;
1303 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
1304 default_uv = "vec3(UV, 0.0)";
1305 } else {
1306 default_uv = "vec3(0.0)";
1307 }
1308
1309 String uv = p_input_vars[0].is_empty() ? default_uv : p_input_vars[0];
1310 if (p_input_vars[1].is_empty()) {
1311 code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
1312 } else {
1313 code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
1314 }
1315 return code;
1316}
1317
1318void VisualShaderNodeSample3D::set_source(Source p_source) {
1319 ERR_FAIL_INDEX(int(p_source), int(SOURCE_MAX));
1320 if (source == p_source) {
1321 return;
1322 }
1323 source = p_source;
1324 emit_changed();
1325}
1326
1327VisualShaderNodeSample3D::Source VisualShaderNodeSample3D::get_source() const {
1328 return source;
1329}
1330
1331void VisualShaderNodeSample3D::_bind_methods() {
1332 ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeSample3D::set_source);
1333 ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeSample3D::get_source);
1334
1335 ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source");
1336
1337 BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
1338 BIND_ENUM_CONSTANT(SOURCE_PORT);
1339 BIND_ENUM_CONSTANT(SOURCE_MAX);
1340}
1341
1342String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
1343 if (is_input_port_connected(2) && source != SOURCE_PORT) {
1344 return RTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'.");
1345 }
1346 return String();
1347}
1348
1349VisualShaderNodeSample3D::VisualShaderNodeSample3D() {
1350 simple_decl = false;
1351}
1352
1353////////////// Texture2DArray
1354
1355String VisualShaderNodeTexture2DArray::get_caption() const {
1356 return "Texture2DArray";
1357}
1358
1359String VisualShaderNodeTexture2DArray::get_input_port_name(int p_port) const {
1360 if (p_port == 2) {
1361 return "sampler2DArray";
1362 }
1363 return VisualShaderNodeSample3D::get_input_port_name(p_port);
1364}
1365
1366Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture2DArray::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
1367 VisualShader::DefaultTextureParam dtp;
1368 dtp.name = make_unique_id(p_type, p_id, "tex3d");
1369 dtp.params.push_back(texture_array);
1370 Vector<VisualShader::DefaultTextureParam> ret;
1371 ret.push_back(dtp);
1372 return ret;
1373}
1374
1375String VisualShaderNodeTexture2DArray::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1376 if (source == SOURCE_TEXTURE) {
1377 return "uniform sampler2DArray " + make_unique_id(p_type, p_id, "tex3d") + ";\n";
1378 }
1379 return String();
1380}
1381
1382void VisualShaderNodeTexture2DArray::set_texture_array(Ref<Texture2DArray> p_texture_array) {
1383 texture_array = p_texture_array;
1384 emit_changed();
1385}
1386
1387Ref<Texture2DArray> VisualShaderNodeTexture2DArray::get_texture_array() const {
1388 return texture_array;
1389}
1390
1391Vector<StringName> VisualShaderNodeTexture2DArray::get_editable_properties() const {
1392 Vector<StringName> props;
1393 props.push_back("source");
1394 if (source == SOURCE_TEXTURE) {
1395 props.push_back("texture_array");
1396 }
1397 return props;
1398}
1399
1400void VisualShaderNodeTexture2DArray::_bind_methods() {
1401 ClassDB::bind_method(D_METHOD("set_texture_array", "value"), &VisualShaderNodeTexture2DArray::set_texture_array);
1402 ClassDB::bind_method(D_METHOD("get_texture_array"), &VisualShaderNodeTexture2DArray::get_texture_array);
1403
1404 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_array", PROPERTY_HINT_RESOURCE_TYPE, "Texture2DArray"), "set_texture_array", "get_texture_array");
1405}
1406
1407VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() {
1408}
1409
1410////////////// Texture3D
1411
1412String VisualShaderNodeTexture3D::get_caption() const {
1413 return "Texture3D";
1414}
1415
1416String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const {
1417 if (p_port == 2) {
1418 return "sampler3D";
1419 }
1420 return VisualShaderNodeSample3D::get_input_port_name(p_port);
1421}
1422
1423Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
1424 VisualShader::DefaultTextureParam dtp;
1425 dtp.name = make_unique_id(p_type, p_id, "tex3d");
1426 dtp.params.push_back(texture);
1427 Vector<VisualShader::DefaultTextureParam> ret;
1428 ret.push_back(dtp);
1429 return ret;
1430}
1431
1432String VisualShaderNodeTexture3D::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1433 if (source == SOURCE_TEXTURE) {
1434 return "uniform sampler3D " + make_unique_id(p_type, p_id, "tex3d") + ";\n";
1435 }
1436 return String();
1437}
1438
1439void VisualShaderNodeTexture3D::set_texture(Ref<Texture3D> p_texture) {
1440 texture = p_texture;
1441 emit_changed();
1442}
1443
1444Ref<Texture3D> VisualShaderNodeTexture3D::get_texture() const {
1445 return texture;
1446}
1447
1448Vector<StringName> VisualShaderNodeTexture3D::get_editable_properties() const {
1449 Vector<StringName> props;
1450 props.push_back("source");
1451 if (source == SOURCE_TEXTURE) {
1452 props.push_back("texture");
1453 }
1454 return props;
1455}
1456
1457void VisualShaderNodeTexture3D::_bind_methods() {
1458 ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture3D::set_texture);
1459 ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture3D::get_texture);
1460
1461 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
1462}
1463
1464VisualShaderNodeTexture3D::VisualShaderNodeTexture3D() {
1465}
1466
1467////////////// Cubemap
1468
1469String VisualShaderNodeCubemap::get_caption() const {
1470 return "Cubemap";
1471}
1472
1473int VisualShaderNodeCubemap::get_input_port_count() const {
1474 return 3;
1475}
1476
1477VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_input_port_type(int p_port) const {
1478 switch (p_port) {
1479 case 0:
1480 return PORT_TYPE_VECTOR_3D;
1481 case 1:
1482 return PORT_TYPE_SCALAR;
1483 case 2:
1484 return PORT_TYPE_SAMPLER;
1485 default:
1486 return PORT_TYPE_SCALAR;
1487 }
1488}
1489
1490String VisualShaderNodeCubemap::get_input_port_name(int p_port) const {
1491 switch (p_port) {
1492 case 0:
1493 return "uv";
1494 case 1:
1495 return "lod";
1496 case 2:
1497 return "samplerCube";
1498 default:
1499 return "";
1500 }
1501}
1502
1503int VisualShaderNodeCubemap::get_output_port_count() const {
1504 return 1;
1505}
1506
1507VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_output_port_type(int p_port) const {
1508 return PORT_TYPE_VECTOR_4D;
1509}
1510
1511String VisualShaderNodeCubemap::get_output_port_name(int p_port) const {
1512 return "color";
1513}
1514
1515bool VisualShaderNodeCubemap::is_output_port_expandable(int p_port) const {
1516 if (p_port == 0) {
1517 return true;
1518 }
1519 return false;
1520}
1521
1522Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
1523 VisualShader::DefaultTextureParam dtp;
1524 dtp.name = make_unique_id(p_type, p_id, "cube");
1525 dtp.params.push_back(cube_map);
1526 Vector<VisualShader::DefaultTextureParam> ret;
1527 ret.push_back(dtp);
1528 return ret;
1529}
1530
1531String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1532 if (source == SOURCE_TEXTURE) {
1533 String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube");
1534 switch (texture_type) {
1535 case TYPE_DATA:
1536 break;
1537 case TYPE_COLOR:
1538 u += " : source_color";
1539 break;
1540 case TYPE_NORMAL_MAP:
1541 u += " : hint_normal";
1542 break;
1543 default:
1544 break;
1545 }
1546 return u + ";\n";
1547 }
1548 return String();
1549}
1550
1551String VisualShaderNodeCubemap::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 {
1552 String code;
1553 String id;
1554
1555 if (source == SOURCE_TEXTURE) {
1556 id = make_unique_id(p_type, p_id, "cube");
1557 } else { // SOURCE_PORT
1558 id = p_input_vars[2];
1559 if (id.is_empty()) {
1560 code += " " + p_output_vars[0] + " = vec4(0.0);\n";
1561 return code;
1562 }
1563 }
1564
1565 String default_uv;
1566 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
1567 default_uv = "vec3(UV, 0.0)";
1568 } else {
1569 default_uv = "vec3(0.0)";
1570 }
1571
1572 String uv = p_input_vars[0].is_empty() ? default_uv : p_input_vars[0];
1573 if (p_input_vars[1].is_empty()) {
1574 code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
1575 } else {
1576 code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
1577 }
1578
1579 return code;
1580}
1581
1582bool VisualShaderNodeCubemap::is_input_port_default(int p_port, Shader::Mode p_mode) const {
1583 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
1584 if (p_port == 0) {
1585 return true;
1586 }
1587 }
1588 return false;
1589}
1590
1591void VisualShaderNodeCubemap::set_source(Source p_source) {
1592 ERR_FAIL_INDEX(int(p_source), int(SOURCE_MAX));
1593 if (source == p_source) {
1594 return;
1595 }
1596 source = p_source;
1597 emit_changed();
1598}
1599
1600VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const {
1601 return source;
1602}
1603
1604void VisualShaderNodeCubemap::set_cube_map(Ref<Cubemap> p_cube_map) {
1605 cube_map = p_cube_map;
1606 emit_changed();
1607}
1608
1609Ref<Cubemap> VisualShaderNodeCubemap::get_cube_map() const {
1610 return cube_map;
1611}
1612
1613void VisualShaderNodeCubemap::set_texture_type(TextureType p_texture_type) {
1614 ERR_FAIL_INDEX(int(p_texture_type), int(TYPE_MAX));
1615 if (texture_type == p_texture_type) {
1616 return;
1617 }
1618 texture_type = p_texture_type;
1619 emit_changed();
1620}
1621
1622VisualShaderNodeCubemap::TextureType VisualShaderNodeCubemap::get_texture_type() const {
1623 return texture_type;
1624}
1625
1626Vector<StringName> VisualShaderNodeCubemap::get_editable_properties() const {
1627 Vector<StringName> props;
1628 props.push_back("source");
1629 if (source == SOURCE_TEXTURE) {
1630 props.push_back("cube_map");
1631 props.push_back("texture_type");
1632 }
1633 return props;
1634}
1635
1636String VisualShaderNodeCubemap::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
1637 if (is_input_port_connected(2) && source != SOURCE_PORT) {
1638 return RTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'.");
1639 }
1640 return String();
1641}
1642
1643void VisualShaderNodeCubemap::_bind_methods() {
1644 ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubemap::set_source);
1645 ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubemap::get_source);
1646
1647 ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubemap::set_cube_map);
1648 ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubemap::get_cube_map);
1649
1650 ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubemap::set_texture_type);
1651 ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubemap::get_texture_type);
1652
1653 ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source");
1654 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map");
1655 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type");
1656
1657 BIND_ENUM_CONSTANT(SOURCE_TEXTURE);
1658 BIND_ENUM_CONSTANT(SOURCE_PORT);
1659 BIND_ENUM_CONSTANT(SOURCE_MAX);
1660
1661 BIND_ENUM_CONSTANT(TYPE_DATA);
1662 BIND_ENUM_CONSTANT(TYPE_COLOR);
1663 BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP);
1664 BIND_ENUM_CONSTANT(TYPE_MAX);
1665}
1666
1667VisualShaderNodeCubemap::VisualShaderNodeCubemap() {
1668 simple_decl = false;
1669}
1670
1671////////////// Linear Depth
1672
1673String VisualShaderNodeLinearSceneDepth::get_caption() const {
1674 return "LinearSceneDepth";
1675}
1676
1677int VisualShaderNodeLinearSceneDepth::get_input_port_count() const {
1678 return 0;
1679}
1680
1681VisualShaderNodeLinearSceneDepth::PortType VisualShaderNodeLinearSceneDepth::get_input_port_type(int p_port) const {
1682 return PORT_TYPE_SCALAR;
1683}
1684
1685String VisualShaderNodeLinearSceneDepth::get_input_port_name(int p_port) const {
1686 return "";
1687}
1688
1689int VisualShaderNodeLinearSceneDepth::get_output_port_count() const {
1690 return 1;
1691}
1692
1693VisualShaderNodeLinearSceneDepth::PortType VisualShaderNodeLinearSceneDepth::get_output_port_type(int p_port) const {
1694 return PORT_TYPE_SCALAR;
1695}
1696
1697String VisualShaderNodeLinearSceneDepth::get_output_port_name(int p_port) const {
1698 return "linear depth";
1699}
1700
1701bool VisualShaderNodeLinearSceneDepth::has_output_port_preview(int p_port) const {
1702 return false;
1703}
1704
1705String VisualShaderNodeLinearSceneDepth::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1706 return "uniform sampler2D " + make_unique_id(p_type, p_id, "depth_tex") + " : hint_depth_texture;\n";
1707}
1708
1709String VisualShaderNodeLinearSceneDepth::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 {
1710 String code;
1711 code += " {\n";
1712
1713 code += " float __log_depth = textureLod(" + make_unique_id(p_type, p_id, "depth_tex") + ", SCREEN_UV, 0.0).x;\n";
1714 if (!RenderingServer::get_singleton()->is_low_end()) {
1715 code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, __log_depth, 1.0);\n";
1716 } else {
1717 code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(vec3(SCREEN_UV, __log_depth) * 2.0 - 1.0, 1.0);\n";
1718 }
1719 code += " __depth_view.xyz /= __depth_view.w;\n";
1720 code += vformat(" %s = -__depth_view.z;\n", p_output_vars[0]);
1721
1722 code += " }\n";
1723 return code;
1724}
1725
1726VisualShaderNodeLinearSceneDepth::VisualShaderNodeLinearSceneDepth() {
1727 simple_decl = false;
1728}
1729
1730////////////// World Position from Depth
1731
1732String VisualShaderNodeWorldPositionFromDepth::get_caption() const {
1733 return "WorldPositionFromDepth";
1734}
1735
1736int VisualShaderNodeWorldPositionFromDepth::get_input_port_count() const {
1737 return 1;
1738}
1739
1740VisualShaderNodeWorldPositionFromDepth::PortType VisualShaderNodeWorldPositionFromDepth::get_input_port_type(int p_port) const {
1741 return PORT_TYPE_VECTOR_2D;
1742}
1743
1744String VisualShaderNodeWorldPositionFromDepth::get_input_port_name(int p_port) const {
1745 return "screen uv";
1746}
1747
1748bool VisualShaderNodeWorldPositionFromDepth::is_input_port_default(int p_port, Shader::Mode p_mode) const {
1749 if (p_port == 0) {
1750 return true;
1751 }
1752 return false;
1753}
1754
1755int VisualShaderNodeWorldPositionFromDepth::get_output_port_count() const {
1756 return 1;
1757}
1758
1759VisualShaderNodeWorldPositionFromDepth::PortType VisualShaderNodeWorldPositionFromDepth::get_output_port_type(int p_port) const {
1760 return PORT_TYPE_VECTOR_3D;
1761}
1762
1763String VisualShaderNodeWorldPositionFromDepth::get_output_port_name(int p_port) const {
1764 return "world position";
1765}
1766
1767bool VisualShaderNodeWorldPositionFromDepth::has_output_port_preview(int p_port) const {
1768 return false;
1769}
1770
1771String VisualShaderNodeWorldPositionFromDepth::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1772 return "uniform sampler2D " + make_unique_id(p_type, p_id, "depth_tex") + " : hint_depth_texture, repeat_disable, filter_nearest;\n";
1773}
1774
1775String VisualShaderNodeWorldPositionFromDepth::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 {
1776 String code;
1777 String uv = p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0];
1778 code += " {\n";
1779
1780 code += " float __log_depth = textureLod(" + make_unique_id(p_type, p_id, "depth_tex") + ", " + uv + ", 0.0).x;\n";
1781 if (!RenderingServer::get_singleton()->is_low_end()) {
1782 code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(" + uv + " * 2.0 - 1.0, __log_depth, 1.0);\n";
1783 } else {
1784 code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(vec3(" + uv + ", __log_depth) * 2.0 - 1.0, 1.0);\n";
1785 }
1786 code += " __depth_view.xyz /= __depth_view.w;\n";
1787 code += vformat(" %s = (INV_VIEW_MATRIX * __depth_view).xyz;\n", p_output_vars[0]);
1788
1789 code += " }\n";
1790 return code;
1791}
1792
1793VisualShaderNodeWorldPositionFromDepth::VisualShaderNodeWorldPositionFromDepth() {
1794 simple_decl = false;
1795}
1796
1797////////////// Unpack Normals in World Space
1798
1799String VisualShaderNodeScreenNormalWorldSpace::get_caption() const {
1800 return "ScreenNormalWorldSpace";
1801}
1802
1803int VisualShaderNodeScreenNormalWorldSpace::get_input_port_count() const {
1804 return 1;
1805}
1806
1807VisualShaderNodeScreenNormalWorldSpace::PortType VisualShaderNodeScreenNormalWorldSpace::get_input_port_type(int p_port) const {
1808 return PORT_TYPE_VECTOR_2D;
1809}
1810
1811String VisualShaderNodeScreenNormalWorldSpace::get_input_port_name(int p_port) const {
1812 return "screen uv";
1813}
1814
1815bool VisualShaderNodeScreenNormalWorldSpace::is_input_port_default(int p_port, Shader::Mode p_mode) const {
1816 if (p_port == 0) {
1817 return true;
1818 }
1819 return false;
1820}
1821
1822int VisualShaderNodeScreenNormalWorldSpace::get_output_port_count() const {
1823 return 1;
1824}
1825
1826VisualShaderNodeScreenNormalWorldSpace::PortType VisualShaderNodeScreenNormalWorldSpace::get_output_port_type(int p_port) const {
1827 return PORT_TYPE_VECTOR_3D;
1828}
1829
1830String VisualShaderNodeScreenNormalWorldSpace::get_output_port_name(int p_port) const {
1831 return "screen normal";
1832}
1833
1834bool VisualShaderNodeScreenNormalWorldSpace::has_output_port_preview(int p_port) const {
1835 return false;
1836}
1837
1838String VisualShaderNodeScreenNormalWorldSpace::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
1839 return "uniform sampler2D " + make_unique_id(p_type, p_id, "normal_rough_tex") + " : hint_normal_roughness_texture, repeat_disable, filter_nearest;\n";
1840}
1841
1842String VisualShaderNodeScreenNormalWorldSpace::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 {
1843 String code;
1844 String uv = p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0];
1845 code += " {\n";
1846
1847 code += " vec3 __normals = textureLod(" + make_unique_id(p_type, p_id, "normal_rough_tex") + ", " + uv + ", 0.0).xyz;\n";
1848 code += " __normals = __normals * 2.0 - 1.0;\n";
1849 code += vformat(" %s = mat3(INV_VIEW_MATRIX) * __normals;\n", p_output_vars[0]);
1850
1851 code += " }\n";
1852 return code;
1853}
1854
1855VisualShaderNodeScreenNormalWorldSpace::VisualShaderNodeScreenNormalWorldSpace() {
1856 simple_decl = false;
1857}
1858
1859////////////// Float Op
1860
1861String VisualShaderNodeFloatOp::get_caption() const {
1862 return "FloatOp";
1863}
1864
1865int VisualShaderNodeFloatOp::get_input_port_count() const {
1866 return 2;
1867}
1868
1869VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_input_port_type(int p_port) const {
1870 return PORT_TYPE_SCALAR;
1871}
1872
1873String VisualShaderNodeFloatOp::get_input_port_name(int p_port) const {
1874 return p_port == 0 ? "a" : "b";
1875}
1876
1877int VisualShaderNodeFloatOp::get_output_port_count() const {
1878 return 1;
1879}
1880
1881VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_output_port_type(int p_port) const {
1882 return PORT_TYPE_SCALAR;
1883}
1884
1885String VisualShaderNodeFloatOp::get_output_port_name(int p_port) const {
1886 return "op"; //no output port means the editor will be used as port
1887}
1888
1889String VisualShaderNodeFloatOp::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 {
1890 String code = " " + p_output_vars[0] + " = ";
1891 switch (op) {
1892 case OP_ADD:
1893 code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
1894 break;
1895 case OP_SUB:
1896 code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
1897 break;
1898 case OP_MUL:
1899 code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
1900 break;
1901 case OP_DIV:
1902 code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
1903 break;
1904 case OP_MOD:
1905 code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
1906 break;
1907 case OP_POW:
1908 code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
1909 break;
1910 case OP_MAX:
1911 code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
1912 break;
1913 case OP_MIN:
1914 code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
1915 break;
1916 case OP_ATAN2:
1917 code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
1918 break;
1919 case OP_STEP:
1920 code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
1921 break;
1922 default:
1923 break;
1924 }
1925 return code;
1926}
1927
1928void VisualShaderNodeFloatOp::set_operator(Operator p_op) {
1929 ERR_FAIL_INDEX(int(p_op), int(OP_ENUM_SIZE));
1930 if (op == p_op) {
1931 return;
1932 }
1933 op = p_op;
1934 emit_changed();
1935}
1936
1937VisualShaderNodeFloatOp::Operator VisualShaderNodeFloatOp::get_operator() const {
1938 return op;
1939}
1940
1941Vector<StringName> VisualShaderNodeFloatOp::get_editable_properties() const {
1942 Vector<StringName> props;
1943 props.push_back("operator");
1944 return props;
1945}
1946
1947void VisualShaderNodeFloatOp::_bind_methods() {
1948 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator);
1949 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator);
1950
1951 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,ATan2,Step"), "set_operator", "get_operator");
1952
1953 BIND_ENUM_CONSTANT(OP_ADD);
1954 BIND_ENUM_CONSTANT(OP_SUB);
1955 BIND_ENUM_CONSTANT(OP_MUL);
1956 BIND_ENUM_CONSTANT(OP_DIV);
1957 BIND_ENUM_CONSTANT(OP_MOD);
1958 BIND_ENUM_CONSTANT(OP_POW);
1959 BIND_ENUM_CONSTANT(OP_MAX);
1960 BIND_ENUM_CONSTANT(OP_MIN);
1961 BIND_ENUM_CONSTANT(OP_ATAN2);
1962 BIND_ENUM_CONSTANT(OP_STEP);
1963 BIND_ENUM_CONSTANT(OP_ENUM_SIZE);
1964}
1965
1966VisualShaderNodeFloatOp::VisualShaderNodeFloatOp() {
1967 set_input_port_default_value(0, 0.0);
1968 set_input_port_default_value(1, 0.0);
1969}
1970
1971////////////// Integer Op
1972
1973String VisualShaderNodeIntOp::get_caption() const {
1974 return "IntOp";
1975}
1976
1977int VisualShaderNodeIntOp::get_input_port_count() const {
1978 return 2;
1979}
1980
1981VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_input_port_type(int p_port) const {
1982 return PORT_TYPE_SCALAR_INT;
1983}
1984
1985String VisualShaderNodeIntOp::get_input_port_name(int p_port) const {
1986 return p_port == 0 ? "a" : "b";
1987}
1988
1989int VisualShaderNodeIntOp::get_output_port_count() const {
1990 return 1;
1991}
1992
1993VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_output_port_type(int p_port) const {
1994 return PORT_TYPE_SCALAR_INT;
1995}
1996
1997String VisualShaderNodeIntOp::get_output_port_name(int p_port) const {
1998 return "op"; // No output port means the editor will be used as port.
1999}
2000
2001String VisualShaderNodeIntOp::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 {
2002 String code = " " + p_output_vars[0] + " = ";
2003 switch (op) {
2004 case OP_ADD:
2005 code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
2006 break;
2007 case OP_SUB:
2008 code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
2009 break;
2010 case OP_MUL:
2011 code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
2012 break;
2013 case OP_DIV:
2014 code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
2015 break;
2016 case OP_MOD:
2017 code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n";
2018 break;
2019 case OP_MAX:
2020 code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2021 break;
2022 case OP_MIN:
2023 code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2024 break;
2025 case OP_BITWISE_AND:
2026 code += p_input_vars[0] + " & " + p_input_vars[1] + ";\n";
2027 break;
2028 case OP_BITWISE_OR:
2029 code += p_input_vars[0] + " | " + p_input_vars[1] + ";\n";
2030 break;
2031 case OP_BITWISE_XOR:
2032 code += p_input_vars[0] + " ^ " + p_input_vars[1] + ";\n";
2033 break;
2034 case OP_BITWISE_LEFT_SHIFT:
2035 code += p_input_vars[0] + " << " + p_input_vars[1] + ";\n";
2036 break;
2037 case OP_BITWISE_RIGHT_SHIFT:
2038 code += p_input_vars[0] + " >> " + p_input_vars[1] + ";\n";
2039 break;
2040 default:
2041 break;
2042 }
2043
2044 return code;
2045}
2046
2047void VisualShaderNodeIntOp::set_operator(Operator p_op) {
2048 ERR_FAIL_INDEX(int(p_op), OP_ENUM_SIZE);
2049 if (op == p_op) {
2050 return;
2051 }
2052 op = p_op;
2053 emit_changed();
2054}
2055
2056VisualShaderNodeIntOp::Operator VisualShaderNodeIntOp::get_operator() const {
2057 return op;
2058}
2059
2060Vector<StringName> VisualShaderNodeIntOp::get_editable_properties() const {
2061 Vector<StringName> props;
2062 props.push_back("operator");
2063 return props;
2064}
2065
2066void VisualShaderNodeIntOp::_bind_methods() {
2067 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator);
2068 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator);
2069
2070 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min,Bitwise AND,Bitwise OR,Bitwise XOR,Bitwise Left Shift,Bitwise Right Shift"), "set_operator", "get_operator");
2071
2072 BIND_ENUM_CONSTANT(OP_ADD);
2073 BIND_ENUM_CONSTANT(OP_SUB);
2074 BIND_ENUM_CONSTANT(OP_MUL);
2075 BIND_ENUM_CONSTANT(OP_DIV);
2076 BIND_ENUM_CONSTANT(OP_MOD);
2077 BIND_ENUM_CONSTANT(OP_MAX);
2078 BIND_ENUM_CONSTANT(OP_MIN);
2079 BIND_ENUM_CONSTANT(OP_BITWISE_AND);
2080 BIND_ENUM_CONSTANT(OP_BITWISE_OR);
2081 BIND_ENUM_CONSTANT(OP_BITWISE_XOR);
2082 BIND_ENUM_CONSTANT(OP_BITWISE_LEFT_SHIFT);
2083 BIND_ENUM_CONSTANT(OP_BITWISE_RIGHT_SHIFT);
2084 BIND_ENUM_CONSTANT(OP_ENUM_SIZE);
2085}
2086
2087VisualShaderNodeIntOp::VisualShaderNodeIntOp() {
2088 set_input_port_default_value(0, 0);
2089 set_input_port_default_value(1, 0);
2090}
2091
2092////////////// Unsigned Integer Op
2093
2094String VisualShaderNodeUIntOp::get_caption() const {
2095 return "UIntOp";
2096}
2097
2098int VisualShaderNodeUIntOp::get_input_port_count() const {
2099 return 2;
2100}
2101
2102VisualShaderNodeUIntOp::PortType VisualShaderNodeUIntOp::get_input_port_type(int p_port) const {
2103 return PORT_TYPE_SCALAR_UINT;
2104}
2105
2106String VisualShaderNodeUIntOp::get_input_port_name(int p_port) const {
2107 return p_port == 0 ? "a" : "b";
2108}
2109
2110int VisualShaderNodeUIntOp::get_output_port_count() const {
2111 return 1;
2112}
2113
2114VisualShaderNodeUIntOp::PortType VisualShaderNodeUIntOp::get_output_port_type(int p_port) const {
2115 return PORT_TYPE_SCALAR_UINT;
2116}
2117
2118String VisualShaderNodeUIntOp::get_output_port_name(int p_port) const {
2119 return "op"; // No output port means the editor will be used as port.
2120}
2121
2122String VisualShaderNodeUIntOp::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 {
2123 String code = " " + p_output_vars[0] + " = ";
2124 switch (op) {
2125 case OP_ADD:
2126 code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
2127 break;
2128 case OP_SUB:
2129 code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
2130 break;
2131 case OP_MUL:
2132 code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
2133 break;
2134 case OP_DIV:
2135 code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
2136 break;
2137 case OP_MOD:
2138 code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n";
2139 break;
2140 case OP_MAX:
2141 code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2142 break;
2143 case OP_MIN:
2144 code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2145 break;
2146 case OP_BITWISE_AND:
2147 code += p_input_vars[0] + " & " + p_input_vars[1] + ";\n";
2148 break;
2149 case OP_BITWISE_OR:
2150 code += p_input_vars[0] + " | " + p_input_vars[1] + ";\n";
2151 break;
2152 case OP_BITWISE_XOR:
2153 code += p_input_vars[0] + " ^ " + p_input_vars[1] + ";\n";
2154 break;
2155 case OP_BITWISE_LEFT_SHIFT:
2156 code += p_input_vars[0] + " << " + p_input_vars[1] + ";\n";
2157 break;
2158 case OP_BITWISE_RIGHT_SHIFT:
2159 code += p_input_vars[0] + " >> " + p_input_vars[1] + ";\n";
2160 break;
2161 default:
2162 break;
2163 }
2164
2165 return code;
2166}
2167
2168void VisualShaderNodeUIntOp::set_operator(Operator p_op) {
2169 ERR_FAIL_INDEX(int(p_op), OP_ENUM_SIZE);
2170 if (op == p_op) {
2171 return;
2172 }
2173 op = p_op;
2174 emit_changed();
2175}
2176
2177VisualShaderNodeUIntOp::Operator VisualShaderNodeUIntOp::get_operator() const {
2178 return op;
2179}
2180
2181Vector<StringName> VisualShaderNodeUIntOp::get_editable_properties() const {
2182 Vector<StringName> props;
2183 props.push_back("operator");
2184 return props;
2185}
2186
2187void VisualShaderNodeUIntOp::_bind_methods() {
2188 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeUIntOp::set_operator);
2189 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeUIntOp::get_operator);
2190
2191 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min,Bitwise AND,Bitwise OR,Bitwise XOR,Bitwise Left Shift,Bitwise Right Shift"), "set_operator", "get_operator");
2192
2193 BIND_ENUM_CONSTANT(OP_ADD);
2194 BIND_ENUM_CONSTANT(OP_SUB);
2195 BIND_ENUM_CONSTANT(OP_MUL);
2196 BIND_ENUM_CONSTANT(OP_DIV);
2197 BIND_ENUM_CONSTANT(OP_MOD);
2198 BIND_ENUM_CONSTANT(OP_MAX);
2199 BIND_ENUM_CONSTANT(OP_MIN);
2200 BIND_ENUM_CONSTANT(OP_BITWISE_AND);
2201 BIND_ENUM_CONSTANT(OP_BITWISE_OR);
2202 BIND_ENUM_CONSTANT(OP_BITWISE_XOR);
2203 BIND_ENUM_CONSTANT(OP_BITWISE_LEFT_SHIFT);
2204 BIND_ENUM_CONSTANT(OP_BITWISE_RIGHT_SHIFT);
2205 BIND_ENUM_CONSTANT(OP_ENUM_SIZE);
2206}
2207
2208VisualShaderNodeUIntOp::VisualShaderNodeUIntOp() {
2209 set_input_port_default_value(0, 0);
2210 set_input_port_default_value(1, 0);
2211}
2212
2213////////////// Vector Op
2214
2215String VisualShaderNodeVectorOp::get_caption() const {
2216 return "VectorOp";
2217}
2218
2219int VisualShaderNodeVectorOp::get_input_port_count() const {
2220 return 2;
2221}
2222
2223String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
2224 return p_port == 0 ? "a" : "b";
2225}
2226
2227int VisualShaderNodeVectorOp::get_output_port_count() const {
2228 return 1;
2229}
2230
2231String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
2232 return "op";
2233}
2234
2235String VisualShaderNodeVectorOp::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 {
2236 String code = " " + p_output_vars[0] + " = ";
2237 switch (op) {
2238 case OP_ADD:
2239 code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
2240 break;
2241 case OP_SUB:
2242 code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
2243 break;
2244 case OP_MUL:
2245 code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
2246 break;
2247 case OP_DIV:
2248 code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
2249 break;
2250 case OP_MOD:
2251 code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2252 break;
2253 case OP_POW:
2254 code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2255 break;
2256 case OP_MAX:
2257 code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2258 break;
2259 case OP_MIN:
2260 code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2261 break;
2262 case OP_CROSS:
2263 if (op_type == OP_TYPE_VECTOR_2D) { // Not supported.
2264 code += "vec2(0.0);\n";
2265 } else if (op_type == OP_TYPE_VECTOR_4D) { // Not supported.
2266 code += "vec4(0.0);\n";
2267 } else {
2268 code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2269 }
2270 break;
2271 case OP_ATAN2:
2272 code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2273 break;
2274 case OP_REFLECT:
2275 code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2276 break;
2277 case OP_STEP:
2278 code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2279 break;
2280 default:
2281 break;
2282 }
2283
2284 return code;
2285}
2286
2287void VisualShaderNodeVectorOp::set_op_type(OpType p_op_type) {
2288 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
2289 if (op_type == p_op_type) {
2290 return;
2291 }
2292 switch (p_op_type) {
2293 case OP_TYPE_VECTOR_2D: {
2294 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
2295 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
2296 } break;
2297 case OP_TYPE_VECTOR_3D: {
2298 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
2299 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
2300 } break;
2301 case OP_TYPE_VECTOR_4D: {
2302 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
2303 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
2304 } break;
2305 default:
2306 break;
2307 }
2308 op_type = p_op_type;
2309 emit_changed();
2310}
2311
2312void VisualShaderNodeVectorOp::set_operator(Operator p_op) {
2313 ERR_FAIL_INDEX(int(p_op), int(OP_ENUM_SIZE));
2314 if (op == p_op) {
2315 return;
2316 }
2317 op = p_op;
2318 emit_changed();
2319}
2320
2321VisualShaderNodeVectorOp::Operator VisualShaderNodeVectorOp::get_operator() const {
2322 return op;
2323}
2324
2325Vector<StringName> VisualShaderNodeVectorOp::get_editable_properties() const {
2326 Vector<StringName> props = VisualShaderNodeVectorBase::get_editable_properties();
2327 props.push_back("operator");
2328 return props;
2329}
2330
2331String VisualShaderNodeVectorOp::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
2332 bool invalid_type = false;
2333
2334 if (op_type == OP_TYPE_VECTOR_2D || op_type == OP_TYPE_VECTOR_4D) {
2335 if (op == OP_CROSS) {
2336 invalid_type = true;
2337 }
2338 }
2339
2340 if (invalid_type) {
2341 return RTR("Invalid operator for that type.");
2342 }
2343
2344 return String();
2345}
2346
2347void VisualShaderNodeVectorOp::_bind_methods() {
2348 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator);
2349 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator);
2350
2351 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,Cross,ATan2,Reflect,Step"), "set_operator", "get_operator");
2352
2353 BIND_ENUM_CONSTANT(OP_ADD);
2354 BIND_ENUM_CONSTANT(OP_SUB);
2355 BIND_ENUM_CONSTANT(OP_MUL);
2356 BIND_ENUM_CONSTANT(OP_DIV);
2357 BIND_ENUM_CONSTANT(OP_MOD);
2358 BIND_ENUM_CONSTANT(OP_POW);
2359 BIND_ENUM_CONSTANT(OP_MAX);
2360 BIND_ENUM_CONSTANT(OP_MIN);
2361 BIND_ENUM_CONSTANT(OP_CROSS);
2362 BIND_ENUM_CONSTANT(OP_ATAN2);
2363 BIND_ENUM_CONSTANT(OP_REFLECT);
2364 BIND_ENUM_CONSTANT(OP_STEP);
2365 BIND_ENUM_CONSTANT(OP_ENUM_SIZE);
2366}
2367
2368VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() {
2369 switch (op_type) {
2370 case OP_TYPE_VECTOR_2D: {
2371 set_input_port_default_value(0, Vector2());
2372 set_input_port_default_value(1, Vector2());
2373 } break;
2374 case OP_TYPE_VECTOR_3D: {
2375 set_input_port_default_value(0, Vector3());
2376 set_input_port_default_value(1, Vector3());
2377 } break;
2378 case OP_TYPE_VECTOR_4D: {
2379 set_input_port_default_value(0, Quaternion());
2380 set_input_port_default_value(1, Quaternion());
2381 } break;
2382 default:
2383 break;
2384 }
2385}
2386
2387////////////// Color Op
2388
2389String VisualShaderNodeColorOp::get_caption() const {
2390 return "ColorOp";
2391}
2392
2393int VisualShaderNodeColorOp::get_input_port_count() const {
2394 return 2;
2395}
2396
2397VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_input_port_type(int p_port) const {
2398 return PORT_TYPE_VECTOR_3D;
2399}
2400
2401String VisualShaderNodeColorOp::get_input_port_name(int p_port) const {
2402 return p_port == 0 ? "a" : "b";
2403}
2404
2405int VisualShaderNodeColorOp::get_output_port_count() const {
2406 return 1;
2407}
2408
2409VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_output_port_type(int p_port) const {
2410 return PORT_TYPE_VECTOR_3D;
2411}
2412
2413String VisualShaderNodeColorOp::get_output_port_name(int p_port) const {
2414 return "op"; //no output port means the editor will be used as port
2415}
2416
2417String VisualShaderNodeColorOp::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 {
2418 String code;
2419 static const char *axisn[3] = { "x", "y", "z" };
2420 switch (op) {
2421 case OP_SCREEN: {
2422 code += " " + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") * (vec3(1.0) - " + p_input_vars[1] + ");\n";
2423 } break;
2424 case OP_DIFFERENCE: {
2425 code += " " + p_output_vars[0] + " = abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ");\n";
2426 } break;
2427 case OP_DARKEN: {
2428 code += " " + p_output_vars[0] + " = min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2429 } break;
2430 case OP_LIGHTEN: {
2431 code += " " + p_output_vars[0] + " = max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2432
2433 } break;
2434 case OP_OVERLAY: {
2435 for (int i = 0; i < 3; i++) {
2436 code += " {\n";
2437 code += " float base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
2438 code += " float blend = " + p_input_vars[1] + "." + axisn[i] + ";\n";
2439 code += " if (base < 0.5) {\n";
2440 code += " " + p_output_vars[0] + "." + axisn[i] + " = 2.0 * base * blend;\n";
2441 code += " } else {\n";
2442 code += " " + p_output_vars[0] + "." + axisn[i] + " = 1.0 - 2.0 * (1.0 - blend) * (1.0 - base);\n";
2443 code += " }\n";
2444 code += " }\n";
2445 }
2446
2447 } break;
2448 case OP_DODGE: {
2449 code += " " + p_output_vars[0] + " = (" + p_input_vars[0] + ") / (vec3(1.0) - " + p_input_vars[1] + ");\n";
2450
2451 } break;
2452 case OP_BURN: {
2453 code += " " + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") / (" + p_input_vars[1] + ");\n";
2454 } break;
2455 case OP_SOFT_LIGHT: {
2456 for (int i = 0; i < 3; i++) {
2457 code += " {\n";
2458 code += " float base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
2459 code += " float blend = " + p_input_vars[1] + "." + axisn[i] + ";\n";
2460 code += " if (base < 0.5) {\n";
2461 code += " " + p_output_vars[0] + "." + axisn[i] + " = (base * (blend + 0.5));\n";
2462 code += " } else {\n";
2463 code += " " + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0 - base) * (1.0 - (blend - 0.5)));\n";
2464 code += " }\n";
2465 code += " }\n";
2466 }
2467
2468 } break;
2469 case OP_HARD_LIGHT: {
2470 for (int i = 0; i < 3; i++) {
2471 code += " {\n";
2472 code += " float base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
2473 code += " float blend = " + p_input_vars[1] + "." + axisn[i] + ";\n";
2474 code += " if (base < 0.5) {\n";
2475 code += " " + p_output_vars[0] + "." + axisn[i] + " = (base * (2.0 * blend));\n";
2476 code += " } else {\n";
2477 code += " " + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0 - base) * (1.0 - 2.0 * (blend - 0.5)));\n";
2478 code += " }\n";
2479 code += " }\n";
2480 }
2481
2482 } break;
2483 default:
2484 break;
2485 }
2486
2487 return code;
2488}
2489
2490void VisualShaderNodeColorOp::set_operator(Operator p_op) {
2491 ERR_FAIL_INDEX(int(p_op), int(OP_MAX));
2492 if (op == p_op) {
2493 return;
2494 }
2495 switch (p_op) {
2496 case OP_SCREEN:
2497 simple_decl = true;
2498 break;
2499 case OP_DIFFERENCE:
2500 simple_decl = true;
2501 break;
2502 case OP_DARKEN:
2503 simple_decl = true;
2504 break;
2505 case OP_LIGHTEN:
2506 simple_decl = true;
2507 break;
2508 case OP_OVERLAY:
2509 simple_decl = false;
2510 break;
2511 case OP_DODGE:
2512 simple_decl = true;
2513 break;
2514 case OP_BURN:
2515 simple_decl = true;
2516 break;
2517 case OP_SOFT_LIGHT:
2518 simple_decl = false;
2519 break;
2520 case OP_HARD_LIGHT:
2521 simple_decl = false;
2522 break;
2523 default:
2524 break;
2525 }
2526 op = p_op;
2527 emit_changed();
2528}
2529
2530VisualShaderNodeColorOp::Operator VisualShaderNodeColorOp::get_operator() const {
2531 return op;
2532}
2533
2534Vector<StringName> VisualShaderNodeColorOp::get_editable_properties() const {
2535 Vector<StringName> props;
2536 props.push_back("operator");
2537 return props;
2538}
2539
2540void VisualShaderNodeColorOp::_bind_methods() {
2541 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator);
2542 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator);
2543
2544 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,Soft Light,Hard Light"), "set_operator", "get_operator");
2545
2546 BIND_ENUM_CONSTANT(OP_SCREEN);
2547 BIND_ENUM_CONSTANT(OP_DIFFERENCE);
2548 BIND_ENUM_CONSTANT(OP_DARKEN);
2549 BIND_ENUM_CONSTANT(OP_LIGHTEN);
2550 BIND_ENUM_CONSTANT(OP_OVERLAY);
2551 BIND_ENUM_CONSTANT(OP_DODGE);
2552 BIND_ENUM_CONSTANT(OP_BURN);
2553 BIND_ENUM_CONSTANT(OP_SOFT_LIGHT);
2554 BIND_ENUM_CONSTANT(OP_HARD_LIGHT);
2555 BIND_ENUM_CONSTANT(OP_MAX);
2556}
2557
2558VisualShaderNodeColorOp::VisualShaderNodeColorOp() {
2559 set_input_port_default_value(0, Vector3());
2560 set_input_port_default_value(1, Vector3());
2561}
2562
2563////////////// Transform Op
2564
2565String VisualShaderNodeTransformOp::get_caption() const {
2566 return "TransformOp";
2567}
2568
2569int VisualShaderNodeTransformOp::get_input_port_count() const {
2570 return 2;
2571}
2572
2573VisualShaderNodeTransformOp::PortType VisualShaderNodeTransformOp::get_input_port_type(int p_port) const {
2574 return PORT_TYPE_TRANSFORM;
2575}
2576
2577String VisualShaderNodeTransformOp::get_input_port_name(int p_port) const {
2578 return p_port == 0 ? "a" : "b";
2579}
2580
2581int VisualShaderNodeTransformOp::get_output_port_count() const {
2582 return 1;
2583}
2584
2585VisualShaderNodeTransformOp::PortType VisualShaderNodeTransformOp::get_output_port_type(int p_port) const {
2586 return PORT_TYPE_TRANSFORM;
2587}
2588
2589String VisualShaderNodeTransformOp::get_output_port_name(int p_port) const {
2590 return "mult"; //no output port means the editor will be used as port
2591}
2592
2593String VisualShaderNodeTransformOp::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 {
2594 switch (op) {
2595 case OP_AxB:
2596 return " " + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
2597 case OP_BxA:
2598 return " " + p_output_vars[0] + " = " + p_input_vars[1] + " * " + p_input_vars[0] + ";\n";
2599 case OP_AxB_COMP:
2600 return " " + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
2601 case OP_BxA_COMP:
2602 return " " + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[1] + ", " + p_input_vars[0] + ");\n";
2603 case OP_ADD:
2604 return " " + p_output_vars[0] + " = " + p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
2605 case OP_A_MINUS_B:
2606 return " " + p_output_vars[0] + " = " + p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
2607 case OP_B_MINUS_A:
2608 return " " + p_output_vars[0] + " = " + p_input_vars[1] + " - " + p_input_vars[0] + ";\n";
2609 case OP_A_DIV_B:
2610 return " " + p_output_vars[0] + " = " + p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
2611 case OP_B_DIV_A:
2612 return " " + p_output_vars[0] + " = " + p_input_vars[1] + " / " + p_input_vars[0] + ";\n";
2613 default:
2614 return "";
2615 }
2616}
2617
2618void VisualShaderNodeTransformOp::set_operator(Operator p_op) {
2619 ERR_FAIL_INDEX(int(p_op), int(OP_MAX));
2620 if (op == p_op) {
2621 return;
2622 }
2623 op = p_op;
2624 emit_changed();
2625}
2626
2627VisualShaderNodeTransformOp::Operator VisualShaderNodeTransformOp::get_operator() const {
2628 return op;
2629}
2630
2631Vector<StringName> VisualShaderNodeTransformOp::get_editable_properties() const {
2632 Vector<StringName> props;
2633 props.push_back("operator");
2634 return props;
2635}
2636
2637void VisualShaderNodeTransformOp::_bind_methods() {
2638 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformOp::set_operator);
2639 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformOp::get_operator);
2640
2641 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B(per component),B x A(per component),A + B,A - B,B - A,A / B,B / A"), "set_operator", "get_operator");
2642
2643 BIND_ENUM_CONSTANT(OP_AxB);
2644 BIND_ENUM_CONSTANT(OP_BxA);
2645 BIND_ENUM_CONSTANT(OP_AxB_COMP);
2646 BIND_ENUM_CONSTANT(OP_BxA_COMP);
2647 BIND_ENUM_CONSTANT(OP_ADD);
2648 BIND_ENUM_CONSTANT(OP_A_MINUS_B);
2649 BIND_ENUM_CONSTANT(OP_B_MINUS_A);
2650 BIND_ENUM_CONSTANT(OP_A_DIV_B);
2651 BIND_ENUM_CONSTANT(OP_B_DIV_A);
2652 BIND_ENUM_CONSTANT(OP_MAX);
2653}
2654
2655VisualShaderNodeTransformOp::VisualShaderNodeTransformOp() {
2656 set_input_port_default_value(0, Transform3D());
2657 set_input_port_default_value(1, Transform3D());
2658}
2659
2660////////////// TransformVec Mult
2661
2662String VisualShaderNodeTransformVecMult::get_caption() const {
2663 return "TransformVectorMult";
2664}
2665
2666int VisualShaderNodeTransformVecMult::get_input_port_count() const {
2667 return 2;
2668}
2669
2670VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const {
2671 return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR_3D;
2672}
2673
2674String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
2675 return p_port == 0 ? "a" : "b";
2676}
2677
2678int VisualShaderNodeTransformVecMult::get_output_port_count() const {
2679 return 1;
2680}
2681
2682VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const {
2683 return PORT_TYPE_VECTOR_3D;
2684}
2685
2686String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const {
2687 return ""; //no output port means the editor will be used as port
2688}
2689
2690String VisualShaderNodeTransformVecMult::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 {
2691 if (op == OP_AxB) {
2692 return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0)).xyz;\n";
2693 } else if (op == OP_BxA) {
2694 return " " + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 1.0) * " + p_input_vars[0] + ").xyz;\n";
2695 } else if (op == OP_3x3_AxB) {
2696 return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 0.0)).xyz;\n";
2697 } else {
2698 return " " + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 0.0) * " + p_input_vars[0] + ").xyz;\n";
2699 }
2700}
2701
2702void VisualShaderNodeTransformVecMult::set_operator(Operator p_op) {
2703 ERR_FAIL_INDEX(int(p_op), int(OP_MAX));
2704 if (op == p_op) {
2705 return;
2706 }
2707 op = p_op;
2708 emit_changed();
2709}
2710
2711VisualShaderNodeTransformVecMult::Operator VisualShaderNodeTransformVecMult::get_operator() const {
2712 return op;
2713}
2714
2715Vector<StringName> VisualShaderNodeTransformVecMult::get_editable_properties() const {
2716 Vector<StringName> props;
2717 props.push_back("operator");
2718 return props;
2719}
2720
2721void VisualShaderNodeTransformVecMult::_bind_methods() {
2722 ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformVecMult::set_operator);
2723 ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformVecMult::get_operator);
2724
2725 ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B (3x3),B x A (3x3)"), "set_operator", "get_operator");
2726
2727 BIND_ENUM_CONSTANT(OP_AxB);
2728 BIND_ENUM_CONSTANT(OP_BxA);
2729 BIND_ENUM_CONSTANT(OP_3x3_AxB);
2730 BIND_ENUM_CONSTANT(OP_3x3_BxA);
2731 BIND_ENUM_CONSTANT(OP_MAX);
2732}
2733
2734VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() {
2735 set_input_port_default_value(0, Transform3D());
2736 set_input_port_default_value(1, Vector3());
2737}
2738
2739////////////// Float Func
2740
2741String VisualShaderNodeFloatFunc::get_caption() const {
2742 return "FloatFunc";
2743}
2744
2745int VisualShaderNodeFloatFunc::get_input_port_count() const {
2746 return 1;
2747}
2748
2749VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_input_port_type(int p_port) const {
2750 return PORT_TYPE_SCALAR;
2751}
2752
2753String VisualShaderNodeFloatFunc::get_input_port_name(int p_port) const {
2754 return "";
2755}
2756
2757int VisualShaderNodeFloatFunc::get_output_port_count() const {
2758 return 1;
2759}
2760
2761VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_output_port_type(int p_port) const {
2762 return PORT_TYPE_SCALAR;
2763}
2764
2765String VisualShaderNodeFloatFunc::get_output_port_name(int p_port) const {
2766 return ""; //no output port means the editor will be used as port
2767}
2768
2769String VisualShaderNodeFloatFunc::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 {
2770 static const char *functions[FUNC_MAX] = {
2771 "sin($)",
2772 "cos($)",
2773 "tan($)",
2774 "asin($)",
2775 "acos($)",
2776 "atan($)",
2777 "sinh($)",
2778 "cosh($)",
2779 "tanh($)",
2780 "log($)",
2781 "exp($)",
2782 "sqrt($)",
2783 "abs($)",
2784 "sign($)",
2785 "floor($)",
2786 "round($)",
2787 "ceil($)",
2788 "fract($)",
2789 "min(max($, 0.0), 1.0)",
2790 "-($)",
2791 "acosh($)",
2792 "asinh($)",
2793 "atanh($)",
2794 "degrees($)",
2795 "exp2($)",
2796 "inversesqrt($)",
2797 "log2($)",
2798 "radians($)",
2799 "1.0 / ($)",
2800 "roundEven($)",
2801 "trunc($)",
2802 "1.0 - $"
2803 };
2804 return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
2805}
2806
2807void VisualShaderNodeFloatFunc::set_function(Function p_func) {
2808 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
2809 if (func == p_func) {
2810 return;
2811 }
2812 func = p_func;
2813 emit_changed();
2814}
2815
2816VisualShaderNodeFloatFunc::Function VisualShaderNodeFloatFunc::get_function() const {
2817 return func;
2818}
2819
2820Vector<StringName> VisualShaderNodeFloatFunc::get_editable_properties() const {
2821 Vector<StringName> props;
2822 props.push_back("function");
2823 return props;
2824}
2825
2826void VisualShaderNodeFloatFunc::_bind_methods() {
2827 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeFloatFunc::set_function);
2828 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeFloatFunc::get_function);
2829
2830 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Fract,Saturate,Negate,ACosH,ASinH,ATanH,Degrees,Exp2,InverseSqrt,Log2,Radians,Reciprocal,RoundEven,Trunc,OneMinus"), "set_function", "get_function");
2831
2832 BIND_ENUM_CONSTANT(FUNC_SIN);
2833 BIND_ENUM_CONSTANT(FUNC_COS);
2834 BIND_ENUM_CONSTANT(FUNC_TAN);
2835 BIND_ENUM_CONSTANT(FUNC_ASIN);
2836 BIND_ENUM_CONSTANT(FUNC_ACOS);
2837 BIND_ENUM_CONSTANT(FUNC_ATAN);
2838 BIND_ENUM_CONSTANT(FUNC_SINH);
2839 BIND_ENUM_CONSTANT(FUNC_COSH);
2840 BIND_ENUM_CONSTANT(FUNC_TANH);
2841 BIND_ENUM_CONSTANT(FUNC_LOG);
2842 BIND_ENUM_CONSTANT(FUNC_EXP);
2843 BIND_ENUM_CONSTANT(FUNC_SQRT);
2844 BIND_ENUM_CONSTANT(FUNC_ABS);
2845 BIND_ENUM_CONSTANT(FUNC_SIGN);
2846 BIND_ENUM_CONSTANT(FUNC_FLOOR);
2847 BIND_ENUM_CONSTANT(FUNC_ROUND);
2848 BIND_ENUM_CONSTANT(FUNC_CEIL);
2849 BIND_ENUM_CONSTANT(FUNC_FRACT);
2850 BIND_ENUM_CONSTANT(FUNC_SATURATE);
2851 BIND_ENUM_CONSTANT(FUNC_NEGATE);
2852 BIND_ENUM_CONSTANT(FUNC_ACOSH);
2853 BIND_ENUM_CONSTANT(FUNC_ASINH);
2854 BIND_ENUM_CONSTANT(FUNC_ATANH);
2855 BIND_ENUM_CONSTANT(FUNC_DEGREES);
2856 BIND_ENUM_CONSTANT(FUNC_EXP2);
2857 BIND_ENUM_CONSTANT(FUNC_INVERSE_SQRT);
2858 BIND_ENUM_CONSTANT(FUNC_LOG2);
2859 BIND_ENUM_CONSTANT(FUNC_RADIANS);
2860 BIND_ENUM_CONSTANT(FUNC_RECIPROCAL);
2861 BIND_ENUM_CONSTANT(FUNC_ROUNDEVEN);
2862 BIND_ENUM_CONSTANT(FUNC_TRUNC);
2863 BIND_ENUM_CONSTANT(FUNC_ONEMINUS);
2864 BIND_ENUM_CONSTANT(FUNC_MAX);
2865}
2866
2867VisualShaderNodeFloatFunc::VisualShaderNodeFloatFunc() {
2868 set_input_port_default_value(0, 0.0);
2869}
2870
2871////////////// Int Func
2872
2873String VisualShaderNodeIntFunc::get_caption() const {
2874 return "IntFunc";
2875}
2876
2877int VisualShaderNodeIntFunc::get_input_port_count() const {
2878 return 1;
2879}
2880
2881VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(int p_port) const {
2882 return PORT_TYPE_SCALAR_INT;
2883}
2884
2885String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const {
2886 return "";
2887}
2888
2889int VisualShaderNodeIntFunc::get_output_port_count() const {
2890 return 1;
2891}
2892
2893VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_output_port_type(int p_port) const {
2894 return PORT_TYPE_SCALAR_INT;
2895}
2896
2897String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const {
2898 return ""; //no output port means the editor will be used as port
2899}
2900
2901String VisualShaderNodeIntFunc::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 {
2902 static const char *functions[FUNC_MAX] = {
2903 "abs($)",
2904 "-($)",
2905 "sign($)",
2906 "~($)"
2907 };
2908
2909 return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
2910}
2911
2912void VisualShaderNodeIntFunc::set_function(Function p_func) {
2913 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
2914 if (func == p_func) {
2915 return;
2916 }
2917 func = p_func;
2918 emit_changed();
2919}
2920
2921VisualShaderNodeIntFunc::Function VisualShaderNodeIntFunc::get_function() const {
2922 return func;
2923}
2924
2925Vector<StringName> VisualShaderNodeIntFunc::get_editable_properties() const {
2926 Vector<StringName> props;
2927 props.push_back("function");
2928 return props;
2929}
2930
2931void VisualShaderNodeIntFunc::_bind_methods() {
2932 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function);
2933 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function);
2934
2935 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign,Bitwise NOT"), "set_function", "get_function");
2936
2937 BIND_ENUM_CONSTANT(FUNC_ABS);
2938 BIND_ENUM_CONSTANT(FUNC_NEGATE);
2939 BIND_ENUM_CONSTANT(FUNC_SIGN);
2940 BIND_ENUM_CONSTANT(FUNC_BITWISE_NOT);
2941 BIND_ENUM_CONSTANT(FUNC_MAX);
2942}
2943
2944VisualShaderNodeIntFunc::VisualShaderNodeIntFunc() {
2945 set_input_port_default_value(0, 0);
2946}
2947
2948////////////// Unsigned Int Func
2949
2950String VisualShaderNodeUIntFunc::get_caption() const {
2951 return "UIntFunc";
2952}
2953
2954int VisualShaderNodeUIntFunc::get_input_port_count() const {
2955 return 1;
2956}
2957
2958VisualShaderNodeUIntFunc::PortType VisualShaderNodeUIntFunc::get_input_port_type(int p_port) const {
2959 return PORT_TYPE_SCALAR_UINT;
2960}
2961
2962String VisualShaderNodeUIntFunc::get_input_port_name(int p_port) const {
2963 return "";
2964}
2965
2966int VisualShaderNodeUIntFunc::get_output_port_count() const {
2967 return 1;
2968}
2969
2970VisualShaderNodeUIntFunc::PortType VisualShaderNodeUIntFunc::get_output_port_type(int p_port) const {
2971 return PORT_TYPE_SCALAR_UINT;
2972}
2973
2974String VisualShaderNodeUIntFunc::get_output_port_name(int p_port) const {
2975 return ""; // No output port means the editor will be used as port.
2976}
2977
2978String VisualShaderNodeUIntFunc::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 {
2979 static const char *functions[FUNC_MAX] = {
2980 "-($)",
2981 "~($)"
2982 };
2983
2984 return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
2985}
2986
2987void VisualShaderNodeUIntFunc::set_function(Function p_func) {
2988 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
2989 if (func == p_func) {
2990 return;
2991 }
2992 func = p_func;
2993 emit_changed();
2994}
2995
2996VisualShaderNodeUIntFunc::Function VisualShaderNodeUIntFunc::get_function() const {
2997 return func;
2998}
2999
3000Vector<StringName> VisualShaderNodeUIntFunc::get_editable_properties() const {
3001 Vector<StringName> props;
3002 props.push_back("function");
3003 return props;
3004}
3005
3006void VisualShaderNodeUIntFunc::_bind_methods() {
3007 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeUIntFunc::set_function);
3008 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeUIntFunc::get_function);
3009
3010 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Negate,Bitwise NOT"), "set_function", "get_function");
3011
3012 BIND_ENUM_CONSTANT(FUNC_NEGATE);
3013 BIND_ENUM_CONSTANT(FUNC_BITWISE_NOT);
3014 BIND_ENUM_CONSTANT(FUNC_MAX);
3015}
3016
3017VisualShaderNodeUIntFunc::VisualShaderNodeUIntFunc() {
3018 set_input_port_default_value(0, 0);
3019}
3020
3021////////////// Vector Func
3022
3023String VisualShaderNodeVectorFunc::get_caption() const {
3024 return "VectorFunc";
3025}
3026
3027int VisualShaderNodeVectorFunc::get_input_port_count() const {
3028 return 1;
3029}
3030
3031String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
3032 return "";
3033}
3034
3035int VisualShaderNodeVectorFunc::get_output_port_count() const {
3036 return 1;
3037}
3038
3039String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
3040 return "result";
3041}
3042
3043String VisualShaderNodeVectorFunc::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 {
3044 static const char *funcs[FUNC_MAX] = {
3045 "normalize($)",
3046 "", // FUNC_SATURATE
3047 "-($)",
3048 "1.0 / ($)",
3049 "abs($)",
3050 "acos($)",
3051 "acosh($)",
3052 "asin($)",
3053 "asinh($)",
3054 "atan($)",
3055 "atanh($)",
3056 "ceil($)",
3057 "cos($)",
3058 "cosh($)",
3059 "degrees($)",
3060 "exp($)",
3061 "exp2($)",
3062 "floor($)",
3063 "fract($)",
3064 "inversesqrt($)",
3065 "log($)",
3066 "log2($)",
3067 "radians($)",
3068 "round($)",
3069 "roundEven($)",
3070 "sign($)",
3071 "sin($)",
3072 "sinh($)",
3073 "sqrt($)",
3074 "tan($)",
3075 "tanh($)",
3076 "trunc($)",
3077 "" // FUNC_ONEMINUS
3078 };
3079
3080 if (func == FUNC_SATURATE) {
3081 String code;
3082
3083 if (op_type == OP_TYPE_VECTOR_2D) {
3084 code = "max(min($, vec2(1.0)), vec2(0.0))";
3085 } else if (op_type == OP_TYPE_VECTOR_3D) {
3086 code = "max(min($, vec3(1.0)), vec3(0.0))";
3087 } else {
3088 code = "max(min($, vec4(1.0)), vec4(0.0))";
3089 }
3090 return " " + p_output_vars[0] + " = " + code.replace("$", p_input_vars[0]) + ";\n";
3091 }
3092
3093 if (func == FUNC_ONEMINUS) {
3094 String code;
3095
3096 if (op_type == OP_TYPE_VECTOR_2D) {
3097 code = "vec2(1.0) - $";
3098 } else if (op_type == OP_TYPE_VECTOR_3D) {
3099 code = "vec3(1.0) - $";
3100 } else {
3101 code = "vec4(1.0) - $";
3102 }
3103 return " " + p_output_vars[0] + " = " + code.replace("$", p_input_vars[0]) + ";\n";
3104 }
3105
3106 return " " + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n";
3107}
3108
3109void VisualShaderNodeVectorFunc::set_op_type(OpType p_op_type) {
3110 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
3111 if (op_type == p_op_type) {
3112 return;
3113 }
3114 switch (p_op_type) {
3115 case OP_TYPE_VECTOR_2D: {
3116 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
3117 } break;
3118 case OP_TYPE_VECTOR_3D: {
3119 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
3120 } break;
3121 case OP_TYPE_VECTOR_4D: {
3122 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
3123 } break;
3124 default:
3125 break;
3126 }
3127 op_type = p_op_type;
3128 emit_changed();
3129}
3130
3131void VisualShaderNodeVectorFunc::set_function(Function p_func) {
3132 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
3133 if (func == p_func) {
3134 return;
3135 }
3136 func = p_func;
3137 emit_changed();
3138}
3139
3140VisualShaderNodeVectorFunc::Function VisualShaderNodeVectorFunc::get_function() const {
3141 return func;
3142}
3143
3144Vector<StringName> VisualShaderNodeVectorFunc::get_editable_properties() const {
3145 Vector<StringName> props = VisualShaderNodeVectorBase::get_editable_properties();
3146 props.push_back("function");
3147 return props;
3148}
3149
3150void VisualShaderNodeVectorFunc::_bind_methods() {
3151 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function);
3152 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function);
3153
3154 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Normalize,Saturate,Negate,Reciprocal,Abs,ACos,ACosH,ASin,ASinH,ATan,ATanH,Ceil,Cos,CosH,Degrees,Exp,Exp2,Floor,Fract,InverseSqrt,Log,Log2,Radians,Round,RoundEven,Sign,Sin,SinH,Sqrt,Tan,TanH,Trunc,OneMinus"), "set_function", "get_function");
3155
3156 BIND_ENUM_CONSTANT(FUNC_NORMALIZE);
3157 BIND_ENUM_CONSTANT(FUNC_SATURATE);
3158 BIND_ENUM_CONSTANT(FUNC_NEGATE);
3159 BIND_ENUM_CONSTANT(FUNC_RECIPROCAL);
3160 BIND_ENUM_CONSTANT(FUNC_ABS);
3161 BIND_ENUM_CONSTANT(FUNC_ACOS);
3162 BIND_ENUM_CONSTANT(FUNC_ACOSH);
3163 BIND_ENUM_CONSTANT(FUNC_ASIN);
3164 BIND_ENUM_CONSTANT(FUNC_ASINH);
3165 BIND_ENUM_CONSTANT(FUNC_ATAN);
3166 BIND_ENUM_CONSTANT(FUNC_ATANH);
3167 BIND_ENUM_CONSTANT(FUNC_CEIL);
3168 BIND_ENUM_CONSTANT(FUNC_COS);
3169 BIND_ENUM_CONSTANT(FUNC_COSH);
3170 BIND_ENUM_CONSTANT(FUNC_DEGREES);
3171 BIND_ENUM_CONSTANT(FUNC_EXP);
3172 BIND_ENUM_CONSTANT(FUNC_EXP2);
3173 BIND_ENUM_CONSTANT(FUNC_FLOOR);
3174 BIND_ENUM_CONSTANT(FUNC_FRACT);
3175 BIND_ENUM_CONSTANT(FUNC_INVERSE_SQRT);
3176 BIND_ENUM_CONSTANT(FUNC_LOG);
3177 BIND_ENUM_CONSTANT(FUNC_LOG2);
3178 BIND_ENUM_CONSTANT(FUNC_RADIANS);
3179 BIND_ENUM_CONSTANT(FUNC_ROUND);
3180 BIND_ENUM_CONSTANT(FUNC_ROUNDEVEN);
3181 BIND_ENUM_CONSTANT(FUNC_SIGN);
3182 BIND_ENUM_CONSTANT(FUNC_SIN);
3183 BIND_ENUM_CONSTANT(FUNC_SINH);
3184 BIND_ENUM_CONSTANT(FUNC_SQRT);
3185 BIND_ENUM_CONSTANT(FUNC_TAN);
3186 BIND_ENUM_CONSTANT(FUNC_TANH);
3187 BIND_ENUM_CONSTANT(FUNC_TRUNC);
3188 BIND_ENUM_CONSTANT(FUNC_ONEMINUS);
3189 BIND_ENUM_CONSTANT(FUNC_MAX);
3190}
3191
3192VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() {
3193 switch (op_type) {
3194 case OP_TYPE_VECTOR_2D: {
3195 set_input_port_default_value(0, Vector2());
3196 } break;
3197 case OP_TYPE_VECTOR_3D: {
3198 set_input_port_default_value(0, Vector3());
3199 } break;
3200 case OP_TYPE_VECTOR_4D: {
3201 set_input_port_default_value(0, Quaternion());
3202 } break;
3203 default:
3204 break;
3205 }
3206}
3207
3208////////////// ColorFunc
3209
3210String VisualShaderNodeColorFunc::get_caption() const {
3211 return "ColorFunc";
3212}
3213
3214int VisualShaderNodeColorFunc::get_input_port_count() const {
3215 return 1;
3216}
3217
3218VisualShaderNodeColorFunc::PortType VisualShaderNodeColorFunc::get_input_port_type(int p_port) const {
3219 return PORT_TYPE_VECTOR_3D;
3220}
3221
3222String VisualShaderNodeColorFunc::get_input_port_name(int p_port) const {
3223 return "";
3224}
3225
3226int VisualShaderNodeColorFunc::get_output_port_count() const {
3227 return 1;
3228}
3229
3230VisualShaderNodeColorFunc::PortType VisualShaderNodeColorFunc::get_output_port_type(int p_port) const {
3231 return PORT_TYPE_VECTOR_3D;
3232}
3233
3234String VisualShaderNodeColorFunc::get_output_port_name(int p_port) const {
3235 return "";
3236}
3237
3238String VisualShaderNodeColorFunc::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 {
3239 String code;
3240
3241 switch (func) {
3242 case FUNC_GRAYSCALE:
3243 code += " {\n";
3244 code += " vec3 c = " + p_input_vars[0] + ";\n";
3245 code += " float max1 = max(c.r, c.g);\n";
3246 code += " float max2 = max(max1, c.b);\n";
3247 code += " " + p_output_vars[0] + " = vec3(max2, max2, max2);\n";
3248 code += " }\n";
3249 break;
3250 case FUNC_HSV2RGB:
3251 code += " {\n";
3252 code += " vec3 c = " + p_input_vars[0] + ";\n";
3253 code += " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n";
3254 code += " vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n";
3255 code += " " + p_output_vars[0] + " = c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n";
3256 code += " }\n";
3257 break;
3258 case FUNC_RGB2HSV:
3259 code += " {\n";
3260 code += " vec3 c = " + p_input_vars[0] + ";\n";
3261 code += " vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n";
3262 code += " vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n";
3263 code += " vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n";
3264 code += " float d = q.x - min(q.w, q.y);\n";
3265 code += " float e = 1.0e-10;\n";
3266 code += " " + p_output_vars[0] + " = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n";
3267 code += " }\n";
3268 break;
3269 case FUNC_SEPIA:
3270 code += " {\n";
3271 code += " vec3 c = " + p_input_vars[0] + ";\n";
3272 code += " float r = (c.r * .393) + (c.g *.769) + (c.b * .189);\n";
3273 code += " float g = (c.r * .349) + (c.g *.686) + (c.b * .168);\n";
3274 code += " float b = (c.r * .272) + (c.g *.534) + (c.b * .131);\n";
3275 code += " " + p_output_vars[0] + " = vec3(r, g, b);\n";
3276 code += " }\n";
3277 break;
3278 default:
3279 break;
3280 }
3281
3282 return code;
3283}
3284
3285void VisualShaderNodeColorFunc::set_function(Function p_func) {
3286 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
3287 if (func == p_func) {
3288 return;
3289 }
3290 func = p_func;
3291 emit_changed();
3292}
3293
3294VisualShaderNodeColorFunc::Function VisualShaderNodeColorFunc::get_function() const {
3295 return func;
3296}
3297
3298Vector<StringName> VisualShaderNodeColorFunc::get_editable_properties() const {
3299 Vector<StringName> props;
3300 props.push_back("function");
3301 return props;
3302}
3303
3304void VisualShaderNodeColorFunc::_bind_methods() {
3305 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeColorFunc::set_function);
3306 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeColorFunc::get_function);
3307
3308 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Grayscale,HSV2RGB,RGB2HSV,Sepia"), "set_function", "get_function");
3309
3310 BIND_ENUM_CONSTANT(FUNC_GRAYSCALE);
3311 BIND_ENUM_CONSTANT(FUNC_HSV2RGB);
3312 BIND_ENUM_CONSTANT(FUNC_RGB2HSV);
3313 BIND_ENUM_CONSTANT(FUNC_SEPIA);
3314 BIND_ENUM_CONSTANT(FUNC_MAX);
3315}
3316
3317VisualShaderNodeColorFunc::VisualShaderNodeColorFunc() {
3318 simple_decl = false;
3319 set_input_port_default_value(0, Vector3());
3320}
3321
3322////////////// Transform Func
3323
3324String VisualShaderNodeTransformFunc::get_caption() const {
3325 return "TransformFunc";
3326}
3327
3328int VisualShaderNodeTransformFunc::get_input_port_count() const {
3329 return 1;
3330}
3331
3332VisualShaderNodeTransformFunc::PortType VisualShaderNodeTransformFunc::get_input_port_type(int p_port) const {
3333 return PORT_TYPE_TRANSFORM;
3334}
3335
3336String VisualShaderNodeTransformFunc::get_input_port_name(int p_port) const {
3337 return "";
3338}
3339
3340int VisualShaderNodeTransformFunc::get_output_port_count() const {
3341 return 1;
3342}
3343
3344VisualShaderNodeTransformFunc::PortType VisualShaderNodeTransformFunc::get_output_port_type(int p_port) const {
3345 return PORT_TYPE_TRANSFORM;
3346}
3347
3348String VisualShaderNodeTransformFunc::get_output_port_name(int p_port) const {
3349 return "";
3350}
3351
3352String VisualShaderNodeTransformFunc::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 {
3353 static const char *functions[FUNC_MAX] = {
3354 "inverse($)",
3355 "transpose($)"
3356 };
3357
3358 String code;
3359 code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
3360 return code;
3361}
3362
3363void VisualShaderNodeTransformFunc::set_function(Function p_func) {
3364 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
3365 if (func == p_func) {
3366 return;
3367 }
3368 func = p_func;
3369 emit_changed();
3370}
3371
3372VisualShaderNodeTransformFunc::Function VisualShaderNodeTransformFunc::get_function() const {
3373 return func;
3374}
3375
3376Vector<StringName> VisualShaderNodeTransformFunc::get_editable_properties() const {
3377 Vector<StringName> props;
3378 props.push_back("function");
3379 return props;
3380}
3381
3382void VisualShaderNodeTransformFunc::_bind_methods() {
3383 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeTransformFunc::set_function);
3384 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeTransformFunc::get_function);
3385
3386 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Inverse,Transpose"), "set_function", "get_function");
3387
3388 BIND_ENUM_CONSTANT(FUNC_INVERSE);
3389 BIND_ENUM_CONSTANT(FUNC_TRANSPOSE);
3390 BIND_ENUM_CONSTANT(FUNC_MAX);
3391}
3392
3393VisualShaderNodeTransformFunc::VisualShaderNodeTransformFunc() {
3394 set_input_port_default_value(0, Transform3D());
3395}
3396
3397////////////// UV Func
3398
3399String VisualShaderNodeUVFunc::get_caption() const {
3400 return "UVFunc";
3401}
3402
3403int VisualShaderNodeUVFunc::get_input_port_count() const {
3404 return 3;
3405}
3406
3407VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_input_port_type(int p_port) const {
3408 switch (p_port) {
3409 case 0:
3410 return PORT_TYPE_VECTOR_2D; // uv
3411 case 1:
3412 return PORT_TYPE_VECTOR_2D; // scale
3413 case 2:
3414 return PORT_TYPE_VECTOR_2D; // offset & pivot
3415 default:
3416 break;
3417 }
3418 return PORT_TYPE_SCALAR;
3419}
3420
3421String VisualShaderNodeUVFunc::get_input_port_name(int p_port) const {
3422 switch (p_port) {
3423 case 0:
3424 return "uv";
3425 case 1:
3426 return "scale";
3427 case 2:
3428 switch (func) {
3429 case FUNC_PANNING:
3430 return "offset";
3431 case FUNC_SCALING:
3432 return "pivot";
3433 default:
3434 break;
3435 }
3436 break;
3437 default:
3438 break;
3439 }
3440 return "";
3441}
3442
3443bool VisualShaderNodeUVFunc::is_input_port_default(int p_port, Shader::Mode p_mode) const {
3444 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
3445 if (p_port == 0) {
3446 return true;
3447 }
3448 }
3449 return false;
3450}
3451
3452int VisualShaderNodeUVFunc::get_output_port_count() const {
3453 return 1;
3454}
3455
3456VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_output_port_type(int p_port) const {
3457 return PORT_TYPE_VECTOR_2D;
3458}
3459
3460String VisualShaderNodeUVFunc::get_output_port_name(int p_port) const {
3461 return "uv";
3462}
3463
3464bool VisualShaderNodeUVFunc::is_show_prop_names() const {
3465 return true;
3466}
3467
3468String VisualShaderNodeUVFunc::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 {
3469 String code;
3470
3471 String uv;
3472 if (p_input_vars[0].is_empty()) {
3473 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
3474 uv = "UV";
3475 } else {
3476 uv = "vec2(0.0)";
3477 }
3478 } else {
3479 uv = vformat("%s", p_input_vars[0]);
3480 }
3481 String scale = vformat("%s", p_input_vars[1]);
3482 String offset_pivot = vformat("%s", p_input_vars[2]);
3483
3484 switch (func) {
3485 case FUNC_PANNING: {
3486 code += vformat(" %s = %s * %s + %s;\n", p_output_vars[0], offset_pivot, scale, uv);
3487 } break;
3488 case FUNC_SCALING: {
3489 code += vformat(" %s = (%s - %s) * %s + %s;\n", p_output_vars[0], uv, offset_pivot, scale, offset_pivot);
3490 } break;
3491 default:
3492 break;
3493 }
3494 return code;
3495}
3496
3497void VisualShaderNodeUVFunc::set_function(VisualShaderNodeUVFunc::Function p_func) {
3498 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
3499 if (func == p_func) {
3500 return;
3501 }
3502 if (p_func == FUNC_PANNING) {
3503 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // offset
3504 } else { // FUNC_SCALING
3505 set_input_port_default_value(2, Vector2(0.5, 0.5), get_input_port_default_value(2)); // pivot
3506 }
3507 func = p_func;
3508 emit_changed();
3509}
3510
3511VisualShaderNodeUVFunc::Function VisualShaderNodeUVFunc::get_function() const {
3512 return func;
3513}
3514
3515Vector<StringName> VisualShaderNodeUVFunc::get_editable_properties() const {
3516 Vector<StringName> props;
3517 props.push_back("function");
3518 return props;
3519}
3520
3521void VisualShaderNodeUVFunc::_bind_methods() {
3522 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeUVFunc::set_function);
3523 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeUVFunc::get_function);
3524
3525 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Panning,Scaling"), "set_function", "get_function");
3526
3527 BIND_ENUM_CONSTANT(FUNC_PANNING);
3528 BIND_ENUM_CONSTANT(FUNC_SCALING);
3529 BIND_ENUM_CONSTANT(FUNC_MAX);
3530}
3531
3532VisualShaderNodeUVFunc::VisualShaderNodeUVFunc() {
3533 set_input_port_default_value(1, Vector2(1.0, 1.0)); // scale
3534 set_input_port_default_value(2, Vector2()); // offset
3535}
3536
3537////////////// UV PolarCoord
3538
3539String VisualShaderNodeUVPolarCoord::get_caption() const {
3540 return "UVPolarCoord";
3541}
3542
3543int VisualShaderNodeUVPolarCoord::get_input_port_count() const {
3544 return 4;
3545}
3546
3547VisualShaderNodeUVPolarCoord::PortType VisualShaderNodeUVPolarCoord::get_input_port_type(int p_port) const {
3548 switch (p_port) {
3549 case 0:
3550 return PORT_TYPE_VECTOR_2D; // uv
3551 case 1:
3552 return PORT_TYPE_VECTOR_2D; // center
3553 case 2:
3554 return PORT_TYPE_SCALAR; // zoom
3555 case 3:
3556 return PORT_TYPE_SCALAR; // repeat
3557 default:
3558 break;
3559 }
3560 return PORT_TYPE_SCALAR;
3561}
3562
3563String VisualShaderNodeUVPolarCoord::get_input_port_name(int p_port) const {
3564 switch (p_port) {
3565 case 0:
3566 return "uv";
3567 case 1:
3568 return "scale";
3569 case 2:
3570 return "zoom strength";
3571 case 3:
3572 return "repeat";
3573 default:
3574 break;
3575 }
3576 return "";
3577}
3578
3579bool VisualShaderNodeUVPolarCoord::is_input_port_default(int p_port, Shader::Mode p_mode) const {
3580 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
3581 if (p_port == 0) {
3582 return true;
3583 }
3584 }
3585 return false;
3586}
3587
3588int VisualShaderNodeUVPolarCoord::get_output_port_count() const {
3589 return 1;
3590}
3591
3592VisualShaderNodeUVPolarCoord::PortType VisualShaderNodeUVPolarCoord::get_output_port_type(int p_port) const {
3593 return PORT_TYPE_VECTOR_2D;
3594}
3595
3596String VisualShaderNodeUVPolarCoord::get_output_port_name(int p_port) const {
3597 return "uv";
3598}
3599
3600String VisualShaderNodeUVPolarCoord::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 {
3601 String code;
3602 code += " {\n";
3603
3604 String uv;
3605 if (p_input_vars[0].is_empty()) {
3606 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
3607 uv = "UV";
3608 } else {
3609 uv = "vec2(0.0)";
3610 }
3611 } else {
3612 uv = vformat("%s", p_input_vars[0]);
3613 }
3614 String center = vformat("%s", p_input_vars[1]);
3615 String zoom = vformat("%s", p_input_vars[2]);
3616 String repeat = vformat("%s", p_input_vars[3]);
3617
3618 if (p_mode == Shader::MODE_CANVAS_ITEM) {
3619 code += vformat(" vec2 __dir = %s - %s;\n", uv, center);
3620 code += " float __radius = length(__dir) * 2.0;\n";
3621 code += " float __angle = atan(__dir.y, __dir.x) * 1.0 / (PI * 2.0);\n";
3622 code += vformat(" %s = mod(vec2(__radius * %s, __angle * %s), 1.0);\n", p_output_vars[0], zoom, repeat);
3623 } else {
3624 code += vformat(" vec2 __dir = %s - %s;\n", uv, center);
3625 code += " float __radius = length(__dir) * 2.0;\n";
3626 code += " float __angle = atan(__dir.y, __dir.x) * 1.0 / (PI * 2.0);\n";
3627 code += vformat(" %s = vec2(__radius * %s, __angle * %s);\n", p_output_vars[0], zoom, repeat);
3628 }
3629
3630 code += " }\n";
3631 return code;
3632}
3633
3634VisualShaderNodeUVPolarCoord::VisualShaderNodeUVPolarCoord() {
3635 set_input_port_default_value(1, Vector2(0.5, 0.5)); // center
3636 set_input_port_default_value(2, 1.0); // zoom
3637 set_input_port_default_value(3, 1.0); // repeat
3638
3639 simple_decl = false;
3640}
3641
3642////////////// Dot Product
3643
3644String VisualShaderNodeDotProduct::get_caption() const {
3645 return "DotProduct";
3646}
3647
3648int VisualShaderNodeDotProduct::get_input_port_count() const {
3649 return 2;
3650}
3651
3652VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_input_port_type(int p_port) const {
3653 return PORT_TYPE_VECTOR_3D;
3654}
3655
3656String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const {
3657 return p_port == 0 ? "a" : "b";
3658}
3659
3660int VisualShaderNodeDotProduct::get_output_port_count() const {
3661 return 1;
3662}
3663
3664VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_output_port_type(int p_port) const {
3665 return PORT_TYPE_SCALAR;
3666}
3667
3668String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const {
3669 return "dot";
3670}
3671
3672String VisualShaderNodeDotProduct::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 {
3673 return " " + p_output_vars[0] + " = dot(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
3674}
3675
3676VisualShaderNodeDotProduct::VisualShaderNodeDotProduct() {
3677 set_input_port_default_value(0, Vector3());
3678 set_input_port_default_value(1, Vector3());
3679}
3680
3681////////////// Vector Len
3682
3683String VisualShaderNodeVectorLen::get_caption() const {
3684 return "VectorLen";
3685}
3686
3687int VisualShaderNodeVectorLen::get_input_port_count() const {
3688 return 1;
3689}
3690
3691String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
3692 return "";
3693}
3694
3695int VisualShaderNodeVectorLen::get_output_port_count() const {
3696 return 1;
3697}
3698
3699VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_output_port_type(int p_port) const {
3700 return PORT_TYPE_SCALAR;
3701}
3702
3703String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const {
3704 return "length";
3705}
3706
3707void VisualShaderNodeVectorLen::set_op_type(OpType p_op_type) {
3708 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
3709 if (op_type == p_op_type) {
3710 return;
3711 }
3712 switch (p_op_type) {
3713 case OP_TYPE_VECTOR_2D: {
3714 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
3715 } break;
3716 case OP_TYPE_VECTOR_3D: {
3717 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
3718 } break;
3719 case OP_TYPE_VECTOR_4D: {
3720 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
3721 } break;
3722 default:
3723 break;
3724 }
3725 op_type = p_op_type;
3726 emit_changed();
3727}
3728
3729String VisualShaderNodeVectorLen::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 {
3730 return " " + p_output_vars[0] + " = length(" + p_input_vars[0] + ");\n";
3731}
3732
3733VisualShaderNodeVectorLen::VisualShaderNodeVectorLen() {
3734 set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
3735}
3736
3737////////////// Determinant
3738
3739String VisualShaderNodeDeterminant::get_caption() const {
3740 return "Determinant";
3741}
3742
3743int VisualShaderNodeDeterminant::get_input_port_count() const {
3744 return 1;
3745}
3746
3747VisualShaderNodeDeterminant::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const {
3748 return PORT_TYPE_TRANSFORM;
3749}
3750
3751String VisualShaderNodeDeterminant::get_input_port_name(int p_port) const {
3752 return "";
3753}
3754
3755int VisualShaderNodeDeterminant::get_output_port_count() const {
3756 return 1;
3757}
3758
3759VisualShaderNodeDeterminant::PortType VisualShaderNodeDeterminant::get_output_port_type(int p_port) const {
3760 return PORT_TYPE_SCALAR;
3761}
3762
3763String VisualShaderNodeDeterminant::get_output_port_name(int p_port) const {
3764 return "";
3765}
3766
3767String VisualShaderNodeDeterminant::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 {
3768 return " " + p_output_vars[0] + " = determinant(" + p_input_vars[0] + ");\n";
3769}
3770
3771VisualShaderNodeDeterminant::VisualShaderNodeDeterminant() {
3772 set_input_port_default_value(0, Transform3D());
3773}
3774
3775////////////// Derivative Function
3776
3777String VisualShaderNodeDerivativeFunc::get_caption() const {
3778 return "DerivativeFunc";
3779}
3780
3781int VisualShaderNodeDerivativeFunc::get_input_port_count() const {
3782 return 1;
3783}
3784
3785VisualShaderNodeDerivativeFunc::PortType VisualShaderNodeDerivativeFunc::get_input_port_type(int p_port) const {
3786 switch (op_type) {
3787 case OP_TYPE_VECTOR_2D:
3788 return PORT_TYPE_VECTOR_2D;
3789 case OP_TYPE_VECTOR_3D:
3790 return PORT_TYPE_VECTOR_3D;
3791 case OP_TYPE_VECTOR_4D:
3792 return PORT_TYPE_VECTOR_4D;
3793 default:
3794 break;
3795 }
3796 return PORT_TYPE_SCALAR;
3797}
3798
3799String VisualShaderNodeDerivativeFunc::get_input_port_name(int p_port) const {
3800 return "p";
3801}
3802
3803int VisualShaderNodeDerivativeFunc::get_output_port_count() const {
3804 return 1;
3805}
3806
3807VisualShaderNodeDerivativeFunc::PortType VisualShaderNodeDerivativeFunc::get_output_port_type(int p_port) const {
3808 switch (op_type) {
3809 case OP_TYPE_VECTOR_2D:
3810 return PORT_TYPE_VECTOR_2D;
3811 case OP_TYPE_VECTOR_3D:
3812 return PORT_TYPE_VECTOR_3D;
3813 case OP_TYPE_VECTOR_4D:
3814 return PORT_TYPE_VECTOR_4D;
3815 default:
3816 break;
3817 }
3818 return PORT_TYPE_SCALAR;
3819}
3820
3821String VisualShaderNodeDerivativeFunc::get_output_port_name(int p_port) const {
3822 return "result";
3823}
3824
3825String VisualShaderNodeDerivativeFunc::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 {
3826 static const char *functions[FUNC_MAX] = {
3827 "fwidth$($)",
3828 "dFdx$($)",
3829 "dFdy$($)"
3830 };
3831
3832 static const char *precisions[PRECISION_MAX] = {
3833 "",
3834 "Coarse",
3835 "Fine"
3836 };
3837
3838 String code;
3839 if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
3840 code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", "").replace_first("$", p_input_vars[0]) + ";\n";
3841 return code;
3842 }
3843
3844 code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", String(precisions[precision])).replace_first("$", p_input_vars[0]) + ";\n";
3845 return code;
3846}
3847
3848String VisualShaderNodeDerivativeFunc::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
3849 if (precision != PRECISION_NONE && OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
3850 String precision_str;
3851 switch (precision) {
3852 case PRECISION_COARSE: {
3853 precision_str = "Coarse";
3854 } break;
3855 case PRECISION_FINE: {
3856 precision_str = "Fine";
3857 } break;
3858 default: {
3859 } break;
3860 }
3861
3862 return vformat(RTR("`%s` precision mode is not available for `gl_compatibility` profile.\nReverted to `None` precision."), precision_str);
3863 }
3864
3865 return String();
3866}
3867
3868void VisualShaderNodeDerivativeFunc::set_op_type(OpType p_op_type) {
3869 ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX));
3870 if (op_type == p_op_type) {
3871 return;
3872 }
3873 switch (p_op_type) {
3874 case OP_TYPE_SCALAR: {
3875 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
3876 } break;
3877 case OP_TYPE_VECTOR_2D: {
3878 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
3879 } break;
3880 case OP_TYPE_VECTOR_3D: {
3881 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
3882 } break;
3883 case OP_TYPE_VECTOR_4D: {
3884 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
3885 } break;
3886 default:
3887 break;
3888 }
3889 op_type = p_op_type;
3890 emit_changed();
3891}
3892
3893VisualShaderNodeDerivativeFunc::OpType VisualShaderNodeDerivativeFunc::get_op_type() const {
3894 return op_type;
3895}
3896
3897void VisualShaderNodeDerivativeFunc::set_function(Function p_func) {
3898 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
3899 if (func == p_func) {
3900 return;
3901 }
3902 func = p_func;
3903 emit_changed();
3904}
3905
3906VisualShaderNodeDerivativeFunc::Function VisualShaderNodeDerivativeFunc::get_function() const {
3907 return func;
3908}
3909
3910void VisualShaderNodeDerivativeFunc::set_precision(Precision p_precision) {
3911 ERR_FAIL_INDEX(int(p_precision), int(PRECISION_MAX));
3912 if (precision == p_precision) {
3913 return;
3914 }
3915 precision = p_precision;
3916 emit_changed();
3917}
3918
3919VisualShaderNodeDerivativeFunc::Precision VisualShaderNodeDerivativeFunc::get_precision() const {
3920 return precision;
3921}
3922
3923Vector<StringName> VisualShaderNodeDerivativeFunc::get_editable_properties() const {
3924 Vector<StringName> props;
3925 props.push_back("op_type");
3926 props.push_back("function");
3927 props.push_back("precision");
3928 return props;
3929}
3930
3931void VisualShaderNodeDerivativeFunc::_bind_methods() {
3932 ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeDerivativeFunc::set_op_type);
3933 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeDerivativeFunc::get_op_type);
3934
3935 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeDerivativeFunc::set_function);
3936 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeDerivativeFunc::get_function);
3937
3938 ClassDB::bind_method(D_METHOD("set_precision", "precision"), &VisualShaderNodeDerivativeFunc::set_precision);
3939 ClassDB::bind_method(D_METHOD("get_precision"), &VisualShaderNodeDerivativeFunc::get_precision);
3940
3941 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
3942 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function");
3943 ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_ENUM, "None,Coarse,Fine"), "set_precision", "get_precision");
3944
3945 BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
3946 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
3947 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
3948 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
3949 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
3950
3951 BIND_ENUM_CONSTANT(FUNC_SUM);
3952 BIND_ENUM_CONSTANT(FUNC_X);
3953 BIND_ENUM_CONSTANT(FUNC_Y);
3954 BIND_ENUM_CONSTANT(FUNC_MAX);
3955
3956 BIND_ENUM_CONSTANT(PRECISION_NONE);
3957 BIND_ENUM_CONSTANT(PRECISION_COARSE);
3958 BIND_ENUM_CONSTANT(PRECISION_FINE);
3959 BIND_ENUM_CONSTANT(PRECISION_MAX);
3960}
3961
3962VisualShaderNodeDerivativeFunc::VisualShaderNodeDerivativeFunc() {
3963 set_input_port_default_value(0, 0.0);
3964}
3965
3966////////////// Clamp
3967
3968String VisualShaderNodeClamp::get_caption() const {
3969 return "Clamp";
3970}
3971
3972int VisualShaderNodeClamp::get_input_port_count() const {
3973 return 3;
3974}
3975
3976VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p_port) const {
3977 switch (op_type) {
3978 case OP_TYPE_INT:
3979 return PORT_TYPE_SCALAR_INT;
3980 case OP_TYPE_UINT:
3981 return PORT_TYPE_SCALAR_UINT;
3982 case OP_TYPE_VECTOR_2D:
3983 return PORT_TYPE_VECTOR_2D;
3984 case OP_TYPE_VECTOR_3D:
3985 return PORT_TYPE_VECTOR_3D;
3986 case OP_TYPE_VECTOR_4D:
3987 return PORT_TYPE_VECTOR_4D;
3988 default:
3989 break;
3990 }
3991 return PORT_TYPE_SCALAR;
3992}
3993
3994String VisualShaderNodeClamp::get_input_port_name(int p_port) const {
3995 if (p_port == 0) {
3996 return "";
3997 } else if (p_port == 1) {
3998 return "min";
3999 } else if (p_port == 2) {
4000 return "max";
4001 }
4002 return "";
4003}
4004
4005int VisualShaderNodeClamp::get_output_port_count() const {
4006 return 1;
4007}
4008
4009VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int p_port) const {
4010 switch (op_type) {
4011 case OP_TYPE_INT:
4012 return PORT_TYPE_SCALAR_INT;
4013 case OP_TYPE_UINT:
4014 return PORT_TYPE_SCALAR_UINT;
4015 case OP_TYPE_VECTOR_2D:
4016 return PORT_TYPE_VECTOR_2D;
4017 case OP_TYPE_VECTOR_3D:
4018 return PORT_TYPE_VECTOR_3D;
4019 case OP_TYPE_VECTOR_4D:
4020 return PORT_TYPE_VECTOR_4D;
4021 default:
4022 break;
4023 }
4024 return PORT_TYPE_SCALAR;
4025}
4026
4027String VisualShaderNodeClamp::get_output_port_name(int p_port) const {
4028 return "";
4029}
4030
4031String VisualShaderNodeClamp::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 {
4032 return " " + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
4033}
4034
4035void VisualShaderNodeClamp::set_op_type(OpType p_op_type) {
4036 ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX));
4037 if (op_type == p_op_type) {
4038 return;
4039 }
4040 switch (p_op_type) {
4041 case OP_TYPE_FLOAT:
4042 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
4043 set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
4044 set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
4045 break;
4046 case OP_TYPE_UINT:
4047 case OP_TYPE_INT:
4048 set_input_port_default_value(0, 0, get_input_port_default_value(0));
4049 set_input_port_default_value(1, 0, get_input_port_default_value(1));
4050 set_input_port_default_value(2, 0, get_input_port_default_value(2));
4051 break;
4052 case OP_TYPE_VECTOR_2D:
4053 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
4054 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
4055 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
4056 break;
4057 case OP_TYPE_VECTOR_3D:
4058 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
4059 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
4060 set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
4061 break;
4062 case OP_TYPE_VECTOR_4D:
4063 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
4064 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
4065 set_input_port_default_value(2, Quaternion(), get_input_port_default_value(2));
4066 break;
4067 default:
4068 break;
4069 }
4070 op_type = p_op_type;
4071 emit_changed();
4072}
4073
4074VisualShaderNodeClamp::OpType VisualShaderNodeClamp::get_op_type() const {
4075 return op_type;
4076}
4077
4078Vector<StringName> VisualShaderNodeClamp::get_editable_properties() const {
4079 Vector<StringName> props;
4080 props.push_back("op_type");
4081 return props;
4082}
4083
4084void VisualShaderNodeClamp::_bind_methods() {
4085 ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeClamp::set_op_type);
4086 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeClamp::get_op_type);
4087
4088 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,UInt,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
4089
4090 BIND_ENUM_CONSTANT(OP_TYPE_FLOAT);
4091 BIND_ENUM_CONSTANT(OP_TYPE_INT);
4092 BIND_ENUM_CONSTANT(OP_TYPE_UINT);
4093 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
4094 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
4095 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
4096 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
4097}
4098
4099VisualShaderNodeClamp::VisualShaderNodeClamp() {
4100 set_input_port_default_value(0, 0.0);
4101 set_input_port_default_value(1, 0.0);
4102 set_input_port_default_value(2, 1.0);
4103}
4104
4105////////////// FaceForward
4106
4107String VisualShaderNodeFaceForward::get_caption() const {
4108 return "FaceForward";
4109}
4110
4111int VisualShaderNodeFaceForward::get_input_port_count() const {
4112 return 3;
4113}
4114
4115String VisualShaderNodeFaceForward::get_input_port_name(int p_port) const {
4116 switch (p_port) {
4117 case 0:
4118 return "N";
4119 case 1:
4120 return "I";
4121 case 2:
4122 return "Nref";
4123 default:
4124 return "";
4125 }
4126}
4127
4128int VisualShaderNodeFaceForward::get_output_port_count() const {
4129 return 1;
4130}
4131
4132String VisualShaderNodeFaceForward::get_output_port_name(int p_port) const {
4133 return "";
4134}
4135
4136void VisualShaderNodeFaceForward::set_op_type(OpType p_op_type) {
4137 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4138 if (op_type == p_op_type) {
4139 return;
4140 }
4141 switch (p_op_type) {
4142 case OP_TYPE_VECTOR_2D: {
4143 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
4144 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
4145 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
4146 } break;
4147 case OP_TYPE_VECTOR_3D: {
4148 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
4149 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
4150 set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
4151 } break;
4152 case OP_TYPE_VECTOR_4D: {
4153 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
4154 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
4155 set_input_port_default_value(2, Quaternion(), get_input_port_default_value(2));
4156 } break;
4157 default:
4158 break;
4159 }
4160 op_type = p_op_type;
4161 emit_changed();
4162}
4163
4164String VisualShaderNodeFaceForward::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 {
4165 return " " + p_output_vars[0] + " = faceforward(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
4166}
4167
4168VisualShaderNodeFaceForward::VisualShaderNodeFaceForward() {
4169 set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
4170 set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
4171 set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
4172}
4173
4174////////////// Outer Product
4175
4176String VisualShaderNodeOuterProduct::get_caption() const {
4177 return "OuterProduct";
4178}
4179
4180int VisualShaderNodeOuterProduct::get_input_port_count() const {
4181 return 2;
4182}
4183
4184VisualShaderNodeOuterProduct::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const {
4185 return PORT_TYPE_VECTOR_3D;
4186}
4187
4188String VisualShaderNodeOuterProduct::get_input_port_name(int p_port) const {
4189 switch (p_port) {
4190 case 0:
4191 return "c";
4192 case 1:
4193 return "r";
4194 default:
4195 return "";
4196 }
4197}
4198
4199int VisualShaderNodeOuterProduct::get_output_port_count() const {
4200 return 1;
4201}
4202
4203VisualShaderNodeOuterProduct::PortType VisualShaderNodeOuterProduct::get_output_port_type(int p_port) const {
4204 return PORT_TYPE_TRANSFORM;
4205}
4206
4207String VisualShaderNodeOuterProduct::get_output_port_name(int p_port) const {
4208 return "";
4209}
4210
4211String VisualShaderNodeOuterProduct::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 {
4212 return " " + p_output_vars[0] + " = outerProduct(vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0));\n";
4213}
4214
4215VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() {
4216 set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
4217 set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
4218}
4219
4220////////////// Step
4221
4222String VisualShaderNodeStep::get_caption() const {
4223 return "Step";
4224}
4225
4226int VisualShaderNodeStep::get_input_port_count() const {
4227 return 2;
4228}
4229
4230VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const {
4231 switch (op_type) {
4232 case OP_TYPE_VECTOR_2D:
4233 return PORT_TYPE_VECTOR_2D;
4234 case OP_TYPE_VECTOR_2D_SCALAR:
4235 if (p_port == 1) {
4236 return PORT_TYPE_VECTOR_2D;
4237 }
4238 break;
4239 case OP_TYPE_VECTOR_3D:
4240 return PORT_TYPE_VECTOR_3D;
4241 case OP_TYPE_VECTOR_3D_SCALAR:
4242 if (p_port == 1) {
4243 return PORT_TYPE_VECTOR_3D;
4244 }
4245 break;
4246 case OP_TYPE_VECTOR_4D:
4247 return PORT_TYPE_VECTOR_4D;
4248 case OP_TYPE_VECTOR_4D_SCALAR:
4249 if (p_port == 1) {
4250 return PORT_TYPE_VECTOR_4D;
4251 }
4252 break;
4253 default:
4254 break;
4255 }
4256 return PORT_TYPE_SCALAR;
4257}
4258
4259String VisualShaderNodeStep::get_input_port_name(int p_port) const {
4260 switch (p_port) {
4261 case 0:
4262 return "edge";
4263 case 1:
4264 return "x";
4265 }
4266 return String();
4267}
4268
4269int VisualShaderNodeStep::get_default_input_port(PortType p_type) const {
4270 return 1;
4271}
4272
4273int VisualShaderNodeStep::get_output_port_count() const {
4274 return 1;
4275}
4276
4277VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const {
4278 switch (op_type) {
4279 case OP_TYPE_VECTOR_2D:
4280 return PORT_TYPE_VECTOR_2D;
4281 case OP_TYPE_VECTOR_2D_SCALAR:
4282 return PORT_TYPE_VECTOR_2D;
4283 case OP_TYPE_VECTOR_3D:
4284 return PORT_TYPE_VECTOR_3D;
4285 case OP_TYPE_VECTOR_3D_SCALAR:
4286 return PORT_TYPE_VECTOR_3D;
4287 case OP_TYPE_VECTOR_4D:
4288 return PORT_TYPE_VECTOR_4D;
4289 case OP_TYPE_VECTOR_4D_SCALAR:
4290 return PORT_TYPE_VECTOR_4D;
4291 default:
4292 break;
4293 }
4294 return PORT_TYPE_SCALAR;
4295}
4296
4297String VisualShaderNodeStep::get_output_port_name(int p_port) const {
4298 return "";
4299}
4300
4301void VisualShaderNodeStep::set_op_type(OpType p_op_type) {
4302 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4303 if (op_type == p_op_type) {
4304 return;
4305 }
4306 switch (p_op_type) {
4307 case OP_TYPE_SCALAR: {
4308 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
4309 set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
4310 } break;
4311 case OP_TYPE_VECTOR_2D: {
4312 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
4313 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
4314 } break;
4315 case OP_TYPE_VECTOR_2D_SCALAR: {
4316 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
4317 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
4318 } break;
4319 case OP_TYPE_VECTOR_3D: {
4320 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
4321 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
4322 } break;
4323 case OP_TYPE_VECTOR_3D_SCALAR: {
4324 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
4325 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
4326 } break;
4327 case OP_TYPE_VECTOR_4D: {
4328 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
4329 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
4330 } break;
4331 case OP_TYPE_VECTOR_4D_SCALAR: {
4332 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
4333 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
4334 } break;
4335 default:
4336 break;
4337 }
4338 op_type = p_op_type;
4339 emit_changed();
4340}
4341
4342VisualShaderNodeStep::OpType VisualShaderNodeStep::get_op_type() const {
4343 return op_type;
4344}
4345
4346String VisualShaderNodeStep::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 {
4347 return " " + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
4348}
4349
4350Vector<StringName> VisualShaderNodeStep::get_editable_properties() const {
4351 Vector<StringName> props;
4352 props.push_back("op_type");
4353 return props;
4354}
4355
4356void VisualShaderNodeStep::_bind_methods() {
4357 ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeStep::set_op_type);
4358 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeStep::get_op_type);
4359
4360 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar,Vector4,Vector4Scalar"), "set_op_type", "get_op_type");
4361
4362 BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
4363 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
4364 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR);
4365 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
4366 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR);
4367 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
4368 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D_SCALAR);
4369 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
4370}
4371
4372VisualShaderNodeStep::VisualShaderNodeStep() {
4373 set_input_port_default_value(0, 0.0);
4374 set_input_port_default_value(1, 0.0);
4375}
4376
4377////////////// SmoothStep
4378
4379String VisualShaderNodeSmoothStep::get_caption() const {
4380 return "SmoothStep";
4381}
4382
4383int VisualShaderNodeSmoothStep::get_input_port_count() const {
4384 return 3;
4385}
4386
4387VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const {
4388 switch (op_type) {
4389 case OP_TYPE_VECTOR_2D:
4390 return PORT_TYPE_VECTOR_2D;
4391 case OP_TYPE_VECTOR_2D_SCALAR:
4392 if (p_port == 2) {
4393 return PORT_TYPE_VECTOR_2D; // x
4394 }
4395 break;
4396 case OP_TYPE_VECTOR_3D:
4397 return PORT_TYPE_VECTOR_3D;
4398 case OP_TYPE_VECTOR_3D_SCALAR:
4399 if (p_port == 2) {
4400 return PORT_TYPE_VECTOR_3D; // x
4401 }
4402 break;
4403 case OP_TYPE_VECTOR_4D:
4404 return PORT_TYPE_VECTOR_4D;
4405 case OP_TYPE_VECTOR_4D_SCALAR:
4406 if (p_port == 2) {
4407 return PORT_TYPE_VECTOR_4D; // x
4408 }
4409 break;
4410 default:
4411 break;
4412 }
4413 return PORT_TYPE_SCALAR;
4414}
4415
4416String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const {
4417 switch (p_port) {
4418 case 0:
4419 return "edge0";
4420 case 1:
4421 return "edge1";
4422 case 2:
4423 return "x";
4424 }
4425 return String();
4426}
4427
4428int VisualShaderNodeSmoothStep::get_default_input_port(PortType p_type) const {
4429 return 2;
4430}
4431
4432int VisualShaderNodeSmoothStep::get_output_port_count() const {
4433 return 1;
4434}
4435
4436VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const {
4437 switch (op_type) {
4438 case OP_TYPE_VECTOR_2D:
4439 return PORT_TYPE_VECTOR_2D;
4440 case OP_TYPE_VECTOR_2D_SCALAR:
4441 return PORT_TYPE_VECTOR_2D;
4442 case OP_TYPE_VECTOR_3D:
4443 return PORT_TYPE_VECTOR_3D;
4444 case OP_TYPE_VECTOR_3D_SCALAR:
4445 return PORT_TYPE_VECTOR_3D;
4446 case OP_TYPE_VECTOR_4D:
4447 return PORT_TYPE_VECTOR_4D;
4448 case OP_TYPE_VECTOR_4D_SCALAR:
4449 return PORT_TYPE_VECTOR_4D;
4450 default:
4451 break;
4452 }
4453 return PORT_TYPE_SCALAR;
4454}
4455
4456String VisualShaderNodeSmoothStep::get_output_port_name(int p_port) const {
4457 return "";
4458}
4459
4460void VisualShaderNodeSmoothStep::set_op_type(OpType p_op_type) {
4461 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4462 if (op_type == p_op_type) {
4463 return;
4464 }
4465 switch (p_op_type) {
4466 case OP_TYPE_SCALAR:
4467 set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
4468 set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
4469 set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // x
4470 break;
4471 case OP_TYPE_VECTOR_2D:
4472 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // edge0
4473 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // edge1
4474 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // x
4475 break;
4476 case OP_TYPE_VECTOR_2D_SCALAR:
4477 set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
4478 set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
4479 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // x
4480 break;
4481 case OP_TYPE_VECTOR_3D:
4482 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // edge0
4483 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // edge1
4484 set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // x
4485 break;
4486 case OP_TYPE_VECTOR_3D_SCALAR:
4487 set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
4488 set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
4489 set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // x
4490 break;
4491 case OP_TYPE_VECTOR_4D:
4492 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0)); // edge0
4493 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1)); // edge1
4494 set_input_port_default_value(2, Quaternion(), get_input_port_default_value(2)); // x
4495 break;
4496 case OP_TYPE_VECTOR_4D_SCALAR:
4497 set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
4498 set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
4499 set_input_port_default_value(2, Quaternion(), get_input_port_default_value(2)); // x
4500 break;
4501 default:
4502 break;
4503 }
4504 op_type = p_op_type;
4505 emit_changed();
4506}
4507
4508VisualShaderNodeSmoothStep::OpType VisualShaderNodeSmoothStep::get_op_type() const {
4509 return op_type;
4510}
4511
4512String VisualShaderNodeSmoothStep::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 {
4513 return " " + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
4514}
4515
4516Vector<StringName> VisualShaderNodeSmoothStep::get_editable_properties() const {
4517 Vector<StringName> props;
4518 props.push_back("op_type");
4519 return props;
4520}
4521
4522void VisualShaderNodeSmoothStep::_bind_methods() {
4523 ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeSmoothStep::set_op_type);
4524 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSmoothStep::get_op_type);
4525
4526 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar,Vector4,Vector4Scalar"), "set_op_type", "get_op_type");
4527
4528 BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
4529 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
4530 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR);
4531 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
4532 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR);
4533 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
4534 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D_SCALAR);
4535 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
4536}
4537
4538VisualShaderNodeSmoothStep::VisualShaderNodeSmoothStep() {
4539 set_input_port_default_value(0, 0.0); // edge0
4540 set_input_port_default_value(1, 1.0); // edge1
4541 set_input_port_default_value(2, 0.5); // x
4542}
4543
4544////////////// Distance
4545
4546String VisualShaderNodeVectorDistance::get_caption() const {
4547 return "Distance";
4548}
4549
4550int VisualShaderNodeVectorDistance::get_input_port_count() const {
4551 return 2;
4552}
4553
4554String VisualShaderNodeVectorDistance::get_input_port_name(int p_port) const {
4555 switch (p_port) {
4556 case 0:
4557 return "a";
4558 case 1:
4559 return "b";
4560 }
4561 return String();
4562}
4563
4564int VisualShaderNodeVectorDistance::get_output_port_count() const {
4565 return 1;
4566}
4567
4568VisualShaderNodeVectorDistance::PortType VisualShaderNodeVectorDistance::get_output_port_type(int p_port) const {
4569 return PORT_TYPE_SCALAR;
4570}
4571
4572String VisualShaderNodeVectorDistance::get_output_port_name(int p_port) const {
4573 return "";
4574}
4575
4576void VisualShaderNodeVectorDistance::set_op_type(OpType p_op_type) {
4577 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4578 if (op_type == p_op_type) {
4579 return;
4580 }
4581 switch (p_op_type) {
4582 case OP_TYPE_VECTOR_2D: {
4583 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a
4584 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b
4585 } break;
4586 case OP_TYPE_VECTOR_3D: {
4587 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a
4588 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b
4589 } break;
4590 case OP_TYPE_VECTOR_4D: {
4591 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0)); // a
4592 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1)); // b
4593 } break;
4594 default:
4595 break;
4596 }
4597 op_type = p_op_type;
4598 emit_changed();
4599}
4600
4601String VisualShaderNodeVectorDistance::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 {
4602 return " " + p_output_vars[0] + " = distance(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
4603}
4604
4605VisualShaderNodeVectorDistance::VisualShaderNodeVectorDistance() {
4606 set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a
4607 set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // b
4608}
4609
4610////////////// Refract Vector
4611
4612String VisualShaderNodeVectorRefract::get_caption() const {
4613 return "Refract";
4614}
4615
4616int VisualShaderNodeVectorRefract::get_input_port_count() const {
4617 return 3;
4618}
4619
4620String VisualShaderNodeVectorRefract::get_input_port_name(int p_port) const {
4621 switch (p_port) {
4622 case 0:
4623 return "I";
4624 case 1:
4625 return "N";
4626 case 2:
4627 return "eta";
4628 }
4629 return String();
4630}
4631
4632int VisualShaderNodeVectorRefract::get_output_port_count() const {
4633 return 1;
4634}
4635
4636String VisualShaderNodeVectorRefract::get_output_port_name(int p_port) const {
4637 return "";
4638}
4639
4640String VisualShaderNodeVectorRefract::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 {
4641 return " " + p_output_vars[0] + " = refract(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
4642}
4643
4644void VisualShaderNodeVectorRefract::set_op_type(OpType p_op_type) {
4645 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4646 if (op_type == p_op_type) {
4647 return;
4648 }
4649 switch (p_op_type) {
4650 case OP_TYPE_VECTOR_2D: {
4651 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
4652 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
4653 } break;
4654 case OP_TYPE_VECTOR_3D: {
4655 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
4656 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
4657 } break;
4658 case OP_TYPE_VECTOR_4D: {
4659 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
4660 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
4661 } break;
4662 default:
4663 break;
4664 }
4665 op_type = p_op_type;
4666 emit_changed();
4667}
4668
4669VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() {
4670 set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
4671 set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
4672 set_input_port_default_value(2, 0.0);
4673}
4674
4675////////////// Mix
4676
4677String VisualShaderNodeMix::get_caption() const {
4678 return "Mix";
4679}
4680
4681int VisualShaderNodeMix::get_input_port_count() const {
4682 return 3;
4683}
4684
4685VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const {
4686 switch (op_type) {
4687 case OP_TYPE_VECTOR_2D:
4688 return PORT_TYPE_VECTOR_2D;
4689 case OP_TYPE_VECTOR_2D_SCALAR:
4690 if (p_port == 2) {
4691 break;
4692 }
4693 return PORT_TYPE_VECTOR_2D;
4694 case OP_TYPE_VECTOR_3D:
4695 return PORT_TYPE_VECTOR_3D;
4696 case OP_TYPE_VECTOR_3D_SCALAR:
4697 if (p_port == 2) {
4698 break;
4699 }
4700 return PORT_TYPE_VECTOR_3D;
4701 case OP_TYPE_VECTOR_4D:
4702 return PORT_TYPE_VECTOR_4D;
4703 case OP_TYPE_VECTOR_4D_SCALAR:
4704 if (p_port == 2) {
4705 break;
4706 }
4707 return PORT_TYPE_VECTOR_4D;
4708 default:
4709 break;
4710 }
4711 return PORT_TYPE_SCALAR;
4712}
4713
4714String VisualShaderNodeMix::get_input_port_name(int p_port) const {
4715 if (p_port == 0) {
4716 return "a";
4717 } else if (p_port == 1) {
4718 return "b";
4719 } else {
4720 return "weight";
4721 }
4722}
4723
4724int VisualShaderNodeMix::get_output_port_count() const {
4725 return 1;
4726}
4727
4728VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const {
4729 switch (op_type) {
4730 case OP_TYPE_VECTOR_2D:
4731 return PORT_TYPE_VECTOR_2D;
4732 case OP_TYPE_VECTOR_2D_SCALAR:
4733 return PORT_TYPE_VECTOR_2D;
4734 case OP_TYPE_VECTOR_3D:
4735 return PORT_TYPE_VECTOR_3D;
4736 case OP_TYPE_VECTOR_3D_SCALAR:
4737 return PORT_TYPE_VECTOR_3D;
4738 case OP_TYPE_VECTOR_4D:
4739 return PORT_TYPE_VECTOR_4D;
4740 case OP_TYPE_VECTOR_4D_SCALAR:
4741 return PORT_TYPE_VECTOR_4D;
4742 default:
4743 break;
4744 }
4745 return PORT_TYPE_SCALAR;
4746}
4747
4748String VisualShaderNodeMix::get_output_port_name(int p_port) const {
4749 return "mix";
4750}
4751
4752void VisualShaderNodeMix::set_op_type(OpType p_op_type) {
4753 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4754 if (op_type == p_op_type) {
4755 return;
4756 }
4757 switch (p_op_type) {
4758 case OP_TYPE_SCALAR: {
4759 set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // a
4760 set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // b
4761 set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
4762 } break;
4763 case OP_TYPE_VECTOR_2D: {
4764 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a
4765 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b
4766 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // weight
4767 } break;
4768 case OP_TYPE_VECTOR_2D_SCALAR: {
4769 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a
4770 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b
4771 set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
4772 } break;
4773 case OP_TYPE_VECTOR_3D: {
4774 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a
4775 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b
4776 set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // weight
4777 } break;
4778 case OP_TYPE_VECTOR_3D_SCALAR: {
4779 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a
4780 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b
4781 set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
4782 } break;
4783 case OP_TYPE_VECTOR_4D: {
4784 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0)); // a
4785 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1)); // b
4786 set_input_port_default_value(2, Quaternion(), get_input_port_default_value(2)); // weight
4787 } break;
4788 case OP_TYPE_VECTOR_4D_SCALAR: {
4789 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0)); // a
4790 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1)); // b
4791 set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
4792 } break;
4793 default:
4794 break;
4795 }
4796 op_type = p_op_type;
4797 emit_changed();
4798}
4799
4800VisualShaderNodeMix::OpType VisualShaderNodeMix::get_op_type() const {
4801 return op_type;
4802}
4803
4804String VisualShaderNodeMix::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 {
4805 return " " + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
4806}
4807
4808Vector<StringName> VisualShaderNodeMix::get_editable_properties() const {
4809 Vector<StringName> props;
4810 props.push_back("op_type");
4811 return props;
4812}
4813
4814void VisualShaderNodeMix::_bind_methods() {
4815 ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeMix::set_op_type);
4816 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMix::get_op_type);
4817
4818 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar,Vector4,Vector4Scalar"), "set_op_type", "get_op_type");
4819
4820 BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
4821 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
4822 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR);
4823 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
4824 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR);
4825 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
4826 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D_SCALAR);
4827 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
4828}
4829
4830VisualShaderNodeMix::VisualShaderNodeMix() {
4831 set_input_port_default_value(0, 0.0); // a
4832 set_input_port_default_value(1, 1.0); // b
4833 set_input_port_default_value(2, 0.5); // weight
4834}
4835
4836////////////// Vector Compose
4837
4838String VisualShaderNodeVectorCompose::get_caption() const {
4839 return "VectorCompose";
4840}
4841
4842int VisualShaderNodeVectorCompose::get_input_port_count() const {
4843 switch (op_type) {
4844 case OP_TYPE_VECTOR_2D:
4845 return 2;
4846 case OP_TYPE_VECTOR_3D:
4847 return 3;
4848 case OP_TYPE_VECTOR_4D:
4849 return 4;
4850 default:
4851 break;
4852 }
4853 return 0;
4854}
4855
4856VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const {
4857 return PORT_TYPE_SCALAR;
4858}
4859
4860String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
4861 switch (op_type) {
4862 case OP_TYPE_VECTOR_2D: {
4863 switch (p_port) {
4864 case 0:
4865 return "x";
4866 case 1:
4867 return "y";
4868 }
4869 } break;
4870 case OP_TYPE_VECTOR_3D: {
4871 switch (p_port) {
4872 case 0:
4873 return "x";
4874 case 1:
4875 return "y";
4876 case 2:
4877 return "z";
4878 }
4879 } break;
4880 case OP_TYPE_VECTOR_4D: {
4881 switch (p_port) {
4882 case 0:
4883 return "x";
4884 case 1:
4885 return "y";
4886 case 2:
4887 return "z";
4888 case 3:
4889 return "w";
4890 }
4891 } break;
4892 default:
4893 break;
4894 }
4895 return String();
4896}
4897
4898int VisualShaderNodeVectorCompose::get_output_port_count() const {
4899 return 1;
4900}
4901
4902String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const {
4903 return "vec";
4904}
4905
4906void VisualShaderNodeVectorCompose::set_op_type(OpType p_op_type) {
4907 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
4908 if (op_type == p_op_type) {
4909 return;
4910 }
4911 switch (p_op_type) {
4912 case OP_TYPE_VECTOR_2D: {
4913 float p1 = get_input_port_default_value(0);
4914 float p2 = get_input_port_default_value(1);
4915
4916 set_input_port_default_value(0, p1);
4917 set_input_port_default_value(1, p2);
4918 } break;
4919 case OP_TYPE_VECTOR_3D: {
4920 float p1 = get_input_port_default_value(0);
4921 float p2 = get_input_port_default_value(1);
4922
4923 set_input_port_default_value(0, p1);
4924 set_input_port_default_value(1, p2);
4925 set_input_port_default_value(2, 0.0);
4926 } break;
4927 case OP_TYPE_VECTOR_4D: {
4928 float p1 = get_input_port_default_value(0);
4929 float p2 = get_input_port_default_value(1);
4930
4931 set_input_port_default_value(0, p1);
4932 set_input_port_default_value(1, p2);
4933 set_input_port_default_value(2, 0.0);
4934 set_input_port_default_value(3, 0.0);
4935 } break;
4936 default:
4937 break;
4938 }
4939 op_type = p_op_type;
4940 emit_changed();
4941}
4942
4943String VisualShaderNodeVectorCompose::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 {
4944 String code;
4945 switch (op_type) {
4946 case OP_TYPE_VECTOR_2D: {
4947 code += " " + p_output_vars[0] + " = vec2(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
4948 } break;
4949 case OP_TYPE_VECTOR_3D: {
4950 code += " " + p_output_vars[0] + " = vec3(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
4951 } break;
4952 case OP_TYPE_VECTOR_4D: {
4953 code += " " + p_output_vars[0] + " = vec4(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ", " + p_input_vars[3] + ");\n";
4954 } break;
4955 default:
4956 break;
4957 }
4958 return code;
4959}
4960
4961VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() {
4962 set_input_port_default_value(0, 0.0);
4963 set_input_port_default_value(1, 0.0);
4964 set_input_port_default_value(2, 0.0);
4965}
4966
4967////////////// Transform Compose
4968
4969String VisualShaderNodeTransformCompose::get_caption() const {
4970 return "TransformCompose";
4971}
4972
4973int VisualShaderNodeTransformCompose::get_input_port_count() const {
4974 return 4;
4975}
4976
4977VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const {
4978 return PORT_TYPE_VECTOR_3D;
4979}
4980
4981String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
4982 if (p_port == 0) {
4983 return "x";
4984 } else if (p_port == 1) {
4985 return "y";
4986 } else if (p_port == 2) {
4987 return "z";
4988 } else {
4989 return "origin";
4990 }
4991}
4992
4993int VisualShaderNodeTransformCompose::get_output_port_count() const {
4994 return 1;
4995}
4996
4997VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_output_port_type(int p_port) const {
4998 return PORT_TYPE_TRANSFORM;
4999}
5000
5001String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const {
5002 return "xform";
5003}
5004
5005String VisualShaderNodeTransformCompose::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 {
5006 return " " + p_output_vars[0] + " = mat4(vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0), vec4(" + p_input_vars[2] + ", 0.0), vec4(" + p_input_vars[3] + ", 1.0));\n";
5007}
5008
5009VisualShaderNodeTransformCompose::VisualShaderNodeTransformCompose() {
5010 set_input_port_default_value(0, Vector3());
5011 set_input_port_default_value(1, Vector3());
5012 set_input_port_default_value(2, Vector3());
5013 set_input_port_default_value(3, Vector3());
5014}
5015
5016////////////// Vector Decompose
5017String VisualShaderNodeVectorDecompose::get_caption() const {
5018 return "VectorDecompose";
5019}
5020
5021int VisualShaderNodeVectorDecompose::get_input_port_count() const {
5022 return 1;
5023}
5024
5025String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
5026 return "vec";
5027}
5028
5029int VisualShaderNodeVectorDecompose::get_output_port_count() const {
5030 switch (op_type) {
5031 case OP_TYPE_VECTOR_2D:
5032 return 2;
5033 case OP_TYPE_VECTOR_3D:
5034 return 3;
5035 case OP_TYPE_VECTOR_4D:
5036 return 4;
5037 default:
5038 break;
5039 }
5040 return 0;
5041}
5042
5043VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const {
5044 return PORT_TYPE_SCALAR;
5045}
5046
5047String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const {
5048 switch (op_type) {
5049 case OP_TYPE_VECTOR_2D: {
5050 switch (p_port) {
5051 case 0:
5052 return "x";
5053 case 1:
5054 return "y";
5055 }
5056 } break;
5057 case OP_TYPE_VECTOR_3D: {
5058 switch (p_port) {
5059 case 0:
5060 return "x";
5061 case 1:
5062 return "y";
5063 case 2:
5064 return "z";
5065 }
5066 } break;
5067 case OP_TYPE_VECTOR_4D: {
5068 switch (p_port) {
5069 case 0:
5070 return "x";
5071 case 1:
5072 return "y";
5073 case 2:
5074 return "z";
5075 case 3:
5076 return "w";
5077 }
5078 } break;
5079 default:
5080 break;
5081 }
5082 return String();
5083}
5084
5085void VisualShaderNodeVectorDecompose::set_op_type(OpType p_op_type) {
5086 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
5087 if (op_type == p_op_type) {
5088 return;
5089 }
5090 switch (p_op_type) {
5091 case OP_TYPE_VECTOR_2D: {
5092 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
5093 } break;
5094 case OP_TYPE_VECTOR_3D: {
5095 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
5096 } break;
5097 case OP_TYPE_VECTOR_4D: {
5098 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
5099 } break;
5100 default:
5101 break;
5102 }
5103 op_type = p_op_type;
5104 emit_changed();
5105}
5106
5107String VisualShaderNodeVectorDecompose::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 {
5108 String code;
5109 switch (op_type) {
5110 case OP_TYPE_VECTOR_2D: {
5111 code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
5112 code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
5113 } break;
5114 case OP_TYPE_VECTOR_3D: {
5115 code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
5116 code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
5117 code += " " + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n";
5118 } break;
5119 case OP_TYPE_VECTOR_4D: {
5120 code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
5121 code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
5122 code += " " + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n";
5123 code += " " + p_output_vars[3] + " = " + p_input_vars[0] + ".w;\n";
5124 } break;
5125 default:
5126 break;
5127 }
5128 return code;
5129}
5130
5131VisualShaderNodeVectorDecompose::VisualShaderNodeVectorDecompose() {
5132 set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
5133}
5134
5135////////////// Transform Decompose
5136
5137String VisualShaderNodeTransformDecompose::get_caption() const {
5138 return "TransformDecompose";
5139}
5140
5141int VisualShaderNodeTransformDecompose::get_input_port_count() const {
5142 return 1;
5143}
5144
5145VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_input_port_type(int p_port) const {
5146 return PORT_TYPE_TRANSFORM;
5147}
5148
5149String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const {
5150 return "xform";
5151}
5152
5153int VisualShaderNodeTransformDecompose::get_output_port_count() const {
5154 return 4;
5155}
5156
5157VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const {
5158 return PORT_TYPE_VECTOR_3D;
5159}
5160
5161String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const {
5162 if (p_port == 0) {
5163 return "x";
5164 } else if (p_port == 1) {
5165 return "y";
5166 } else if (p_port == 2) {
5167 return "z";
5168 } else {
5169 return "origin";
5170 }
5171}
5172
5173String VisualShaderNodeTransformDecompose::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 {
5174 String code;
5175 code += " " + p_output_vars[0] + " = " + p_input_vars[0] + "[0].xyz;\n";
5176 code += " " + p_output_vars[1] + " = " + p_input_vars[0] + "[1].xyz;\n";
5177 code += " " + p_output_vars[2] + " = " + p_input_vars[0] + "[2].xyz;\n";
5178 code += " " + p_output_vars[3] + " = " + p_input_vars[0] + "[3].xyz;\n";
5179 return code;
5180}
5181
5182VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() {
5183 set_input_port_default_value(0, Transform3D());
5184}
5185
5186////////////// Float Parameter
5187
5188String VisualShaderNodeFloatParameter::get_caption() const {
5189 return "FloatParameter";
5190}
5191
5192int VisualShaderNodeFloatParameter::get_input_port_count() const {
5193 return 0;
5194}
5195
5196VisualShaderNodeFloatParameter::PortType VisualShaderNodeFloatParameter::get_input_port_type(int p_port) const {
5197 return PORT_TYPE_SCALAR;
5198}
5199
5200String VisualShaderNodeFloatParameter::get_input_port_name(int p_port) const {
5201 return String();
5202}
5203
5204int VisualShaderNodeFloatParameter::get_output_port_count() const {
5205 return 1;
5206}
5207
5208VisualShaderNodeFloatParameter::PortType VisualShaderNodeFloatParameter::get_output_port_type(int p_port) const {
5209 return PORT_TYPE_SCALAR;
5210}
5211
5212String VisualShaderNodeFloatParameter::get_output_port_name(int p_port) const {
5213 return ""; //no output port means the editor will be used as port
5214}
5215
5216String VisualShaderNodeFloatParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
5217 String code = "";
5218 if (hint == HINT_RANGE) {
5219 code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")";
5220 } else if (hint == HINT_RANGE_STEP) {
5221 code += _get_qual_str() + "uniform float " + get_parameter_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")";
5222 } else {
5223 code += _get_qual_str() + "uniform float " + get_parameter_name();
5224 }
5225 if (default_value_enabled) {
5226 code += " = " + rtos(default_value);
5227 }
5228 code += ";\n";
5229 return code;
5230}
5231
5232String VisualShaderNodeFloatParameter::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 {
5233 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
5234}
5235
5236bool VisualShaderNodeFloatParameter::is_show_prop_names() const {
5237 return true;
5238}
5239
5240bool VisualShaderNodeFloatParameter::is_use_prop_slots() const {
5241 return true;
5242}
5243
5244void VisualShaderNodeFloatParameter::set_hint(Hint p_hint) {
5245 ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX));
5246 if (hint == p_hint) {
5247 return;
5248 }
5249 hint = p_hint;
5250 emit_changed();
5251}
5252
5253VisualShaderNodeFloatParameter::Hint VisualShaderNodeFloatParameter::get_hint() const {
5254 return hint;
5255}
5256
5257void VisualShaderNodeFloatParameter::set_min(float p_value) {
5258 if (Math::is_equal_approx(hint_range_min, p_value)) {
5259 return;
5260 }
5261 hint_range_min = p_value;
5262 emit_changed();
5263}
5264
5265float VisualShaderNodeFloatParameter::get_min() const {
5266 return hint_range_min;
5267}
5268
5269void VisualShaderNodeFloatParameter::set_max(float p_value) {
5270 if (Math::is_equal_approx(hint_range_max, p_value)) {
5271 return;
5272 }
5273 hint_range_max = p_value;
5274 emit_changed();
5275}
5276
5277float VisualShaderNodeFloatParameter::get_max() const {
5278 return hint_range_max;
5279}
5280
5281void VisualShaderNodeFloatParameter::set_step(float p_value) {
5282 if (Math::is_equal_approx(hint_range_step, p_value)) {
5283 return;
5284 }
5285 hint_range_step = p_value;
5286 emit_changed();
5287}
5288
5289float VisualShaderNodeFloatParameter::get_step() const {
5290 return hint_range_step;
5291}
5292
5293void VisualShaderNodeFloatParameter::set_default_value_enabled(bool p_enabled) {
5294 if (default_value_enabled == p_enabled) {
5295 return;
5296 }
5297 default_value_enabled = p_enabled;
5298 emit_changed();
5299}
5300
5301bool VisualShaderNodeFloatParameter::is_default_value_enabled() const {
5302 return default_value_enabled;
5303}
5304
5305void VisualShaderNodeFloatParameter::set_default_value(float p_value) {
5306 if (Math::is_equal_approx(default_value, p_value)) {
5307 return;
5308 }
5309 default_value = p_value;
5310 emit_changed();
5311}
5312
5313float VisualShaderNodeFloatParameter::get_default_value() const {
5314 return default_value;
5315}
5316
5317void VisualShaderNodeFloatParameter::_bind_methods() {
5318 ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatParameter::set_hint);
5319 ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatParameter::get_hint);
5320
5321 ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatParameter::set_min);
5322 ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatParameter::get_min);
5323
5324 ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatParameter::set_max);
5325 ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatParameter::get_max);
5326
5327 ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatParameter::set_step);
5328 ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatParameter::get_step);
5329
5330 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatParameter::set_default_value_enabled);
5331 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatParameter::is_default_value_enabled);
5332
5333 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatParameter::set_default_value);
5334 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatParameter::get_default_value);
5335
5336 ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint");
5337 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min");
5338 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max"), "set_max", "get_max");
5339 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step"), "set_step", "get_step");
5340 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
5341 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_value"), "set_default_value", "get_default_value");
5342
5343 BIND_ENUM_CONSTANT(HINT_NONE);
5344 BIND_ENUM_CONSTANT(HINT_RANGE);
5345 BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
5346 BIND_ENUM_CONSTANT(HINT_MAX);
5347}
5348
5349bool VisualShaderNodeFloatParameter::is_qualifier_supported(Qualifier p_qual) const {
5350 return true; // all qualifiers are supported
5351}
5352
5353bool VisualShaderNodeFloatParameter::is_convertible_to_constant() const {
5354 return true; // conversion is allowed
5355}
5356
5357Vector<StringName> VisualShaderNodeFloatParameter::get_editable_properties() const {
5358 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
5359 props.push_back("hint");
5360 if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
5361 props.push_back("min");
5362 props.push_back("max");
5363 }
5364 if (hint == HINT_RANGE_STEP) {
5365 props.push_back("step");
5366 }
5367 props.push_back("default_value_enabled");
5368 if (default_value_enabled) {
5369 props.push_back("default_value");
5370 }
5371 return props;
5372}
5373
5374VisualShaderNodeFloatParameter::VisualShaderNodeFloatParameter() {
5375}
5376
5377////////////// Integer Parameter
5378
5379String VisualShaderNodeIntParameter::get_caption() const {
5380 return "IntParameter";
5381}
5382
5383int VisualShaderNodeIntParameter::get_input_port_count() const {
5384 return 0;
5385}
5386
5387VisualShaderNodeIntParameter::PortType VisualShaderNodeIntParameter::get_input_port_type(int p_port) const {
5388 return PORT_TYPE_SCALAR_INT;
5389}
5390
5391String VisualShaderNodeIntParameter::get_input_port_name(int p_port) const {
5392 return String();
5393}
5394
5395int VisualShaderNodeIntParameter::get_output_port_count() const {
5396 return 1;
5397}
5398
5399VisualShaderNodeIntParameter::PortType VisualShaderNodeIntParameter::get_output_port_type(int p_port) const {
5400 return PORT_TYPE_SCALAR_INT;
5401}
5402
5403String VisualShaderNodeIntParameter::get_output_port_name(int p_port) const {
5404 return ""; //no output port means the editor will be used as port
5405}
5406
5407String VisualShaderNodeIntParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
5408 String code = "";
5409 if (hint == HINT_RANGE) {
5410 code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")";
5411 } else if (hint == HINT_RANGE_STEP) {
5412 code += _get_qual_str() + "uniform int " + get_parameter_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")";
5413 } else {
5414 code += _get_qual_str() + "uniform int " + get_parameter_name();
5415 }
5416 if (default_value_enabled) {
5417 code += " = " + itos(default_value);
5418 }
5419 code += ";\n";
5420 return code;
5421}
5422
5423String VisualShaderNodeIntParameter::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 {
5424 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
5425}
5426
5427bool VisualShaderNodeIntParameter::is_show_prop_names() const {
5428 return true;
5429}
5430
5431bool VisualShaderNodeIntParameter::is_use_prop_slots() const {
5432 return true;
5433}
5434
5435void VisualShaderNodeIntParameter::set_hint(Hint p_hint) {
5436 ERR_FAIL_INDEX(int(p_hint), int(HINT_MAX));
5437 if (hint == p_hint) {
5438 return;
5439 }
5440 hint = p_hint;
5441 emit_changed();
5442}
5443
5444VisualShaderNodeIntParameter::Hint VisualShaderNodeIntParameter::get_hint() const {
5445 return hint;
5446}
5447
5448void VisualShaderNodeIntParameter::set_min(int p_value) {
5449 if (hint_range_min == p_value) {
5450 return;
5451 }
5452 hint_range_min = p_value;
5453 emit_changed();
5454}
5455
5456int VisualShaderNodeIntParameter::get_min() const {
5457 return hint_range_min;
5458}
5459
5460void VisualShaderNodeIntParameter::set_max(int p_value) {
5461 if (hint_range_max == p_value) {
5462 return;
5463 }
5464 hint_range_max = p_value;
5465 emit_changed();
5466}
5467
5468int VisualShaderNodeIntParameter::get_max() const {
5469 return hint_range_max;
5470}
5471
5472void VisualShaderNodeIntParameter::set_step(int p_value) {
5473 if (hint_range_step == p_value) {
5474 return;
5475 }
5476 hint_range_step = p_value;
5477 emit_changed();
5478}
5479
5480int VisualShaderNodeIntParameter::get_step() const {
5481 return hint_range_step;
5482}
5483
5484void VisualShaderNodeIntParameter::set_default_value_enabled(bool p_default_value_enabled) {
5485 if (default_value_enabled == p_default_value_enabled) {
5486 return;
5487 }
5488 default_value_enabled = p_default_value_enabled;
5489 emit_changed();
5490}
5491
5492bool VisualShaderNodeIntParameter::is_default_value_enabled() const {
5493 return default_value_enabled;
5494}
5495
5496void VisualShaderNodeIntParameter::set_default_value(int p_default_value) {
5497 if (default_value == p_default_value) {
5498 return;
5499 }
5500 default_value = p_default_value;
5501 emit_changed();
5502}
5503
5504int VisualShaderNodeIntParameter::get_default_value() const {
5505 return default_value;
5506}
5507
5508void VisualShaderNodeIntParameter::_bind_methods() {
5509 ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntParameter::set_hint);
5510 ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntParameter::get_hint);
5511
5512 ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntParameter::set_min);
5513 ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntParameter::get_min);
5514
5515 ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntParameter::set_max);
5516 ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntParameter::get_max);
5517
5518 ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntParameter::set_step);
5519 ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntParameter::get_step);
5520
5521 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntParameter::set_default_value_enabled);
5522 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntParameter::is_default_value_enabled);
5523
5524 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntParameter::set_default_value);
5525 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntParameter::get_default_value);
5526
5527 ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range + Step"), "set_hint", "get_hint");
5528 ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min");
5529 ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max");
5530 ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step");
5531 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
5532 ADD_PROPERTY(PropertyInfo(Variant::INT, "default_value"), "set_default_value", "get_default_value");
5533
5534 BIND_ENUM_CONSTANT(HINT_NONE);
5535 BIND_ENUM_CONSTANT(HINT_RANGE);
5536 BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
5537 BIND_ENUM_CONSTANT(HINT_MAX);
5538}
5539
5540bool VisualShaderNodeIntParameter::is_qualifier_supported(Qualifier p_qual) const {
5541 return true; // all qualifiers are supported
5542}
5543
5544bool VisualShaderNodeIntParameter::is_convertible_to_constant() const {
5545 return true; // conversion is allowed
5546}
5547
5548Vector<StringName> VisualShaderNodeIntParameter::get_editable_properties() const {
5549 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
5550 props.push_back("hint");
5551 if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
5552 props.push_back("min");
5553 props.push_back("max");
5554 }
5555 if (hint == HINT_RANGE_STEP) {
5556 props.push_back("step");
5557 }
5558 props.push_back("default_value_enabled");
5559 if (default_value_enabled) {
5560 props.push_back("default_value");
5561 }
5562 return props;
5563}
5564
5565VisualShaderNodeIntParameter::VisualShaderNodeIntParameter() {
5566}
5567
5568////////////// Unsigned Integer Parameter
5569
5570String VisualShaderNodeUIntParameter::get_caption() const {
5571 return "UIntParameter";
5572}
5573
5574int VisualShaderNodeUIntParameter::get_input_port_count() const {
5575 return 0;
5576}
5577
5578VisualShaderNodeUIntParameter::PortType VisualShaderNodeUIntParameter::get_input_port_type(int p_port) const {
5579 return PORT_TYPE_SCALAR_UINT;
5580}
5581
5582String VisualShaderNodeUIntParameter::get_input_port_name(int p_port) const {
5583 return String();
5584}
5585
5586int VisualShaderNodeUIntParameter::get_output_port_count() const {
5587 return 1;
5588}
5589
5590VisualShaderNodeUIntParameter::PortType VisualShaderNodeUIntParameter::get_output_port_type(int p_port) const {
5591 return PORT_TYPE_SCALAR_UINT;
5592}
5593
5594String VisualShaderNodeUIntParameter::get_output_port_name(int p_port) const {
5595 return ""; // No output port means the editor will be used as port.
5596}
5597
5598String VisualShaderNodeUIntParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
5599 String code = _get_qual_str() + "uniform uint " + get_parameter_name();
5600 if (default_value_enabled) {
5601 code += " = " + itos(default_value);
5602 }
5603 code += ";\n";
5604 return code;
5605}
5606
5607String VisualShaderNodeUIntParameter::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 {
5608 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
5609}
5610
5611bool VisualShaderNodeUIntParameter::is_show_prop_names() const {
5612 return true;
5613}
5614
5615bool VisualShaderNodeUIntParameter::is_use_prop_slots() const {
5616 return true;
5617}
5618
5619void VisualShaderNodeUIntParameter::set_default_value_enabled(bool p_default_value_enabled) {
5620 if (default_value_enabled == p_default_value_enabled) {
5621 return;
5622 }
5623 default_value_enabled = p_default_value_enabled;
5624 emit_changed();
5625}
5626
5627bool VisualShaderNodeUIntParameter::is_default_value_enabled() const {
5628 return default_value_enabled;
5629}
5630
5631void VisualShaderNodeUIntParameter::set_default_value(int p_default_value) {
5632 if (default_value == p_default_value) {
5633 return;
5634 }
5635 default_value = p_default_value;
5636 emit_changed();
5637}
5638
5639int VisualShaderNodeUIntParameter::get_default_value() const {
5640 return default_value;
5641}
5642
5643void VisualShaderNodeUIntParameter::_bind_methods() {
5644 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeUIntParameter::set_default_value_enabled);
5645 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeUIntParameter::is_default_value_enabled);
5646
5647 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeUIntParameter::set_default_value);
5648 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeUIntParameter::get_default_value);
5649
5650 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
5651 ADD_PROPERTY(PropertyInfo(Variant::INT, "default_value"), "set_default_value", "get_default_value");
5652}
5653
5654bool VisualShaderNodeUIntParameter::is_qualifier_supported(Qualifier p_qual) const {
5655 return true; // All qualifiers are supported.
5656}
5657
5658bool VisualShaderNodeUIntParameter::is_convertible_to_constant() const {
5659 return true; // Conversion is allowed.
5660}
5661
5662Vector<StringName> VisualShaderNodeUIntParameter::get_editable_properties() const {
5663 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
5664 props.push_back("default_value_enabled");
5665 if (default_value_enabled) {
5666 props.push_back("default_value");
5667 }
5668 return props;
5669}
5670
5671VisualShaderNodeUIntParameter::VisualShaderNodeUIntParameter() {
5672}
5673
5674////////////// Boolean Parameter
5675
5676String VisualShaderNodeBooleanParameter::get_caption() const {
5677 return "BooleanParameter";
5678}
5679
5680int VisualShaderNodeBooleanParameter::get_input_port_count() const {
5681 return 0;
5682}
5683
5684VisualShaderNodeBooleanParameter::PortType VisualShaderNodeBooleanParameter::get_input_port_type(int p_port) const {
5685 return PORT_TYPE_BOOLEAN;
5686}
5687
5688String VisualShaderNodeBooleanParameter::get_input_port_name(int p_port) const {
5689 return String();
5690}
5691
5692int VisualShaderNodeBooleanParameter::get_output_port_count() const {
5693 return 1;
5694}
5695
5696VisualShaderNodeBooleanParameter::PortType VisualShaderNodeBooleanParameter::get_output_port_type(int p_port) const {
5697 return PORT_TYPE_BOOLEAN;
5698}
5699
5700String VisualShaderNodeBooleanParameter::get_output_port_name(int p_port) const {
5701 return ""; //no output port means the editor will be used as port
5702}
5703
5704void VisualShaderNodeBooleanParameter::set_default_value_enabled(bool p_default_value_enabled) {
5705 if (default_value_enabled == p_default_value_enabled) {
5706 return;
5707 }
5708 default_value_enabled = p_default_value_enabled;
5709 emit_changed();
5710}
5711
5712bool VisualShaderNodeBooleanParameter::is_default_value_enabled() const {
5713 return default_value_enabled;
5714}
5715
5716void VisualShaderNodeBooleanParameter::set_default_value(bool p_default_value) {
5717 if (default_value == p_default_value) {
5718 return;
5719 }
5720 default_value = p_default_value;
5721 emit_changed();
5722}
5723
5724bool VisualShaderNodeBooleanParameter::get_default_value() const {
5725 return default_value;
5726}
5727
5728String VisualShaderNodeBooleanParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
5729 String code = _get_qual_str() + "uniform bool " + get_parameter_name();
5730 if (default_value_enabled) {
5731 if (default_value) {
5732 code += " = true";
5733 } else {
5734 code += " = false";
5735 }
5736 }
5737 code += ";\n";
5738 return code;
5739}
5740
5741String VisualShaderNodeBooleanParameter::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 {
5742 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
5743}
5744
5745bool VisualShaderNodeBooleanParameter::is_show_prop_names() const {
5746 return true;
5747}
5748
5749bool VisualShaderNodeBooleanParameter::is_use_prop_slots() const {
5750 return true;
5751}
5752
5753void VisualShaderNodeBooleanParameter::_bind_methods() {
5754 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanParameter::set_default_value_enabled);
5755 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanParameter::is_default_value_enabled);
5756
5757 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanParameter::set_default_value);
5758 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanParameter::get_default_value);
5759
5760 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
5761 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value"), "set_default_value", "get_default_value");
5762}
5763
5764bool VisualShaderNodeBooleanParameter::is_qualifier_supported(Qualifier p_qual) const {
5765 return true; // all qualifiers are supported
5766}
5767
5768bool VisualShaderNodeBooleanParameter::is_convertible_to_constant() const {
5769 return true; // conversion is allowed
5770}
5771
5772Vector<StringName> VisualShaderNodeBooleanParameter::get_editable_properties() const {
5773 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
5774 props.push_back("default_value_enabled");
5775 if (default_value_enabled) {
5776 props.push_back("default_value");
5777 }
5778 return props;
5779}
5780
5781VisualShaderNodeBooleanParameter::VisualShaderNodeBooleanParameter() {
5782}
5783
5784////////////// Color Parameter
5785
5786String VisualShaderNodeColorParameter::get_caption() const {
5787 return "ColorParameter";
5788}
5789
5790int VisualShaderNodeColorParameter::get_input_port_count() const {
5791 return 0;
5792}
5793
5794VisualShaderNodeColorParameter::PortType VisualShaderNodeColorParameter::get_input_port_type(int p_port) const {
5795 return PORT_TYPE_SCALAR;
5796}
5797
5798String VisualShaderNodeColorParameter::get_input_port_name(int p_port) const {
5799 return String();
5800}
5801
5802int VisualShaderNodeColorParameter::get_output_port_count() const {
5803 return 1;
5804}
5805
5806VisualShaderNodeColorParameter::PortType VisualShaderNodeColorParameter::get_output_port_type(int p_port) const {
5807 return p_port == 0 ? PORT_TYPE_VECTOR_4D : PORT_TYPE_SCALAR;
5808}
5809
5810String VisualShaderNodeColorParameter::get_output_port_name(int p_port) const {
5811 return "color";
5812}
5813
5814bool VisualShaderNodeColorParameter::is_output_port_expandable(int p_port) const {
5815 if (p_port == 0) {
5816 return true;
5817 }
5818 return false;
5819}
5820
5821void VisualShaderNodeColorParameter::set_default_value_enabled(bool p_enabled) {
5822 if (default_value_enabled == p_enabled) {
5823 return;
5824 }
5825 default_value_enabled = p_enabled;
5826 emit_changed();
5827}
5828
5829bool VisualShaderNodeColorParameter::is_default_value_enabled() const {
5830 return default_value_enabled;
5831}
5832
5833void VisualShaderNodeColorParameter::set_default_value(const Color &p_value) {
5834 if (default_value.is_equal_approx(p_value)) {
5835 return;
5836 }
5837 default_value = p_value;
5838 emit_changed();
5839}
5840
5841Color VisualShaderNodeColorParameter::get_default_value() const {
5842 return default_value;
5843}
5844
5845String VisualShaderNodeColorParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
5846 String code = _get_qual_str() + "uniform vec4 " + get_parameter_name() + " : source_color";
5847 if (default_value_enabled) {
5848 code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a);
5849 }
5850 code += ";\n";
5851 return code;
5852}
5853
5854String VisualShaderNodeColorParameter::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 {
5855 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
5856}
5857
5858bool VisualShaderNodeColorParameter::is_show_prop_names() const {
5859 return true;
5860}
5861
5862void VisualShaderNodeColorParameter::_bind_methods() {
5863 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorParameter::set_default_value_enabled);
5864 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorParameter::is_default_value_enabled);
5865
5866 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorParameter::set_default_value);
5867 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorParameter::get_default_value);
5868
5869 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
5870 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_value"), "set_default_value", "get_default_value");
5871}
5872
5873bool VisualShaderNodeColorParameter::is_qualifier_supported(Qualifier p_qual) const {
5874 return true; // all qualifiers are supported
5875}
5876
5877bool VisualShaderNodeColorParameter::is_convertible_to_constant() const {
5878 return true; // conversion is allowed
5879}
5880
5881Vector<StringName> VisualShaderNodeColorParameter::get_editable_properties() const {
5882 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
5883 props.push_back("default_value_enabled");
5884 if (default_value_enabled) {
5885 props.push_back("default_value");
5886 }
5887 return props;
5888}
5889
5890VisualShaderNodeColorParameter::VisualShaderNodeColorParameter() {
5891}
5892
5893////////////// Vector2 Parameter
5894
5895String VisualShaderNodeVec2Parameter::get_caption() const {
5896 return "Vector2Parameter";
5897}
5898
5899int VisualShaderNodeVec2Parameter::get_input_port_count() const {
5900 return 0;
5901}
5902
5903VisualShaderNodeVec2Parameter::PortType VisualShaderNodeVec2Parameter::get_input_port_type(int p_port) const {
5904 return PORT_TYPE_VECTOR_2D;
5905}
5906
5907String VisualShaderNodeVec2Parameter::get_input_port_name(int p_port) const {
5908 return String();
5909}
5910
5911int VisualShaderNodeVec2Parameter::get_output_port_count() const {
5912 return 1;
5913}
5914
5915VisualShaderNodeVec2Parameter::PortType VisualShaderNodeVec2Parameter::get_output_port_type(int p_port) const {
5916 return PORT_TYPE_VECTOR_2D;
5917}
5918
5919String VisualShaderNodeVec2Parameter::get_output_port_name(int p_port) const {
5920 return String();
5921}
5922
5923void VisualShaderNodeVec2Parameter::set_default_value_enabled(bool p_enabled) {
5924 default_value_enabled = p_enabled;
5925 emit_changed();
5926}
5927
5928bool VisualShaderNodeVec2Parameter::is_default_value_enabled() const {
5929 return default_value_enabled;
5930}
5931
5932void VisualShaderNodeVec2Parameter::set_default_value(const Vector2 &p_value) {
5933 default_value = p_value;
5934 emit_changed();
5935}
5936
5937Vector2 VisualShaderNodeVec2Parameter::get_default_value() const {
5938 return default_value;
5939}
5940
5941String VisualShaderNodeVec2Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
5942 String code = _get_qual_str() + "uniform vec2 " + get_parameter_name();
5943 if (default_value_enabled) {
5944 code += vformat(" = vec2(%.6f, %.6f)", default_value.x, default_value.y);
5945 }
5946 code += ";\n";
5947 return code;
5948}
5949
5950String VisualShaderNodeVec2Parameter::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 {
5951 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
5952}
5953
5954void VisualShaderNodeVec2Parameter::_bind_methods() {
5955 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Parameter::set_default_value_enabled);
5956 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Parameter::is_default_value_enabled);
5957
5958 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Parameter::set_default_value);
5959 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Parameter::get_default_value);
5960
5961 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
5962 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "default_value"), "set_default_value", "get_default_value");
5963}
5964
5965bool VisualShaderNodeVec2Parameter::is_show_prop_names() const {
5966 return true;
5967}
5968
5969bool VisualShaderNodeVec2Parameter::is_use_prop_slots() const {
5970 return true;
5971}
5972
5973bool VisualShaderNodeVec2Parameter::is_qualifier_supported(Qualifier p_qual) const {
5974 return true; // all qualifiers are supported
5975}
5976
5977bool VisualShaderNodeVec2Parameter::is_convertible_to_constant() const {
5978 return true; // conversion is allowed
5979}
5980
5981Vector<StringName> VisualShaderNodeVec2Parameter::get_editable_properties() const {
5982 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
5983 props.push_back("default_value_enabled");
5984 if (default_value_enabled) {
5985 props.push_back("default_value");
5986 }
5987 return props;
5988}
5989
5990VisualShaderNodeVec2Parameter::VisualShaderNodeVec2Parameter() {
5991}
5992
5993////////////// Vector3 Parameter
5994
5995String VisualShaderNodeVec3Parameter::get_caption() const {
5996 return "Vector3Parameter";
5997}
5998
5999int VisualShaderNodeVec3Parameter::get_input_port_count() const {
6000 return 0;
6001}
6002
6003VisualShaderNodeVec3Parameter::PortType VisualShaderNodeVec3Parameter::get_input_port_type(int p_port) const {
6004 return PORT_TYPE_VECTOR_3D;
6005}
6006
6007String VisualShaderNodeVec3Parameter::get_input_port_name(int p_port) const {
6008 return String();
6009}
6010
6011int VisualShaderNodeVec3Parameter::get_output_port_count() const {
6012 return 1;
6013}
6014
6015VisualShaderNodeVec3Parameter::PortType VisualShaderNodeVec3Parameter::get_output_port_type(int p_port) const {
6016 return PORT_TYPE_VECTOR_3D;
6017}
6018
6019String VisualShaderNodeVec3Parameter::get_output_port_name(int p_port) const {
6020 return ""; //no output port means the editor will be used as port
6021}
6022
6023void VisualShaderNodeVec3Parameter::set_default_value_enabled(bool p_enabled) {
6024 default_value_enabled = p_enabled;
6025 emit_changed();
6026}
6027
6028bool VisualShaderNodeVec3Parameter::is_default_value_enabled() const {
6029 return default_value_enabled;
6030}
6031
6032void VisualShaderNodeVec3Parameter::set_default_value(const Vector3 &p_value) {
6033 default_value = p_value;
6034 emit_changed();
6035}
6036
6037Vector3 VisualShaderNodeVec3Parameter::get_default_value() const {
6038 return default_value;
6039}
6040
6041String VisualShaderNodeVec3Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6042 String code = _get_qual_str() + "uniform vec3 " + get_parameter_name();
6043 if (default_value_enabled) {
6044 code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z);
6045 }
6046 code += ";\n";
6047 return code;
6048}
6049
6050String VisualShaderNodeVec3Parameter::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 {
6051 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
6052}
6053
6054void VisualShaderNodeVec3Parameter::_bind_methods() {
6055 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Parameter::set_default_value_enabled);
6056 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Parameter::is_default_value_enabled);
6057
6058 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Parameter::set_default_value);
6059 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Parameter::get_default_value);
6060
6061 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
6062 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value");
6063}
6064
6065bool VisualShaderNodeVec3Parameter::is_show_prop_names() const {
6066 return true;
6067}
6068
6069bool VisualShaderNodeVec3Parameter::is_use_prop_slots() const {
6070 return true;
6071}
6072
6073bool VisualShaderNodeVec3Parameter::is_qualifier_supported(Qualifier p_qual) const {
6074 return true; // all qualifiers are supported
6075}
6076
6077bool VisualShaderNodeVec3Parameter::is_convertible_to_constant() const {
6078 return true; // conversion is allowed
6079}
6080
6081Vector<StringName> VisualShaderNodeVec3Parameter::get_editable_properties() const {
6082 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
6083 props.push_back("default_value_enabled");
6084 if (default_value_enabled) {
6085 props.push_back("default_value");
6086 }
6087 return props;
6088}
6089
6090VisualShaderNodeVec3Parameter::VisualShaderNodeVec3Parameter() {
6091}
6092
6093////////////// Vector4 Parameter
6094
6095String VisualShaderNodeVec4Parameter::get_caption() const {
6096 return "Vector4Parameter";
6097}
6098
6099int VisualShaderNodeVec4Parameter::get_input_port_count() const {
6100 return 0;
6101}
6102
6103VisualShaderNodeVec4Parameter::PortType VisualShaderNodeVec4Parameter::get_input_port_type(int p_port) const {
6104 return PORT_TYPE_VECTOR_4D;
6105}
6106
6107String VisualShaderNodeVec4Parameter::get_input_port_name(int p_port) const {
6108 return String();
6109}
6110
6111int VisualShaderNodeVec4Parameter::get_output_port_count() const {
6112 return 1;
6113}
6114
6115VisualShaderNodeVec4Parameter::PortType VisualShaderNodeVec4Parameter::get_output_port_type(int p_port) const {
6116 return PORT_TYPE_VECTOR_4D;
6117}
6118
6119String VisualShaderNodeVec4Parameter::get_output_port_name(int p_port) const {
6120 return ""; // No output port means the editor will be used as port.
6121}
6122
6123void VisualShaderNodeVec4Parameter::set_default_value_enabled(bool p_enabled) {
6124 default_value_enabled = p_enabled;
6125 emit_changed();
6126}
6127
6128bool VisualShaderNodeVec4Parameter::is_default_value_enabled() const {
6129 return default_value_enabled;
6130}
6131
6132void VisualShaderNodeVec4Parameter::set_default_value(const Vector4 &p_value) {
6133 default_value = p_value;
6134 emit_changed();
6135}
6136
6137Vector4 VisualShaderNodeVec4Parameter::get_default_value() const {
6138 return default_value;
6139}
6140
6141String VisualShaderNodeVec4Parameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6142 String code = _get_qual_str() + "uniform vec4 " + get_parameter_name();
6143 if (default_value_enabled) {
6144 code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z, default_value.w);
6145 }
6146 code += ";\n";
6147 return code;
6148}
6149
6150String VisualShaderNodeVec4Parameter::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 {
6151 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
6152}
6153
6154void VisualShaderNodeVec4Parameter::_bind_methods() {
6155 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec4Parameter::set_default_value_enabled);
6156 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec4Parameter::is_default_value_enabled);
6157
6158 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec4Parameter::set_default_value);
6159 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec4Parameter::get_default_value);
6160
6161 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
6162 ADD_PROPERTY(PropertyInfo(Variant::VECTOR4, "default_value"), "set_default_value", "get_default_value");
6163}
6164
6165bool VisualShaderNodeVec4Parameter::is_show_prop_names() const {
6166 return true;
6167}
6168
6169bool VisualShaderNodeVec4Parameter::is_use_prop_slots() const {
6170 return true;
6171}
6172
6173bool VisualShaderNodeVec4Parameter::is_qualifier_supported(Qualifier p_qual) const {
6174 return true; // All qualifiers are supported.
6175}
6176
6177bool VisualShaderNodeVec4Parameter::is_convertible_to_constant() const {
6178 return true; // Conversion is allowed.
6179}
6180
6181Vector<StringName> VisualShaderNodeVec4Parameter::get_editable_properties() const {
6182 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
6183 props.push_back("default_value_enabled");
6184 if (default_value_enabled) {
6185 props.push_back("default_value");
6186 }
6187 return props;
6188}
6189
6190VisualShaderNodeVec4Parameter::VisualShaderNodeVec4Parameter() {
6191}
6192
6193////////////// Transform Parameter
6194
6195String VisualShaderNodeTransformParameter::get_caption() const {
6196 return "TransformParameter";
6197}
6198
6199int VisualShaderNodeTransformParameter::get_input_port_count() const {
6200 return 0;
6201}
6202
6203VisualShaderNodeTransformParameter::PortType VisualShaderNodeTransformParameter::get_input_port_type(int p_port) const {
6204 return PORT_TYPE_VECTOR_3D;
6205}
6206
6207String VisualShaderNodeTransformParameter::get_input_port_name(int p_port) const {
6208 return String();
6209}
6210
6211int VisualShaderNodeTransformParameter::get_output_port_count() const {
6212 return 1;
6213}
6214
6215VisualShaderNodeTransformParameter::PortType VisualShaderNodeTransformParameter::get_output_port_type(int p_port) const {
6216 return PORT_TYPE_TRANSFORM;
6217}
6218
6219String VisualShaderNodeTransformParameter::get_output_port_name(int p_port) const {
6220 return ""; //no output port means the editor will be used as port
6221}
6222
6223void VisualShaderNodeTransformParameter::set_default_value_enabled(bool p_enabled) {
6224 default_value_enabled = p_enabled;
6225 emit_changed();
6226}
6227
6228bool VisualShaderNodeTransformParameter::is_default_value_enabled() const {
6229 return default_value_enabled;
6230}
6231
6232void VisualShaderNodeTransformParameter::set_default_value(const Transform3D &p_value) {
6233 default_value = p_value;
6234 emit_changed();
6235}
6236
6237Transform3D VisualShaderNodeTransformParameter::get_default_value() const {
6238 return default_value;
6239}
6240
6241String VisualShaderNodeTransformParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6242 String code = _get_qual_str() + "uniform mat4 " + get_parameter_name();
6243 if (default_value_enabled) {
6244 Vector3 row0 = default_value.basis.rows[0];
6245 Vector3 row1 = default_value.basis.rows[1];
6246 Vector3 row2 = default_value.basis.rows[2];
6247 Vector3 origin = default_value.origin;
6248 code += " = mat4(" + vformat("vec4(%.6f, %.6f, %.6f, 0.0)", row0.x, row0.y, row0.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row1.x, row1.y, row1.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row2.x, row2.y, row2.z) + vformat(", vec4(%.6f, %.6f, %.6f, 1.0)", origin.x, origin.y, origin.z) + ")";
6249 }
6250 code += ";\n";
6251 return code;
6252}
6253
6254String VisualShaderNodeTransformParameter::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 {
6255 return " " + p_output_vars[0] + " = " + get_parameter_name() + ";\n";
6256}
6257
6258void VisualShaderNodeTransformParameter::_bind_methods() {
6259 ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformParameter::set_default_value_enabled);
6260 ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformParameter::is_default_value_enabled);
6261
6262 ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformParameter::set_default_value);
6263 ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformParameter::get_default_value);
6264
6265 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
6266 ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "default_value"), "set_default_value", "get_default_value");
6267}
6268
6269bool VisualShaderNodeTransformParameter::is_show_prop_names() const {
6270 return true;
6271}
6272
6273bool VisualShaderNodeTransformParameter::is_use_prop_slots() const {
6274 return true;
6275}
6276
6277bool VisualShaderNodeTransformParameter::is_qualifier_supported(Qualifier p_qual) const {
6278 if (p_qual == Qualifier::QUAL_INSTANCE) {
6279 return false;
6280 }
6281 return true;
6282}
6283
6284bool VisualShaderNodeTransformParameter::is_convertible_to_constant() const {
6285 return true; // conversion is allowed
6286}
6287
6288Vector<StringName> VisualShaderNodeTransformParameter::get_editable_properties() const {
6289 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
6290 props.push_back("default_value_enabled");
6291 if (default_value_enabled) {
6292 props.push_back("default_value");
6293 }
6294 return props;
6295}
6296
6297VisualShaderNodeTransformParameter::VisualShaderNodeTransformParameter() {
6298}
6299
6300//////////////
6301
6302String get_sampler_hint(VisualShaderNodeTextureParameter::TextureType p_texture_type, VisualShaderNodeTextureParameter::ColorDefault p_color_default, VisualShaderNodeTextureParameter::TextureFilter p_texture_filter, VisualShaderNodeTextureParameter::TextureRepeat p_texture_repeat, VisualShaderNodeTextureParameter::TextureSource p_texture_source) {
6303 String code;
6304 bool has_colon = false;
6305
6306 // type
6307 {
6308 String type_code;
6309
6310 switch (p_texture_type) {
6311 case VisualShaderNodeTextureParameter::TYPE_DATA:
6312 if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_BLACK) {
6313 type_code = "hint_default_black";
6314 } else if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_TRANSPARENT) {
6315 type_code = "hint_default_transparent";
6316 }
6317 break;
6318 case VisualShaderNodeTextureParameter::TYPE_COLOR:
6319 type_code = "source_color";
6320 if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_BLACK) {
6321 type_code += ", hint_default_black";
6322 } else if (p_color_default == VisualShaderNodeTextureParameter::COLOR_DEFAULT_TRANSPARENT) {
6323 type_code += ", hint_default_transparent";
6324 }
6325 break;
6326 case VisualShaderNodeTextureParameter::TYPE_NORMAL_MAP:
6327 type_code = "hint_normal";
6328 break;
6329 case VisualShaderNodeTextureParameter::TYPE_ANISOTROPY:
6330 type_code = "hint_anisotropy";
6331 break;
6332 default:
6333 break;
6334 }
6335
6336 if (!type_code.is_empty()) {
6337 code += " : " + type_code;
6338 has_colon = true;
6339 }
6340 }
6341
6342 // filter
6343 {
6344 String filter_code;
6345
6346 switch (p_texture_filter) {
6347 case VisualShaderNodeTextureParameter::FILTER_NEAREST:
6348 filter_code = "filter_nearest";
6349 break;
6350 case VisualShaderNodeTextureParameter::FILTER_LINEAR:
6351 filter_code = "filter_linear";
6352 break;
6353 case VisualShaderNodeTextureParameter::FILTER_NEAREST_MIPMAP:
6354 filter_code = "filter_nearest_mipmap";
6355 break;
6356 case VisualShaderNodeTextureParameter::FILTER_LINEAR_MIPMAP:
6357 filter_code = "filter_linear_mipmap";
6358 break;
6359 case VisualShaderNodeTextureParameter::FILTER_NEAREST_MIPMAP_ANISOTROPIC:
6360 filter_code = "filter_nearest_mipmap_anisotropic";
6361 break;
6362 case VisualShaderNodeTextureParameter::FILTER_LINEAR_MIPMAP_ANISOTROPIC:
6363 filter_code = "filter_linear_mipmap_anisotropic";
6364 break;
6365 default:
6366 break;
6367 }
6368
6369 if (!filter_code.is_empty()) {
6370 if (!has_colon) {
6371 code += " : ";
6372 has_colon = true;
6373 } else {
6374 code += ", ";
6375 }
6376 code += filter_code;
6377 }
6378 }
6379
6380 // repeat
6381 {
6382 String repeat_code;
6383
6384 switch (p_texture_repeat) {
6385 case VisualShaderNodeTextureParameter::REPEAT_ENABLED:
6386 repeat_code = "repeat_enable";
6387 break;
6388 case VisualShaderNodeTextureParameter::REPEAT_DISABLED:
6389 repeat_code = "repeat_disable";
6390 break;
6391 default:
6392 break;
6393 }
6394
6395 if (!repeat_code.is_empty()) {
6396 if (!has_colon) {
6397 code += " : ";
6398 } else {
6399 code += ", ";
6400 }
6401 code += repeat_code;
6402 }
6403 }
6404
6405 {
6406 String source_code;
6407
6408 switch (p_texture_source) {
6409 case VisualShaderNodeTextureParameter::SOURCE_SCREEN:
6410 source_code = "hint_screen_texture";
6411 break;
6412 case VisualShaderNodeTextureParameter::SOURCE_DEPTH:
6413 source_code = "hint_depth_texture";
6414 break;
6415 case VisualShaderNodeTextureParameter::SOURCE_NORMAL_ROUGHNESS:
6416 source_code = "hint_normal_roughness_texture";
6417 break;
6418 default:
6419 break;
6420 }
6421
6422 if (!source_code.is_empty()) {
6423 if (!has_colon) {
6424 code += " : ";
6425 } else {
6426 code += ", ";
6427 }
6428 code += source_code;
6429 }
6430 }
6431
6432 return code;
6433}
6434
6435////////////// Texture Parameter
6436
6437int VisualShaderNodeTextureParameter::get_input_port_count() const {
6438 return 0;
6439}
6440
6441VisualShaderNodeTextureParameter::PortType VisualShaderNodeTextureParameter::get_input_port_type(int p_port) const {
6442 return PORT_TYPE_SCALAR;
6443}
6444
6445String VisualShaderNodeTextureParameter::get_input_port_name(int p_port) const {
6446 return "";
6447}
6448
6449int VisualShaderNodeTextureParameter::get_output_port_count() const {
6450 return 1;
6451}
6452
6453VisualShaderNodeTextureParameter::PortType VisualShaderNodeTextureParameter::get_output_port_type(int p_port) const {
6454 switch (p_port) {
6455 case 0:
6456 return PORT_TYPE_SAMPLER;
6457 default:
6458 return PORT_TYPE_SCALAR;
6459 }
6460}
6461
6462String VisualShaderNodeTextureParameter::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 {
6463 return "";
6464}
6465
6466void VisualShaderNodeTextureParameter::set_texture_type(TextureType p_texture_type) {
6467 ERR_FAIL_INDEX(int(p_texture_type), int(TYPE_MAX));
6468 if (texture_type == p_texture_type) {
6469 return;
6470 }
6471 texture_type = p_texture_type;
6472 emit_changed();
6473}
6474
6475VisualShaderNodeTextureParameter::TextureType VisualShaderNodeTextureParameter::get_texture_type() const {
6476 return texture_type;
6477}
6478
6479void VisualShaderNodeTextureParameter::set_color_default(ColorDefault p_color_default) {
6480 ERR_FAIL_INDEX(int(p_color_default), int(COLOR_DEFAULT_MAX));
6481 if (color_default == p_color_default) {
6482 return;
6483 }
6484 color_default = p_color_default;
6485 emit_changed();
6486}
6487
6488VisualShaderNodeTextureParameter::ColorDefault VisualShaderNodeTextureParameter::get_color_default() const {
6489 return color_default;
6490}
6491
6492void VisualShaderNodeTextureParameter::set_texture_filter(TextureFilter p_filter) {
6493 ERR_FAIL_INDEX(int(p_filter), int(FILTER_MAX));
6494 if (texture_filter == p_filter) {
6495 return;
6496 }
6497 texture_filter = p_filter;
6498 emit_changed();
6499}
6500
6501VisualShaderNodeTextureParameter::TextureFilter VisualShaderNodeTextureParameter::get_texture_filter() const {
6502 return texture_filter;
6503}
6504
6505void VisualShaderNodeTextureParameter::set_texture_repeat(TextureRepeat p_repeat) {
6506 ERR_FAIL_INDEX(int(p_repeat), int(REPEAT_MAX));
6507 if (texture_repeat == p_repeat) {
6508 return;
6509 }
6510 texture_repeat = p_repeat;
6511 emit_changed();
6512}
6513
6514VisualShaderNodeTextureParameter::TextureRepeat VisualShaderNodeTextureParameter::get_texture_repeat() const {
6515 return texture_repeat;
6516}
6517
6518void VisualShaderNodeTextureParameter::set_texture_source(TextureSource p_source) {
6519 ERR_FAIL_INDEX(int(p_source), int(SOURCE_MAX));
6520 if (texture_source == p_source) {
6521 return;
6522 }
6523 texture_source = p_source;
6524 emit_changed();
6525}
6526
6527VisualShaderNodeTextureParameter::TextureSource VisualShaderNodeTextureParameter::get_texture_source() const {
6528 return texture_source;
6529}
6530
6531Vector<StringName> VisualShaderNodeTextureParameter::get_editable_properties() const {
6532 Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
6533 props.push_back("texture_type");
6534 if (texture_type == TYPE_DATA || texture_type == TYPE_COLOR) {
6535 props.push_back("color_default");
6536 }
6537 props.push_back("texture_filter");
6538 props.push_back("texture_repeat");
6539 props.push_back("texture_source");
6540 return props;
6541}
6542
6543bool VisualShaderNodeTextureParameter::is_show_prop_names() const {
6544 return true;
6545}
6546
6547HashMap<StringName, String> VisualShaderNodeTextureParameter::get_editable_properties_names() const {
6548 HashMap<StringName, String> names;
6549 names.insert("texture_type", RTR("Type"));
6550 names.insert("color_default", RTR("Default Color"));
6551 names.insert("texture_filter", RTR("Filter"));
6552 names.insert("texture_repeat", RTR("Repeat"));
6553 names.insert("texture_source", RTR("Source"));
6554 return names;
6555}
6556
6557void VisualShaderNodeTextureParameter::_bind_methods() {
6558 ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureParameter::set_texture_type);
6559 ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureParameter::get_texture_type);
6560
6561 ClassDB::bind_method(D_METHOD("set_color_default", "color"), &VisualShaderNodeTextureParameter::set_color_default);
6562 ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureParameter::get_color_default);
6563
6564 ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureParameter::set_texture_filter);
6565 ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureParameter::get_texture_filter);
6566
6567 ClassDB::bind_method(D_METHOD("set_texture_repeat", "repeat"), &VisualShaderNodeTextureParameter::set_texture_repeat);
6568 ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureParameter::get_texture_repeat);
6569
6570 ClassDB::bind_method(D_METHOD("set_texture_source", "source"), &VisualShaderNodeTextureParameter::set_texture_source);
6571 ClassDB::bind_method(D_METHOD("get_texture_source"), &VisualShaderNodeTextureParameter::get_texture_source);
6572
6573 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type");
6574 ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default");
6575 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
6576 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat");
6577 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_source", PROPERTY_HINT_ENUM, "None,Screen,Depth,NormalRoughness"), "set_texture_source", "get_texture_source");
6578
6579 BIND_ENUM_CONSTANT(TYPE_DATA);
6580 BIND_ENUM_CONSTANT(TYPE_COLOR);
6581 BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP);
6582 BIND_ENUM_CONSTANT(TYPE_ANISOTROPY);
6583 BIND_ENUM_CONSTANT(TYPE_MAX);
6584
6585 BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE);
6586 BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK);
6587 BIND_ENUM_CONSTANT(COLOR_DEFAULT_TRANSPARENT);
6588 BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX);
6589
6590 BIND_ENUM_CONSTANT(FILTER_DEFAULT);
6591 BIND_ENUM_CONSTANT(FILTER_NEAREST);
6592 BIND_ENUM_CONSTANT(FILTER_LINEAR);
6593 BIND_ENUM_CONSTANT(FILTER_NEAREST_MIPMAP);
6594 BIND_ENUM_CONSTANT(FILTER_LINEAR_MIPMAP);
6595 BIND_ENUM_CONSTANT(FILTER_NEAREST_MIPMAP_ANISOTROPIC);
6596 BIND_ENUM_CONSTANT(FILTER_LINEAR_MIPMAP_ANISOTROPIC);
6597 BIND_ENUM_CONSTANT(FILTER_MAX);
6598
6599 BIND_ENUM_CONSTANT(REPEAT_DEFAULT);
6600 BIND_ENUM_CONSTANT(REPEAT_ENABLED);
6601 BIND_ENUM_CONSTANT(REPEAT_DISABLED);
6602 BIND_ENUM_CONSTANT(REPEAT_MAX);
6603
6604 BIND_ENUM_CONSTANT(SOURCE_NONE);
6605 BIND_ENUM_CONSTANT(SOURCE_SCREEN);
6606 BIND_ENUM_CONSTANT(SOURCE_DEPTH);
6607 BIND_ENUM_CONSTANT(SOURCE_NORMAL_ROUGHNESS);
6608 BIND_ENUM_CONSTANT(SOURCE_MAX);
6609}
6610
6611bool VisualShaderNodeTextureParameter::is_qualifier_supported(Qualifier p_qual) const {
6612 switch (p_qual) {
6613 case Qualifier::QUAL_NONE:
6614 return true;
6615 case Qualifier::QUAL_GLOBAL:
6616 return true;
6617 case Qualifier::QUAL_INSTANCE:
6618 return false;
6619 default:
6620 break;
6621 }
6622 return false;
6623}
6624
6625bool VisualShaderNodeTextureParameter::is_convertible_to_constant() const {
6626 return false; // conversion is not allowed
6627}
6628
6629VisualShaderNodeTextureParameter::VisualShaderNodeTextureParameter() {
6630}
6631
6632////////////// Texture2D Parameter
6633
6634String VisualShaderNodeTexture2DParameter::get_caption() const {
6635 return "Texture2DParameter";
6636}
6637
6638String VisualShaderNodeTexture2DParameter::get_output_port_name(int p_port) const {
6639 switch (p_port) {
6640 case 0:
6641 return "sampler2D";
6642 default:
6643 return "";
6644 }
6645}
6646
6647String VisualShaderNodeTexture2DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6648 String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name();
6649 code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
6650 code += ";\n";
6651 return code;
6652}
6653
6654VisualShaderNodeTexture2DParameter::VisualShaderNodeTexture2DParameter() {
6655}
6656
6657////////////// Texture Parameter (Triplanar)
6658
6659String VisualShaderNodeTextureParameterTriplanar::get_caption() const {
6660 return "TextureParameterTriplanar";
6661}
6662
6663int VisualShaderNodeTextureParameterTriplanar::get_input_port_count() const {
6664 return 2;
6665}
6666
6667VisualShaderNodeTextureParameterTriplanar::PortType VisualShaderNodeTextureParameterTriplanar::get_input_port_type(int p_port) const {
6668 if (p_port == 0 || p_port == 1) {
6669 return PORT_TYPE_VECTOR_3D;
6670 }
6671 return PORT_TYPE_SCALAR;
6672}
6673
6674String VisualShaderNodeTextureParameterTriplanar::get_input_port_name(int p_port) const {
6675 if (p_port == 0) {
6676 return "weights";
6677 } else if (p_port == 1) {
6678 return "pos";
6679 }
6680 return "";
6681}
6682
6683int VisualShaderNodeTextureParameterTriplanar::get_output_port_count() const {
6684 return 2;
6685}
6686
6687VisualShaderNodeTextureParameterTriplanar::PortType VisualShaderNodeTextureParameterTriplanar::get_output_port_type(int p_port) const {
6688 switch (p_port) {
6689 case 0:
6690 return PORT_TYPE_VECTOR_4D;
6691 case 1:
6692 return PORT_TYPE_SAMPLER;
6693 default:
6694 return PORT_TYPE_SCALAR;
6695 }
6696}
6697
6698String VisualShaderNodeTextureParameterTriplanar::get_output_port_name(int p_port) const {
6699 switch (p_port) {
6700 case 0:
6701 return "color";
6702 case 1:
6703 return "sampler2D";
6704 default:
6705 return "";
6706 }
6707}
6708
6709String VisualShaderNodeTextureParameterTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
6710 String code;
6711
6712 code += "// " + get_caption() + "\n";
6713 code += " vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n";
6714 code += " vec4 samp = vec4(0.0);\n";
6715 code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n";
6716 code += " samp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;\n";
6717 code += " samp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;\n";
6718 code += " return samp;\n";
6719 code += " }\n";
6720 code += "\n";
6721 code += " uniform vec3 triplanar_scale = vec3(1.0, 1.0, 1.0);\n";
6722 code += " uniform vec3 triplanar_offset;\n";
6723 code += " uniform float triplanar_sharpness = 0.5;\n";
6724 code += "\n";
6725 code += " varying vec3 triplanar_power_normal;\n";
6726 code += " varying vec3 triplanar_pos;\n";
6727
6728 return code;
6729}
6730
6731String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6732 String code;
6733
6734 if (p_type == VisualShader::TYPE_VERTEX) {
6735 code += "// " + get_caption() + "\n";
6736 code += " {\n";
6737 code += " triplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n";
6738 code += " triplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n";
6739 code += " triplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n";
6740 code += " triplanar_pos *= vec3(1.0, -1.0, 1.0);\n";
6741 code += " }\n";
6742 }
6743
6744 return code;
6745}
6746
6747String VisualShaderNodeTextureParameterTriplanar::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6748 String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name();
6749 code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
6750 code += ";\n";
6751 return code;
6752}
6753
6754String VisualShaderNodeTextureParameterTriplanar::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 {
6755 String id = get_parameter_name();
6756
6757 String code;
6758 if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) {
6759 code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n";
6760 } else if (!p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) {
6761 code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n";
6762 } else if (p_input_vars[0].is_empty() && !p_input_vars[1].is_empty()) {
6763 code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n";
6764 } else {
6765 code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
6766 }
6767
6768 return code;
6769}
6770
6771bool VisualShaderNodeTextureParameterTriplanar::is_input_port_default(int p_port, Shader::Mode p_mode) const {
6772 if (p_port == 0) {
6773 return true;
6774 } else if (p_port == 1) {
6775 return true;
6776 }
6777 return false;
6778}
6779
6780VisualShaderNodeTextureParameterTriplanar::VisualShaderNodeTextureParameterTriplanar() {
6781}
6782
6783////////////// Texture2DArray Parameter
6784
6785String VisualShaderNodeTexture2DArrayParameter::get_caption() const {
6786 return "Texture2DArrayParameter";
6787}
6788
6789String VisualShaderNodeTexture2DArrayParameter::get_output_port_name(int p_port) const {
6790 return "sampler2DArray";
6791}
6792
6793String VisualShaderNodeTexture2DArrayParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6794 String code = _get_qual_str() + "uniform sampler2DArray " + get_parameter_name();
6795 code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
6796 code += ";\n";
6797 return code;
6798}
6799
6800VisualShaderNodeTexture2DArrayParameter::VisualShaderNodeTexture2DArrayParameter() {
6801}
6802
6803////////////// Texture3D Parameter
6804
6805String VisualShaderNodeTexture3DParameter::get_caption() const {
6806 return "Texture3DParameter";
6807}
6808
6809String VisualShaderNodeTexture3DParameter::get_output_port_name(int p_port) const {
6810 return "sampler3D";
6811}
6812
6813String VisualShaderNodeTexture3DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6814 String code = _get_qual_str() + "uniform sampler3D " + get_parameter_name();
6815 code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
6816 code += ";\n";
6817 return code;
6818}
6819
6820VisualShaderNodeTexture3DParameter::VisualShaderNodeTexture3DParameter() {
6821}
6822
6823////////////// Cubemap Parameter
6824
6825String VisualShaderNodeCubemapParameter::get_caption() const {
6826 return "CubemapParameter";
6827}
6828
6829String VisualShaderNodeCubemapParameter::get_output_port_name(int p_port) const {
6830 return "samplerCube";
6831}
6832
6833String VisualShaderNodeCubemapParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
6834 String code = _get_qual_str() + "uniform samplerCube " + get_parameter_name();
6835 code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
6836 code += ";\n";
6837 return code;
6838}
6839
6840VisualShaderNodeCubemapParameter::VisualShaderNodeCubemapParameter() {
6841}
6842
6843////////////// If
6844
6845String VisualShaderNodeIf::get_caption() const {
6846 return "If";
6847}
6848
6849int VisualShaderNodeIf::get_input_port_count() const {
6850 return 6;
6851}
6852
6853VisualShaderNodeIf::PortType VisualShaderNodeIf::get_input_port_type(int p_port) const {
6854 if (p_port == 0 || p_port == 1 || p_port == 2) {
6855 return PORT_TYPE_SCALAR;
6856 }
6857 return PORT_TYPE_VECTOR_3D;
6858}
6859
6860String VisualShaderNodeIf::get_input_port_name(int p_port) const {
6861 switch (p_port) {
6862 case 0:
6863 return "a";
6864 case 1:
6865 return "b";
6866 case 2:
6867 return "tolerance";
6868 case 3:
6869 return "a == b";
6870 case 4:
6871 return "a > b";
6872 case 5:
6873 return "a < b";
6874 default:
6875 return "";
6876 }
6877}
6878
6879int VisualShaderNodeIf::get_output_port_count() const {
6880 return 1;
6881}
6882
6883VisualShaderNodeIf::PortType VisualShaderNodeIf::get_output_port_type(int p_port) const {
6884 return PORT_TYPE_VECTOR_3D;
6885}
6886
6887String VisualShaderNodeIf::get_output_port_name(int p_port) const {
6888 return "result";
6889}
6890
6891String VisualShaderNodeIf::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 {
6892 String code;
6893 code += " if(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b
6894 code += " {\n";
6895 code += " " + p_output_vars[0] + " = " + p_input_vars[3] + ";\n";
6896 code += " }\n";
6897 code += " else if(" + p_input_vars[0] + " < " + p_input_vars[1] + ")\n"; // a < b
6898 code += " {\n";
6899 code += " " + p_output_vars[0] + " = " + p_input_vars[5] + ";\n";
6900 code += " }\n";
6901 code += " else\n"; // a > b (or a >= b if abs(a - b) < tolerance is false)
6902 code += " {\n";
6903 code += " " + p_output_vars[0] + " = " + p_input_vars[4] + ";\n";
6904 code += " }\n";
6905 return code;
6906}
6907
6908VisualShaderNodeIf::VisualShaderNodeIf() {
6909 simple_decl = false;
6910 set_input_port_default_value(0, 0.0);
6911 set_input_port_default_value(1, 0.0);
6912 set_input_port_default_value(2, CMP_EPSILON);
6913 set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0));
6914 set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0));
6915 set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0));
6916}
6917
6918////////////// Switch
6919
6920String VisualShaderNodeSwitch::get_caption() const {
6921 return "Switch";
6922}
6923
6924int VisualShaderNodeSwitch::get_input_port_count() const {
6925 return 3;
6926}
6927
6928VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int p_port) const {
6929 if (p_port == 0) {
6930 return PORT_TYPE_BOOLEAN;
6931 }
6932 if (p_port == 1 || p_port == 2) {
6933 switch (op_type) {
6934 case OP_TYPE_INT:
6935 return PORT_TYPE_SCALAR_INT;
6936 case OP_TYPE_UINT:
6937 return PORT_TYPE_SCALAR_UINT;
6938 case OP_TYPE_VECTOR_2D:
6939 return PORT_TYPE_VECTOR_2D;
6940 case OP_TYPE_VECTOR_3D:
6941 return PORT_TYPE_VECTOR_3D;
6942 case OP_TYPE_VECTOR_4D:
6943 return PORT_TYPE_VECTOR_4D;
6944 case OP_TYPE_BOOLEAN:
6945 return PORT_TYPE_BOOLEAN;
6946 case OP_TYPE_TRANSFORM:
6947 return PORT_TYPE_TRANSFORM;
6948 default:
6949 break;
6950 }
6951 }
6952 return PORT_TYPE_SCALAR;
6953}
6954
6955String VisualShaderNodeSwitch::get_input_port_name(int p_port) const {
6956 switch (p_port) {
6957 case 0:
6958 return "value";
6959 case 1:
6960 return "true";
6961 case 2:
6962 return "false";
6963 default:
6964 return "";
6965 }
6966}
6967
6968int VisualShaderNodeSwitch::get_output_port_count() const {
6969 return 1;
6970}
6971
6972VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const {
6973 switch (op_type) {
6974 case OP_TYPE_INT:
6975 return PORT_TYPE_SCALAR_INT;
6976 case OP_TYPE_UINT:
6977 return PORT_TYPE_SCALAR_UINT;
6978 case OP_TYPE_VECTOR_2D:
6979 return PORT_TYPE_VECTOR_2D;
6980 case OP_TYPE_VECTOR_3D:
6981 return PORT_TYPE_VECTOR_3D;
6982 case OP_TYPE_VECTOR_4D:
6983 return PORT_TYPE_VECTOR_4D;
6984 case OP_TYPE_BOOLEAN:
6985 return PORT_TYPE_BOOLEAN;
6986 case OP_TYPE_TRANSFORM:
6987 return PORT_TYPE_TRANSFORM;
6988 default:
6989 break;
6990 }
6991 return PORT_TYPE_SCALAR;
6992}
6993
6994String VisualShaderNodeSwitch::get_output_port_name(int p_port) const {
6995 return "result";
6996}
6997
6998void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) {
6999 ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
7000 if (op_type == p_op_type) {
7001 return;
7002 }
7003 switch (p_op_type) {
7004 case OP_TYPE_FLOAT:
7005 set_input_port_default_value(1, 1.0, get_input_port_default_value(1));
7006 set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
7007 break;
7008 case OP_TYPE_UINT:
7009 case OP_TYPE_INT:
7010 set_input_port_default_value(1, 1, get_input_port_default_value(1));
7011 set_input_port_default_value(2, 0, get_input_port_default_value(2));
7012 break;
7013 case OP_TYPE_VECTOR_2D:
7014 set_input_port_default_value(1, Vector2(1.0, 1.0), get_input_port_default_value(1));
7015 set_input_port_default_value(2, Vector2(0.0, 0.0), get_input_port_default_value(2));
7016 break;
7017 case OP_TYPE_VECTOR_3D:
7018 set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0), get_input_port_default_value(1));
7019 set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0), get_input_port_default_value(2));
7020 break;
7021 case OP_TYPE_VECTOR_4D:
7022 set_input_port_default_value(1, Quaternion(1.0, 1.0, 1.0, 1.0), get_input_port_default_value(1));
7023 set_input_port_default_value(2, Quaternion(0.0, 0.0, 0.0, 0.0), get_input_port_default_value(2));
7024 break;
7025 case OP_TYPE_BOOLEAN:
7026 set_input_port_default_value(1, true);
7027 set_input_port_default_value(2, false);
7028 break;
7029 case OP_TYPE_TRANSFORM:
7030 set_input_port_default_value(1, Transform3D());
7031 set_input_port_default_value(2, Transform3D());
7032 break;
7033 default:
7034 break;
7035 }
7036 op_type = p_op_type;
7037 emit_changed();
7038}
7039
7040VisualShaderNodeSwitch::OpType VisualShaderNodeSwitch::get_op_type() const {
7041 return op_type;
7042}
7043
7044Vector<StringName> VisualShaderNodeSwitch::get_editable_properties() const {
7045 Vector<StringName> props;
7046 props.push_back("op_type");
7047 return props;
7048}
7049
7050void VisualShaderNodeSwitch::_bind_methods() { // static
7051 ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSwitch::set_op_type);
7052 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSwitch::get_op_type);
7053
7054 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,UInt,Vector2,Vector3,Vector4,Boolean,Transform"), "set_op_type", "get_op_type");
7055
7056 BIND_ENUM_CONSTANT(OP_TYPE_FLOAT);
7057 BIND_ENUM_CONSTANT(OP_TYPE_INT);
7058 BIND_ENUM_CONSTANT(OP_TYPE_UINT);
7059 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
7060 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
7061 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
7062 BIND_ENUM_CONSTANT(OP_TYPE_BOOLEAN);
7063 BIND_ENUM_CONSTANT(OP_TYPE_TRANSFORM);
7064 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
7065}
7066
7067String VisualShaderNodeSwitch::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 {
7068 bool use_mix = false;
7069 switch (op_type) {
7070 case OP_TYPE_FLOAT: {
7071 use_mix = true;
7072 } break;
7073 case OP_TYPE_VECTOR_2D: {
7074 use_mix = true;
7075 } break;
7076 case OP_TYPE_VECTOR_3D: {
7077 use_mix = true;
7078 } break;
7079 case OP_TYPE_VECTOR_4D: {
7080 use_mix = true;
7081 } break;
7082 default: {
7083 } break;
7084 }
7085
7086 String code;
7087 if (use_mix) {
7088 code += " " + p_output_vars[0] + " = mix(" + p_input_vars[2] + ", " + p_input_vars[1] + ", float(" + p_input_vars[0] + "));\n";
7089 } else {
7090 code += " if (" + p_input_vars[0] + ") {\n";
7091 code += " " + p_output_vars[0] + " = " + p_input_vars[1] + ";\n";
7092 code += " } else {\n";
7093 code += " " + p_output_vars[0] + " = " + p_input_vars[2] + ";\n";
7094 code += " }\n";
7095 }
7096 return code;
7097}
7098
7099VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
7100 simple_decl = false;
7101 set_input_port_default_value(0, false);
7102 set_input_port_default_value(1, 1.0);
7103 set_input_port_default_value(2, 0.0);
7104}
7105
7106////////////// Fresnel
7107
7108String VisualShaderNodeFresnel::get_caption() const {
7109 return "Fresnel";
7110}
7111
7112int VisualShaderNodeFresnel::get_input_port_count() const {
7113 return 4;
7114}
7115
7116VisualShaderNodeFresnel::PortType VisualShaderNodeFresnel::get_input_port_type(int p_port) const {
7117 switch (p_port) {
7118 case 0:
7119 return PORT_TYPE_VECTOR_3D;
7120 case 1:
7121 return PORT_TYPE_VECTOR_3D;
7122 case 2:
7123 return PORT_TYPE_BOOLEAN;
7124 case 3:
7125 return PORT_TYPE_SCALAR;
7126 default:
7127 return PORT_TYPE_VECTOR_3D;
7128 }
7129}
7130
7131String VisualShaderNodeFresnel::get_input_port_name(int p_port) const {
7132 switch (p_port) {
7133 case 0:
7134 return "normal";
7135 case 1:
7136 return "view";
7137 case 2:
7138 return "invert";
7139 case 3:
7140 return "power";
7141 default:
7142 return "";
7143 }
7144}
7145
7146int VisualShaderNodeFresnel::get_output_port_count() const {
7147 return 1;
7148}
7149
7150VisualShaderNodeFresnel::PortType VisualShaderNodeFresnel::get_output_port_type(int p_port) const {
7151 return PORT_TYPE_SCALAR;
7152}
7153
7154String VisualShaderNodeFresnel::get_output_port_name(int p_port) const {
7155 return "result";
7156}
7157
7158bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const {
7159 if (p_port == 2) {
7160 return false;
7161 }
7162 return true;
7163}
7164
7165String VisualShaderNodeFresnel::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 {
7166 String normal;
7167 String view;
7168 if (p_input_vars[0].is_empty()) {
7169 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
7170 normal = "NORMAL";
7171 } else {
7172 normal = "vec3(0.0)";
7173 }
7174 } else {
7175 normal = p_input_vars[0];
7176 }
7177 if (p_input_vars[1].is_empty()) {
7178 if (p_mode == Shader::MODE_SPATIAL) {
7179 view = "VIEW";
7180 } else {
7181 view = "vec3(0.0)";
7182 }
7183 } else {
7184 view = p_input_vars[1];
7185 }
7186
7187 if (is_input_port_connected(2)) {
7188 return " " + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n";
7189 } else {
7190 if (get_input_port_default_value(2)) {
7191 return " " + p_output_vars[0] + " = pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
7192 } else {
7193 return " " + p_output_vars[0] + " = pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n";
7194 }
7195 }
7196}
7197
7198bool VisualShaderNodeFresnel::is_input_port_default(int p_port, Shader::Mode p_mode) const {
7199 if (p_port == 0) {
7200 if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
7201 return true;
7202 }
7203 } else if (p_port == 1) {
7204 if (p_mode == Shader::MODE_SPATIAL) {
7205 return true;
7206 }
7207 }
7208 return false;
7209}
7210
7211VisualShaderNodeFresnel::VisualShaderNodeFresnel() {
7212 set_input_port_default_value(2, false);
7213 set_input_port_default_value(3, 1.0);
7214}
7215
7216////////////// Is
7217
7218String VisualShaderNodeIs::get_caption() const {
7219 return "Is";
7220}
7221
7222int VisualShaderNodeIs::get_input_port_count() const {
7223 return 1;
7224}
7225
7226VisualShaderNodeIs::PortType VisualShaderNodeIs::get_input_port_type(int p_port) const {
7227 return PORT_TYPE_SCALAR;
7228}
7229
7230String VisualShaderNodeIs::get_input_port_name(int p_port) const {
7231 return "";
7232}
7233
7234int VisualShaderNodeIs::get_output_port_count() const {
7235 return 1;
7236}
7237
7238VisualShaderNodeIs::PortType VisualShaderNodeIs::get_output_port_type(int p_port) const {
7239 return PORT_TYPE_BOOLEAN;
7240}
7241
7242String VisualShaderNodeIs::get_output_port_name(int p_port) const {
7243 return "";
7244}
7245
7246String VisualShaderNodeIs::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 {
7247 static const char *functions[FUNC_MAX] = {
7248 "isinf($)",
7249 "isnan($)"
7250 };
7251
7252 String code;
7253 code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
7254 return code;
7255}
7256
7257void VisualShaderNodeIs::set_function(Function p_func) {
7258 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
7259 if (func == p_func) {
7260 return;
7261 }
7262 func = p_func;
7263 emit_changed();
7264}
7265
7266VisualShaderNodeIs::Function VisualShaderNodeIs::get_function() const {
7267 return func;
7268}
7269
7270Vector<StringName> VisualShaderNodeIs::get_editable_properties() const {
7271 Vector<StringName> props;
7272 props.push_back("function");
7273 return props;
7274}
7275
7276void VisualShaderNodeIs::_bind_methods() {
7277 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIs::set_function);
7278 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIs::get_function);
7279
7280 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Inf,NaN"), "set_function", "get_function");
7281
7282 BIND_ENUM_CONSTANT(FUNC_IS_INF);
7283 BIND_ENUM_CONSTANT(FUNC_IS_NAN);
7284 BIND_ENUM_CONSTANT(FUNC_MAX);
7285}
7286
7287VisualShaderNodeIs::VisualShaderNodeIs() {
7288 set_input_port_default_value(0, 0.0);
7289}
7290
7291////////////// Compare
7292
7293String VisualShaderNodeCompare::get_caption() const {
7294 return "Compare";
7295}
7296
7297int VisualShaderNodeCompare::get_input_port_count() const {
7298 if (comparison_type == CTYPE_SCALAR && (func == FUNC_EQUAL || func == FUNC_NOT_EQUAL)) {
7299 return 3;
7300 }
7301 return 2;
7302}
7303
7304VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const {
7305 switch (comparison_type) {
7306 case CTYPE_SCALAR:
7307 return PORT_TYPE_SCALAR;
7308 case CTYPE_SCALAR_INT:
7309 return PORT_TYPE_SCALAR_INT;
7310 case CTYPE_SCALAR_UINT:
7311 return PORT_TYPE_SCALAR_UINT;
7312 case CTYPE_VECTOR_2D:
7313 return PORT_TYPE_VECTOR_2D;
7314 case CTYPE_VECTOR_3D:
7315 return PORT_TYPE_VECTOR_3D;
7316 case CTYPE_VECTOR_4D:
7317 return PORT_TYPE_VECTOR_4D;
7318 case CTYPE_BOOLEAN:
7319 return PORT_TYPE_BOOLEAN;
7320 case CTYPE_TRANSFORM:
7321 return PORT_TYPE_TRANSFORM;
7322 default:
7323 return PORT_TYPE_SCALAR;
7324 }
7325}
7326
7327String VisualShaderNodeCompare::get_input_port_name(int p_port) const {
7328 if (p_port == 0) {
7329 return "a";
7330 } else if (p_port == 1) {
7331 return "b";
7332 } else if (p_port == 2) {
7333 return "tolerance";
7334 }
7335 return "";
7336}
7337
7338int VisualShaderNodeCompare::get_output_port_count() const {
7339 return 1;
7340}
7341
7342VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_output_port_type(int p_port) const {
7343 return PORT_TYPE_BOOLEAN;
7344}
7345
7346String VisualShaderNodeCompare::get_output_port_name(int p_port) const {
7347 if (p_port == 0) {
7348 return "result";
7349 }
7350 return "";
7351}
7352
7353String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
7354 if (comparison_type == CTYPE_BOOLEAN || comparison_type == CTYPE_TRANSFORM) {
7355 if (func > FUNC_NOT_EQUAL) {
7356 return RTR("Invalid comparison function for that type.");
7357 }
7358 }
7359 return "";
7360}
7361
7362String VisualShaderNodeCompare::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 {
7363 static const char *operators[FUNC_MAX] = {
7364 "==",
7365 "!=",
7366 ">",
7367 ">=",
7368 "<",
7369 "<=",
7370 };
7371
7372 static const char *functions[FUNC_MAX] = {
7373 "equal($)",
7374 "notEqual($)",
7375 "greaterThan($)",
7376 "greaterThanEqual($)",
7377 "lessThan($)",
7378 "lessThanEqual($)",
7379 };
7380
7381 static const char *conditions[COND_MAX] = {
7382 "all($)",
7383 "any($)",
7384 };
7385
7386 String code;
7387 switch (comparison_type) {
7388 case CTYPE_SCALAR: {
7389 if (func == FUNC_EQUAL) {
7390 code += " " + p_output_vars[0] + " = (abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");";
7391 } else if (func == FUNC_NOT_EQUAL) {
7392 code += " " + p_output_vars[0] + " = !(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");";
7393 } else {
7394 code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
7395 }
7396 } break;
7397 case CTYPE_SCALAR_UINT:
7398 case CTYPE_SCALAR_INT: {
7399 code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
7400 } break;
7401 case CTYPE_VECTOR_2D: {
7402 code += " {\n";
7403 code += " bvec2 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n";
7404 code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n";
7405 code += " }\n";
7406 } break;
7407 case CTYPE_VECTOR_3D: {
7408 code += " {\n";
7409 code += " bvec3 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n";
7410 code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n";
7411 code += " }\n";
7412 } break;
7413 case CTYPE_VECTOR_4D: {
7414 code += " {\n";
7415 code += " bvec4 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n";
7416 code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n";
7417 code += " }\n";
7418 } break;
7419 case CTYPE_BOOLEAN: {
7420 if (func > FUNC_NOT_EQUAL) {
7421 return " " + p_output_vars[0] + " = false;\n";
7422 }
7423 code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
7424 } break;
7425 case CTYPE_TRANSFORM: {
7426 if (func > FUNC_NOT_EQUAL) {
7427 return " " + p_output_vars[0] + " = false;\n";
7428 }
7429 code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
7430 } break;
7431 default:
7432 break;
7433 }
7434 return code;
7435}
7436
7437void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_comparison_type) {
7438 ERR_FAIL_INDEX(int(p_comparison_type), int(CTYPE_MAX));
7439 if (comparison_type == p_comparison_type) {
7440 return;
7441 }
7442 switch (p_comparison_type) {
7443 case CTYPE_SCALAR:
7444 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
7445 set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
7446 simple_decl = true;
7447 break;
7448 case CTYPE_SCALAR_UINT:
7449 case CTYPE_SCALAR_INT:
7450 set_input_port_default_value(0, 0, get_input_port_default_value(0));
7451 set_input_port_default_value(1, 0, get_input_port_default_value(1));
7452 simple_decl = true;
7453 break;
7454 case CTYPE_VECTOR_2D:
7455 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
7456 set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
7457 simple_decl = false;
7458 break;
7459 case CTYPE_VECTOR_3D:
7460 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
7461 set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
7462 simple_decl = false;
7463 break;
7464 case CTYPE_VECTOR_4D:
7465 set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0));
7466 set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
7467 simple_decl = false;
7468 break;
7469 case CTYPE_BOOLEAN:
7470 set_input_port_default_value(0, false);
7471 set_input_port_default_value(1, false);
7472 simple_decl = true;
7473 break;
7474 case CTYPE_TRANSFORM:
7475 set_input_port_default_value(0, Transform3D());
7476 set_input_port_default_value(1, Transform3D());
7477 simple_decl = true;
7478 break;
7479 default:
7480 break;
7481 }
7482 comparison_type = p_comparison_type;
7483 emit_changed();
7484}
7485
7486VisualShaderNodeCompare::ComparisonType VisualShaderNodeCompare::get_comparison_type() const {
7487 return comparison_type;
7488}
7489
7490void VisualShaderNodeCompare::set_function(Function p_func) {
7491 ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
7492 if (func == p_func) {
7493 return;
7494 }
7495 func = p_func;
7496 emit_changed();
7497}
7498
7499VisualShaderNodeCompare::Function VisualShaderNodeCompare::get_function() const {
7500 return func;
7501}
7502
7503void VisualShaderNodeCompare::set_condition(Condition p_condition) {
7504 ERR_FAIL_INDEX(int(p_condition), int(COND_MAX));
7505 if (condition == p_condition) {
7506 return;
7507 }
7508 condition = p_condition;
7509 emit_changed();
7510}
7511
7512VisualShaderNodeCompare::Condition VisualShaderNodeCompare::get_condition() const {
7513 return condition;
7514}
7515
7516Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const {
7517 Vector<StringName> props;
7518 props.push_back("type");
7519 props.push_back("function");
7520 if (comparison_type == CTYPE_VECTOR_2D || comparison_type == CTYPE_VECTOR_3D || comparison_type == CTYPE_VECTOR_4D) {
7521 props.push_back("condition");
7522 }
7523 return props;
7524}
7525
7526void VisualShaderNodeCompare::_bind_methods() {
7527 ClassDB::bind_method(D_METHOD("set_comparison_type", "type"), &VisualShaderNodeCompare::set_comparison_type);
7528 ClassDB::bind_method(D_METHOD("get_comparison_type"), &VisualShaderNodeCompare::get_comparison_type);
7529
7530 ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeCompare::set_function);
7531 ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeCompare::get_function);
7532
7533 ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition);
7534 ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition);
7535
7536 ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,UInt,Vector2,Vector3,Vector4,Boolean,Transform"), "set_comparison_type", "get_comparison_type");
7537 ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function");
7538 ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition");
7539
7540 BIND_ENUM_CONSTANT(CTYPE_SCALAR);
7541 BIND_ENUM_CONSTANT(CTYPE_SCALAR_INT);
7542 BIND_ENUM_CONSTANT(CTYPE_SCALAR_UINT);
7543 BIND_ENUM_CONSTANT(CTYPE_VECTOR_2D);
7544 BIND_ENUM_CONSTANT(CTYPE_VECTOR_3D);
7545 BIND_ENUM_CONSTANT(CTYPE_VECTOR_4D);
7546 BIND_ENUM_CONSTANT(CTYPE_BOOLEAN);
7547 BIND_ENUM_CONSTANT(CTYPE_TRANSFORM);
7548 BIND_ENUM_CONSTANT(CTYPE_MAX);
7549
7550 BIND_ENUM_CONSTANT(FUNC_EQUAL);
7551 BIND_ENUM_CONSTANT(FUNC_NOT_EQUAL);
7552 BIND_ENUM_CONSTANT(FUNC_GREATER_THAN);
7553 BIND_ENUM_CONSTANT(FUNC_GREATER_THAN_EQUAL);
7554 BIND_ENUM_CONSTANT(FUNC_LESS_THAN);
7555 BIND_ENUM_CONSTANT(FUNC_LESS_THAN_EQUAL);
7556 BIND_ENUM_CONSTANT(FUNC_MAX);
7557
7558 BIND_ENUM_CONSTANT(COND_ALL);
7559 BIND_ENUM_CONSTANT(COND_ANY);
7560 BIND_ENUM_CONSTANT(COND_MAX);
7561}
7562
7563VisualShaderNodeCompare::VisualShaderNodeCompare() {
7564 set_input_port_default_value(0, 0.0);
7565 set_input_port_default_value(1, 0.0);
7566 set_input_port_default_value(2, CMP_EPSILON);
7567}
7568
7569////////////// Fma
7570
7571String VisualShaderNodeMultiplyAdd::get_caption() const {
7572 return "MultiplyAdd";
7573}
7574
7575int VisualShaderNodeMultiplyAdd::get_input_port_count() const {
7576 return 3;
7577}
7578
7579VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const {
7580 switch (op_type) {
7581 case OP_TYPE_VECTOR_2D:
7582 return PORT_TYPE_VECTOR_2D;
7583 case OP_TYPE_VECTOR_3D:
7584 return PORT_TYPE_VECTOR_3D;
7585 case OP_TYPE_VECTOR_4D:
7586 return PORT_TYPE_VECTOR_4D;
7587 default:
7588 break;
7589 }
7590 return PORT_TYPE_SCALAR;
7591}
7592
7593String VisualShaderNodeMultiplyAdd::get_input_port_name(int p_port) const {
7594 if (p_port == 0) {
7595 return "a";
7596 } else if (p_port == 1) {
7597 return "b(*)";
7598 } else if (p_port == 2) {
7599 return "c(+)";
7600 }
7601 return "";
7602}
7603
7604int VisualShaderNodeMultiplyAdd::get_output_port_count() const {
7605 return 1;
7606}
7607
7608VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_output_port_type(int p_port) const {
7609 switch (op_type) {
7610 case OP_TYPE_VECTOR_2D:
7611 return PORT_TYPE_VECTOR_2D;
7612 case OP_TYPE_VECTOR_3D:
7613 return PORT_TYPE_VECTOR_3D;
7614 case OP_TYPE_VECTOR_4D:
7615 return PORT_TYPE_VECTOR_4D;
7616 default:
7617 break;
7618 }
7619 return PORT_TYPE_SCALAR;
7620}
7621
7622String VisualShaderNodeMultiplyAdd::get_output_port_name(int p_port) const {
7623 return "";
7624}
7625
7626String VisualShaderNodeMultiplyAdd::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 {
7627 if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
7628 return " " + p_output_vars[0] + " = (" + p_input_vars[0] + " * " + p_input_vars[1] + ") + " + p_input_vars[2] + ";\n";
7629 }
7630 return " " + p_output_vars[0] + " = fma(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
7631}
7632
7633void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) {
7634 ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX));
7635 if (op_type == p_op_type) {
7636 return;
7637 }
7638 switch (p_op_type) {
7639 case OP_TYPE_SCALAR: {
7640 set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
7641 set_input_port_default_value(1, 1.0, get_input_port_default_value(1));
7642 set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
7643 } break;
7644 case OP_TYPE_VECTOR_2D: {
7645 set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
7646 set_input_port_default_value(1, Vector2(1.0, 1.0), get_input_port_default_value(1));
7647 set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
7648 } break;
7649 case OP_TYPE_VECTOR_3D: {
7650 set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
7651 set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0), get_input_port_default_value(1));
7652 set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
7653 } break;
7654 case OP_TYPE_VECTOR_4D: {
7655 set_input_port_default_value(0, Vector4(), get_input_port_default_value(0));
7656 set_input_port_default_value(1, Vector4(1.0, 1.0, 1.0, 1.0), get_input_port_default_value(1));
7657 set_input_port_default_value(2, Vector4(), get_input_port_default_value(2));
7658 } break;
7659 default:
7660 break;
7661 }
7662 op_type = p_op_type;
7663 emit_changed();
7664}
7665
7666VisualShaderNodeMultiplyAdd::OpType VisualShaderNodeMultiplyAdd::get_op_type() const {
7667 return op_type;
7668}
7669
7670Vector<StringName> VisualShaderNodeMultiplyAdd::get_editable_properties() const {
7671 Vector<StringName> props;
7672 props.push_back("op_type");
7673 return props;
7674}
7675
7676void VisualShaderNodeMultiplyAdd::_bind_methods() {
7677 ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMultiplyAdd::set_op_type);
7678 ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMultiplyAdd::get_op_type);
7679
7680 ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
7681
7682 BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
7683 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
7684 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
7685 BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
7686 BIND_ENUM_CONSTANT(OP_TYPE_MAX);
7687}
7688
7689VisualShaderNodeMultiplyAdd::VisualShaderNodeMultiplyAdd() {
7690 set_input_port_default_value(0, 0.0);
7691 set_input_port_default_value(1, 1.0);
7692 set_input_port_default_value(2, 0.0);
7693}
7694
7695////////////// Billboard
7696
7697String VisualShaderNodeBillboard::get_caption() const {
7698 return "GetBillboardMatrix";
7699}
7700
7701int VisualShaderNodeBillboard::get_input_port_count() const {
7702 return 0;
7703}
7704
7705VisualShaderNodeBillboard::PortType VisualShaderNodeBillboard::get_input_port_type(int p_port) const {
7706 return PORT_TYPE_SCALAR;
7707}
7708
7709String VisualShaderNodeBillboard::get_input_port_name(int p_port) const {
7710 return "";
7711}
7712
7713int VisualShaderNodeBillboard::get_output_port_count() const {
7714 return 1;
7715}
7716
7717VisualShaderNodeBillboard::PortType VisualShaderNodeBillboard::get_output_port_type(int p_port) const {
7718 return PORT_TYPE_TRANSFORM;
7719}
7720
7721String VisualShaderNodeBillboard::get_output_port_name(int p_port) const {
7722 return "model_view_matrix";
7723}
7724
7725String VisualShaderNodeBillboard::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 {
7726 String code;
7727
7728 switch (billboard_type) {
7729 case BILLBOARD_TYPE_ENABLED:
7730 code += " {\n";
7731 code += " mat4 __mvm = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n";
7732 if (keep_scale) {
7733 code += " __mvm = __mvm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
7734 }
7735 code += " " + p_output_vars[0] + " = __mvm;\n";
7736 code += " }\n";
7737 break;
7738 case BILLBOARD_TYPE_FIXED_Y:
7739 code += " {\n";
7740 code += " mat4 __mvm = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], MODEL_MATRIX[1], vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, MODEL_MATRIX[1].xyz)), 0.0), MODEL_MATRIX[3]);\n";
7741 if (keep_scale) {
7742 code += " __mvm = __mvm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
7743 } else {
7744 code += " __mvm = __mvm * mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0 / length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
7745 }
7746 code += " " + p_output_vars[0] + " = __mvm;\n";
7747 code += " }\n";
7748 break;
7749 case BILLBOARD_TYPE_PARTICLES:
7750 code += " {\n";
7751 code += " mat4 __wm = mat4(normalize(INV_VIEW_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]), normalize(INV_VIEW_MATRIX[2]), MODEL_MATRIX[3]);\n";
7752 code += " __wm = __wm * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
7753 if (keep_scale) {
7754 code += " __wm = __wm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
7755 }
7756 code += " " + p_output_vars[0] + " = VIEW_MATRIX * __wm;\n";
7757 code += " }\n";
7758 break;
7759 default:
7760 code += " " + p_output_vars[0] + " = mat4(1.0);\n";
7761 break;
7762 }
7763
7764 return code;
7765}
7766
7767bool VisualShaderNodeBillboard::is_show_prop_names() const {
7768 return true;
7769}
7770
7771void VisualShaderNodeBillboard::set_billboard_type(BillboardType p_billboard_type) {
7772 ERR_FAIL_INDEX(int(p_billboard_type), int(BILLBOARD_TYPE_MAX));
7773 if (billboard_type == p_billboard_type) {
7774 return;
7775 }
7776 billboard_type = p_billboard_type;
7777 simple_decl = bool(billboard_type == BILLBOARD_TYPE_DISABLED);
7778 set_disabled(simple_decl);
7779 emit_changed();
7780}
7781
7782VisualShaderNodeBillboard::BillboardType VisualShaderNodeBillboard::get_billboard_type() const {
7783 return billboard_type;
7784}
7785
7786void VisualShaderNodeBillboard::set_keep_scale_enabled(bool p_enabled) {
7787 keep_scale = p_enabled;
7788 emit_changed();
7789}
7790
7791bool VisualShaderNodeBillboard::is_keep_scale_enabled() const {
7792 return keep_scale;
7793}
7794
7795Vector<StringName> VisualShaderNodeBillboard::get_editable_properties() const {
7796 Vector<StringName> props;
7797 props.push_back("billboard_type");
7798 if (billboard_type == BILLBOARD_TYPE_ENABLED || billboard_type == BILLBOARD_TYPE_FIXED_Y || billboard_type == BILLBOARD_TYPE_PARTICLES) {
7799 props.push_back("keep_scale");
7800 }
7801 return props;
7802}
7803
7804void VisualShaderNodeBillboard::_bind_methods() {
7805 ClassDB::bind_method(D_METHOD("set_billboard_type", "billboard_type"), &VisualShaderNodeBillboard::set_billboard_type);
7806 ClassDB::bind_method(D_METHOD("get_billboard_type"), &VisualShaderNodeBillboard::get_billboard_type);
7807
7808 ClassDB::bind_method(D_METHOD("set_keep_scale_enabled", "enabled"), &VisualShaderNodeBillboard::set_keep_scale_enabled);
7809 ClassDB::bind_method(D_METHOD("is_keep_scale_enabled"), &VisualShaderNodeBillboard::is_keep_scale_enabled);
7810
7811 ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_type", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particles"), "set_billboard_type", "get_billboard_type");
7812 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_scale"), "set_keep_scale_enabled", "is_keep_scale_enabled");
7813
7814 BIND_ENUM_CONSTANT(BILLBOARD_TYPE_DISABLED);
7815 BIND_ENUM_CONSTANT(BILLBOARD_TYPE_ENABLED);
7816 BIND_ENUM_CONSTANT(BILLBOARD_TYPE_FIXED_Y);
7817 BIND_ENUM_CONSTANT(BILLBOARD_TYPE_PARTICLES);
7818 BIND_ENUM_CONSTANT(BILLBOARD_TYPE_MAX);
7819}
7820
7821VisualShaderNodeBillboard::VisualShaderNodeBillboard() {
7822 simple_decl = false;
7823}
7824
7825////////////// DistanceFade
7826
7827String VisualShaderNodeDistanceFade::get_caption() const {
7828 return "DistanceFade";
7829}
7830
7831int VisualShaderNodeDistanceFade::get_input_port_count() const {
7832 return 2;
7833}
7834
7835VisualShaderNodeDistanceFade::PortType VisualShaderNodeDistanceFade::get_input_port_type(int p_port) const {
7836 switch (p_port) {
7837 case 0:
7838 return PORT_TYPE_SCALAR;
7839 case 1:
7840 return PORT_TYPE_SCALAR;
7841 }
7842
7843 return PORT_TYPE_SCALAR;
7844}
7845
7846String VisualShaderNodeDistanceFade::get_input_port_name(int p_port) const {
7847 switch (p_port) {
7848 case 0:
7849 return "min";
7850 case 1:
7851 return "max";
7852 }
7853
7854 return "";
7855}
7856
7857int VisualShaderNodeDistanceFade::get_output_port_count() const {
7858 return 1;
7859}
7860
7861VisualShaderNodeDistanceFade::PortType VisualShaderNodeDistanceFade::get_output_port_type(int p_port) const {
7862 return PORT_TYPE_SCALAR;
7863}
7864
7865String VisualShaderNodeDistanceFade::get_output_port_name(int p_port) const {
7866 return "amount";
7867}
7868
7869bool VisualShaderNodeDistanceFade::has_output_port_preview(int p_port) const {
7870 return false;
7871}
7872
7873String VisualShaderNodeDistanceFade::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 {
7874 String code;
7875 code += vformat(" %s = clamp(smoothstep(%s, %s,-VERTEX.z),0.0,1.0);\n", p_output_vars[0], p_input_vars[0], p_input_vars[1]);
7876 return code;
7877}
7878
7879VisualShaderNodeDistanceFade::VisualShaderNodeDistanceFade() {
7880 set_input_port_default_value(0, 0.0);
7881 set_input_port_default_value(1, 10.0);
7882}
7883
7884////////////// ProximityFade
7885
7886String VisualShaderNodeProximityFade::get_caption() const {
7887 return "ProximityFade";
7888}
7889
7890int VisualShaderNodeProximityFade::get_input_port_count() const {
7891 return 1;
7892}
7893
7894VisualShaderNodeProximityFade::PortType VisualShaderNodeProximityFade::get_input_port_type(int p_port) const {
7895 return PORT_TYPE_SCALAR;
7896}
7897
7898String VisualShaderNodeProximityFade::get_input_port_name(int p_port) const {
7899 return "distance";
7900}
7901
7902int VisualShaderNodeProximityFade::get_output_port_count() const {
7903 return 1;
7904}
7905
7906VisualShaderNodeProximityFade::PortType VisualShaderNodeProximityFade::get_output_port_type(int p_port) const {
7907 return PORT_TYPE_SCALAR;
7908}
7909
7910String VisualShaderNodeProximityFade::get_output_port_name(int p_port) const {
7911 return "fade";
7912}
7913
7914bool VisualShaderNodeProximityFade::has_output_port_preview(int p_port) const {
7915 return false;
7916}
7917
7918String VisualShaderNodeProximityFade::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
7919 return "uniform sampler2D " + make_unique_id(p_type, p_id, "depth_tex") + " : hint_depth_texture;\n";
7920}
7921
7922String VisualShaderNodeProximityFade::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 {
7923 String code;
7924 code += " {\n";
7925
7926 code += " float __depth_tex = texture(" + make_unique_id(p_type, p_id, "depth_tex") + ", SCREEN_UV).r;\n";
7927 if (!RenderingServer::get_singleton()->is_low_end()) {
7928 code += " vec4 __depth_world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, __depth_tex, 1.0);\n";
7929 } else {
7930 code += " vec4 __depth_world_pos = INV_PROJECTION_MATRIX * vec4(vec3(SCREEN_UV, __depth_tex) * 2.0 - 1.0, 1.0);\n";
7931 }
7932 code += " __depth_world_pos.xyz /= __depth_world_pos.w;\n";
7933 code += vformat(" %s = clamp(1.0 - smoothstep(__depth_world_pos.z + %s, __depth_world_pos.z, VERTEX.z), 0.0, 1.0);\n", p_output_vars[0], p_input_vars[0]);
7934
7935 code += " }\n";
7936 return code;
7937}
7938
7939VisualShaderNodeProximityFade::VisualShaderNodeProximityFade() {
7940 set_input_port_default_value(0, 1.0);
7941
7942 simple_decl = false;
7943}
7944
7945////////////// Random Range
7946
7947String VisualShaderNodeRandomRange::get_caption() const {
7948 return "RandomRange";
7949}
7950
7951int VisualShaderNodeRandomRange::get_input_port_count() const {
7952 return 3;
7953}
7954
7955VisualShaderNodeRandomRange::PortType VisualShaderNodeRandomRange::get_input_port_type(int p_port) const {
7956 switch (p_port) {
7957 case 0:
7958 return PORT_TYPE_VECTOR_3D;
7959 case 1:
7960 return PORT_TYPE_SCALAR;
7961 case 2:
7962 return PORT_TYPE_SCALAR;
7963 default:
7964 break;
7965 }
7966
7967 return PORT_TYPE_SCALAR;
7968}
7969
7970String VisualShaderNodeRandomRange::get_input_port_name(int p_port) const {
7971 switch (p_port) {
7972 case 0:
7973 return "seed";
7974 case 1:
7975 return "min";
7976 case 2:
7977 return "max";
7978 default:
7979 break;
7980 }
7981
7982 return "";
7983}
7984
7985int VisualShaderNodeRandomRange::get_output_port_count() const {
7986 return 1;
7987}
7988
7989VisualShaderNodeRandomRange::PortType VisualShaderNodeRandomRange::get_output_port_type(int p_port) const {
7990 return PORT_TYPE_SCALAR;
7991}
7992
7993String VisualShaderNodeRandomRange::get_output_port_name(int p_port) const {
7994 return "value";
7995}
7996
7997String VisualShaderNodeRandomRange::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
7998 String code;
7999
8000 code += "\n\n";
8001 code += "// 3D Noise with friendly permission by Inigo Quilez\n";
8002 code += "vec3 hash_noise_range( vec3 p ) {\n";
8003 code += " p *= mat3(vec3(127.1, 311.7, -53.7), vec3(269.5, 183.3, 77.1), vec3(-301.7, 27.3, 215.3));\n";
8004 code += " return 2.0 * fract(fract(p)*4375.55) -1.;\n";
8005 code += "}\n";
8006 code += "\n";
8007
8008 return code;
8009}
8010
8011String VisualShaderNodeRandomRange::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 {
8012 String code;
8013
8014 code += vformat(" %s = mix(%s, %s, hash_noise_range(%s).x);\n", p_output_vars[0], p_input_vars[1], p_input_vars[2], p_input_vars[0]);
8015
8016 return code;
8017}
8018
8019VisualShaderNodeRandomRange::VisualShaderNodeRandomRange() {
8020 set_input_port_default_value(0, Vector3(1.0, 1.0, 1.0));
8021 set_input_port_default_value(1, 0.0);
8022 set_input_port_default_value(2, 1.0);
8023}
8024
8025////////////// Remap
8026
8027String VisualShaderNodeRemap::get_caption() const {
8028 return "Remap";
8029}
8030
8031int VisualShaderNodeRemap::get_input_port_count() const {
8032 return 5;
8033}
8034
8035VisualShaderNodeRemap::PortType VisualShaderNodeRemap::get_input_port_type(int p_port) const {
8036 switch (p_port) {
8037 case 0:
8038 return PORT_TYPE_SCALAR;
8039 case 1:
8040 return PORT_TYPE_SCALAR;
8041 case 2:
8042 return PORT_TYPE_SCALAR;
8043 case 3:
8044 return PORT_TYPE_SCALAR;
8045 case 4:
8046 return PORT_TYPE_SCALAR;
8047 default:
8048 break;
8049 }
8050
8051 return PORT_TYPE_SCALAR;
8052}
8053
8054String VisualShaderNodeRemap::get_input_port_name(int p_port) const {
8055 switch (p_port) {
8056 case 0:
8057 return "value";
8058 case 1:
8059 return "input min";
8060 case 2:
8061 return "input max";
8062 case 3:
8063 return "output min";
8064 case 4:
8065 return "output max";
8066 default:
8067 break;
8068 }
8069
8070 return "";
8071}
8072
8073int VisualShaderNodeRemap::get_output_port_count() const {
8074 return 1;
8075}
8076
8077VisualShaderNodeRemap::PortType VisualShaderNodeRemap::get_output_port_type(int p_port) const {
8078 return PORT_TYPE_SCALAR;
8079}
8080
8081String VisualShaderNodeRemap::get_output_port_name(int p_port) const {
8082 return "value";
8083}
8084
8085String VisualShaderNodeRemap::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 {
8086 String code;
8087 code += " {\n";
8088 code += vformat(" float __input_range = %s - %s;\n", p_input_vars[2], p_input_vars[1]);
8089 code += vformat(" float __output_range = %s - %s;\n", p_input_vars[4], p_input_vars[3]);
8090 code += vformat(" %s = %s + __output_range * ((%s - %s) / __input_range);\n", p_output_vars[0], p_input_vars[3], p_input_vars[0], p_input_vars[1]);
8091 code += " }\n";
8092 return code;
8093}
8094
8095VisualShaderNodeRemap::VisualShaderNodeRemap() {
8096 set_input_port_default_value(1, 0.0);
8097 set_input_port_default_value(2, 1.0);
8098 set_input_port_default_value(3, 0.0);
8099 set_input_port_default_value(4, 1.0);
8100
8101 simple_decl = false;
8102}
8103
8104////////////// RotationByAxis
8105
8106String VisualShaderNodeRotationByAxis::get_caption() const {
8107 return "RotationByAxis";
8108}
8109
8110int VisualShaderNodeRotationByAxis::get_input_port_count() const {
8111 return 3;
8112}
8113
8114VisualShaderNodeRotationByAxis::PortType VisualShaderNodeRotationByAxis::get_input_port_type(int p_port) const {
8115 switch (p_port) {
8116 case 0:
8117 return PORT_TYPE_VECTOR_3D;
8118 case 1:
8119 return PORT_TYPE_SCALAR;
8120 case 2:
8121 return PORT_TYPE_VECTOR_3D;
8122 default:
8123 break;
8124 }
8125
8126 return PORT_TYPE_SCALAR;
8127}
8128
8129String VisualShaderNodeRotationByAxis::get_input_port_name(int p_port) const {
8130 switch (p_port) {
8131 case 0:
8132 return "input";
8133 case 1:
8134 return "angle";
8135 case 2:
8136 return "axis";
8137 default:
8138 break;
8139 }
8140
8141 return "";
8142}
8143
8144int VisualShaderNodeRotationByAxis::get_output_port_count() const {
8145 return 2;
8146}
8147
8148VisualShaderNodeRotationByAxis::PortType VisualShaderNodeRotationByAxis::get_output_port_type(int p_port) const {
8149 switch (p_port) {
8150 case 0:
8151 return PORT_TYPE_VECTOR_3D;
8152 case 1:
8153 return PORT_TYPE_TRANSFORM;
8154 default:
8155 break;
8156 }
8157
8158 return PORT_TYPE_SCALAR;
8159}
8160
8161String VisualShaderNodeRotationByAxis::get_output_port_name(int p_port) const {
8162 switch (p_port) {
8163 case 0:
8164 return "output";
8165 case 1:
8166 return "rotationMat";
8167 default:
8168 break;
8169 }
8170
8171 return "";
8172}
8173
8174bool VisualShaderNodeRotationByAxis::has_output_port_preview(int p_port) const {
8175 return false;
8176}
8177
8178String VisualShaderNodeRotationByAxis::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 {
8179 String code;
8180 code += " {\n";
8181 code += vformat(" float __angle = %s;\n", p_input_vars[1]);
8182 code += vformat(" vec3 __axis = normalize(%s);\n", p_input_vars[2]);
8183 code += vformat(" mat3 __rot_matrix = mat3(\n");
8184 code += vformat(" vec3( cos(__angle)+__axis.x*__axis.x*(1.0 - cos(__angle)), __axis.x*__axis.y*(1.0-cos(__angle))-__axis.z*sin(__angle), __axis.x*__axis.z*(1.0-cos(__angle))+__axis.y*sin(__angle) ),\n");
8185 code += vformat(" vec3( __axis.y*__axis.x*(1.0-cos(__angle))+__axis.z*sin(__angle), cos(__angle)+__axis.y*__axis.y*(1.0-cos(__angle)), __axis.y*__axis.z*(1.0-cos(__angle))-__axis.x*sin(__angle) ),\n");
8186 code += vformat(" vec3( __axis.z*__axis.x*(1.0-cos(__angle))-__axis.y*sin(__angle), __axis.z*__axis.y*(1.0-cos(__angle))+__axis.x*sin(__angle), cos(__angle)+__axis.z*__axis.z*(1.0-cos(__angle)) )\n");
8187 code += vformat(" );\n");
8188 code += vformat(" %s = %s * __rot_matrix;\n", p_output_vars[0], p_input_vars[0]);
8189 code += vformat(" %s = mat4(__rot_matrix);\n", p_output_vars[1]);
8190 code += " }\n";
8191 return code;
8192}
8193
8194VisualShaderNodeRotationByAxis::VisualShaderNodeRotationByAxis() {
8195 set_input_port_default_value(1, 0.0);
8196 set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
8197
8198 simple_decl = false;
8199}
8200