Pixel-Composer/scripts/node_custom_shader/node_custom_shader.gml
2025-01-10 09:04:53 +07:00

205 lines
No EOL
6.2 KiB
Text

#region shader cache
globalvar SHADER_CACHE;
SHADER_CACHE = {};
function shader_compile_vs(file) {
if(struct_has(SHADER_CACHE, file)) return SHADER_CACHE[$ file];
var _sh = d3d11_shader_compile_vs(file, "main", "vs_4_0");
SHADER_CACHE[$ file] = _sh;
return _sh;
}
function shader_compile_ps(file) {
if(struct_has(SHADER_CACHE, file)) return SHADER_CACHE[$ file];
var _sh = d3d11_shader_compile_ps(file, "main", "ps_4_0");
SHADER_CACHE[$ file] = _sh;
return _sh;
}
#endregion
function Node_Custom_Shader(_x, _y, _group = noone, _param = {}) : Node_Processor(_x, _y, _group) constructor {
itype = _param[$ "iname"] ?? noone;
shader_vs = noone;
shader_fs = noone;
sourceDir = _param[$ "sourceDir"] ?? "";
dataPath = _param[$ "data"] ?? "";
uniforms = [];
surface_in_index = 0;
var _infoPath = sourceDir + "/" + dataPath;
if(file_exists_empty(_infoPath)) {
var info = json_load_struct(_infoPath);
var _dir = sourceDir;
shader_vs = shader_compile_vs($"{_dir}/{info.shader_vs}");
if(!d3d11_shader_exists(shader_vs)) noti_warning(d3d11_get_error_string());
shader_fs = shader_compile_ps($"{_dir}/{info.shader_fs}");
if(!d3d11_shader_exists(shader_fs)) noti_warning(d3d11_get_error_string());
inputs = [];
outputs = [];
for( var i = 0, n = array_length(info.inputs); i < n; i++ ) {
var _input = info.inputs[i];
var _name = _input.name;
var _type = _input.type;
var _valu = _input.value;
var _showIns = _input[$ "show_in_inspector"] ?? true;
var _showGra = _input[$ "show_in_graph"] ?? false;
var _flag = _input[$ "flag"];
var _unif = _input[$ "uniform"];
var _n = noone;
switch(_type) {
case "surface" : _n = nodeValue(_name, self, CONNECT_TYPE.input, VALUE_TYPE.surface, _valu); break;
case "float" : _n = nodeValue(_name, self, CONNECT_TYPE.input, VALUE_TYPE.float, _valu); break;
case "int" : _n = nodeValue(_name, self, CONNECT_TYPE.input, VALUE_TYPE.integer, _valu); break;
case "color" : _n = nodeValue(_name, self, CONNECT_TYPE.input, VALUE_TYPE.color, _valu); break;
}
if(_flag == "SURFACE_IN") {
_showGra = true;
surface_in_index = i;
}
newInput(i, _n).setVisible(_showIns, _showGra);
if(_unif != undefined) {
array_push(uniforms, {
uniform: _unif,
type: _type,
index: i
});
}
}
for( var i = 0, n = array_length(info.outputs); i < n; i++ ) {
var _output = info.outputs[i];
var _name = _output.name;
var _type = _output.type;
var _valu = _output.value;
var _showGra = _output[$ "show_in_graph"] ?? false;
var _flag = _output[$ "flag"];
newOutput(i, nodeValue_Output(_name, self, value_type_from_string(_type), _valu)).setVisible(_showGra);
}
if(struct_has(info, "input_display")) input_display_list = info.input_display;
if(struct_has(info, "output_display")) output_display_list = info.output_display;
}
static processData = function(_output, _data, _output_index, _array_index = 0) {
if(!d3d11_shader_exists(shader_vs)) return noone;
if(!d3d11_shader_exists(shader_fs)) return noone;
var _surf = _data[surface_in_index];
_output = surface_verify(_output, surface_get_width_safe(_surf), surface_get_height_safe(_surf));
surface_set_target(_output);
DRAW_CLEAR
d3d11_shader_override_vs(shader_vs);
d3d11_shader_override_ps(shader_fs);
d3d11_cbuffer_begin();
var _buffer = buffer_create(1, buffer_grow, 1);
var _sample = 1;
var _cbSize = 0;
for( var i = 0, n = array_length(uniforms); i < n; i++ ) {
var _unif = uniforms[i];
var _index = _unif.index;
var _utype = _unif.type;
var _value = _data[_index];
switch(_utype) {
case "float" : // u_float
d3d11_cbuffer_add_float(1);
_cbSize++;
buffer_write(_buffer, buffer_f32, _value);
break;
case "int" : // u_int
d3d11_cbuffer_add_int(1);
_cbSize++;
buffer_write(_buffer, buffer_s32, _value);
break;
case "vec2" : // u_vec2
case "vec3" : // u_vec3
case "vec4" : // u_vec4
case "mat3" : // u_mat3
case "mat4" : // u_mat4
if(is_array(_value)) {
d3d11_cbuffer_add_float(array_length(_value));
_cbSize += array_length(_value);
for( var j = 0, m = array_length(_value); j < m; j++ )
buffer_write(_buffer, buffer_f32, _value[j]);
}
break;
case "surface" : // u_sampler2D
if(is_surface(_value))
d3d11_texture_set_stage_ps(_sample, surface_get_texture(_value));
_sample++;
break;
case "color" : // u_vec4 color
var _clr = colToVec4(_value);
d3d11_cbuffer_add_float(4);
_cbSize += 4;
for( var j = 0, m = 4; j < m; j++ )
buffer_write(_buffer, buffer_f32, _clr[i]);
break;
}
}
d3d11_cbuffer_add_float(4 - _cbSize % 4);
var cbuff = d3d11_cbuffer_end();
d3d11_cbuffer_update(cbuff, _buffer);
buffer_delete(_buffer);
d3d11_shader_set_cbuffer_ps(10, cbuff);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
d3d11_cbuffer_begin();
var _buffer = buffer_create(1, buffer_grow, 1);
var _cbSize = 0;
buffer_write(_buffer, buffer_f32, surface_get_width_safe(_surf));
buffer_write(_buffer, buffer_f32, surface_get_height_safe(_surf));
d3d11_cbuffer_add_float(2); _cbSize += 2;
d3d11_cbuffer_add_float(4 - _cbSize % 4);
var cbuff = d3d11_cbuffer_end();
d3d11_cbuffer_update(cbuff, _buffer);
buffer_delete(_buffer);
d3d11_shader_set_cbuffer_ps(4, cbuff);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
matrix_set(matrix_world, matrix_build(0, 0, 0, 0, 0, 0, surface_get_width_safe(_surf), surface_get_height_safe(_surf), 1));
vertex_submit(global.HLSL_VB_PLANE, pr_trianglestrip, surface_get_texture(_surf));
matrix_set(matrix_world, matrix_build_identity());
d3d11_shader_override_vs(-1);
d3d11_shader_override_ps(-1);
surface_reset_target();
return _output;
}
}