SSAO and other things

This commit is contained in:
Tanasart 2023-08-28 12:56:00 +02:00
parent a80d684a65
commit 5ebf1703f7
23 changed files with 651 additions and 177 deletions

View file

@ -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",},

View file

@ -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",},},

View file

@ -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;

View file

@ -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];

View file

@ -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
}

View file

@ -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
}

View file

@ -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}]" }
}

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -0,0 +1,10 @@
{
"resourceType": "GMShader",
"resourceVersion": "1.0",
"name": "sh_d3d_background",
"parent": {
"name": "3d",
"path": "folders/shader/3d.yy",
},
"type": 1,
}

View file

@ -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.);

View file

@ -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.);
}

View file

@ -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;
}

View file

@ -0,0 +1,10 @@
{
"resourceType": "GMShader",
"resourceVersion": "1.0",
"name": "sh_d3d_geometry",
"parent": {
"name": "3d",
"path": "folders/shader/3d.yy",
},
"type": 1,
}

View file

@ -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.);
}

View file

@ -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;
}

View file

@ -0,0 +1,10 @@
{
"resourceType": "GMShader",
"resourceVersion": "1.0",
"name": "sh_d3d_ssao",
"parent": {
"name": "ssao",
"path": "folders/shader/3d/ssao.yy",
},
"type": 1,
}

View file

@ -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.);
}

View file

@ -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;
}

View file

@ -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,
}