diff --git a/#backups/scripts/d3d_object/d3d_object.gml.backup0 b/#backups/scripts/d3d_object/d3d_object.gml.backup0 index f7f3570ed..ba4ffe5db 100644 --- a/#backups/scripts/d3d_object/d3d_object.gml.backup0 +++ b/#backups/scripts/d3d_object/d3d_object.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-05-01 15:54:59 +// 2024-05-01 20:00:00 #region vertex format vertex_format_begin(); vertex_format_add_position_3d(); @@ -110,6 +110,11 @@ function __3dObject() constructor { static getCenter = function() { return new __vec3(transform.position.x, transform.position.y, transform.position.z); } static getBBOX = function() { return new __bbox3D(size.multiplyVec(transform.scale).multiply(-0.5), size.multiplyVec(transform.scale).multiply(0.5)); } + #region params + defDrawParam = { wireframe: false }; + defDrawParamW = { wireframe: true }; + #endregion + static submit = function(scene = {}, shader = noone) { submitVertex(scene, shader); } static submitUI = function(scene = {}, shader = noone) { submitVertex(scene, shader); } static submitSel = function(scene = {}, shader = noone) { #region @@ -120,7 +125,7 @@ function __3dObject() constructor { static submitShader = function(scene = {}, shader = noone) {} static submitShadow = function(scene = {}, object = noone) {} - static submitVertex = function(scene = {}, shader = noone) { #region + static submitVertex = function(scene = {}, shader = noone, param = defDrawParam) { #region var _shader = sh_d3d_default; switch(VF) { @@ -171,8 +176,6 @@ function __3dObject() constructor { vertex_submit(VB[i], render_type, _tex); } else vertex_submit(VB[i], render_type, _tex); - - // print($"Submit vertex ({scene}) [{VB[i]}: {vertex_get_buffer_size(VB[i])}]"); } gpu_set_tex_repeat(false); diff --git a/#backups/scripts/d3d_object/d3d_object.gml.backup1 b/#backups/scripts/d3d_object/d3d_object.gml.backup1 index 431db7da0..77157db4b 100644 --- a/#backups/scripts/d3d_object/d3d_object.gml.backup1 +++ b/#backups/scripts/d3d_object/d3d_object.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-05-01 15:51:30 +// 2024-05-01 19:56:01 #region vertex format vertex_format_begin(); vertex_format_add_position_3d(); @@ -110,6 +110,11 @@ function __3dObject() constructor { static getCenter = function() { return new __vec3(transform.position.x, transform.position.y, transform.position.z); } static getBBOX = function() { return new __bbox3D(size.multiplyVec(transform.scale).multiply(-0.5), size.multiplyVec(transform.scale).multiply(0.5)); } + #region params + defDrawParam = { wireframe: false }; + defDrawParamW = { wireframe: true }; + #endregion + static submit = function(scene = {}, shader = noone) { submitVertex(scene, shader); } static submitUI = function(scene = {}, shader = noone) { submitVertex(scene, shader); } static submitSel = function(scene = {}, shader = noone) { #region @@ -120,7 +125,7 @@ function __3dObject() constructor { static submitShader = function(scene = {}, shader = noone) {} static submitShadow = function(scene = {}, object = noone) {} - static submitVertex = function(scene = {}, shader = noone) { #region + static submitVertex = function(scene = {}, shader = noone, param = defDrawParam) { #region var _shader = sh_d3d_default; switch(VF) { @@ -171,8 +176,6 @@ function __3dObject() constructor { vertex_submit(VB[i], render_type, _tex); } else vertex_submit(VB[i], render_type, _tex); - - // print($"Submit vertex ({scene}) [{VB[i]}: {vertex_get_buffer_size(VB[i])}]"); } gpu_set_tex_repeat(false); diff --git a/#backups/scripts/d3d_scene/d3d_scene.gml.backup0 b/#backups/scripts/d3d_scene/d3d_scene.gml.backup0 new file mode 100644 index 000000000..8cf271a55 --- /dev/null +++ b/#backups/scripts/d3d_scene/d3d_scene.gml.backup0 @@ -0,0 +1,334 @@ +// 2024-05-01 20:34:59 +#region global preview camera + globalvar D3D_GLOBAL_PREVIEW; + + function set3DGlobalPreview() { + var d3_view_camera = new __3dCamera(); + d3_view_camera.setViewSize(2, 2); + d3_view_camera.setFocusAngle(135, 45, 8); + d3_view_camera.position.set(d3d_PolarToCart(0, 0, 0, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist)); + + d3_view_camera.projection = CAMERA_PROJECTION.orthograph; + d3_view_camera.setMatrix(); + + D3D_GLOBAL_PREVIEW = new __3dScene(d3_view_camera, "Global node preview"); + D3D_GLOBAL_PREVIEW.apply_transform = true; + D3D_GLOBAL_PREVIEW.defer_normal = false; + + var d3_scene_light0 = new __3dLightDirectional(); + d3_scene_light0.transform.position.set(-1, -2, 3); + d3_scene_light0.color = $AAAAAA; + + var d3_scene_light1 = new __3dLightDirectional(); + d3_scene_light1.transform.position.set(1, 2, 3); + d3_scene_light1.color = $FFFFFF; + + D3D_GLOBAL_PREVIEW.lightAmbient = $404040; + D3D_GLOBAL_PREVIEW.addLightDirectional(d3_scene_light0); + D3D_GLOBAL_PREVIEW.addLightDirectional(d3_scene_light1); + } +#endregion + +#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; + self.name = name; + + apply_transform = false; + custom_transform = new __transform(); + + lightAmbient = c_black; + lightDir_max = 16; + lightDir_shadow_max = 4; + lightPnt_max = 16; + lightPnt_shadow_max = 4; + + cull_mode = cull_noculling; + enviroment_map = noone; + gammaCorrection = true; + + draw_background = false; + + defer_normal = true; + defer_normal_radius = 0; + + show_normal = false; + + ssao_enabled = false; + ssao_sample = 32; + ssao_radius = 0.1; + ssao_bias = 0.1; + ssao_strength = 1.; + + static reset = function() { #region + lightDir_count = 0; + lightDir_direction = []; + lightDir_color = []; + lightDir_intensity = []; + + lightDir_shadow_count = 0; + lightDir_shadow = []; + lightDir_shadowMap = []; + lightDir_viewMat = []; + lightDir_projMat = []; + lightDir_shadowBias = []; + + lightPnt_count = 0; + lightPnt_position = []; + lightPnt_color = []; + lightPnt_intensity = []; + lightPnt_radius = []; + + lightPnt_shadow_count = 0; + lightPnt_shadow = []; + lightPnt_shadowMap = []; + lightPnt_viewMat = []; + lightPnt_projMat = []; + lightPnt_shadowBias = []; + } reset(); #endregion + + 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 deferPass = function(object, w, h, deferData = noone) { #region + if(deferData == noone) deferData = { + geometry_data: [ noone, noone, noone ], + ssao : noone, + }; + + geometryPass(deferData, object, w, h); + ssaoPass(deferData); + + return deferData; + } #endregion + + static renderBackground = function(w, h, surf = noone) { #region + surf = surface_verify(surf, w, h); + surface_set_shader(surf, sh_d3d_background); + shader_set_color("light_ambient", lightAmbient); + shader_set_f("cameraPosition", camera.position.toArray()); + shader_set_i("env_use_mapping", is_surface(enviroment_map) ); + shader_set_surface("env_map", enviroment_map ); + shader_set_dim("env_map_dimension", enviroment_map ); + + camera.setMatrix(); + camera.applyCamera(); + + gpu_set_cullmode(cull_noculling); + var _s = (camera.view_near + camera.view_far) / 2; + + matrix_set(matrix_world, matrix_build(camera.position.x, camera.position.y, camera.position.z, 0, 0, 0, _s, _s, _s)); + vertex_submit(global.SKY_SPHERE.VB[0], pr_trianglelist, -1); + matrix_set(matrix_world, matrix_build_identity()); + surface_reset_shader(); + + return surf; + } #endregion + + static geometryPass = function(deferData, object, w = 512, h = 512) { #region + deferData.geometry_data[0] = surface_verify(deferData.geometry_data[0], w, h, OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + deferData.geometry_data[1] = surface_verify(deferData.geometry_data[1], w, h, OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + deferData.geometry_data[2] = surface_verify(deferData.geometry_data[2], w, h, OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + + surface_set_target_ext(0, deferData.geometry_data[0]); + surface_set_target_ext(1, deferData.geometry_data[1]); + 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(); + camera.applyCamera(); + + gpu_set_cullmode(cull_mode); + + shader_set(sh_d3d_geometry); + shader_set_f("planeNear", camera.view_near); + shader_set_f("planeFar", camera.view_far); + shader_set_i("use_8bit", OS == os_macosx); + + submit(object, sh_d3d_geometry); + + shader_reset(); + + gpu_set_ztestenable(false); + gpu_set_alphatestenable(false); + surface_reset_target(); + + if(defer_normal_radius) { + var _normal_blurred = surface_create_size(deferData.geometry_data[2], OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + surface_set_shader(_normal_blurred, sh_d3d_normal_blur); + shader_set_f("radius", defer_normal_radius); + shader_set_i("use_8bit", OS == os_macosx); + shader_set_dim("dimension", deferData.geometry_data[2]); + + draw_surface_safe(deferData.geometry_data[2]); + surface_reset_shader(); + + surface_free(deferData.geometry_data[2]); + deferData.geometry_data[2] = _normal_blurred; + } + } #endregion + + static ssaoPass = function(deferData) { #region + if(!ssao_enabled) return; + + var _sw = surface_get_width_safe(deferData.geometry_data[0]); + var _sh = surface_get_height_safe(deferData.geometry_data[0]); + var _ssao_surf = surface_create(_sw, _sh); + + surface_set_shader(_ssao_surf, sh_d3d_ssao); + shader_set_surface("vPosition", deferData.geometry_data[0]); + shader_set_surface("vNormal", deferData.geometry_data[2]); + shader_set_f("radius", ssao_radius); + shader_set_f("bias", ssao_bias); + shader_set_f("strength", ssao_strength * 2); + shader_set_f("projMatrix", camera.getCombinedMatrix()); + shader_set_f("cameraPosition", camera.position.toArray()); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _sw, _sh); + surface_reset_shader(); + + deferData.ssao = surface_verify(deferData.ssao, _sw, _sh); + surface_set_shader(deferData.ssao, sh_d3d_ssao_blur); + shader_set_f("dimension", _sw, _sh); + shader_set_surface("vNormal", deferData.geometry_data[2]); + + draw_surface_safe(_ssao_surf); + surface_reset_shader(); + + surface_free(_ssao_surf); + } #endregion + + static apply = function(deferData = noone) { #region + shader_set(sh_d3d_default); + shader_set_i("use_8bit", OS == os_macosx); + + #region ---- background ---- + shader_set_f("light_ambient", colToVec4(lightAmbient)); + shader_set_i("env_use_mapping", is_surface(enviroment_map) ); + shader_set_surface("env_map", enviroment_map, false, true ); + shader_set_dim("env_map_dimension", enviroment_map ); + if(deferData != noone) shader_set_surface("ao_map", deferData.ssao ); + #endregion + + shader_set_i("light_dir_count", lightDir_count); #region + if(lightDir_count) { + shader_set_f("light_dir_direction", lightDir_direction); + shader_set_f("light_dir_color", lightDir_color); + shader_set_f("light_dir_intensity", lightDir_intensity); + shader_set_i("light_dir_shadow_active", lightDir_shadow); + for( var i = 0, n = array_length(lightDir_shadowMap); i < n; i++ ) { + var _sid = shader_set_surface($"light_dir_shadowmap_{i}", lightDir_shadowMap[i], true); + gpu_set_tex_repeat_ext(_sid, false); + } + shader_set_f("light_dir_view", lightDir_viewMat); + shader_set_f("light_dir_proj", lightDir_projMat); + shader_set_f("light_dir_shadow_bias", lightDir_shadowBias); + } #endregion + + shader_set_i("light_pnt_count", lightPnt_count); #region + if(lightPnt_count) { + shader_set_f("light_pnt_position", lightPnt_position); + shader_set_f("light_pnt_color", lightPnt_color); + shader_set_f("light_pnt_intensity", lightPnt_intensity); + shader_set_f("light_pnt_radius", lightPnt_radius); + + shader_set_i("light_pnt_shadow_active", lightPnt_shadow); + + if(OS == os_windows) { + for( var i = 0, n = array_length(lightPnt_shadowMap); i < n; i++ ) { + var _sid = shader_set_surface($"light_pnt_shadowmap_{i}", lightPnt_shadowMap[i], true, true); + gpu_set_tex_repeat_ext(_sid, false); + } + shader_set_f("light_pnt_view", lightPnt_viewMat); + shader_set_f("light_pnt_proj", lightPnt_projMat); + shader_set_f("light_pnt_shadow_bias", lightPnt_shadowBias); + } + } #endregion + + if(OS == os_windows && defer_normal && deferData != noone && array_length(deferData.geometry_data) > 2) { + shader_set_i("mat_defer_normal", 1); + shader_set_surface("mat_normal_map", deferData.geometry_data[2]); + } else + shader_set_i("mat_defer_normal", 0); + + #region ---- camera ---- + shader_set_f("cameraPosition", camera.position.toArray()); + shader_set_i("gammaCorrection", gammaCorrection); + shader_set_f("planeNear", camera.view_near); + shader_set_f("planeFar", camera.view_far ); + + shader_set_f("viewProjMat", camera.getCombinedMatrix() ); + #endregion + + //print($"Submitting scene with {lightDir_count} dir, {lightPnt_count} pnt lights."); + shader_reset(); + } #endregion + + static addLightDirectional = function(light) { #region + if(lightDir_count >= lightDir_max) { + noti_warning("Direction light limit exceeded"); + return self; + } + + array_append(lightDir_direction, [ light.transform.position.x, light.transform.position.y, light.transform.position.z ]); + array_append(lightDir_color, colToVec4(light.color)); + + array_push(lightDir_intensity, light.intensity); + array_push(lightDir_shadow, light.shadow_active); + + if(light.shadow_active) { + if(lightDir_shadow_count < lightDir_shadow_max) { + array_push(lightDir_shadowMap, light.shadow_map); + lightDir_shadow_count++; + } else + noti_warning("Direction light shadow caster limit exceeded"); + } + array_append(lightDir_viewMat, light.shadow_map_view); + array_append(lightDir_projMat, light.shadow_map_proj); + array_push(lightDir_shadowBias, light.shadow_bias); + lightDir_count++; + + return self; + } #endregion + + static addLightPoint = function(light) { #region + if(lightPnt_count >= lightPnt_max) { + noti_warning("Point light limit exceeded"); + return self; + } + + array_append(lightPnt_position, [ light.transform.position.x, light.transform.position.y, light.transform.position.z ]); + array_append(lightPnt_color, colToVec4(light.color)); + + array_push(lightPnt_intensity, light.intensity); + array_push(lightPnt_radius, light.radius); + array_push(lightPnt_shadow, OS == os_windows && light.shadow_active); + + if(light.shadow_active) { + if(lightPnt_shadow_count < lightPnt_shadow_max) { + array_push(lightPnt_shadowMap, light.shadow_map); + lightPnt_shadow_count++; + } else + noti_warning("Point light shadow caster limit exceeded"); + } + array_append(lightPnt_viewMat, light.shadow_map_view); + array_append(lightPnt_projMat, light.shadow_map_proj); + array_push(lightPnt_shadowBias, light.shadow_bias); + lightPnt_count++; + + return self; + } #endregion + + static toString = function() { #region + return $"[3D Scene] {name}"; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/d3d_scene/d3d_scene.gml.backup1 b/#backups/scripts/d3d_scene/d3d_scene.gml.backup1 new file mode 100644 index 000000000..9655fee63 --- /dev/null +++ b/#backups/scripts/d3d_scene/d3d_scene.gml.backup1 @@ -0,0 +1,334 @@ +// 2024-05-01 20:17:56 +#region global preview camera + globalvar D3D_GLOBAL_PREVIEW; + + function set3DGlobalPreview() { + var d3_view_camera = new __3dCamera(); + d3_view_camera.setViewSize(2, 2); + d3_view_camera.setFocusAngle(135, 45, 8); + d3_view_camera.position.set(d3d_PolarToCart(0, 0, 0, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist)); + + d3_view_camera.projection = CAMERA_PROJECTION.orthograph; + d3_view_camera.setMatrix(); + + D3D_GLOBAL_PREVIEW = new __3dScene(d3_view_camera, "Global node preview"); + D3D_GLOBAL_PREVIEW.apply_transform = true; + D3D_GLOBAL_PREVIEW.defer_normal = false; + + var d3_scene_light0 = new __3dLightDirectional(); + d3_scene_light0.transform.position.set(-1, -2, 3); + d3_scene_light0.color = $AAAAAA; + + var d3_scene_light1 = new __3dLightDirectional(); + d3_scene_light1.transform.position.set(1, 2, 3); + d3_scene_light1.color = $FFFFFF; + + D3D_GLOBAL_PREVIEW.lightAmbient = $404040; + D3D_GLOBAL_PREVIEW.addLightDirectional(d3_scene_light0); + D3D_GLOBAL_PREVIEW.addLightDirectional(d3_scene_light1); + } +#endregion + +#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; + self.name = name; + + apply_transform = false; + custom_transform = new __transform(); + + lightAmbient = c_black; + lightDir_max = 16; + lightDir_shadow_max = 4; + lightPnt_max = 16; + lightPnt_shadow_max = 4; + + cull_mode = cull_noculling; + enviroment_map = noone; + gammaCorrection = true; + + draw_background = false; + + defer_normal = true; + defer_normal_radius = 0; + + show_normal = false; + + ssao_enabled = false; + ssao_sample = 32; + ssao_radius = 0.1; + ssao_bias = 0.1; + ssao_strength = 1.; + + static reset = function() { #region + lightDir_count = 0; + lightDir_direction = []; + lightDir_color = []; + lightDir_intensity = []; + + lightDir_shadow_count = 0; + lightDir_shadow = []; + lightDir_shadowMap = []; + lightDir_viewMat = []; + lightDir_projMat = []; + lightDir_shadowBias = []; + + lightPnt_count = 0; + lightPnt_position = []; + lightPnt_color = []; + lightPnt_intensity = []; + lightPnt_radius = []; + + lightPnt_shadow_count = 0; + lightPnt_shadow = []; + lightPnt_shadowMap = []; + lightPnt_viewMat = []; + lightPnt_projMat = []; + lightPnt_shadowBias = []; + } reset(); #endregion + + 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 deferPass = function(object, w, h, deferData = noone) { #region + if(deferData == noone) deferData = { + geometry_data: [ noone, noone, noone ], + ssao : noone, + }; + + geometryPass(deferData, object, w, h); + ssaoPass(deferData); + + return deferData; + } #endregion + + static renderBackground = function(w, h, surf = noone) { #region + surf = surface_verify(surf, w, h); + surface_set_shader(surf, sh_d3d_background); + shader_set_color("light_ambient", lightAmbient); + shader_set_f("cameraPosition", camera.position.toArray()); + shader_set_i("env_use_mapping", is_surface(enviroment_map) ); + shader_set_surface("env_map", enviroment_map ); + shader_set_dim("env_map_dimension", enviroment_map ); + + camera.setMatrix(); + camera.applyCamera(); + + gpu_set_cullmode(cull_noculling); + var _s = (camera.view_near + camera.view_far) / 2; + + matrix_set(matrix_world, matrix_build(camera.position.x, camera.position.y, camera.position.z, 0, 0, 0, _s, _s, _s)); + vertex_submit(global.SKY_SPHERE.VB[0], pr_trianglelist, -1); + matrix_set(matrix_world, matrix_build_identity()); + surface_reset_shader(); + + return surf; + } #endregion + + static geometryPass = function(deferData, object, w = 512, h = 512) { #region + deferData.geometry_data[0] = surface_verify(deferData.geometry_data[0], w, h, OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + deferData.geometry_data[1] = surface_verify(deferData.geometry_data[1], w, h, OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + deferData.geometry_data[2] = surface_verify(deferData.geometry_data[2], w, h, OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + + surface_set_target_ext(0, deferData.geometry_data[0]); + surface_set_target_ext(1, deferData.geometry_data[1]); + 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(); + camera.applyCamera(); + + gpu_set_cullmode(cull_mode); + + shader_set(sh_d3d_geometry); + shader_set_f("planeNear", camera.view_near); + shader_set_f("planeFar", camera.view_far); + shader_set_i("use_8bit", OS == os_macosx); + + submit(object, sh_d3d_geometry); + + shader_reset(); + + gpu_set_ztestenable(false); + gpu_set_alphatestenable(false); + surface_reset_target(); + + if(defer_normal_radius) { + var _normal_blurred = surface_create_size(deferData.geometry_data[2], OS == os_macosx? surface_rgba8unorm : surface_rgba32float); + surface_set_shader(_normal_blurred, sh_d3d_normal_blur); + shader_set_f("radius", defer_normal_radius); + shader_set_i("use_8bit", OS == os_macosx); + shader_set_dim("dimension", deferData.geometry_data[2]); + + draw_surface_safe(deferData.geometry_data[2]); + surface_reset_shader(); + + surface_free(deferData.geometry_data[2]); + deferData.geometry_data[2] = _normal_blurred; + } + } #endregion + + static ssaoPass = function(deferData) { #region + if(!ssao_enabled) return; + + var _sw = surface_get_width_safe(deferData.geometry_data[0]); + var _sh = surface_get_height_safe(deferData.geometry_data[0]); + var _ssao_surf = surface_create(_sw, _sh); + + surface_set_shader(_ssao_surf, sh_d3d_ssao); + shader_set_surface("vPosition", deferData.geometry_data[0]); + shader_set_surface("vNormal", deferData.geometry_data[2]); + shader_set_f("radius", ssao_radius); + shader_set_f("bias", ssao_bias); + shader_set_f("strength", ssao_strength * 2); + shader_set_f("projMatrix", camera.getCombinedMatrix()); + shader_set_f("cameraPosition", camera.position.toArray()); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _sw, _sh); + surface_reset_shader(); + + deferData.ssao = surface_verify(deferData.ssao, _sw, _sh); + surface_set_shader(deferData.ssao, sh_d3d_ssao_blur); + shader_set_f("dimension", _sw, _sh); + shader_set_surface("vNormal", deferData.geometry_data[2]); + + draw_surface_safe(_ssao_surf); + surface_reset_shader(); + + surface_free(_ssao_surf); + } #endregion + + static apply = function(deferData = noone) { #region + shader_set(sh_d3d_default); + shader_set_i("use_8bit", OS == os_macosx); + + #region ---- background ---- + shader_set_f("light_ambient", colToVec4(lightAmbient)); + shader_set_i("env_use_mapping", is_surface(enviroment_map) ); + shader_set_surface("env_map", enviroment_map, false, true ); + shader_set_dim("env_map_dimension", enviroment_map ); + if(deferData != noone) shader_set_surface("ao_map", deferData.ssao ); + #endregion + + shader_set_i("light_dir_count", lightDir_count); #region + if(lightDir_count) { + shader_set_f("light_dir_direction", lightDir_direction); + shader_set_f("light_dir_color", lightDir_color); + shader_set_f("light_dir_intensity", lightDir_intensity); + shader_set_i("light_dir_shadow_active", lightDir_shadow); + for( var i = 0, n = array_length(lightDir_shadowMap); i < n; i++ ) { + var _sid = shader_set_surface($"light_dir_shadowmap_{i}", lightDir_shadowMap[i], true); + gpu_set_tex_repeat_ext(_sid, false); + } + shader_set_f("light_dir_view", lightDir_viewMat); + shader_set_f("light_dir_proj", lightDir_projMat); + shader_set_f("light_dir_shadow_bias", lightDir_shadowBias); + } #endregion + + shader_set_i("light_pnt_count", lightPnt_count); #region + if(lightPnt_count) { + shader_set_f("light_pnt_position", lightPnt_position); + shader_set_f("light_pnt_color", lightPnt_color); + shader_set_f("light_pnt_intensity", lightPnt_intensity); + shader_set_f("light_pnt_radius", lightPnt_radius); + + shader_set_i("light_pnt_shadow_active", lightPnt_shadow); + + if(OS == os_windows) { + for( var i = 0, n = array_length(lightPnt_shadowMap); i < n; i++ ) { + var _sid = shader_set_surface($"light_pnt_shadowmap_{i}", lightPnt_shadowMap[i], true, true); + gpu_set_tex_repeat_ext(_sid, false); + } + shader_set_f("light_pnt_view", lightPnt_viewMat); + shader_set_f("light_pnt_proj", lightPnt_projMat); + shader_set_f("light_pnt_shadow_bias", lightPnt_shadowBias); + } + } #endregion + + if(OS == os_windows && defer_normal && deferData != noone && array_length(deferData.geometry_data) > 2) { + shader_set_i("mat_defer_normal", 1); + shader_set_surface("mat_normal_map", deferData.geometry_data[2]); + } else + shader_set_i("mat_defer_normal", 0); + + #region ---- camera ---- + shader_set_f("cameraPosition", camera.position.toArray()); + shader_set_i("gammaCorrection", gammaCorrection); + shader_set_f("planeNear", camera.view_near); + shader_set_f("planeFar", camera.view_far ); + + shader_set_f("viewProjMat", camera.getCombinedMatrix() ); + #endregion + + //print($"Submitting scene with {lightDir_count} dir, {lightPnt_count} pnt lights."); + shader_reset(); + } #endregion + + static addLightDirectional = function(light) { #region + if(lightDir_count >= lightDir_max) { + noti_warning("Direction light limit exceeded"); + return self; + } + + array_append(lightDir_direction, [ light.transform.position.x, light.transform.position.y, light.transform.position.z ]); + array_append(lightDir_color, colToVec4(light.color)); + + array_push(lightDir_intensity, light.intensity); + array_push(lightDir_shadow, light.shadow_active); + + if(light.shadow_active) { + if(lightDir_shadow_count < lightDir_shadow_max) { + array_push(lightDir_shadowMap, light.shadow_map); + lightDir_shadow_count++; + } else + noti_warning("Direction light shadow caster limit exceeded"); + } + array_append(lightDir_viewMat, light.shadow_map_view); + array_append(lightDir_projMat, light.shadow_map_proj); + array_push(lightDir_shadowBias, light.shadow_bias); + lightDir_count++; + + return self; + } #endregion + + static addLightPoint = function(light) { #region + if(lightPnt_count >= lightPnt_max) { + noti_warning("Point light limit exceeded"); + return self; + } + + array_append(lightPnt_position, [ light.transform.position.x, light.transform.position.y, light.transform.position.z ]); + array_append(lightPnt_color, colToVec4(light.color)); + + array_push(lightPnt_intensity, light.intensity); + array_push(lightPnt_radius, light.radius); + array_push(lightPnt_shadow, OS == os_windows && light.shadow_active); + + if(light.shadow_active) { + if(lightPnt_shadow_count < lightPnt_shadow_max) { + array_push(lightPnt_shadowMap, light.shadow_map); + lightPnt_shadow_count++; + } else + noti_warning("Point light shadow caster limit exceeded"); + } + array_append(lightPnt_viewMat, light.shadow_map_view); + array_append(lightPnt_projMat, light.shadow_map_proj); + array_push(lightPnt_shadowBias, light.shadow_bias); + lightPnt_count++; + + return self; + } #endregion + + static toString = function() { #region + return $"[3D Scene] {name}"; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/mtl_reader/mtl_reader.gml.backup0 b/#backups/scripts/mtl_reader/mtl_reader.gml.backup0 new file mode 100644 index 000000000..ecccbd44e --- /dev/null +++ b/#backups/scripts/mtl_reader/mtl_reader.gml.backup0 @@ -0,0 +1,51 @@ +// 2024-05-01 20:07:20 +function MTLmaterial(name) constructor { + self.name = name; + self.refc = 0; + self.diff = c_white; + self.spec = 0; + + self.refc_path = ""; + self.diff_path = ""; + self.spec_path = ""; +} + +function str_strip_nr(str) { + str = string_replace_all(str, "\n", ""); + str = string_replace_all(str, "\r", ""); + str = string_replace_all(str, "\\", "/"); + return str; +} + +function readMtl(path) { + if(!file_exists_empty(path)) return []; + + var mat = []; + var cur_mat = noone; + + var file = file_text_open_read(path); + while(!file_text_eof(file)) { + var l = file_text_readln(file); + l = string_trim(l); + + var sep = string_splice(l, " "); + if(array_length(sep) == 0 || sep[0] == "") continue; + + switch(sep[0]) { + case "newmtl" : + cur_mat = new MTLmaterial(str_strip_nr(sep[1])); + array_push(mat, cur_mat); + break; + case "Ka" : cur_mat.refc = colorFromRGBArray([sep[1], sep[2], sep[3]]); break; + case "Kd" : cur_mat.diff = colorFromRGBArray([sep[1], sep[2], sep[3]]); break; + case "Ks" : cur_mat.spec = colorFromRGBArray([sep[1], sep[2], sep[3]]); break; + case "map_Ka": cur_mat.refc_path = filename_dir(path) + "/" + str_strip_nr(sep[1]); break; + case "map_Kd": cur_mat.diff_path = filename_dir(path) + "/" + str_strip_nr(sep[1]); break; + case "map_Ks": cur_mat.spec_path = filename_dir(path) + "/" + str_strip_nr(sep[1]); break; + } + } + + file_text_close(file); + + return mat; +} \ No newline at end of file diff --git a/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup0 b/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup0 index ec44a4d23..bfcb861a6 100644 --- a/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup0 +++ b/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-05-01 15:53:22 +// 2024-05-01 20:10:28 function Node_create_3D_Obj(_x, _y, _group = noone) { #region var path = ""; if(!LOADING && !APPENDING && !CLONING) { @@ -151,8 +151,8 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) materialNames = [ "Material" ]; materialIndex = [ 0 ]; materials = [ new MTLmaterial("Material") ]; - - if(array_length(materialNames)) { + + if(obj_raw.use_material) { var _dir = filename_dir(current_path); var _pathMtl = string_copy(current_path, 1, string_length(current_path) - 4) + ".mtl"; if(obj_raw.mtl_path != "") _pathMtl = _dir + "/" + obj_raw.mtl_path; @@ -181,8 +181,6 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) for(var i = 0; i < array_length(materialNames); i++) createMaterial(i); - outputs[| 0].setValue(object); - triggerRender(); } #endregion diff --git a/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup1 b/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup1 index a5013ceb2..ffe6bd49b 100644 --- a/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup1 +++ b/#backups/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-05-01 15:53:20 +// 2024-05-01 20:07:23 function Node_create_3D_Obj(_x, _y, _group = noone) { #region var path = ""; if(!LOADING && !APPENDING && !CLONING) { @@ -151,8 +151,8 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) materialNames = [ "Material" ]; materialIndex = [ 0 ]; materials = [ new MTLmaterial("Material") ]; - - if(array_length(materialNames)) { + + if(obj_raw.use_material) { var _dir = filename_dir(current_path); var _pathMtl = string_copy(current_path, 1, string_length(current_path) - 4) + ".mtl"; if(obj_raw.mtl_path != "") _pathMtl = _dir + "/" + obj_raw.mtl_path; @@ -181,8 +181,6 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) for(var i = 0; i < array_length(materialNames); i++) createMaterial(i); - outputs[| 0].setValue(object); - triggerRender(); } #endregion diff --git a/#backups/scripts/node_value/node_value.gml.backup0 b/#backups/scripts/node_value/node_value.gml.backup0 index 08a401d10..a54300f4b 100644 --- a/#backups/scripts/node_value/node_value.gml.backup0 +++ b/#backups/scripts/node_value/node_value.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-05-01 19:28:09 +// 2024-05-01 19:40:14 #region ---- global names ---- global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ]; @@ -2014,7 +2014,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru var _eval = new BBMOD_Quaternion(_qval[0], _qval[1], _qval[2], _qval[3]).ToEuler(true); return setValueDirect(_qval); } - return setValueDirect(val, index); } diff --git a/#backups/scripts/node_value/node_value.gml.backup1 b/#backups/scripts/node_value/node_value.gml.backup1 index 5a7b8b26c..15998662b 100644 --- a/#backups/scripts/node_value/node_value.gml.backup1 +++ b/#backups/scripts/node_value/node_value.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-05-01 19:27:29 +// 2024-05-01 19:40:13 #region ---- global names ---- global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ]; @@ -2014,7 +2014,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru var _eval = new BBMOD_Quaternion(_qval[0], _qval[1], _qval[2], _qval[3]).ToEuler(true); return setValueDirect(_qval); } - return setValueDirect(val, index); } diff --git a/#backups/scripts/obj_reader/obj_reader.gml.backup0 b/#backups/scripts/obj_reader/obj_reader.gml.backup0 index d12026b0b..016be7745 100644 --- a/#backups/scripts/obj_reader/obj_reader.gml.backup0 +++ b/#backups/scripts/obj_reader/obj_reader.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-05-01 13:45:32 +// 2024-05-01 20:05:32 function readObj_init(_scale = 1) { obj_reading = true; obj_read_progress = 0; @@ -16,7 +16,8 @@ function readObj_init(_scale = 1) { matIndex = []; tris = []; mtlPath = ""; - use_normal = true; + use_material = false; + use_normal = true; v = ds_list_create(); vt = ds_list_create(); @@ -85,6 +86,7 @@ function readObj_file() { break; case "usemtl" : + use_material = true; var mname = ""; for( var i = 1; i < array_length(sep); i++ ) mname += (i == 1? "" : " ") + sep[i]; @@ -286,6 +288,7 @@ function readObj_buff() { vertex_groups: VBS, object_counts: _vblen, + use_material: use_material, materials: mats, material_index: matIndex, use_normal: use_normal, diff --git a/#backups/scripts/obj_reader/obj_reader.gml.backup1 b/#backups/scripts/obj_reader/obj_reader.gml.backup1 index c20ca6732..f34d60d2a 100644 --- a/#backups/scripts/obj_reader/obj_reader.gml.backup1 +++ b/#backups/scripts/obj_reader/obj_reader.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-05-01 13:44:23 +// 2024-05-01 20:05:28 function readObj_init(_scale = 1) { obj_reading = true; obj_read_progress = 0; @@ -16,7 +16,8 @@ function readObj_init(_scale = 1) { matIndex = []; tris = []; mtlPath = ""; - use_normal = true; + use_material = false; + use_normal = true; v = ds_list_create(); vt = ds_list_create(); @@ -85,6 +86,7 @@ function readObj_file() { break; case "usemtl" : + use_material = true; var mname = ""; for( var i = 1; i < array_length(sep); i++ ) mname += (i == 1? "" : " ") + sep[i]; @@ -183,7 +185,7 @@ function readObj_cent() { _bmax[2] - _bmin[2], ); - print($"{obj_size}"); + //print($"{obj_size}"); var sc = 1; //var span = max(abs(_size.x), abs(_size.y), abs(_size.z)); @@ -286,6 +288,7 @@ function readObj_buff() { vertex_groups: VBS, object_counts: _vblen, + use_material: use_material, materials: mats, material_index: matIndex, use_normal: use_normal, diff --git a/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 b/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 index 539546583..5e1bc2bbd 100644 --- a/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 +++ b/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-30 13:07:08 +// 2024-05-01 19:40:08 #region funtion calls function __fnInit_Inspector() { __registerFunction("inspector_copy_prop", panel_inspector_copy_prop); @@ -754,9 +754,8 @@ function Panel_Inspector() : PanelContent() constructor { } #region color picker - if(key_mod_press(ALT) && color_picker_index) { - pickers[picker_index].editWidget.onColorPick(); - } + // if(key_mod_press(ALT) && color_picker_index) + // pickers[picker_index].editWidget.onColorPick(); if(MESSAGE != noone && MESSAGE.type == "Color") { var inp = array_safe_get_fast(pickers, picker_index, 0); diff --git a/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 b/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 index ef119ef64..01ae82083 100644 --- a/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 +++ b/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-30 13:07:07 +// 2024-05-01 19:39:33 #region funtion calls function __fnInit_Inspector() { __registerFunction("inspector_copy_prop", panel_inspector_copy_prop); @@ -754,9 +754,8 @@ function Panel_Inspector() : PanelContent() constructor { } #region color picker - if(key_mod_press(ALT) && color_picker_index) { - pickers[picker_index].editWidget.onColorPick(); - } + // if(key_mod_press(ALT) && color_picker_index) + // pickers[picker_index].editWidget.onColorPick(); if(MESSAGE != noone && MESSAGE.type == "Color") { var inp = array_safe_get_fast(pickers, picker_index, 0); diff --git a/#backups/shaders/sh_d3d_default/sh_d3d_default.fsh.backup0 b/#backups/shaders/sh_d3d_default/sh_d3d_default.fsh.backup0 new file mode 100644 index 000000000..3b3cb32c2 --- /dev/null +++ b/#backups/shaders/sh_d3d_default/sh_d3d_default.fsh.backup0 @@ -0,0 +1,325 @@ +// 2024-05-01 20:25:29 +// PC3D rendering shader + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; +varying vec3 v_vNormal; + +varying vec4 v_worldPosition; +varying vec3 v_viewPosition; +varying float v_cameraDistance; + +#define PI 3.14159265359 +#define TAU 6.28318530718 + +uniform int use_8bit; + +#region ---- light ---- + uniform vec4 light_ambient; + uniform float shadowBias; + + #define LIGHT_DIR_LIMIT 16 + uniform int light_dir_count; + uniform vec3 light_dir_direction[LIGHT_DIR_LIMIT]; + uniform vec4 light_dir_color[LIGHT_DIR_LIMIT]; + uniform float light_dir_intensity[LIGHT_DIR_LIMIT]; + + uniform mat4 light_dir_view[LIGHT_DIR_LIMIT]; + uniform mat4 light_dir_proj[LIGHT_DIR_LIMIT]; + uniform int light_dir_shadow_active[LIGHT_DIR_LIMIT]; + uniform float light_dir_shadow_bias[LIGHT_DIR_LIMIT]; + uniform sampler2D light_dir_shadowmap_0; + uniform sampler2D light_dir_shadowmap_1; + //uniform sampler2D light_dir_shadowmap_2; + //uniform sampler2D light_dir_shadowmap_3; + + #define LIGHT_PNT_LIMIT 16 + uniform int light_pnt_count; + uniform vec3 light_pnt_position[LIGHT_PNT_LIMIT]; + uniform vec4 light_pnt_color[LIGHT_PNT_LIMIT]; + uniform float light_pnt_intensity[LIGHT_PNT_LIMIT]; + uniform float light_pnt_radius[LIGHT_PNT_LIMIT]; + + uniform mat4 light_pnt_view[96]; + uniform mat4 light_pnt_proj[LIGHT_PNT_LIMIT]; + uniform int light_pnt_shadow_active[LIGHT_PNT_LIMIT]; + uniform float light_pnt_shadow_bias[LIGHT_DIR_LIMIT]; + uniform sampler2D light_pnt_shadowmap_0; + uniform sampler2D light_pnt_shadowmap_1; + //uniform sampler2D light_pnt_shadowmap_2; + //uniform sampler2D light_pnt_shadowmap_3; +#endregion + +#region ---- material ---- + vec4 mat_baseColor; + + uniform float mat_diffuse; + uniform float mat_specular; + uniform float mat_shine; + uniform int mat_metalic; + uniform float mat_reflective; + + uniform int mat_defer_normal; + uniform float mat_normal_strength; + uniform sampler2D mat_normal_map; + + uniform int mat_flip; +#endregion + +#region ---- rendering ---- + uniform vec3 cameraPosition; + uniform int gammaCorrection; + + uniform int env_use_mapping; + uniform sampler2D env_map; + uniform vec2 env_map_dimension; + + uniform mat4 viewProjMat; +#endregion + +#region ++++ mapping ++++ + vec2 equirectangularUv(vec3 dir) { + vec3 n = normalize(dir); + return vec2((atan(n.x, n.y) / TAU) + 0.5, 1. - acos(n.z) / PI); + } + + float unormToFloat(vec3 v) { + v *= 256.; + return (v.r * 65536. + v.g * 256. + v.b) / (65536.); + } +#endregion + +#region ++++ matrix ++++ + float matrixGet(mat4 matrix, int index) { + if(index < 0 || index > 15) return 0.; + + int _x = int(floor(float(index) / 4.)); + int _y = int(mod(float(index), 4.)); + return matrix[_x][_y]; + } + + mat4 matrixSet(mat4 matrix, int index, float value) { + if(index < 0 || index > 15) return matrix; + + int _x = int(floor(float(index) / 4.)); + int _y = int(mod(float(index), 4.)); + matrix[_x][_y] = value; + return matrix; + } +#endregion + +#region ++++ shadow sampler ++++ + float sampleDirShadowMap(int index, vec2 position) { + vec4 d; + + if(index == 0) d = texture2D(light_dir_shadowmap_0, position); + else if(index == 1) d = texture2D(light_dir_shadowmap_1, position); + //else if(index == 2) d = texture2D(light_dir_shadowmap_2, position); + //else if(index == 3) d = texture2D(light_dir_shadowmap_3, position); + + if(use_8bit == 1) + return unormToFloat(d.rgb); + return d.r; + } + + float samplePntShadowMap(int index, vec2 position, int side) { + float d = 0.; + + position.x /= 2.; + if(side >= 3) { + position.x += 0.5; + side -= 3; + } + + if(index == 0) d = texture2D(light_pnt_shadowmap_0, position)[side]; + else if(index == 1) d = texture2D(light_pnt_shadowmap_1, position)[side]; + //else if(index == 2) d = texture2D(light_pnt_shadowmap_2, position)[side]; + //else if(index == 3) d = texture2D(light_pnt_shadowmap_3, position)[side]; + + return d; + } +#endregion + +#region ++++ Phong shading ++++ + vec3 phongLight(vec3 normal, vec3 lightVec, vec3 viewVec, vec3 light) { + vec3 lightDir = normalize(lightVec); + vec3 viewDir = normalize(viewVec); + vec3 refcDir = reflect(-lightDir, normal); + + float kD = 1., kS = 0.; + + if(mat_diffuse + mat_specular != 0.) { + kD = mat_diffuse / (mat_diffuse + mat_specular); + kS = mat_specular / (mat_diffuse + mat_specular); + } + + vec3 lLambert = max(0., dot(normal, lightDir)) * light; + + float specular = pow(max(dot(viewDir, refcDir), 0.), max(0.001, mat_shine)); + vec3 lSpecular = specular * light; + if(mat_metalic == 1) lSpecular *= mat_baseColor.rgb; + + return kD * lLambert + kS * lSpecular; + } +#endregion + +void main() { + vec2 uv_coord = v_vTexcoord; + if(mat_flip == 1) uv_coord.y = -uv_coord.y; + + mat_baseColor = texture2D( gm_BaseTexture, uv_coord ); + mat_baseColor *= v_vColour; + + vec4 final_color = mat_baseColor; + vec3 viewDirection = normalize(cameraPosition - v_worldPosition.xyz); + + vec4 viewProjPos = viewProjMat * vec4(v_worldPosition.xyz, 1.); + viewProjPos /= viewProjPos.w; + viewProjPos = viewProjPos * 0.5 + 0.5; + + #region ++++ normal ++++ + vec3 _norm = v_vNormal; + + if(mat_defer_normal == 1) + _norm = texture2D(mat_normal_map, viewProjPos.xy).rgb; + + vec3 normal = normalize(_norm); + #endregion + + #region ++++ environment ++++ + if(env_use_mapping == 1 && mat_reflective > 0.) { + vec3 reflectDir = reflect(viewDirection, normal); + + float refRad = mix(16., 0., mat_reflective); + vec2 tx = 1. / env_map_dimension; + vec2 reflect_sample_pos = equirectangularUv(reflectDir); + vec4 env_sampled = vec4(0.); + float weight = 0.; + + for(float i = -refRad; i <= refRad; i++) + for(float j = -refRad; j <= refRad; j++) { + vec2 _map_pos = reflect_sample_pos + vec2(i, j) * tx; + if(_map_pos.y < 0.) _map_pos.y = -_map_pos.y; + else if(_map_pos.y > 1.) _map_pos.y = 1. - (_map_pos.y - 1.); + + vec4 _samp = texture2D(env_map, _map_pos); + env_sampled += _samp; + weight += _samp.a; + } + env_sampled /= weight; + env_sampled.a = 1.; + + vec4 env_effect = mat_metalic == 1? env_sampled * final_color : env_sampled; + env_effect = 1. - ( mat_reflective * ( 1. - env_effect )); + + final_color *= env_effect; + } + #endregion + + #region ++++ light ++++ + int shadow_map_index = 0; + vec3 light_effect = light_ambient.rgb; + float val = 0.; + + #region ++++ directional ++++ + float light_map_depth; + float lightDistance; + float shadow_culled; + + shadow_map_index = 0; + for(int i = 0; i < light_dir_count; i++) { + vec3 lightVector = normalize(light_dir_direction[i]); + + if(light_dir_shadow_active[i] == 1) { //use shadow + vec4 cameraSpace = light_dir_view[i] * v_worldPosition; + vec4 screenSpace = light_dir_proj[i] * cameraSpace; + + float v_lightDistance = screenSpace.z / screenSpace.w; + vec2 lightMapPosition = (screenSpace.xy / screenSpace.w * 0.5) + 0.5; + + if(lightMapPosition.x >= 0. && lightMapPosition.x <= 1. && lightMapPosition.y >= 0. && lightMapPosition.y <= 1.) { + light_map_depth = sampleDirShadowMap(shadow_map_index, lightMapPosition); + + //gl_FragData[0] = texture2D(light_dir_shadowmap_0, lightMapPosition); + //return; + + shadow_map_index++; + lightDistance = v_lightDistance; + float shadowFactor = dot(normal, lightVector); + float bias = mix(light_dir_shadow_bias[i], 0., shadowFactor); + + if(lightDistance > light_map_depth + bias) + continue; + } + } + + vec3 light_phong = phongLight(normal, lightVector, viewDirection, light_dir_color[i].rgb); + + light_effect += light_phong * light_dir_intensity[i]; + } + #endregion + + #region ++++ point ++++ + float light_distance; + float light_attenuation; + + shadow_map_index = 0; + for(int i = 0; i < light_pnt_count; i++) { + vec3 lightVector = normalize(light_pnt_position[i] - v_worldPosition.xyz); + + light_distance = length(lightVector); + if(light_distance > light_pnt_radius[i]) + continue; + + 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) : + (dirAbs.y > dirAbs.z ? 1 : 2); + side *= 2; + if(side == 0 && lightVector.x > 0.) side += 1; + else if(side == 2 && lightVector.y > 0.) side += 1; + else if(side == 4 && lightVector.z > 0.) side += 1; + + vec4 cameraSpace = light_pnt_view[i * 6 + side] * v_worldPosition; + vec4 screenSpace = light_pnt_proj[i] * cameraSpace; + float v_lightDistance = screenSpace.z / screenSpace.w; + vec2 lightMapPosition = (screenSpace.xy / screenSpace.w * 0.5) + 0.5; + + if(lightMapPosition.x >= 0. && lightMapPosition.x <= 1. && lightMapPosition.y >= 0. && lightMapPosition.y <= 1.) { + float shadowFactor = dot(normal, lightVector); + float bias = mix(light_pnt_shadow_bias[i], 0., shadowFactor); + + light_map_depth = samplePntShadowMap(shadow_map_index, lightMapPosition, side); + shadow_map_index++; + + if(v_lightDistance > light_map_depth + bias) + continue; + } + } + + light_attenuation = 1. - pow(light_distance / light_pnt_radius[i], 2.); + + vec3 light_phong = phongLight(normal, lightVector, viewDirection, light_pnt_color[i].rgb * light_attenuation); + + light_effect += light_phong * light_pnt_intensity[i]; + } + #endregion + + light_effect = max(light_effect, 0.); + + if(gammaCorrection == 1) { + light_effect.r = pow(light_effect.r, 1. / 2.2); + light_effect.g = pow(light_effect.g, 1. / 2.2); + light_effect.b = pow(light_effect.b, 1. / 2.2); + } + + final_color.rgb *= light_effect; + #endregion + + if(final_color.a < 0.1) discard; + + gl_FragData[0] = final_color; + gl_FragData[1] = vec4(0.5 + normal * 0.5, final_color.a); + gl_FragData[2] = vec4(vec3(1. - abs(v_cameraDistance)), final_color.a); +} diff --git a/#backups/shaders/sh_d3d_default/sh_d3d_default.fsh.backup1 b/#backups/shaders/sh_d3d_default/sh_d3d_default.fsh.backup1 new file mode 100644 index 000000000..f97b642f2 --- /dev/null +++ b/#backups/shaders/sh_d3d_default/sh_d3d_default.fsh.backup1 @@ -0,0 +1,325 @@ +// 2024-05-01 20:20:23 +// PC3D rendering shader + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; +varying vec3 v_vNormal; + +varying vec4 v_worldPosition; +varying vec3 v_viewPosition; +varying float v_cameraDistance; + +#define PI 3.14159265359 +#define TAU 6.28318530718 + +uniform int use_8bit; + +#region ---- light ---- + uniform vec4 light_ambient; + uniform float shadowBias; + + #define LIGHT_DIR_LIMIT 16 + uniform int light_dir_count; + uniform vec3 light_dir_direction[LIGHT_DIR_LIMIT]; + uniform vec4 light_dir_color[LIGHT_DIR_LIMIT]; + uniform float light_dir_intensity[LIGHT_DIR_LIMIT]; + + uniform mat4 light_dir_view[LIGHT_DIR_LIMIT]; + uniform mat4 light_dir_proj[LIGHT_DIR_LIMIT]; + uniform int light_dir_shadow_active[LIGHT_DIR_LIMIT]; + uniform float light_dir_shadow_bias[LIGHT_DIR_LIMIT]; + uniform sampler2D light_dir_shadowmap_0; + uniform sampler2D light_dir_shadowmap_1; + //uniform sampler2D light_dir_shadowmap_2; + //uniform sampler2D light_dir_shadowmap_3; + + #define LIGHT_PNT_LIMIT 16 + uniform int light_pnt_count; + uniform vec3 light_pnt_position[LIGHT_PNT_LIMIT]; + uniform vec4 light_pnt_color[LIGHT_PNT_LIMIT]; + uniform float light_pnt_intensity[LIGHT_PNT_LIMIT]; + uniform float light_pnt_radius[LIGHT_PNT_LIMIT]; + + uniform mat4 light_pnt_view[96]; + uniform mat4 light_pnt_proj[LIGHT_PNT_LIMIT]; + uniform int light_pnt_shadow_active[LIGHT_PNT_LIMIT]; + uniform float light_pnt_shadow_bias[LIGHT_DIR_LIMIT]; + uniform sampler2D light_pnt_shadowmap_0; + uniform sampler2D light_pnt_shadowmap_1; + //uniform sampler2D light_pnt_shadowmap_2; + //uniform sampler2D light_pnt_shadowmap_3; +#endregion + +#region ---- material ---- + vec4 mat_baseColor; + + uniform float mat_diffuse; + uniform float mat_specular; + uniform float mat_shine; + uniform int mat_metalic; + uniform float mat_reflective; + + uniform int mat_defer_normal; + uniform float mat_normal_strength; + uniform sampler2D mat_normal_map; + + uniform int mat_flip; +#endregion + +#region ---- rendering ---- + uniform vec3 cameraPosition; + uniform int gammaCorrection; + + uniform int env_use_mapping; + uniform sampler2D env_map; + uniform vec2 env_map_dimension; + + uniform mat4 viewProjMat; +#endregion + +#region ++++ mapping ++++ + vec2 equirectangularUv(vec3 dir) { + vec3 n = normalize(dir); + return vec2((atan(n.x, n.y) / TAU) + 0.5, 1. - acos(n.z) / PI); + } + + float unormToFloat(vec3 v) { + v *= 256.; + return (v.r * 65536. + v.g * 256. + v.b) / (65536.); + } +#endregion + +#region ++++ matrix ++++ + float matrixGet(mat4 matrix, int index) { + if(index < 0 || index > 15) return 0.; + + int _x = int(floor(float(index) / 4.)); + int _y = int(mod(float(index), 4.)); + return matrix[_x][_y]; + } + + mat4 matrixSet(mat4 matrix, int index, float value) { + if(index < 0 || index > 15) return matrix; + + int _x = int(floor(float(index) / 4.)); + int _y = int(mod(float(index), 4.)); + matrix[_x][_y] = value; + return matrix; + } +#endregion + +#region ++++ shadow sampler ++++ + float sampleDirShadowMap(int index, vec2 position) { + vec4 d; + + if(index == 0) d = texture2D(light_dir_shadowmap_0, position); + else if(index == 1) d = texture2D(light_dir_shadowmap_1, position); + //else if(index == 2) d = texture2D(light_dir_shadowmap_2, position); + //else if(index == 3) d = texture2D(light_dir_shadowmap_3, position); + + if(use_8bit == 1) + return unormToFloat(d.rgb); + return d.r; + } + + float samplePntShadowMap(int index, vec2 position, int side) { + float d = 0.; + + position.x /= 2.; + if(side >= 3) { + position.x += 0.5; + side -= 3; + } + + if(index == 0) d = texture2D(light_pnt_shadowmap_0, position)[side]; + else if(index == 1) d = texture2D(light_pnt_shadowmap_1, position)[side]; + //else if(index == 2) d = texture2D(light_pnt_shadowmap_2, position)[side]; + //else if(index == 3) d = texture2D(light_pnt_shadowmap_3, position)[side]; + + return d; + } +#endregion + +#region ++++ Phong shading ++++ + vec3 phongLight(vec3 normal, vec3 lightVec, vec3 viewVec, vec3 light) { + vec3 lightDir = normalize(lightVec); + vec3 viewDir = normalize(viewVec); + vec3 refcDir = reflect(-lightDir, normal); + + float kD = 1., kS = 0.; + + if(mat_diffuse + mat_specular != 0.) { + kD = mat_diffuse / (mat_diffuse + mat_specular); + kS = mat_specular / (mat_diffuse + mat_specular); + } + + vec3 lLambert = max(0., dot(normal, lightDir)) * light; + + float specular = pow(max(dot(viewDir, refcDir), 0.), max(0.001, mat_shine)); + vec3 lSpecular = specular * light; + if(mat_metalic == 1) lSpecular *= mat_baseColor.rgb; + + return kD * lLambert + kS * lSpecular; + } +#endregion + +void main() { + vec2 uv_coord = v_vTexcoord; + if(mat_flip == 1) uv_coord.y = -uv_coord.y; + + mat_baseColor = texture2D( gm_BaseTexture, uv_coord ); + mat_baseColor *= v_vColour; + + vec4 final_color = mat_baseColor; + vec3 viewDirection = normalize(cameraPosition - v_worldPosition.xyz); + + vec4 viewProjPos = viewProjMat * vec4(v_worldPosition.xyz, 1.); + viewProjPos /= viewProjPos.w; + viewProjPos = viewProjPos * 0.5 + 0.5; + + #region ++++ normal ++++ + vec3 _norm = v_vNormal; + + if(mat_defer_normal == 1) + _norm = texture2D(mat_normal_map, viewProjPos.xy).rgb; + + vec3 normal = normalize(_norm); + #endregion + + #region ++++ environment ++++ + if(env_use_mapping == 1 && mat_reflective > 0.) { + vec3 reflectDir = reflect(viewDirection, normal); + + float refRad = mix(16., 0., mat_reflective); + vec2 tx = 1. / env_map_dimension; + vec2 reflect_sample_pos = equirectangularUv(reflectDir); + vec4 env_sampled = vec4(0.); + float weight = 0.; + + for(float i = -refRad; i <= refRad; i++) + for(float j = -refRad; j <= refRad; j++) { + vec2 _map_pos = reflect_sample_pos + vec2(i, j) * tx; + if(_map_pos.y < 0.) _map_pos.y = -_map_pos.y; + else if(_map_pos.y > 1.) _map_pos.y = 1. - (_map_pos.y - 1.); + + vec4 _samp = texture2D(env_map, _map_pos); + env_sampled += _samp; + weight += _samp.a; + } + env_sampled /= weight; + env_sampled.a = 1.; + + vec4 env_effect = mat_metalic == 1? env_sampled * final_color : env_sampled; + env_effect = 1. - ( mat_reflective * ( 1. - env_effect )); + + final_color *= env_effect; + } + #endregion + + #region ++++ light ++++ + int shadow_map_index = 0; + vec3 light_effect = light_ambient.rgb; + float val = 0.; + + #region ++++ directional ++++ + float light_map_depth; + float lightDistance; + float shadow_culled; + + shadow_map_index = 0; + for(int i = 0; i < light_dir_count; i++) { + vec3 lightVector = normalize(light_dir_direction[i]); + + if(light_dir_shadow_active[i] == 1) { //use shadow + vec4 cameraSpace = light_dir_view[i] * v_worldPosition; + vec4 screenSpace = light_dir_proj[i] * cameraSpace; + + float v_lightDistance = screenSpace.z / screenSpace.w; + vec2 lightMapPosition = (screenSpace.xy / screenSpace.w * 0.5) + 0.5; + + if(lightMapPosition.x >= 0. && lightMapPosition.x <= 1. && lightMapPosition.y >= 0. && lightMapPosition.y <= 1.) { + light_map_depth = sampleDirShadowMap(shadow_map_index, lightMapPosition); + + //gl_FragData[0] = texture2D(light_dir_shadowmap_0, lightMapPosition); + //return; + + shadow_map_index++; + lightDistance = v_lightDistance; + float shadowFactor = dot(normal, lightVector); + float bias = mix(light_dir_shadow_bias[i], 0., shadowFactor); + + if(lightDistance > light_map_depth + bias) + continue; + } + } + + vec3 light_phong = phongLight(normal, lightVector, viewDirection, light_dir_color[i].rgb); + + light_effect += light_phong * light_dir_intensity[i]; + } + #endregion + + #region ++++ point ++++ + float light_distance; + float light_attenuation; + + shadow_map_index = 0; + for(int i = 0; i < light_pnt_count; i++) { + vec3 lightVector = normalize(light_pnt_position[i] - v_worldPosition.xyz); + + light_distance = length(lightVector); + if(light_distance > light_pnt_radius[i]) + continue; + + 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) : + (dirAbs.y > dirAbs.z ? 1 : 2); + side *= 2; + if(side == 0 && lightVector.x > 0.) side += 1; + else if(side == 2 && lightVector.y > 0.) side += 1; + else if(side == 4 && lightVector.z > 0.) side += 1; + + vec4 cameraSpace = light_pnt_view[i * 6 + side] * v_worldPosition; + vec4 screenSpace = light_pnt_proj[i] * cameraSpace; + float v_lightDistance = screenSpace.z / screenSpace.w; + vec2 lightMapPosition = (screenSpace.xy / screenSpace.w * 0.5) + 0.5; + + if(lightMapPosition.x >= 0. && lightMapPosition.x <= 1. && lightMapPosition.y >= 0. && lightMapPosition.y <= 1.) { + float shadowFactor = dot(normal, lightVector); + float bias = mix(light_pnt_shadow_bias[i], 0., shadowFactor); + + light_map_depth = samplePntShadowMap(shadow_map_index, lightMapPosition, side); + shadow_map_index++; + + if(v_lightDistance > light_map_depth + bias) + continue; + } + } + + light_attenuation = 1. - pow(light_distance / light_pnt_radius[i], 2.); + + vec3 light_phong = phongLight(normal, lightVector, viewDirection, light_pnt_color[i].rgb * light_attenuation); + + light_effect += light_phong * light_pnt_intensity[i]; + } + #endregion + + light_effect = max(light_effect, 0.); + + if(gammaCorrection == 1) { + light_effect.r = pow(light_effect.r, 1. / 2.2); + light_effect.g = pow(light_effect.g, 1. / 2.2); + light_effect.b = pow(light_effect.b, 1. / 2.2); + } + + final_color.rgb *= light_effect; + #endregion + + if(final_color.a < 0.1) discard; + + gl_FragData[0] = final_color; + gl_FragData[1] = vec4(0.5 + normal * 0.5, final_color.a); + gl_FragData[2] = vec4(vec3(1. - abs(v_cameraDistance)), final_color.a); +} diff --git a/scripts/d3d_object/d3d_object.gml b/scripts/d3d_object/d3d_object.gml index 1379107e2..299e771a5 100644 --- a/scripts/d3d_object/d3d_object.gml +++ b/scripts/d3d_object/d3d_object.gml @@ -109,6 +109,11 @@ function __3dObject() constructor { static getCenter = function() { return new __vec3(transform.position.x, transform.position.y, transform.position.z); } static getBBOX = function() { return new __bbox3D(size.multiplyVec(transform.scale).multiply(-0.5), size.multiplyVec(transform.scale).multiply(0.5)); } + #region params + defDrawParam = { wireframe: false }; + defDrawParamW = { wireframe: true }; + #endregion + static submit = function(scene = {}, shader = noone) { submitVertex(scene, shader); } static submitUI = function(scene = {}, shader = noone) { submitVertex(scene, shader); } static submitSel = function(scene = {}, shader = noone) { #region @@ -119,7 +124,7 @@ function __3dObject() constructor { static submitShader = function(scene = {}, shader = noone) {} static submitShadow = function(scene = {}, object = noone) {} - static submitVertex = function(scene = {}, shader = noone) { #region + static submitVertex = function(scene = {}, shader = noone, param = defDrawParam) { #region var _shader = sh_d3d_default; switch(VF) { @@ -170,8 +175,6 @@ function __3dObject() constructor { vertex_submit(VB[i], render_type, _tex); } else vertex_submit(VB[i], render_type, _tex); - - // print($"Submit vertex ({scene}) [{VB[i]}: {vertex_get_buffer_size(VB[i])}]"); } gpu_set_tex_repeat(false); diff --git a/scripts/d3d_scene/d3d_scene.gml b/scripts/d3d_scene/d3d_scene.gml index 36e762954..e35efc3ad 100644 --- a/scripts/d3d_scene/d3d_scene.gml +++ b/scripts/d3d_scene/d3d_scene.gml @@ -68,12 +68,12 @@ function __3dScene(camera, name = "New scene") constructor { lightDir_intensity = []; lightDir_shadow_count = 0; - lightDir_shadow = []; - lightDir_shadowMap = []; - lightDir_viewMat = []; - lightDir_projMat = []; - lightDir_shadowBias = []; - + lightDir_shadow = []; + lightDir_shadowMap = []; + lightDir_viewMat = []; + lightDir_projMat = []; + lightDir_shadowBias = []; + lightPnt_count = 0; lightPnt_position = []; lightPnt_color = []; @@ -81,11 +81,11 @@ function __3dScene(camera, name = "New scene") constructor { lightPnt_radius = []; lightPnt_shadow_count = 0; - lightPnt_shadow = []; - lightPnt_shadowMap = []; - lightPnt_viewMat = []; - lightPnt_projMat = []; - lightPnt_shadowBias = []; + lightPnt_shadow = []; + lightPnt_shadowMap = []; + lightPnt_viewMat = []; + lightPnt_projMat = []; + lightPnt_shadowBias = []; } reset(); #endregion static submit = function(object, shader = noone) { D3DSCENE_PRESUBMIT object.submit (self, shader); D3DSCENE_POSTSUBMIT } @@ -136,7 +136,7 @@ function __3dScene(camera, name = "New scene") constructor { surface_set_target_ext(0, deferData.geometry_data[0]); surface_set_target_ext(1, deferData.geometry_data[1]); surface_set_target_ext(2, deferData.geometry_data[2]); - + gpu_set_zwriteenable(true); gpu_set_ztestenable(true); diff --git a/scripts/mtl_reader/mtl_reader.gml b/scripts/mtl_reader/mtl_reader.gml index f20189a84..7952aab95 100644 --- a/scripts/mtl_reader/mtl_reader.gml +++ b/scripts/mtl_reader/mtl_reader.gml @@ -1,7 +1,7 @@ function MTLmaterial(name) constructor { self.name = name; self.refc = 0; - self.diff = 0; + self.diff = c_white; self.spec = 0; self.refc_path = ""; diff --git a/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml b/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml index cdea5f5eb..07d2843c8 100644 --- a/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml +++ b/scripts/node_3d_mesh_obj/node_3d_mesh_obj.gml @@ -150,8 +150,8 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) materialNames = [ "Material" ]; materialIndex = [ 0 ]; materials = [ new MTLmaterial("Material") ]; - - if(array_length(materialNames)) { + + if(obj_raw.use_material) { var _dir = filename_dir(current_path); var _pathMtl = string_copy(current_path, 1, string_length(current_path) - 4) + ".mtl"; if(obj_raw.mtl_path != "") _pathMtl = _dir + "/" + obj_raw.mtl_path; @@ -180,8 +180,6 @@ function Node_3D_Mesh_Obj(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) for(var i = 0; i < array_length(materialNames); i++) createMaterial(i); - outputs[| 0].setValue(object); - triggerRender(); } #endregion diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index d6ba442fc..c44bbaf9a 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -2013,7 +2013,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru var _eval = new BBMOD_Quaternion(_qval[0], _qval[1], _qval[2], _qval[3]).ToEuler(true); return setValueDirect(_qval); } - return setValueDirect(val, index); } diff --git a/scripts/obj_reader/obj_reader.gml b/scripts/obj_reader/obj_reader.gml index 67b00377c..92100b449 100644 --- a/scripts/obj_reader/obj_reader.gml +++ b/scripts/obj_reader/obj_reader.gml @@ -15,7 +15,8 @@ function readObj_init(_scale = 1) { matIndex = []; tris = []; mtlPath = ""; - use_normal = true; + use_material = false; + use_normal = true; v = ds_list_create(); vt = ds_list_create(); @@ -84,6 +85,7 @@ function readObj_file() { break; case "usemtl" : + use_material = true; var mname = ""; for( var i = 1; i < array_length(sep); i++ ) mname += (i == 1? "" : " ") + sep[i]; @@ -285,6 +287,7 @@ function readObj_buff() { vertex_groups: VBS, object_counts: _vblen, + use_material: use_material, materials: mats, material_index: matIndex, use_normal: use_normal, diff --git a/scripts/panel_inspector/panel_inspector.gml b/scripts/panel_inspector/panel_inspector.gml index 946797247..fad497d43 100644 --- a/scripts/panel_inspector/panel_inspector.gml +++ b/scripts/panel_inspector/panel_inspector.gml @@ -753,9 +753,8 @@ function Panel_Inspector() : PanelContent() constructor { } #region color picker - if(key_mod_press(ALT) && color_picker_index) { - pickers[picker_index].editWidget.onColorPick(); - } + // if(key_mod_press(ALT) && color_picker_index) + // pickers[picker_index].editWidget.onColorPick(); if(MESSAGE != noone && MESSAGE.type == "Color") { var inp = array_safe_get_fast(pickers, picker_index, 0);