diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 72fa08c66..dc282ddfe 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -191,6 +191,7 @@ {"name":"biterator","order":2,"path":"folders/VCT/biterator.yy",}, {"name":"widget","order":3,"path":"folders/VCT/widget.yy",}, {"name":"widgets","order":5,"path":"folders/widgets.yy",}, + {"name":"ssao","order":24,"path":"folders/shader/3d/ssao.yy",}, ], "ResourceOrderSettings": [ {"name":"s_node_corner","order":16,"path":"sprites/s_node_corner/s_node_corner.yy",}, @@ -669,6 +670,7 @@ {"name":"s_node_alpha_cut","order":3,"path":"sprites/s_node_alpha_cut/s_node_alpha_cut.yy",}, {"name":"node_iterator_length","order":4,"path":"scripts/node_iterator_length/node_iterator_length.yy",}, {"name":"node_VFX_effect_attract","order":8,"path":"scripts/node_VFX_effect_attract/node_VFX_effect_attract.yy",}, + {"name":"sh_d3d_ssao_blur","order":1,"path":"shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy",}, {"name":"panel_addon","order":5,"path":"scripts/panel_addon/panel_addon.yy",}, {"name":"s_node_text_splice","order":6,"path":"sprites/s_node_text_splice/s_node_text_splice.yy",}, {"name":"__atlas","order":6,"path":"scripts/__atlas/__atlas.yy",}, @@ -969,6 +971,7 @@ {"name":"o_dialog_preview_snap","order":4,"path":"objects/o_dialog_preview_snap/o_dialog_preview_snap.yy",}, {"name":"sh_blend_min","order":9,"path":"shaders/sh_blend_min/sh_blend_min.yy",}, {"name":"d3d_gizmo_circle_z","order":4,"path":"scripts/d3d_gizmo_circle_z/d3d_gizmo_circle_z.yy",}, + {"name":"sh_d3d_background","order":21,"path":"shaders/sh_d3d_background/sh_d3d_background.yy",}, {"name":"s_node_3d_scene","order":14,"path":"sprites/s_node_3d_scene/s_node_3d_scene.yy",}, {"name":"sh_pb_shade_half","order":5,"path":"shaders/sh_pb_shade_half/sh_pb_shade_half.yy",}, {"name":"node_polar","order":4,"path":"scripts/node_polar/node_polar.yy",}, @@ -1149,6 +1152,7 @@ {"name":"node_iterator_input","order":1,"path":"scripts/node_iterator_input/node_iterator_input.yy",}, {"name":"s_node_atlas","order":5,"path":"sprites/s_node_atlas/s_node_atlas.yy",}, {"name":"node_fluid_add","order":4,"path":"scripts/node_fluid_add/node_fluid_add.yy",}, + {"name":"sh_d3d_geometry","order":23,"path":"shaders/sh_d3d_geometry/sh_d3d_geometry.yy",}, {"name":"BBMOD_Quaternion","order":3,"path":"scripts/BBMOD_Quaternion/BBMOD_Quaternion.yy",}, {"name":"d3d_cube","order":1,"path":"scripts/d3d_cube/d3d_cube.yy",}, {"name":"d3d_group","order":9,"path":"scripts/d3d_group/d3d_group.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index cd5bef5b0..2d237bf29 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -229,6 +229,7 @@ {"resourceType":"GMFolder","resourceVersion":"1.0","name":"biterator","folderPath":"folders/VCT/biterator.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"widget","folderPath":"folders/VCT/widget.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"widgets","folderPath":"folders/widgets.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"ssao","folderPath":"folders/shader/3d/ssao.yy",}, ], "IncludedFiles": [ {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"ApolloHelp.html","ConfigValues":{"Itch":{"CopyToMask":"0",},},"CopyToMask":-1,"filePath":"datafiles",}, @@ -1258,6 +1259,7 @@ {"id":{"name":"node_iterator_length","path":"scripts/node_iterator_length/node_iterator_length.yy",},}, {"id":{"name":"node_VFX_effect_attract","path":"scripts/node_VFX_effect_attract/node_VFX_effect_attract.yy",},}, {"id":{"name":"node_fluid_repulse","path":"scripts/node_fluid_repulse/node_fluid_repulse.yy",},}, + {"id":{"name":"sh_d3d_ssao_blur","path":"shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy",},}, {"id":{"name":"panel_addon","path":"scripts/panel_addon/panel_addon.yy",},}, {"id":{"name":"s_node_text_splice","path":"sprites/s_node_text_splice/s_node_text_splice.yy",},}, {"id":{"name":"__atlas","path":"scripts/__atlas/__atlas.yy",},}, @@ -1590,6 +1592,7 @@ {"id":{"name":"o_dialog_preview_snap","path":"objects/o_dialog_preview_snap/o_dialog_preview_snap.yy",},}, {"id":{"name":"sh_blend_min","path":"shaders/sh_blend_min/sh_blend_min.yy",},}, {"id":{"name":"d3d_gizmo_circle_z","path":"scripts/d3d_gizmo_circle_z/d3d_gizmo_circle_z.yy",},}, + {"id":{"name":"sh_d3d_background","path":"shaders/sh_d3d_background/sh_d3d_background.yy",},}, {"id":{"name":"s_node_3d_scene","path":"sprites/s_node_3d_scene/s_node_3d_scene.yy",},}, {"id":{"name":"sh_pb_shade_half","path":"shaders/sh_pb_shade_half/sh_pb_shade_half.yy",},}, {"id":{"name":"node_polar","path":"scripts/node_polar/node_polar.yy",},}, @@ -1791,6 +1794,7 @@ {"id":{"name":"node_iterator_input","path":"scripts/node_iterator_input/node_iterator_input.yy",},}, {"id":{"name":"s_node_atlas","path":"sprites/s_node_atlas/s_node_atlas.yy",},}, {"id":{"name":"node_fluid_add","path":"scripts/node_fluid_add/node_fluid_add.yy",},}, + {"id":{"name":"sh_d3d_geometry","path":"shaders/sh_d3d_geometry/sh_d3d_geometry.yy",},}, {"id":{"name":"BBMOD_Quaternion","path":"scripts/BBMOD_Quaternion/BBMOD_Quaternion.yy",},}, {"id":{"name":"d3d_cube","path":"scripts/d3d_cube/d3d_cube.yy",},}, {"id":{"name":"d3d_group","path":"scripts/d3d_group/d3d_group.yy",},}, @@ -1894,6 +1898,7 @@ {"id":{"name":"BBMOD_Matrix","path":"scripts/BBMOD_Matrix/BBMOD_Matrix.yy",},}, {"id":{"name":"pack_shelf","path":"scripts/pack_shelf/pack_shelf.yy",},}, {"id":{"name":"s_node_path_trim","path":"sprites/s_node_path_trim/s_node_path_trim.yy",},}, + {"id":{"name":"sh_d3d_ssao","path":"shaders/sh_d3d_ssao/sh_d3d_ssao.yy",},}, {"id":{"name":"libfilesystem","path":"extensions/libfilesystem/libfilesystem.yy",},}, {"id":{"name":"node_channels_hsv","path":"scripts/node_channels_hsv/node_channels_hsv.yy",},}, {"id":{"name":"sh_stripe","path":"shaders/sh_stripe/sh_stripe.yy",},}, diff --git a/scripts/__node_3d/__node_3d.gml b/scripts/__node_3d/__node_3d.gml index 7fec7278f..ba4e9d779 100644 --- a/scripts/__node_3d/__node_3d.gml +++ b/scripts/__node_3d/__node_3d.gml @@ -14,27 +14,29 @@ function Node_3D(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constr static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {} static getPreviewObject = function() { #region - if(ds_list_empty(outputs)) return []; + if(ds_list_empty(outputs)) return noone; switch(outputs[| preview_channel].type) { case VALUE_TYPE.d3Mesh : case VALUE_TYPE.d3Light : case VALUE_TYPE.d3Camera : case VALUE_TYPE.d3Scene : break; - default : return []; + default : return noone; } var _obj = outputs[| 0].getValue(); if(is_array(_obj)) _obj = array_safe_get(_obj, preview_index, noone); - return [ _obj ]; + return _obj; } #endregion - static getPreviewObjectOutline = function() { return getPreviewObject() } + static getPreviewObjects = function() { return [ getPreviewObject() ]; } + + static getPreviewObjectOutline = function() { return getPreviewObjects() } static refreshPreview = function() { #region - var _prev_obj = getPreviewObject(); + var _prev_obj = getPreviewObjects(); mesh_prev_surface = surface_verify(mesh_prev_surface, 64, 64); surface_set_target(mesh_prev_surface); @@ -50,6 +52,7 @@ function Node_3D(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constr for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { var _prev = _prev_obj[i]; if(_prev == noone) continue; + var _b = _prev.getBBOX(); var _c = _prev.getCenter(); if(_b == noone || _c == noone) continue; diff --git a/scripts/__node_3d_object/__node_3d_object.gml b/scripts/__node_3d_object/__node_3d_object.gml index 4067c68e0..ecf9e56e7 100644 --- a/scripts/__node_3d_object/__node_3d_object.gml +++ b/scripts/__node_3d_object/__node_3d_object.gml @@ -576,7 +576,7 @@ function Node_3D_Object(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constr } #endregion static drawOverlay3D = function(active, params, _mx, _my, _snx, _sny, _panel) { #region - var object = getPreviewObject(); + var object = getPreviewObjects(); if(array_empty(object)) return; object = object[0]; diff --git a/scripts/d3d_camera/d3d_camera.gml b/scripts/d3d_camera/d3d_camera.gml index de9c32248..40c16986b 100644 --- a/scripts/d3d_camera/d3d_camera.gml +++ b/scripts/d3d_camera/d3d_camera.gml @@ -29,7 +29,7 @@ function __3dCamera() constructor { viewMat = new __mat4(); projMat = new __mat4(); - static getUp = function(_x = 1, _y = 1, _z = 1) { + static getUp = function(_x = 1, _y = 1, _z = 1) { #region var upVector = new __vec3(0, 0, -1); var hRad = degtorad(focus_angle_x); @@ -40,24 +40,23 @@ function __3dCamera() constructor { upVector.z = cos(vRad) * _z; return upVector._normalize(); - } + } #endregion - static applyCamera = function() { + static getCombinedMatrix = function() { return matrix_multiply(viewMat.raw, projMat.raw); } + + static applyCamera = function() { #region camera_set_view_mat(raw, viewMat.raw); camera_set_proj_mat(raw, projMat.raw); - var _viewMat = viewMat.transpose(); - var _projMat = projMat.transpose(); - camera_apply(raw); - } + } #endregion - static resetCamera = function() { + static resetCamera = function() { #region camera_apply(0); gpu_set_cullmode(cull_noculling); - } + } #endregion - static setMatrix = function() { + static setMatrix = function() { #region if(projection == CAMERA_PROJECTION.perspective) projMat.setRaw(matrix_build_projection_perspective_fov(fov, view_aspect, view_near, view_far)); else @@ -75,38 +74,38 @@ function __3dCamera() constructor { } return self; - } + } #endregion - static setFocusAngle = function(ax, ay, dist) { + static setFocusAngle = function(ax, ay, dist) { #region focus_angle_x = ax; focus_angle_y = ay; focus_dist = dist; return self; - } + } #endregion - static setViewFov = function(fov, near = view_near, far = view_far) { + static setViewFov = function(fov, near, far) { #region self.fov = fov; self.view_near = near; self.view_far = far; return self; - } + } #endregion - static setViewSize = function(w, h) { + static setViewSize = function(w, h) { #region view_w = w; view_h = h; view_aspect = w / h; return self; - } + } #endregion - static setCameraLookRotate = function() { + static setCameraLookRotate = function() { #region var _fPos = calculate_3d_position(focus.x, focus.y, focus.z, focus_angle_x, focus_angle_y, focus_dist); position.set(_fPos); - } + } #endregion - static worldPointToViewPoint = function(vec3) { + static worldPointToViewPoint = function(vec3) { #region var _vec4 = new __vec4().set(vec3, 1); var _view = viewMat.transpose().multiplyVector(_vec4); var _proj = projMat.transpose().multiplyVector(_view); @@ -116,9 +115,9 @@ function __3dCamera() constructor { _proj.y = view_h / 2 + _proj.y * view_h / 2; return _proj; - } + } #endregion - static viewPointToWorldRay = function(_x, _y) { + static viewPointToWorldRay = function(_x, _y) { #region var rayOrigin = position; var normalizedX = (2 * _x / view_w) - 1; @@ -134,5 +133,5 @@ function __3dCamera() constructor { ._normalize(); return new __ray(rayOrigin, rayDirection); - } + } #endregion } \ No newline at end of file diff --git a/scripts/d3d_group/d3d_group.gml b/scripts/d3d_group/d3d_group.gml index 3f345c1a6..438a5b5f0 100644 --- a/scripts/d3d_group/d3d_group.gml +++ b/scripts/d3d_group/d3d_group.gml @@ -1,7 +1,7 @@ function __3dGroup() constructor { objects = []; - static getCenter = function() { + static getCenter = function() { #region var _v = new __vec3(); var _i = 0; @@ -13,9 +13,9 @@ function __3dGroup() constructor { } return _i == 0? new __vec3() : _v.multiply(1 / _i); - } + } #endregion - static getBBOX = function() { + static getBBOX = function() { #region if(array_empty(objects)) return new __bbox3D(new __vec3(-0.5), new __vec3(0.5)); var _m0 = noone; var _m1 = noone; @@ -40,20 +40,20 @@ function __3dGroup() constructor { _m1._subtract(_cc); return new __bbox3D(_m0, _m1); - } + } #endregion - static _submit = function(callback, params = {}, shader = noone) { + static _submit = function(callback, scene = {}, shader = noone) { #region for( var i = 0, n = array_length(objects); i < n; i++ ) - callback(objects[i], params, shader); - } + callback(objects[i], scene, shader); + } #endregion - static submitShader = function(params = {}) { _submit(function(_obj, params) { _obj.submitShader(params); }, params); } - static submitSel = function(params = {}) { _submit(function(_obj, params) { _obj.submitSel(params); }, params); } - static submitUI = function(params = {}, shader = noone) { _submit(function(_obj, params, shader) { _obj.submitUI(params, shader); }, params, shader); } - static submit = function(params = {}, shader = noone) { _submit(function(_obj, params, shader) { _obj.submit(params, shader); }, params, shader); } + static submitShader = function(scene = {}) { _submit(function(_obj, scene) { _obj.submitShader(scene); }, scene); } + static submitSel = function(scene = {}) { _submit(function(_obj, scene) { _obj.submitSel(scene); }, scene); } + static submitUI = function(scene = {}, shader = noone) { _submit(function(_obj, scene, shader) { _obj.submitUI(scene, shader); }, scene, shader); } + static submit = function(scene = {}, shader = noone) { _submit(function(_obj, scene, shader) { _obj.submit(scene, shader); }, scene, shader); } - static map = function(callback, params = {}) { + static map = function(callback, scene = {}) { #region for( var i = 0, n = array_length(objects); i < n; i++ ) - callback(objects[i], params); - } + callback(objects[i], scene); + } #endregion } \ No newline at end of file diff --git a/scripts/d3d_object/d3d_object.gml b/scripts/d3d_object/d3d_object.gml index 273b8c2f5..855f26274 100644 --- a/scripts/d3d_object/d3d_object.gml +++ b/scripts/d3d_object/d3d_object.gml @@ -101,41 +101,42 @@ function __3dObject() constructor { return _res; } #endregion - static preSubmitVertex = function(params = {}) {} - static postSubmitVertex = function(params = {}) {} + static preSubmitVertex = function(scene = {}) {} + static postSubmitVertex = function(scene = {}) {} static getCenter = function() { return new __vec3(position.x, position.y, position.z); } static getBBOX = function() { return new __bbox3D(size.multiplyVec(scale).multiply(-0.5), size.multiplyVec(scale).multiply(0.5)); } - static submitShader = function(params = {}, shader = noone) {} + static submitShader = function(scene = {}, shader = noone) {} - static submit = function(params = {}, shader = noone) { submitVertex(params, shader); } - static submitUI = function(params = {}, shader = noone) { submitVertex(params, shader); } + static submit = function(scene = {}, shader = noone) { submitVertex(scene, shader); } + static submitUI = function(scene = {}, shader = noone) { submitVertex(scene, shader); } - static submitSel = function(params = {}) { #region - var _p = variable_clone(params); - _p.show_normal = false; - submitVertex(_p, sh_d3d_silhouette); + static submitSel = function(scene = {}) { #region + var _s = variable_clone(scene); + _s.show_normal = false; + submitVertex(_s, sh_d3d_silhouette); } #endregion - static submitVertex = function(params = {}, shader = noone) { #region - if(shader != noone) - shader_set(shader); - else if(custom_shader != noone) - shader_set(custom_shader); - else { - switch(VF) { - case global.VF_POS_NORM_TEX_COL: shader_set(sh_d3d_default); break; - case global.VF_POS_COL: shader_set(sh_d3d_wireframe); break; - } + static submitVertex = function(scene = {}, shader = noone) { #region + var _shader = sh_d3d_default; + + switch(VF) { + case global.VF_POS_NORM_TEX_COL: _shader = sh_d3d_default; break; + case global.VF_POS_COL: _shader = sh_d3d_wireframe; break; } - preSubmitVertex(params); + if(custom_shader != noone) _shader = custom_shader; + if(shader != noone) _shader = shader; + + shader_set(_shader); + + preSubmitVertex(scene); if(VB != noone) { #region matrix_stack_clear(); - if(params.apply_transform) { + if(scene.apply_transform) { var pos = matrix_build(position.x, position.y, position.z, 0, 0, 0, 1, 1, 1); @@ -149,7 +150,7 @@ function __3dObject() constructor { matrix_stack_push(sca); matrix_set(matrix_world, matrix_stack_top()); } else { - var pos = matrix_build(position.x - params.custom_transform.x, position.y - params.custom_transform.y, position.z - params.custom_transform.z, + var pos = matrix_build(position.x - scene.custom_transform.x, position.y - scene.custom_transform.y, position.z - scene.custom_transform.z, 0, 0, 0, 1, 1, 1); var siz = matrix_build(0, 0, 0, @@ -157,7 +158,7 @@ function __3dObject() constructor { scale.x, scale.y, scale.z); var sca = matrix_build(0, 0, 0, 0, 0, 0, - params.custom_scale.x, params.custom_scale.y, params.custom_scale.z); + scene.custom_scale.x, scene.custom_scale.y, scene.custom_scale.z); matrix_stack_push(pos); matrix_stack_push(siz); @@ -168,7 +169,7 @@ function __3dObject() constructor { #region ++++ Submit & Material ++++ for( var i = 0, n = array_length(VB); i < n; i++ ) { - if(VF == global.VF_POS_NORM_TEX_COL) { + if(_shader == sh_d3d_default) { var _mat = array_safe_get(materials, i, noone); if(_mat == noone) { shader_set_f("mat_diffuse", 1); @@ -182,12 +183,14 @@ function __3dObject() constructor { var _tex = _mat == noone? -1 : _mat.getTexture(); vertex_submit(VB[i], render_type, _tex); - } else + } else vertex_submit(VB[i], render_type, -1); } #endregion - if(params.show_normal && NVB != noone) { #region + shader_reset(); + + if(scene.show_normal && NVB != noone) { #region shader_set(sh_d3d_wireframe); for( var i = 0, n = array_length(NVB); i < n; i++ ) vertex_submit(NVB[i], pr_linelist, -1); @@ -197,9 +200,8 @@ function __3dObject() constructor { matrix_stack_clear(); matrix_set(matrix_world, matrix_build_identity()); - postSubmitVertex(params); + postSubmitVertex(scene); - shader_reset(); } #endregion static clone = function() { #region @@ -217,4 +219,6 @@ function __3dObject() constructor { } #endregion static onDestroy = function() { } + + static toString = function() { return $"[D3D Object\n\t{array_length(vertex)} vertex groups\n\tPosition: {position}\n\tRotation: {rotation}\n\tScale: {scale}]" } } \ No newline at end of file diff --git a/scripts/d3d_scene/d3d_scene.gml b/scripts/d3d_scene/d3d_scene.gml index 57a398dd2..d957e9d75 100644 --- a/scripts/d3d_scene/d3d_scene.gml +++ b/scripts/d3d_scene/d3d_scene.gml @@ -35,19 +35,28 @@ function __3dScene(camera) constructor { custom_transform = new __vec3(); custom_scale = new __vec3(1, 1, 1); - lightAmbient = c_black; - - lightDir_max = 16; + lightAmbient = c_black; + lightDir_max = 16; lightDir_shadow_max = 4; - - lightPnt_max = 16; + lightPnt_max = 16; lightPnt_shadow_max = 4; + cull_mode = cull_noculling; + enviroment_map = noone; gammaCorrection = true; show_normal = false; - static reset = function() { + geometry_data = []; + + ssao_enabled = false; + ssao = noone; + 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 = []; @@ -72,18 +81,118 @@ function __3dScene(camera) constructor { lightPnt_viewMat = []; lightPnt_projMat = []; lightPnt_shadowBias = []; - - enviroment_map = noone; - } reset(); + } reset(); #endregion static applyCamera = function() { camera.applyCamera(); } static resetCamera = function() { camera.resetCamera(); } - static apply = function() { - shader_set(sh_d3d_default); - shader_set_f("light_ambient", colToVec4(lightAmbient)); + static submit = function(object, shader = noone) { object.submit(self, shader); } + static submitUI = function(object, shader = noone) { object.submitUI(self, shader); } + static submitSel = function(object, shader = noone) { object.submitSel(self, shader); } + static submitShader = function(object, shader = noone) { object.submitShader(self, shader); } + + static deferPass = function(object, w, h) { #region + geometryPass(object, w, h); + ssaoPass(); + } #endregion + + static renderBackground = function(w, h) { #region + var _bgSurf = surface_create(w, h); + surface_set_shader(_bgSurf, 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; - shader_set_i("light_dir_count", lightDir_count); + 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 _bgSurf; + } #endregion + + static geometryPass = function(object, w = 512, h = 512) { #region + var world = surface_create(w, h, surface_rgba32float); + var view = surface_create(w, h, surface_rgba32float); + var normal = surface_create(w, h, surface_rgba32float); + + surface_set_target_ext(0, world); + surface_set_target_ext(1, view); + surface_set_target_ext(2, normal); + gpu_set_zwriteenable(true); + gpu_set_ztestenable(true); + + DRAW_CLEAR + camera.setMatrix(); + 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); + + submit(object, sh_d3d_geometry); + + shader_reset(); + gpu_set_ztestenable(false); + surface_reset_target(); + + geometry_data = [ world, view, normal ]; + } #endregion + + static ssaoPass = function() { #region + surface_free_safe(ssao); + if(!ssao_enabled) return; + + var _sw = surface_get_width(geometry_data[0]); + var _sh = surface_get_height(geometry_data[0]); + var _ssao_surf = surface_create(_sw, _sh); + + surface_set_shader(_ssao_surf, sh_d3d_ssao); + shader_set_surface("vPosition", geometry_data[0]); + shader_set_surface("vNormal", 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(); + + var _ssao_blur = surface_create(_sw, _sh); + surface_set_shader(_ssao_blur, sh_d3d_ssao_blur); + shader_set_f("dimension", _sw, _sh); + shader_set_surface("vNormal", geometry_data[2]); + + draw_surface_safe(_ssao_surf); + surface_reset_shader(); + + surface_free(_ssao_surf); + + ssao = _ssao_blur; + } #endregion + + static apply = function() { #region + shader_set(sh_d3d_default); + #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 ); + shader_set_surface("ao_map", 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); @@ -94,9 +203,9 @@ function __3dScene(camera) constructor { 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); + 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); @@ -108,18 +217,16 @@ function __3dScene(camera) constructor { 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 - 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_i("env_use_mapping", is_surface(enviroment_map) ); - shader_set_surface("env_map", enviroment_map ); - shader_set_dim("env_map_dimension", enviroment_map ); + #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 ); + #endregion shader_reset(); - } + } #endregion static addLightDirectional = function(light) { #region if(lightDir_count >= lightDir_max) { diff --git a/scripts/node_3d_camera/node_3d_camera.gml b/scripts/node_3d_camera/node_3d_camera.gml index 4bfbb7885..af2e25669 100644 --- a/scripts/node_3d_camera/node_3d_camera.gml +++ b/scripts/node_3d_camera/node_3d_camera.gml @@ -13,10 +13,12 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) scene = new __3dScene(camera); scene.name = "Camera"; + global.SKY_SPHERE = new __3dUVSphere(0.5, 16, 8, true); + inputs[| in_d3d + 0] = nodeValue("FOV", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 60 ) .setDisplay(VALUE_DISPLAY.slider, [ 10, 90, 1 ]); - inputs[| in_d3d + 1] = nodeValue("Clipping Distance", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0.01, 10 ] ) + inputs[| in_d3d + 1] = nodeValue("Clipping Distance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 10 ] ) .setDisplay(VALUE_DISPLAY.vector); inputs[| in_d3d + 2] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF ) @@ -28,7 +30,7 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) inputs[| in_d3d + 4] = nodeValue("Scene", self, JUNCTION_CONNECT.input, VALUE_TYPE.d3Scene, noone ) .setVisible(true, true); - inputs[| in_d3d + 5] = nodeValue("Ambient Light", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_black ); + inputs[| in_d3d + 5] = nodeValue("Ambient Light", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_grey ); inputs[| in_d3d + 6] = nodeValue("Show Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ); @@ -59,6 +61,15 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) inputs[| in_d3d + 16] = nodeValue("Environment Texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone ); + inputs[| in_d3d + 17] = nodeValue("Ambient Occlusion", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ); + + inputs[| in_d3d + 18] = nodeValue("AO Radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.25 ); + + inputs[| in_d3d + 19] = nodeValue("AO Bias", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.05 ); + + inputs[| in_d3d + 20] = nodeValue("AO Strength", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1. ) + .setDisplay(VALUE_DISPLAY.slider, [ 0.01, 4, 0.01 ]); + outputs[| 0] = nodeValue("Rendered", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone ); outputs[| 1] = nodeValue("Normal", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone ) @@ -72,6 +83,7 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) ["Transform", false], in_d3d + 9, 0, 1, in_d3d + 10, in_d3d + 11, in_d3d + 12, in_d3d + 13, in_d3d + 14, ["Camera", false], in_d3d + 3, in_d3d + 0, in_d3d + 1, in_d3d + 8, ["Render", false], in_d3d + 5, in_d3d + 16, in_d3d + 6, in_d3d + 7, in_d3d + 15, + ["Ambient Occlusion", false], in_d3d + 17, in_d3d + 20, in_d3d + 18, in_d3d + 19, ]; tool_lookat = new NodeTool( "Move Target", THEME.tools_3d_transform_object ); @@ -89,7 +101,7 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) } #endregion static drawOverlay3D = function(active, params, _mx, _my, _snx, _sny, _panel) { #region - var object = getPreviewObject(); + var object = getPreviewObjects(); if(array_empty(object)) return; object = object[0]; @@ -116,8 +128,9 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) } static step = function() { #region - var _proj = inputs[| in_d3d + 3].getValue(); - var _posm = inputs[| in_d3d + 9].getValue(); + var _proj = inputs[| in_d3d + 3].getValue(); + var _posm = inputs[| in_d3d + 9].getValue(); + var _ao = inputs[| in_d3d + 17].getValue(); inputs[| in_d3d + 0].setVisible(_proj == 0); inputs[| in_d3d + 8].setVisible(_proj == 1); @@ -130,6 +143,10 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) inputs[| in_d3d + 13].setVisible(_posm == 2); inputs[| in_d3d + 14].setVisible(_posm == 2); + inputs[| in_d3d + 18].setVisible(_ao); + inputs[| in_d3d + 19].setVisible(_ao); + inputs[| in_d3d + 20].setVisible(_ao); + switch(_posm) { case 0 : tools = [ tool_pos, tool_rot ]; @@ -168,11 +185,16 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) var _gamm = _data[in_d3d + 15]; var _env = _data[in_d3d + 16]; + var _aoEn = _data[in_d3d + 17]; + var _aoRa = _data[in_d3d + 18]; + var _aoBi = _data[in_d3d + 19]; + var _aoSr = _data[in_d3d + 20]; + var _qi1 = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(0, 1, 0), 90); var _qi2 = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(1, 0, 0), -90); var _qi3 = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(1, 0, 0), 90); - switch(_posm) { + switch(_posm) { #region ++++ camera positioning ++++ case 0 : camera.useFocus = false; camera.position.set(_pos); @@ -210,7 +232,7 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) lookRad.scale.set(_rad, _rad, 1); lookRad.position.set(new __vec3(camera.focus.x, camera.focus.y, camera.position.z)); break; - } + } #endregion object.position.set(camera.position); object.rotation = camera.rotation.Clone(); @@ -222,45 +244,80 @@ function Node_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) camera.setViewFov(_fov, _clip[0], _clip[1]); if(_proj == 0) camera.setViewSize(_dim[0], _dim[1]); else if(_proj == 1) camera.setViewSize(1 / _orts, _dim[0] / _dim[1] / _orts); + camera.setMatrix(); - var _render = surface_create(_dim[0], _dim[1]); - var _normal = surface_create(_dim[0], _dim[1]); - var _depth = surface_create(_dim[0], _dim[1]); + scene.camera = camera; + scene.lightAmbient = _ambt; + scene.gammaCorrection = _gamm; + scene.enviroment_map = _env; + scene.cull_mode = _back; + scene.ssao_enabled = _aoEn; + scene.ssao_radius = _aoRa; + scene.ssao_bias = _aoBi; + scene.ssao_strength = _aoSr; + + var _bgSurf = _dbg? scene.renderBackground(_dim[0], _dim[1]) : noone; + scene.deferPass(_scne, _dim[0], _dim[1]); + + var _render = outputs[| 0].getValue(); + var _normal = outputs[| 1].getValue(); + var _depth = outputs[| 2].getValue(); + + _render = surface_verify(_render, _dim[0], _dim[1]); + _normal = surface_verify(_normal, _dim[0], _dim[1]); + _depth = surface_verify(_depth , _dim[0], _dim[1]); surface_set_target_ext(0, _render); surface_set_target_ext(1, _normal); surface_set_target_ext(2, _depth ); - if(_dbg) draw_clear(_ambt); - else DRAW_CLEAR + DRAW_CLEAR gpu_set_zwriteenable(true); gpu_set_ztestenable(true); gpu_set_cullmode(_back); - camera.setMatrix(); camera.applyCamera(); - - scene.reset(); - scene.lightAmbient = _ambt; - scene.gammaCorrection = _gamm; - scene.enviroment_map = _env; - - _scne.submitShader(scene); - scene.apply(); - _scne.submit(scene); //////////////// SUBMIT //////////////// + scene.reset(); + scene.submitShader(_scne); + scene.apply(); + scene.submit(_scne); surface_reset_target(); - scene.resetCamera(); + camera.resetCamera(); - return [ _render, _normal, _depth ]; + var _finalRender = surface_create(_dim[0], _dim[1]); + surface_set_target(_finalRender); + DRAW_CLEAR + BLEND_ALPHA + + if(_dbg) { + draw_surface(_bgSurf, 0, 0); + surface_free(_bgSurf); + } + draw_surface(_render, 0, 0); + + BLEND_MULTIPLY + draw_surface_safe(scene.ssao); + BLEND_NORMAL + surface_reset_target(); + surface_free(_render); + + return [ _finalRender, _normal, _depth ]; } #endregion static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {} static getPreviewObject = function() { #region + var _scene = array_safe_get(all_inputs, in_d3d + 4, noone); + if(is_array(_scene)) + _scene = array_safe_get(_scene, preview_index, noone); + return _scene; + } #endregion + + static getPreviewObjects = function() { #region var _posm = inputs[| in_d3d + 9].getValue(); var _scene = array_safe_get(all_inputs, in_d3d + 4, noone); diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index fd37af8e8..5a7b3248e 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -100,8 +100,11 @@ function Panel_Preview() : PanelContent() constructor { d3_surface_normal = noone; d3_surface_depth = noone; d3_surface_outline = noone; + d3_surface_bg = noone; d3_preview_channel = 0; + global.SKY_SPHERE = new __3dUVSphere(0.5, 16, 8, true); + #region camera d3_view_camera = new __3dCamera(); d3_camW = 1; @@ -123,6 +126,7 @@ function Panel_Preview() : PanelContent() constructor { #region scene d3_scene = new __3dScene(d3_view_camera); d3_scene.lightAmbient = $404040; + d3_scene_preview = d3_scene; d3_scene_light_enabled = true; @@ -288,9 +292,7 @@ function Panel_Preview() : PanelContent() constructor { if(preview_node[1] == node) preview_node[1] = noone; } #endregion - function resetNodePreview() { #region - preview_node = [ noone, noone ]; - } #endregion + function resetNodePreview() { preview_node = [ noone, noone ]; } function getNodePreview() { return preview_node[splitView? splitSelection : 0]; } function getNodePreviewSurface() { return preview_surface[splitView? splitSelection : 0]; } @@ -302,7 +304,6 @@ function Panel_Preview() : PanelContent() constructor { for( var i = 0; i < 2; i++ ) { var node = preview_node[i]; - preview_sequence[i] = 0; if(node == noone) continue; if(!node.active) { @@ -592,9 +593,9 @@ function Panel_Preview() : PanelContent() constructor { } #endregion function drawNodePreview() { #region - var ss = canvas_s; - var psx = 0, psy = 0; - var psw = 0, psh = 0; + var ss = canvas_s; + var psx = 0, psy = 0; + var psw = 0, psh = 0; var pswd = 0, pshd = 0; var psx1 = 0, psy1 = 0; @@ -637,7 +638,7 @@ function Panel_Preview() : PanelContent() constructor { draw_surface_ext_safe(preview_surface[0], psx, psy, ss, ss, 0, c_white, aa); } - switch(splitView) { + switch(splitView) { #region draw surfaces case 0 : if(is_surface(preview_surface[0])) { preview_node[0].previewing = 1; @@ -707,9 +708,9 @@ function Panel_Preview() : PanelContent() constructor { draw_surface_part_ext_safe(preview_surface[1], 0, sY, ssw, ssh - sY, ssx, spy, ss, ss, 0, c_white, 1); } break; - } + } #endregion - if(!instance_exists(o_dialog_menubox)) { + if(!instance_exists(o_dialog_menubox)) { #region color sample sample_color = noone; sample_x = noone; sample_y = noone; @@ -724,9 +725,9 @@ function Panel_Preview() : PanelContent() constructor { if(is_surface(surf)) sample_color = surface_get_pixel_ext(surf, sample_x, sample_y); } - } + } #endregion - if(is_surface(preview_surface[0])) { + if(is_surface(preview_surface[0])) { #region outline if(PROJECT.previewGrid.show) { var _gw = PROJECT.previewGrid.width * canvas_s; var _gh = PROJECT.previewGrid.height * canvas_s; @@ -755,16 +756,19 @@ function Panel_Preview() : PanelContent() constructor { draw_set_color(COLORS.panel_preview_surface_outline); draw_rectangle(psx, psy, psx + pswd - 1, psy + pshd - 1, true); - } + } #endregion } #endregion function draw3D() { #region var _prev_node = getNodePreview(); _prev_node.previewing = 1; + d3_scene_preview = struct_has(_prev_node, "scene")? _prev_node.scene : d3_scene; + d3_scene_preview.camera = d3_view_camera; + #region view var _pos, targ, _blend = 1; - + targ = d3_camTarget; _pos = calculate_3d_position(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist); @@ -800,12 +804,19 @@ function Panel_Preview() : PanelContent() constructor { d3_view_camera.setMatrix(); #endregion + #region background + surface_free_safe(d3_surface_bg); + + if(_prev_node.is_3D && d3_scene_preview != d3_scene) + d3_surface_bg = d3_scene_preview.renderBackground(w, h); + #endregion + #region shadow - if(_prev_node.is_3D) { + if(_prev_node.is_3D && d3_scene_preview == d3_scene) { d3_scene_light0.shadow_map_scale = d3_view_camera.focus_dist * 2; - var _prev_obj = _prev_node.getPreviewObject(); - d3_scene_light0.shadowProjectVertex(d3_scene, _prev_obj); + var _prev_obj = _prev_node.getPreviewObjects(); + d3_scene_light0.shadowProjectVertex(d3_scene_preview, _prev_obj); for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { var _prev = _prev_obj[i]; @@ -817,7 +828,7 @@ function Panel_Preview() : PanelContent() constructor { _prev.map(function(object, params) { if(!is_instanceof(object, __3dLight)) return; object.shadowProjectVertex(params.scene, params.objs); - }, { scene: d3_scene, objs:_prev_obj }); + }, { scene: d3_scene_preview, objs:_prev_obj }); } } #endregion @@ -827,12 +838,19 @@ function Panel_Preview() : PanelContent() constructor { d3_surface_depth = surface_verify(d3_surface_depth, w, h); d3_surface_outline = surface_verify(d3_surface_outline, w, h); + #region defer + if(_prev_node.is_3D && d3_scene_preview != d3_scene) { + var _prev_obj = _prev_node.getPreviewObject(); + d3_scene_preview.deferPass(_prev_obj, w, h); + } + #endregion + #region grid surface_set_target_ext(0, d3_surface); surface_set_target_ext(1, d3_surface_normal); surface_set_target_ext(2, d3_surface_depth); - draw_clear(bg_color); + draw_clear_alpha(bg_color, 0); d3_view_camera.applyCamera(); @@ -852,41 +870,52 @@ function Panel_Preview() : PanelContent() constructor { draw_sprite_stretched(s_fx_pixel, 0, _tx - _dist, _ty - _dist, _dist * 2, _dist * 2); shader_reset(); gpu_set_zwriteenable(true); - - d3_scene.reset(); #endregion #region draw + if(d3_scene_preview == d3_scene) + d3_scene_preview.reset(); gpu_set_cullmode(cull_counterclockwise); + if(_prev_node.is_3D) { - var _prev_obj = _prev_node.getPreviewObject(); + var _prev_obj = _prev_node.getPreviewObjects(); - if(d3_scene_light_enabled) { + if(d3_scene_light_enabled && d3_scene_preview == d3_scene) { d3_scene.addLightDirectional(d3_scene_light0); - //d3_scene.addLightDirectional(d3_scene_light1); + d3_scene.addLightDirectional(d3_scene_light1); } + if(d3_scene_preview == d3_scene) for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { var _prev = _prev_obj[i]; if(_prev == noone) continue; - _prev.submitShader(d3_scene); + _prev.submitShader(d3_scene_preview); } - d3_scene.apply(); + d3_scene_preview.apply(); for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { var _prev = _prev_obj[i]; if(_prev == noone) continue; - _prev.submitUI(d3_scene); //////////////// SUBMIT //////////////// + _prev.submitUI(d3_scene_preview); //////////////// SUBMIT //////////////// } } gpu_set_cullmode(cull_noculling); surface_reset_target(); + draw_clear(bg_color); + switch(d3_preview_channel) { - case 0 : draw_surface_safe(d3_surface); break; + case 0 : + draw_surface_safe(d3_surface_bg); + draw_surface_safe(d3_surface); + + BLEND_MULTIPLY + draw_surface_safe(d3_scene_preview.ssao); + BLEND_NORMAL + break; case 1 : draw_surface_safe(d3_surface_normal); break; case 2 : draw_surface_safe(d3_surface_depth); break; } @@ -920,7 +949,7 @@ function Panel_Preview() : PanelContent() constructor { } #endregion - d3_scene.resetCamera(); + d3_scene_preview.resetCamera(); } #endregion function drawPreviewOverlay() { #region @@ -1378,6 +1407,8 @@ function Panel_Preview() : PanelContent() constructor { bg_color = lerp_color(bg_color, d3_active? COLORS.panel_3d_bg : COLORS.panel_bg_clear, 0.3); title = __txt("Preview"); + getPreviewData(); + if(d3_active) { dragCanvas3D(); draw3D(); @@ -1386,7 +1417,6 @@ function Panel_Preview() : PanelContent() constructor { drawNodePreview(); } - getPreviewData(); drawPreviewOverlay(); var inspect_node = PANEL_INSPECTOR.inspecting; diff --git a/shaders/sh_d3d_background/sh_d3d_background.fsh b/shaders/sh_d3d_background/sh_d3d_background.fsh new file mode 100644 index 000000000..7cd9c6005 --- /dev/null +++ b/shaders/sh_d3d_background/sh_d3d_background.fsh @@ -0,0 +1,29 @@ +// +// Simple passthrough fragment shader +// +varying vec2 v_vTexcoord; +varying vec4 v_vColour; +varying vec4 v_worldPosition; + +#define PI 3.14159265359 +#define TAU 6.28318530718 + +uniform vec4 light_ambient; +uniform vec3 cameraPosition; +uniform int env_use_mapping; +uniform sampler2D env_map; +uniform vec2 env_map_dimension; + +vec2 equirectangularUv(vec3 dir) { + vec3 n = normalize(dir); + return vec2((atan(n.x, n.y) / TAU) + 0.5, 1. - acos(n.z) / PI); +} + +void main() { + if(env_use_mapping == 1) { + vec3 viewDirection = normalize(cameraPosition - v_worldPosition.xyz); + vec2 viewSample = equirectangularUv(viewDirection); + gl_FragColor = light_ambient * texture2D(env_map, viewSample); + } else + gl_FragColor = light_ambient; +} diff --git a/shaders/sh_d3d_background/sh_d3d_background.vsh b/shaders/sh_d3d_background/sh_d3d_background.vsh new file mode 100644 index 000000000..1f26f7770 --- /dev/null +++ b/shaders/sh_d3d_background/sh_d3d_background.vsh @@ -0,0 +1,20 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; +varying vec4 v_worldPosition; + +void main() { + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; + v_worldPosition = gm_Matrices[MATRIX_WORLD] * object_space_pos; +} diff --git a/shaders/sh_d3d_background/sh_d3d_background.yy b/shaders/sh_d3d_background/sh_d3d_background.yy new file mode 100644 index 000000000..aadc5a88c --- /dev/null +++ b/shaders/sh_d3d_background/sh_d3d_background.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_d3d_background", + "parent": { + "name": "3d", + "path": "folders/shader/3d.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/shaders/sh_d3d_default/sh_d3d_default.fsh b/shaders/sh_d3d_default/sh_d3d_default.fsh index 0cc7c4360..32345b798 100644 --- a/shaders/sh_d3d_default/sh_d3d_default.fsh +++ b/shaders/sh_d3d_default/sh_d3d_default.fsh @@ -160,6 +160,36 @@ void main() { 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; @@ -253,33 +283,6 @@ void main() { final_color.rgb *= light_effect; #endregion - #region ++++ environment ++++ - if(env_use_mapping == 1) { - 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; - 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 - gl_FragData[0] = final_color; gl_FragData[1] = vec4(0.5 + normal * 0.5, 1.); gl_FragData[2] = vec4(vec3(v_cameraDistance), 1.); diff --git a/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh b/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh new file mode 100644 index 000000000..ffd77ee38 --- /dev/null +++ b/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh @@ -0,0 +1,9 @@ +varying vec4 v_worldPosition; +varying vec3 v_viewPosition; +varying vec3 v_vNormal; + +void main() { + gl_FragData[0] = vec4(v_worldPosition.xyz, 1.); + gl_FragData[1] = vec4(v_viewPosition, 1.); + gl_FragData[2] = vec4(v_vNormal, 1.); +} diff --git a/shaders/sh_d3d_geometry/sh_d3d_geometry.vsh b/shaders/sh_d3d_geometry/sh_d3d_geometry.vsh new file mode 100644 index 000000000..79b2017e1 --- /dev/null +++ b/shaders/sh_d3d_geometry/sh_d3d_geometry.vsh @@ -0,0 +1,25 @@ +attribute vec3 in_Position; +attribute vec3 in_Normal; +attribute vec4 in_Colour; +attribute vec2 in_TextureCoord; + +varying vec4 v_worldPosition; +varying vec3 v_viewPosition; +varying vec3 v_vNormal; + +uniform float planeNear; +uniform float planeFar; + +void main() { + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_worldPosition = gm_Matrices[MATRIX_WORLD] * object_space_pos; + vec4 viewPos = gm_Matrices[MATRIX_WORLD_VIEW] * object_space_pos; + //viewPos.xy /= viewPos.w; + //viewPos.z = (viewPos.z - planeNear - planeFar) / (planeFar - planeNear); + v_viewPosition = viewPos.xyz; + + vec3 worldNormal = normalize(gm_Matrices[MATRIX_WORLD] * vec4(in_Normal, 0.)).xyz; + v_vNormal = worldNormal; +} diff --git a/shaders/sh_d3d_geometry/sh_d3d_geometry.yy b/shaders/sh_d3d_geometry/sh_d3d_geometry.yy new file mode 100644 index 000000000..6ed10a1b1 --- /dev/null +++ b/shaders/sh_d3d_geometry/sh_d3d_geometry.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_d3d_geometry", + "parent": { + "name": "3d", + "path": "folders/shader/3d.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/shaders/sh_d3d_ssao/sh_d3d_ssao.fsh b/shaders/sh_d3d_ssao/sh_d3d_ssao.fsh new file mode 100644 index 000000000..a0980329b --- /dev/null +++ b/shaders/sh_d3d_ssao/sh_d3d_ssao.fsh @@ -0,0 +1,70 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +#define MAX_SAMPLE 256 + +uniform sampler2D vPosition; +uniform sampler2D vNormal; +uniform float radius; +uniform float bias; +uniform float strength; +uniform vec3 cameraPosition; + +uniform mat4 projMatrix; + +float seed = 234234.453; +float rand(vec2 pos) { + float value = dot(pos, vec2(12.9898, 78.233)); + value = fract(sin(value + seed) * 43758.5453); + seed++; + return value; +} + +float rand(vec3 pos) { + float value = dot(pos, vec3(12.9898, 78.233, 45.164)); + value = fract(sin(value + seed) * 43758.5453); + seed++; + return value; +} + +void main() { + vec3 cPosition = texture2D( vPosition, v_vTexcoord ).rgb; + vec3 cNormal = texture2D( vNormal, v_vTexcoord ).rgb; + cNormal = normalize(cNormal); + + gl_FragColor = vec4(0.); + + float occluded = 0.; + float raysTotal = float(MAX_SAMPLE); + + vec3 rvec = vec3(rand(v_vTexcoord), rand(v_vTexcoord), rand(v_vTexcoord)) * 2. - 1.; + vec3 tangent = normalize(rvec - cNormal * dot(rvec, cNormal)); + vec3 bitangent = cross(cNormal, tangent); + mat3 tbn = mat3(tangent, bitangent, cNormal); //matrix to align the deviated vector to the normal hemisphere. + + for(int i = 0; i < MAX_SAMPLE; i++ ) { + vec3 sNormal = tbn * vec3( rand(v_vTexcoord) * 2. - 1., rand(v_vTexcoord) * 2. - 1., rand(v_vTexcoord) ); // genetate random point inside the hemisphere. + float scale = length(sNormal); + scale = mix(0.1, 1.0, scale * scale); + sNormal = normalize(sNormal) * scale; + + vec3 wPosition = cPosition + sNormal * radius; //add random vector to current world position. + float vecToCamDist = distance(wPosition, cameraPosition); + + vec4 projPos = projMatrix * vec4(wPosition, 1.); + projPos.xyz /= projPos.w; + projPos = (projPos + 1.) / 2.; //project new world position to view space. + + vec3 sPosition = texture2D( vPosition, projPos.xy ).xyz; //sample depth at the new point in the view space. + if(sPosition == vec3(0.)) continue; + + float geoToCamDist = distance(sPosition, cameraPosition); + + if(distance(sPosition, cPosition) < radius) + if(vecToCamDist - bias > geoToCamDist) + occluded++; + } + + gl_FragColor = vec4(vec3(1. - occluded / raysTotal * strength), 1.); + //gl_FragColor = vec4(vec3(distance(cPosition, cameraPosition) / 10.), 1.); +} diff --git a/shaders/sh_d3d_ssao/sh_d3d_ssao.vsh b/shaders/sh_d3d_ssao/sh_d3d_ssao.vsh new file mode 100644 index 000000000..2f60536ef --- /dev/null +++ b/shaders/sh_d3d_ssao/sh_d3d_ssao.vsh @@ -0,0 +1,15 @@ +attribute vec3 in_Position; // (x,y,z) +attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() { + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_d3d_ssao/sh_d3d_ssao.yy b/shaders/sh_d3d_ssao/sh_d3d_ssao.yy new file mode 100644 index 000000000..ee9791222 --- /dev/null +++ b/shaders/sh_d3d_ssao/sh_d3d_ssao.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_d3d_ssao", + "parent": { + "name": "ssao", + "path": "folders/shader/3d/ssao.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.fsh b/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.fsh new file mode 100644 index 000000000..b35757fb1 --- /dev/null +++ b/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.fsh @@ -0,0 +1,35 @@ +// +// Simple passthrough fragment shader +// +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform sampler2D vNormal; +uniform vec2 dimension; + +void main() { + vec3 cNormal = texture2D( vNormal, v_vTexcoord ).rgb; + vec2 tx = 1. / dimension; + + vec3 sampled = vec3(0.); + float weight = 0.; + float radius = 3.; + + for(float i = -radius; i <= radius; i++) + for(float j = -radius; j <= radius; j++) { + vec2 pos = v_vTexcoord + vec2(i, j) * tx; + if(pos.x < 0. || pos.y < 0. || pos.x > 1. || pos.y > 1.) + continue; + + float str = 1. - length(vec2(i, j)) / radius; + if(str < 0.) continue; + + vec3 _normal = texture2D( vNormal, pos ).rgb; + if(distance(_normal, cNormal) > 0.2) continue; + + sampled += texture2D( gm_BaseTexture, pos ).rgb * str; + weight += str; + } + + gl_FragColor = vec4(sampled / weight, 1.); +} diff --git a/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.vsh b/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.vsh @@ -0,0 +1,19 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() +{ + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy b/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy new file mode 100644 index 000000000..1aeca3fc4 --- /dev/null +++ b/shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_d3d_ssao_blur", + "parent": { + "name": "ssao", + "path": "folders/shader/3d/ssao.yy", + }, + "type": 1, +} \ No newline at end of file