Fix 3D defer normal for transparent texture.

This commit is contained in:
MakhamDev 2023-10-05 11:29:20 +07:00
parent b368270cac
commit b2cdc639df
34 changed files with 264 additions and 197 deletions

View file

@ -566,7 +566,7 @@ function Node_3D_Object(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constr
drag_cx = cx;
drag_cy = cy;
drag_val = _sca;
drag_val = [ _sca[0], _sca[1], _sca[2] ];
drag_original = new __vec3(_sca);
} #endregion
} #endregion
@ -598,6 +598,7 @@ function Node_3D_Object(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constr
object.transform.position.set(_pos[0], _pos[1], _pos[2]);
object.transform.rotation.set(_rot[0], _rot[1], _rot[2], _rot[3]);
object.transform.scale.set(_sca[0], _sca[1], _sca[2]);
return object;
} #endregion

View file

@ -31,19 +31,19 @@ function Node_Iterator(_x, _y, _group = noone) : Node_Collection(_x, _y, _group)
static outputNextNode = function() {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, "[outputNextNode] Get next node from Loop output");
LOG_IF(global.FLAG.render == 1, "[outputNextNode] Get next node from Loop output");
var _nodes = [];
for( var i = 0; i < ds_list_size(nodes); i++ ) { // check if every node is updated
if(!nodes[| i].rendered) {
LOG_IF(global.FLAG.render, $"Skipped due to node {nodes[| i].internalName} not rendered.");
LOG_IF(global.FLAG.render == 1, $"Skipped due to node {nodes[| i].internalName} not rendered.");
LOG_BLOCK_END();
return _nodes;
}
}
if(willRestart) {
LOG_IF(global.FLAG.render, $"Restart");
LOG_IF(global.FLAG.render == 1, $"Restart");
resetRender();
willRestart = false;
}
@ -51,10 +51,10 @@ function Node_Iterator(_x, _y, _group = noone) : Node_Collection(_x, _y, _group)
var _ren = iterationStatus();
if(_ren == ITERATION_STATUS.loop) { //Go back to the beginning of the loop, reset render status for leaf node inside?
LOG_IF(global.FLAG.render, $"Loop restart: iteration {iterated}");
LOG_IF(global.FLAG.render == 1, $"Loop restart: iteration {iterated}");
_nodes = array_append(_nodes, __nodeLeafList(getNodeList()));
} else if(_ren == ITERATION_STATUS.complete) { //Go out of loop
LOG_IF(global.FLAG.render, "Loop completed get next node external");
LOG_IF(global.FLAG.render == 1, "Loop completed get next node external");
setRenderStatus(true);
_nodes = getNextNodesExternal();
}

View file

@ -206,7 +206,7 @@ function __vec2(_x = 0, _y = _x) constructor {
return new __vec2(x, y);
} #endregion
static toString = function() { return $"[{x}, {y}]"; }
static toString = function() { return $"[__vec2] ({x}, {y})"; }
static toBBMOD = function() { return new BBMOD_Vec2(x, y); }

View file

@ -203,7 +203,7 @@ function __vec3(_x = 0, _y = _x, _z = _x) constructor {
return new __vec3(x, y, z);
} #endregion
static toString = function() { return $"[{x}, {y}, {z}]"; }
static toString = function() { return $"[__vec3] ({x}, {y}, {z})"; }
static toBBMOD = function() { return new BBMOD_Vec3(x, y, z); }

View file

@ -191,7 +191,7 @@ function __vec4(_x = 0, _y = _x, _z = _x, _w = _x) constructor {
return new __vec4(x, y, z, w);
}
static toString = function() { return $"[{x}, {y}, {z}, {w}]"; }
static toString = function() { return $"[__vec4] ({x}, {y}, {z}, {w})"; }
static toArray = function() { return [ x, y, z, w ]; }
}

View file

@ -49,19 +49,36 @@ function __3dGroup() constructor {
return new __bbox3D(_m0, _m1);
} #endregion
static _submit = function(callback, scene = {}, shader = noone) { #region
static submit = function(scene = {}, shader = noone) {
transform.submitMatrix();
for( var i = 0, n = array_length(objects); i < n; i++ )
callback(objects[i], scene, shader);
objects[i].submit(scene, shader);
transform.clearMatrix();
} #endregion
}
static submit = function(scene = {}, shader = noone) { _submit(function(_obj, scene, shader) { _obj.submit (scene, shader); }, scene, shader); }
static submitUI = function(scene = {}, shader = noone) { _submit(function(_obj, scene, shader) { _obj.submitUI (scene, shader); }, scene, shader); }
static submitSel = function(scene = {}, shader = noone) { _submit(function(_obj, scene, shader) { _obj.submitSel (scene, shader); }, scene, shader); }
static submitShader = function(scene = {}, shader = noone) { _submit(function(_obj, scene, shader) { _obj.submitShader (scene, shader); }, scene, shader); }
static submitUI = function(scene = {}, shader = noone) {
transform.submitMatrix();
for( var i = 0, n = array_length(objects); i < n; i++ )
objects[i].submitUI(scene, shader);
transform.clearMatrix();
}
static submitSel = function(scene = {}, shader = noone) {
transform.submitMatrix();
for( var i = 0, n = array_length(objects); i < n; i++ )
objects[i].submitSel(scene, shader);
transform.clearMatrix();
}
static submitShader = function(scene = {}, shader = noone) {
transform.submitMatrix();
for( var i = 0, n = array_length(objects); i < n; i++ )
objects[i].submitShader(scene, shader);
transform.clearMatrix();
}
static submitShadow = function(scene = {}, object = noone) { _submit(function(_obj, scene, object) { _obj.submitShadow (scene, object); }, scene, object); }
static submitShadow = function(scene = {}, object = noone) {
for( var i = 0, n = array_length(objects); i < n; i++ )
objects[i].submitShadow(scene, object.objects);
}
static map = function(callback, scene = {}) { #region
for( var i = 0, n = array_length(objects); i < n; i++ )

View file

@ -40,7 +40,8 @@ function __3dLight() : __3dObject() constructor {
shadowProjectBegin();
for( var i = 0, n = array_length(objects); i < n; i++ ) {
var _prev = objects[i];
if(_prev == noone) continue;
if(!is_struct(_prev)) continue;
_prev.submit(scene, shadow_mapper);
}
shadowProjectEnd();

View file

@ -146,6 +146,9 @@ function __3dObject() constructor {
var _ind = array_safe_get(material_index, i, i);
var _mat = array_safe_get(materials, _ind, noone);
shader_set_i("mat_flip", texture_flip);
var _tex = _mat == noone? -1 : _mat.getTexture();
if(_shader == sh_d3d_default) {
if(_mat == noone) {
shader_set_f("mat_diffuse", 1);
@ -156,8 +159,6 @@ function __3dObject() constructor {
} else
_mat.submitShader();
shader_set_i("mat_flip", texture_flip);
var _tex = _mat == noone? -1 : _mat.getTexture();
vertex_submit(VB[i], render_type, _tex);
} else if(_shader == sh_d3d_geometry) {
if(_mat == noone)
@ -165,9 +166,9 @@ function __3dObject() constructor {
else
_mat.submitGeometry();
vertex_submit(VB[i], render_type, -1);
vertex_submit(VB[i], render_type, _tex);
} else
vertex_submit(VB[i], render_type, -1);
vertex_submit(VB[i], render_type, _tex);
}
gpu_set_tex_repeat(false);
@ -208,5 +209,5 @@ function __3dObject() constructor {
static onDestroy = function() { }
static toString = function() { return $"[D3D Object\n\t{array_length(vertex)} vertex groups\n\tPosition: {transform.position}\n\tRotation: {transform.rotation}\n\tScale: {transform.scale}]" }
static toString = function() { return $"[D3D Object]\n\t({array_length(vertex)} vertex groups\n\tPosition: {transform.position}\n\tRotation: {transform.rotation}\n\tScale: {transform.scale})" }
}

View file

@ -72,7 +72,7 @@ function __rot3(_x = 0, _y = 0, _z = 0) constructor {
return new __rot3(x, y, z);
}
static toString = function() { return $"[{x}, {y}, {z}]"; }
static toString = function() { return $"[__rot3] ({x}, {y}, {z})"; }
static toArray = function() { return [ x, y, z ]; }
}

View file

@ -28,9 +28,12 @@
}
#endregion
function __3dScene(camera) constructor {
#macro D3DSCENE_PRESUBMIT if(!is_struct(object)) return; matrix_stack_clear(); if(apply_transform) custom_transform.submitMatrix();
#macro D3DSCENE_POSTSUBMIT if(apply_transform) custom_transform.clearMatrix();
function __3dScene(camera, name = "New scene") constructor {
self.camera = camera;
name = "New scene";
self.name = name;
apply_transform = false;
custom_transform = new __transform();
@ -85,22 +88,11 @@ function __3dScene(camera) constructor {
lightPnt_shadowBias = [];
} reset(); #endregion
static _submit = function(callback, object = noone, shader = noone) {
if(object == noone) return;
if(!is_struct(object)) return;
matrix_stack_clear();
if(apply_transform) custom_transform.submitMatrix();
callback(object, shader);
if(apply_transform) custom_transform.clearMatrix();
}
static submit = function(object, shader = noone) { _submit(function(object, shader) { object.submit (self, shader); }, object, shader) }
static submitUI = function(object, shader = noone) { _submit(function(object, shader) { object.submitUI (self, shader); }, object, shader) }
static submitSel = function(object, shader = noone) { _submit(function(object, shader) { object.submitSel (self, shader); }, object, shader) }
static submitShader = function(object, shader = noone) { _submit(function(object, shader) { object.submitShader (self, shader); }, object, shader) }
static submitShadow = function(object) { object.submitShadow(self, object) }
static submit = function(object, shader = noone) { D3DSCENE_PRESUBMIT object.submit (self, shader); D3DSCENE_POSTSUBMIT }
static submitUI = function(object, shader = noone) { D3DSCENE_PRESUBMIT object.submitUI (self, shader); D3DSCENE_POSTSUBMIT }
static submitSel = function(object, shader = noone) { D3DSCENE_PRESUBMIT object.submitSel (self, shader); D3DSCENE_POSTSUBMIT }
static submitShader = function(object, shader = noone) { D3DSCENE_PRESUBMIT object.submitShader (self, shader); D3DSCENE_POSTSUBMIT }
static submitShadow = function(object) { D3DSCENE_PRESUBMIT object.submitShadow (self, object); D3DSCENE_POSTSUBMIT }
static deferPass = function(object, w, h, deferData = noone) { #region
if(deferData == noone) deferData = {
@ -147,6 +139,7 @@ function __3dScene(camera) constructor {
surface_set_target_ext(2, deferData.geometry_data[2]);
gpu_set_zwriteenable(true);
gpu_set_ztestenable(true);
gpu_set_alphatestenable(true);
DRAW_CLEAR
camera.setMatrix();
@ -162,6 +155,7 @@ function __3dScene(camera) constructor {
shader_reset();
gpu_set_ztestenable(false);
gpu_set_alphatestenable(false);
surface_reset_target();
if(defer_normal_radius) {

View file

@ -32,7 +32,7 @@ function __vertex(_x = 0, _y = _x, _z = _x, color = c_white, alpha = 1) construc
return self;
}
static toString = function() { return $"[ pos: ({x}, {y}, {z}), nor: ({nx}, {ny}, {nz}), uv: ({u}, {v}), {color}, {alpha} ]"; }
static toString = function() { return $"[__vertex] ( pos: ({x}, {y}, {z}), nor: ({nx}, {ny}, {nz}), uv: ({u}, {v}), {color}, {alpha} )"; }
static clone = function() {
gml_pragma("forceinline");

View file

@ -45,13 +45,10 @@ function draw_surface_blend(background, foreground, blend = 0, alpha = 1, _pre_a
}
function draw_surface_blend_ext(bg, fg, _x, _y, _sx = 1, _sy = 1, _rot = 0, _col = c_white, _alpha = 1, _blend = 0) {
static _tempS = surface_create(1, 1);
_tempS = surface_verify(_tempS, surface_get_width_safe(bg), surface_get_height_safe(bg));
surface_set_shader(_tempS);
surface_set_shader(blend_temp_surface);
shader_set_interpolation(fg);
draw_surface_ext_safe(fg, _x, _y, _sx, _sy, _rot, _col, 1);
surface_reset_shader();
draw_surface_blend(bg, _tempS, _blend, _alpha, false);
draw_surface_blend(bg, blend_temp_surface, _blend, _alpha, false);
}

View file

@ -271,10 +271,11 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group)
scene.draw_background = _dbg;
#endregion
#region submit
var _bgSurf = _dbg? scene.renderBackground(_dim[0], _dim[1]) : noone;
scene.submitShadow(_sobj);
deferData = scene.deferPass(_sobj, _dim[0], _dim[1], deferData);
#region surface
var _render = outputs[| 0].getValue();
var _normal = outputs[| 1].getValue();
var _depth = outputs[| 2].getValue();
@ -288,17 +289,13 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group)
surface_set_target_ext(2, _depth );
DRAW_CLEAR
#endregion
#region submit
gpu_set_zwriteenable(true);
gpu_set_ztestenable(true);
gpu_set_cullmode(_back);
camera.applyCamera();
scene.reset();
scene.submitShadow(_sobj);
scene.submitShader(_sobj);
scene.apply(deferData);
scene.submit(_sobj);

View file

@ -46,6 +46,7 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group)
obj_read_progress = 0;
obj_read_prog_sub = 0;
obj_read_prog_tot = 3;
obj_read_time = 0;
current_path = "";
materials = [];
@ -101,7 +102,9 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group)
readObj_init();
obj_read_time = get_timer();
obj_read_file = file_text_open_read(current_path);
use_display_list = false;
}
static updateObjProcess = function() {
@ -113,6 +116,7 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group)
}
static updateObjComplete = function() { #region
use_display_list = true;
if(obj_raw == noone) return;
var txt = $"========== OBJ import ==========\n";
@ -120,6 +124,7 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group)
txt += $"Object counts: {obj_raw.object_counts}\n";
txt += $"Material counts: {array_length(obj_raw.materials)}\n";
txt += $"Model BBOX: {obj_raw.model_size}\n";
txt += $"Load completed in {(get_timer() - obj_read_time) / 1000} ms\n";
print(txt);
var span = max(abs(obj_raw.model_size.x), abs(obj_raw.model_size.y), abs(obj_raw.model_size.z));

View file

@ -7,14 +7,14 @@ function Node_3D_Scene(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru
object_lists = [];
static createNewInput = function() {
static createNewInput = function() { #region
var index = ds_list_size(inputs);
inputs[| index] = nodeValue("Object", self, JUNCTION_CONNECT.input, VALUE_TYPE.d3Mesh, noone )
.setVisible(true, true);
}
} #endregion
if(!LOADING && !APPENDING) createNewInput();
static refreshDynamicInput = function() {
static refreshDynamicInput = function() { #region
var _l = ds_list_create();
for( var i = 0; i < ds_list_size(inputs); i++ ) {
if(i < input_fix_len || inputs[| i].value_from)
@ -30,16 +30,16 @@ function Node_3D_Scene(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru
inputs = _l;
createNewInput();
}
} #endregion
static onValueFromUpdate = function(index) {
static onValueFromUpdate = function(index) { #region
if(index < input_fix_len) return;
if(LOADING || APPENDING) return;
refreshDynamicInput();
}
} #endregion
static processData = function(_output, _data, _output_index, _array_index = 0) {
static processData = function(_output, _data, _output_index, _array_index = 0) { #region
var _scene = new __3dGroup();
for( var i = input_fix_len, n = ds_list_size(inputs); i < n; i += data_length ) {
@ -50,5 +50,5 @@ function Node_3D_Scene(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru
}
return _scene;
}
} #endregion
}

View file

@ -414,7 +414,8 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
if(!LOADING && !APPENDING) createNewInput();
temp_surface = [ surface_create(1, 1), surface_create(1, 1) ];
temp_surface = [ surface_create(1, 1), surface_create(1, 1), surface_create(1, 1) ];
blend_temp_surface = temp_surface[2];
surf_dragging = -1;
drag_type = 0;
@ -792,7 +793,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
overlay_w = _dim[0];
overlay_h = _dim[1];
for(var i = 0; i < 2; i++) {
for(var i = 0; i < 3; i++) {
temp_surface[i] = surface_verify(temp_surface[i], _dim[0], _dim[1], cDep);
surface_clear(temp_surface[i]);
}
@ -858,6 +859,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
});
surface_set_shader(temp_surface[_bg], sh_sample, true, BLEND.over);
blend_temp_surface = temp_surface[2];
draw_surface_blend_ext(temp_surface[!_bg], _s, _pos[0], _pos[1], _sca[0], _sca[1], _rot);
surface_reset_shader();

View file

@ -982,11 +982,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
static step = function() { #region
var fram = attributes.frames;
var anim = getInputData(12);
var anims = getInputData(12);
inputs[| 12].setVisible(fram > 1);
inputs[| 13].setVisible(fram > 1 && anim);
update_on_frame = fram > 1 && anim;
if(update_on_frame)
preview_index = safe_mod(PROJECT.animator.current_frame * anims, fram);
} #endregion
static update = function(frame = PROJECT.animator.current_frame) { #region

View file

@ -156,7 +156,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
static getNextNodes = function() { #region //get node inside the group
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"→→→→→ Call get next node from group");
LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from group");
var nodes = [];
if(isRenderActive()) {
@ -166,7 +166,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
if(!_in.isRenderActive()) continue;
if(!_in.isRenderable()) {
LOG_IF(global.FLAG.render, $"Node {_in.internalName} not ready, loop skip.");
LOG_IF(global.FLAG.render == 1, $"Node {_in.internalName} not ready, loop skip.");
LOG_BLOCK_END();
return [];
}
@ -180,7 +180,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
} #endregion
static getNextNodesExternal = function() { #region //get node connected to the parent object
LOG_IF(global.FLAG.render, $"Checking next node external for {INAME}");
LOG_IF(global.FLAG.render == 1, $"Checking next node external for {INAME}");
LOG_BLOCK_START();
var nodes = [];
@ -192,7 +192,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
var _to = _tos[j];
var _node = _to.node;
LOG_IF(global.FLAG.render, $"Checking node {_node.internalName} : {_node.isRenderable()}");
LOG_IF(global.FLAG.render == 1, $"Checking node {_node.internalName} : {_node.isRenderable()}");
if(!_node.isRenderable()) continue;
array_push(nodes, _to.node);
@ -205,7 +205,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
static setRenderStatus = function(result) { #region
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"Set render status for {INAME} : {result}");
LOG_IF(global.FLAG.render == 1, $"Set render status for {INAME} : {result}");
rendered = result;
if(result)
@ -213,7 +213,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
var _o = outputs[| i];
if(_o.from.rendered) continue;
LOG_IF(global.FLAG.render, $"Set fail because {_o.from.internalName} is not rendered.");
LOG_IF(global.FLAG.render == 1, $"Set fail because {_o.from.internalName} is not rendered.");
rendered = false;
break;
}
@ -444,10 +444,10 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
static resetRender = function() { #region
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"Reset Render for {INAME}");
LOG_IF(global.FLAG.render == 1, $"Reset Render for {INAME}");
for( var i = 0; i < ds_list_size(nodes); i++ ) {
LOG_IF(global.FLAG.render, $"Reseting {nodes[| i].internalName}");
LOG_IF(global.FLAG.render == 1, $"Reseting {nodes[| i].internalName}");
nodes[| i].resetRender();
}

View file

@ -243,7 +243,8 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, [])
.rejectArrayProcess();
temp_surface = [ surface_create(1, 1), surface_create(1, 1) ];
temp_surface = [ surface_create(1, 1), surface_create(1, 1), surface_create(1, 1) ];
blend_temp_surface = temp_surface[2];
surf_dragging = -1;
input_dragging = -1;
@ -770,7 +771,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
overlay_w = ww;
overlay_h = hh;
for(var i = 0; i < 2; i++) {
for(var i = 0; i < 3; i++) {
temp_surface[i] = surface_verify(temp_surface[i], ww, hh, cDep);
surface_clear(temp_surface[i]);
}
@ -805,6 +806,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
array_push(atlas_data, new SurfaceAtlas(_s, [ _d0[0], _d0[1] ], _rot, [ _sca[0], _sca[1] ]));
surface_set_shader(temp_surface[_bg], sh_sample, true, BLEND.over);
blend_temp_surface = temp_surface[2];
draw_surface_blend_ext(temp_surface[!_bg], _s, _d0[0], _d0[1], _sca[0], _sca[1], _rot);
surface_reset_shader();

View file

@ -93,6 +93,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
inputMap = ds_map_create();
outputMap = ds_map_create();
use_display_list = true;
input_display_list = -1;
output_display_list = -1;
inspector_display_list = -1;
@ -240,7 +241,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
run_in(1, method(self, resetDefault));
static getInputJunctionIndex = function(index) { #region
if(input_display_list == -1)
if(input_display_list == -1 || !use_display_list)
return index;
var jun_list_arr = input_display_list[index];
@ -448,7 +449,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
anim_last_step = isAnimated() || /*_hash != input_hash || */!rendered;
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $">>>>>>>>>> DoUpdate called from {INAME} [{anim_last_step}] <<<<<<<<<<");
LOG_IF(global.FLAG.render == 1, $">>>>>>>>>> DoUpdate called from {INAME} [{anim_last_step}] <<<<<<<<<<");
if(!is_instanceof(self, Node_Collection)) setRenderStatus(true);
@ -503,7 +504,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
static triggerRender = function() { #region
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"Trigger render for {INAME}");
LOG_IF(global.FLAG.render == 1, $"Trigger render for {INAME}");
setRenderStatus(false);
UPDATE |= RENDER_TYPE.partial;
@ -521,6 +522,22 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
LOG_BLOCK_END();
} #endregion
static resetRenderForward = function() {
setRenderStatus(false);
for( var i = 0, n = ds_list_size(outputs); i < n; i++ ) {
var _outp = outputs[| i];
for(var j = 0; j < ds_list_size(_outp.value_to); j++) {
var _to = _outp.value_to[| j];
if(!_to.node.active || _to.value_from == noone) continue;
if(_to.value_from != self) continue;
if(!_to.node.rendered) continue;
_to.node.resetRenderForward();
}
}
}
static resetRender = function() { setRenderStatus(false); }
static isRenderActive = function() { return renderActive || (PREF_MAP[? "render_all_export"] && PROJECT.animator.rendering); }
@ -539,7 +556,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
if(!val_from.node.active) continue;
if(!val_from.node.isRenderActive()) continue;
if!(val_from.node.rendered || val_from.node.update_on_frame) {
LOG_LINE_IF(global.FLAG.render, $"Node {INAME} is not renderable because input {val_from.node.internalName} is not rendered ({val_from.node.rendered})");
LOG_LINE_IF(global.FLAG.render == 1, $"Node {INAME} is not renderable because input {val_from.node.internalName} is not rendered ({val_from.node.rendered})");
return false;
}
}
@ -554,7 +571,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
var nodeNames = [];
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"→→→→→ Call get next node from: {INAME}");
LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from: {INAME}");
LOG_BLOCK_START();
for(var i = 0; i < ds_list_size(outputs); i++) {
@ -569,11 +586,11 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
array_push(nodes, _to.node);
array_push(nodeNames, _to.node.internalName);
//LOG_IF(global.FLAG.render, $"→→ Check output: {_ot.name} connect to node {_to.node.internalName}");
//LOG_IF(global.FLAG.render == 1, $"→→ Check output: {_ot.name} connect to node {_to.node.internalName}");
}
}
LOG_IF(global.FLAG.render, $"→→ Push {nodeNames} to queue.");
LOG_IF(global.FLAG.render == 1, $"→→ Push {nodeNames} to queue.");
LOG_BLOCK_END();
LOG_BLOCK_END();
@ -592,7 +609,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
static onInspect = function() {}
static setRenderStatus = function(result) { #region
LOG_LINE_IF(global.FLAG.render, $"Set render status for {INAME} : {result}");
gml_pragma("forceinline");
LOG_LINE_IF(global.FLAG.render == 1, $"Set render status for {INAME} : {result}");
rendered = result;
} #endregion
@ -635,7 +653,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
updatedTrigger.x = xx + w * _s;
updatedTrigger.y = yy + 10;
var inamo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list);
var inamo = (input_display_list == -1 || !use_display_list)? ds_list_size(inputs) : array_length(input_display_list);
var _in = yy + ui(junction_draw_pad_y) * _s;
for(var i = 0; i < inamo; i++) {

View file

@ -35,7 +35,7 @@ function Node_Group_Output(_x, _y, _group = noone) : Node(_x, _y, _group) constr
}
static setRenderStatus = function(result) {
LOG_LINE_IF(global.FLAG.render, $"Set render status for {INAME} : {result}");
LOG_LINE_IF(global.FLAG.render == 1, $"Set render status for {INAME} : {result}");
rendered = result;
if(group) group.setRenderStatus(result);
@ -72,7 +72,7 @@ function Node_Group_Output(_x, _y, _group = noone) : Node(_x, _y, _group) constr
//printIf(global.FLAG.render, "Group output ready " + string(_to.node.isRenderable()));
array_push(nodes, _to.node);
LOG_IF(global.FLAG.render, $"Check complete, push {_to.node.internalName} to queue.");
LOG_IF(global.FLAG.render == 1, $"Check complete, push {_to.node.internalName} to queue.");
}
LOG_BLOCK_END();

View file

@ -46,7 +46,7 @@ function Node_Iterator_Filter_Output(_x, _y, _group = noone) : Node(_x, _y, _gro
array_push(_val, _new_val);
}
LOG_IF(global.FLAG.render, "Value " + string(val) + " filter result " + string(res) + " to array " + string(_val));
LOG_IF(global.FLAG.render == 1, "Value " + string(val) + " filter result " + string(res) + " to array " + string(_val));
group.outputs[| 0].setValue(_val);
group.iterationUpdate();

View file

@ -176,10 +176,8 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor {
if(ds_list_size(values) == 0) return processTypeDefault();
if(ds_list_size(values) == 1) return processType(values[| 0].value);
if(prop.type == VALUE_TYPE.path)
return processType(values[| 0].value);
if(!prop.is_anim)
return processType(values[| 0].value);
if(prop.type == VALUE_TYPE.path) return processType(values[| 0].value);
if(!prop.is_anim) return processType(values[| 0].value);
var _time_first = prop.loop_range == -1? values[| 0].time : values[| ds_list_size(values) - 1 - prop.loop_range].time;
var _time_last = values[| ds_list_size(values) - 1].time;
@ -267,11 +265,11 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor {
if(is_undefined(_val)) return 0;
if(prop.type == VALUE_TYPE.integer && prop.unit.mode == VALUE_UNIT.constant)
return round(toNumber(_val));
return round(_val);
switch(prop.type) {
case VALUE_TYPE.integer :
case VALUE_TYPE.float : return toNumber(_val);
case VALUE_TYPE.float : return _val;
case VALUE_TYPE.text : return string_real(_val);
case VALUE_TYPE.surface :
if(is_string(_val))

View file

@ -531,10 +531,8 @@ function Node_Vector_Split(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {
draw_set_text(f_h1, fa_center, fa_center, COLORS._main_text);
var str = "";
for( var i = 0; i < 4; i++ ) {
if(outputs[| i].visible)
str += $"{outputs[| 0].getValueCached()}\n";
}
for( var i = 0; i < 4; i++ )
if(outputs[| i].visible) str += $"{outputs[| i].getValueCached()}\n";
str = string_trim(str);
var bbox = drawGetBbox(xx, yy, _s);

View file

@ -75,7 +75,7 @@ function Node_Pixel_Builder(_x, _y, _group = noone) : Node_Collection(_x, _y, _g
static buildPixel = function() {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"================== BUILD PIXEL ==================");
LOG_IF(global.FLAG.render == 1, $"================== BUILD PIXEL ==================");
LOG_BLOCK_START();
var _dim = getInputData(0);

View file

@ -30,7 +30,7 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct
triggerRender();
}, false) ]);
static getInputData = function(index, def = 0) { return array_safe_get(inputs_data, index, def); }
static getInputData = function(index, def = 0) { gml_pragma("forceinline"); return array_safe_get(inputs_data, index, def); }
static processData_prebatch = function() {}
static processData_postbatch = function() {}
@ -40,8 +40,7 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct
static getSingleValue = function(_index, _arr = 0, output = false) { #region
var _l = output? outputs : inputs;
var _n = _l[| _index];
var _in = _n.getValue();
var _in = output? _n.getValue() : getInputData(_index);
if(!_n.isArray()) return _in;
switch(attributes.array_process) {

View file

@ -127,7 +127,7 @@ function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) construct
var k = ds_map_find_first(TUNNELS_OUT);
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"→→→→→ Call get next node from: {INAME}");
LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from: {INAME}");
LOG_BLOCK_START();
repeat(amo) {
@ -139,7 +139,7 @@ function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) construct
k = ds_map_find_next(TUNNELS_OUT, k);
}
LOG_IF(global.FLAG.render, $"→→ Push {nodeNames} to queue.");
LOG_IF(global.FLAG.render == 1, $"→→ Push {nodeNames} to queue.");
LOG_BLOCK_END();
LOG_BLOCK_END();

View file

@ -1139,7 +1139,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
case VALUE_DISPLAY.path_load:
var path = animator.getValue();
if(is_array(path)) path = path[0];
if(try_get_path(path) == -1) {
if(path != "" && try_get_path(path) == -1) {
value_validation = VALIDATION.error;
str = "File not exist: " + string(path);
}

View file

@ -34,23 +34,23 @@ function readObj_file() {
switch(sep[0]) {
case "v" :
ds_list_add(v, [ toNumber(sep[1]), toNumber(sep[2]), toNumber(sep[3]) ]);
ds_list_add(v, [ toNumberFast(sep[1]), toNumberFast(sep[2]), toNumberFast(sep[3]) ]);
break;
case "vt" :
var _u = toNumber(sep[1]);
var _v = toNumber(sep[2]);
var _u = toNumberFast(sep[1]);
var _v = toNumberFast(sep[2]);
ds_list_add(vt, [ _u, _v ]);
break;
case "vn" :
var _nx = toNumber(sep[1]);
var _ny = toNumber(sep[2]);
var _nz = toNumber(sep[3]);
var _di = sqrt(_nx * _nx + _ny * _ny + _nz * _nz);
var _nx = toNumberFast(sep[1]);
var _ny = toNumberFast(sep[2]);
var _nz = toNumberFast(sep[3]);
//var _di = sqrt(_nx * _nx + _ny * _ny + _nz * _nz);
_nx /= _di;
_ny /= _di;
_nz /= _di;
//_nx /= _di;
//_ny /= _di;
//_nz /= _di;
ds_list_add(vn, [ _nx, _ny, _nz ]);
break;
@ -64,9 +64,9 @@ function readObj_file() {
var _sp = string_split(sep[i], "/");
if(array_length(_sp) < 2) continue;
_f[i - 1] = toNumber(array_safe_get(_sp, 0, 1));
_ft[i - 1] = toNumber(array_safe_get(_sp, 1, 1));
_fn[i - 1] = toNumber(array_safe_get(_sp, 2, 1));
_f[i - 1] = toNumberFast(_sp[0]);
_ft[i - 1] = toNumberFast(_sp[1]);
_fn[i - 1] = toNumberFast(_sp[2]);
if(array_length(_sp) < 3) use_normal = false;
}

View file

@ -128,8 +128,9 @@ function Panel_Preview() : PanelContent() constructor {
#endregion
#region scene
d3_scene = new __3dScene(d3_view_camera);
d3_scene = new __3dScene(d3_view_camera, "Preview");
d3_scene.lightAmbient = $404040;
d3_scene.cull_mode = cull_counterclockwise;
d3_scene_preview = d3_scene;
d3_scene_light_enabled = true;
@ -816,14 +817,9 @@ function Panel_Preview() : PanelContent() constructor {
if(d3_scene_preview == d3_scene) {
d3_scene_light0.shadow_map_scale = d3_view_camera.focus_dist * 2;
var _prev_obj = _prev_node.getPreviewObjects();
var _prev_obj = _prev_node.getPreviewObject();
d3_scene_light0.submitShadow(d3_scene_preview, _prev_obj);
for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) {
var _prev = _prev_obj[i];
if(_prev == noone) continue;
_prev.submitShadow(d3_scene_preview, _prev_obj);
}
_prev_obj.submitShadow(d3_scene_preview, _prev_obj);
}
#endregion
@ -846,8 +842,10 @@ function Panel_Preview() : PanelContent() constructor {
d3_view_camera.applyCamera();
gpu_set_cullmode(cull_noculling);
gpu_set_ztestenable(true);
gpu_set_zwriteenable(false);
shader_set(sh_d3d_grid_view);
var _dist = round(d3_view_camera.focus.distance(d3_view_camera.position));
var _tx = round(d3_view_camera.focus.x);
@ -861,6 +859,7 @@ function Panel_Preview() : PanelContent() constructor {
shader_set_f("shift", _tx / _dist / 2, _ty / _dist / 2);
draw_sprite_stretched(s_fx_pixel, 0, _tx - _dist, _ty - _dist, _dist * 2, _dist * 2);
shader_reset();
gpu_set_zwriteenable(true);
#endregion
@ -901,6 +900,7 @@ function Panel_Preview() : PanelContent() constructor {
case 0 :
if(d3_scene_preview.draw_background)
draw_surface_safe(d3_surface_bg);
draw_surface_safe(d3_surface);
BLEND_MULTIPLY

View file

@ -8,7 +8,7 @@ enum RENDER_TYPE {
globalvar UPDATE, RENDER_QUEUE, RENDER_ORDER, UPDATE_RENDER_ORDER;
UPDATE_RENDER_ORDER = false;
global.FLAG.render = false;
global.FLAG.render = 0;
global.group_inputs = [ "Node_Group_Input", "Node_Feedback_Input", "Node_Iterator_Input", "Node_Iterator_Each_Input" ];
#macro RENDER_ALL_REORDER UPDATE_RENDER_ORDER = true; UPDATE |= RENDER_TYPE.full;
@ -32,7 +32,7 @@ function __nodeLeafList(_list) { #region
}
}
LOG_LINE_IF(global.FLAG.render, $"Push node {nodeNames} to queue");
LOG_LINE_IF(global.FLAG.render == 1, $"Push node {nodeNames} to queue");
return nodes;
} #endregion
@ -41,7 +41,7 @@ function __nodeIsLoop(_node) { #region
case "Node_Iterate" :
case "Node_Iterate_Each" :
case "Node_Iterate_Filter" :
case "Node_Feedback" :
case "Node_Iterate_Sort" :
return true;
}
return false;
@ -57,7 +57,7 @@ function __nodeInLoop(_node) { #region
} #endregion
function ResetAllNodesRender() { #region
LOG_IF(global.FLAG.render, $"XXXXXXXXXXXXXXXXXXXX RESETTING ALL NODES [frame {PROJECT.animator.current_frame}] XXXXXXXXXXXXXXXXXXXX");
LOG_IF(global.FLAG.render == 1, $"XXXXXXXXXXXXXXXXXXXX RESETTING ALL NODES [frame {PROJECT.animator.current_frame}] XXXXXXXXXXXXXXXXXXXX");
var _key = ds_map_find_first(PROJECT.nodeMap);
var amo = ds_map_size(PROJECT.nodeMap);
@ -73,11 +73,16 @@ function ResetAllNodesRender() { #region
} #endregion
function Render(partial = false, runAction = false) { #region
var t = get_timer();
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"============================== RENDER START [{partial? "PARTIAL" : "FULL"}] [frame {PROJECT.animator.current_frame}] ==============================");
try {
var t = get_timer();
var t1 = get_timer();
var _render_time = 0;
var _leaf_time = 0;
var rendering = noone;
var error = 0;
var reset_all = !partial || ALWAYS_FULL;
@ -101,50 +106,55 @@ function Render(partial = false, runAction = false) { #region
var _node = PROJECT.nodeMap[? key];
key = ds_map_find_next(PROJECT.nodeMap, key);
if(is_undefined(_node)) continue;
if(!is_struct(_node)) continue;
if(array_exists(global.group_inputs, instanceof(_node))) continue;
_node.render_time = 0;
if(!_node.active) continue;
if(!_node.isRenderActive()) continue;
if(_node.rendered && !_node.isAnimated()) {
_node.anim_last_step = false;
LOG_IF(global.FLAG.render, $"Skip rendered {_node.internalName}");
if(is_undefined(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip undefiend {_node}"); continue; }
if(!is_struct(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip non-struct {_node}"); continue; }
if(array_exists(global.group_inputs, instanceof(_node))) {
LOG_IF(global.FLAG.render == 1, $"Skip group IO {_node.internalName}");
continue;
}
if(_node.group != noone) continue;
_node.render_time = 0;
if(!_node.active) { LOG_IF(global.FLAG.render == 1, $"Skip inactive {_node.internalName}"); continue; }
if(!_node.isRenderActive()) { LOG_IF(global.FLAG.render == 1, $"Skip non-renderActive {_node.internalName}"); continue; }
if(_node.rendered && !_node.isAnimated()) {
_node.anim_last_step = false;
LOG_IF(global.FLAG.render == 1, $"Skip rendered {_node.internalName}");
continue;
}
if(__nodeInLoop(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip in-loop {_node.internalName}"); continue; }
LOG_BLOCK_START();
var _startNode = _node.isRenderable(global.FLAG.render);
if(_startNode) {
LOG_IF(global.FLAG.render, $"Found leaf {_node.internalName}");
if(!reset_all) _node.triggerRender();
LOG_IF(global.FLAG.render == 1, $"Found leaf {_node.internalName}");
//if(!reset_all) _node.resetRenderForward();
RENDER_QUEUE.enqueue(_node);
} else
LOG_IF(global.FLAG.render, $"Skip non-leaf {_node.internalName}");
LOG_IF(global.FLAG.render == 1, $"Skip non-leaf {_node.internalName}");
LOG_BLOCK_END();
}
LOG_IF(global.FLAG.render, $"Get leaf complete: found {RENDER_QUEUE.size()} leaves.");
LOG_IF(global.FLAG.render, "================== Start rendering ==================");
_leaf_time = get_timer() - t;
LOG_IF(global.FLAG.render >= 1, $"Get leaf complete: found {RENDER_QUEUE.size()} leaves in {(get_timer() - t) / 1000} ms."); t = get_timer();
LOG_IF(global.FLAG.render == 1, "================== Start rendering ==================");
// render forward
while(!RENDER_QUEUE.empty()) {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"➤➤➤➤➤➤ CURRENT RENDER QUEUE {RENDER_QUEUE} [{RENDER_QUEUE.size()}] ");
LOG_IF(global.FLAG.render == 1, $"➤➤➤➤➤➤ CURRENT RENDER QUEUE {RENDER_QUEUE} [{RENDER_QUEUE.size()}] ");
rendering = RENDER_QUEUE.dequeue();
var renderable = rendering.isRenderable();
LOG_IF(global.FLAG.render, $"Rendering {rendering.internalName} ({rendering.display_name}) : {renderable? "Update" : "Pass"}");
LOG_IF(global.FLAG.render == 1, $"Rendering {rendering.internalName} ({rendering.display_name}) : {renderable? "Update" : "Pass"}");
if(renderable) {
var _render_pt = get_timer();
rendering.doUpdate();
_render_time += get_timer() - _render_pt;
var nextNodes = rendering.getNextNodes();
for( var i = 0, n = array_length(nextNodes); i < n; i++ ) {
@ -157,11 +167,21 @@ function Render(partial = false, runAction = false) { #region
LOG_BLOCK_END();
}
_render_time /= 1000;
LOG_IF(global.FLAG.render >= 1, $"=== RENDER COMPLETE IN {(get_timer() - t1) / 1000} ms ===\n");
LOG_IF(global.FLAG.render > 1, $"=== RENDER SUMMARY STA ===");
LOG_IF(global.FLAG.render > 1, $" total time: {(get_timer() - t1) / 1000} ms");
LOG_IF(global.FLAG.render > 1, $" leaf: {_leaf_time / 1000} ms");
LOG_IF(global.FLAG.render > 1, $" render loop: {(get_timer() - t) / 1000} ms");
LOG_IF(global.FLAG.render > 1, $" render only: {_render_time} ms");
LOG_IF(global.FLAG.render > 1, $"=== RENDER SUMMARY END ===");
} catch(e) {
noti_warning(exception_print(e));
}
LOG_IF(global.FLAG.render, $"=== RENDER COMPLETE IN {(get_timer() - t) / 1000} ms ===\n");
LOG_END();
} #endregion
@ -176,7 +196,7 @@ function __renderListReset(list) { #region
function RenderList(list) { #region
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, "=============== RENDER LIST START ===============");
LOG_IF(global.FLAG.render == 1, "=============== RENDER LIST START ===============");
var queue = ds_queue_create();
try {
@ -201,18 +221,18 @@ function RenderList(list) { #region
ds_queue_enqueue(queue, _node);
}
LOG_IF(global.FLAG.render, "Get leaf complete: found " + string(ds_queue_size(queue)) + " leaves.");
LOG_IF(global.FLAG.render, "=== Start rendering ===");
LOG_IF(global.FLAG.render == 1, "Get leaf complete: found " + string(ds_queue_size(queue)) + " leaves.");
LOG_IF(global.FLAG.render == 1, "=== Start rendering ===");
// render forward
while(!ds_queue_empty(queue)) {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"➤➤➤➤➤➤ CURRENT RENDER QUEUE {RENDER_QUEUE}");
LOG_IF(global.FLAG.render == 1, $"➤➤➤➤➤➤ CURRENT RENDER QUEUE {RENDER_QUEUE}");
rendering = RENDER_QUEUE.dequeue();
if(!ds_list_exist(list, rendering)) continue;
var renderable = rendering.isRenderable();
LOG_IF(global.FLAG.render, $"Rendering {rendering.internalName} ({rendering.display_name}) : {renderable? "Update" : "Pass"}");
LOG_IF(global.FLAG.render == 1, $"Rendering {rendering.internalName} ({rendering.display_name}) : {renderable? "Update" : "Pass"}");
if(renderable) {
rendering.doUpdate();
@ -234,7 +254,7 @@ function RenderList(list) { #region
noti_warning(exception_print(e));
}
LOG_IF(global.FLAG.render, "=== RENDER COMPLETE ===\n");
LOG_IF(global.FLAG.render == 1, "=== RENDER COMPLETE ===\n");
LOG_END();
ds_queue_destroy(queue);
@ -271,12 +291,12 @@ function RenderListAction(list, context = PANEL_GRAPH.getCurrentContext()) { #re
// render forward
while(!RENDER_QUEUE.empty()) {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"➤➤➤➤➤➤ CURRENT RENDER QUEUE {RENDER_QUEUE}");
LOG_IF(global.FLAG.render == 1, $"➤➤➤➤➤➤ CURRENT RENDER QUEUE {RENDER_QUEUE}");
rendering = RENDER_QUEUE.dequeue();
if(!ds_list_exist(list, rendering)) continue;
var renderable = rendering.isRenderable();
LOG_IF(global.FLAG.render, $"Rendering {rendering.internalName} ({rendering.display_name}) : {renderable? "Update" : "Pass"}");
LOG_IF(global.FLAG.render == 1, $"Rendering {rendering.internalName} ({rendering.display_name}) : {renderable? "Update" : "Pass"}");
if(renderable) {
rendering.doUpdate();

View file

@ -22,8 +22,17 @@ function string_decimal(str) {
return (neg? "-" : "") + string_digits(pre) + "." + string_digits(pos);
}
function toNumberFast(str) {
gml_pragma("forceinline");
var r = real(str);
if(is_real(r)) return r;
return 0;
}
function toNumber(str) {
gml_pragma("forceinline");
if(is_real(str)) return str;
if(!isNumber(str)) return 0;

View file

@ -214,7 +214,7 @@ void main() {
for(int i = 0; i < light_dir_count; i++) {
vec3 lightVector = normalize(light_dir_direction[i]);
if(light_dir_shadow_active[i] == 1) {
if(light_dir_shadow_active[i] == 1) { //use shadow
vec4 cameraSpace = light_dir_view[i] * v_worldPosition;
vec4 screenSpace = light_dir_proj[i] * cameraSpace;
@ -249,7 +249,7 @@ void main() {
if(light_distance > light_pnt_radius[i])
continue;
if(light_pnt_shadow_active[i] == 1) {
if(light_pnt_shadow_active[i] == 1) { //use shadow
vec3 dirAbs = abs(lightVector);
int side = dirAbs.x > dirAbs.y ?
(dirAbs.x > dirAbs.z ? 0 : 2) :
@ -294,6 +294,6 @@ void main() {
#endregion
gl_FragData[0] = final_color;
gl_FragData[1] = vec4(0.5 + normal * 0.5, 1.);
gl_FragData[2] = vec4(vec3(v_cameraDistance), 1.);
gl_FragData[1] = vec4(0.5 + normal * 0.5, final_color.a);
gl_FragData[2] = vec4(vec3(v_cameraDistance), final_color.a);
}

View file

@ -3,17 +3,21 @@ varying vec4 v_worldPosition;
varying vec3 v_viewPosition;
varying vec3 v_vNormal;
uniform int mat_flip;
uniform int use_normal;
uniform float normal_strength;
uniform sampler2D normal_map;
void main() {
gl_FragData[0] = vec4(v_worldPosition.xyz, 1.);
gl_FragData[1] = vec4(v_viewPosition, 1.);
vec2 uv_coord = v_vTexcoord;
if(mat_flip == 1) uv_coord.y = -uv_coord.y;
vec4 mat_baseColor = texture2D( gm_BaseTexture, uv_coord );
gl_FragData[0] = vec4(v_worldPosition.xyz, mat_baseColor.a);
gl_FragData[1] = vec4(v_viewPosition, mat_baseColor.a);
vec3 normal = v_vNormal;
if(use_normal == 1)
normal += (texture2D(normal_map, v_vTexcoord).rgb * 2. - 1.) * normal_strength;
if(use_normal == 1) normal += (texture2D(normal_map, uv_coord).rgb * 2. - 1.) * normal_strength;
gl_FragData[2] = vec4(normalize(normal), 1.);
gl_FragData[2] = vec4(normalize(normal), mat_baseColor.a);
}