Pixel-Composer/scripts/d3d_light_point/d3d_light_point.gml
2023-08-30 16:40:45 +02:00

129 lines
4.4 KiB
Plaintext

function __3dLightPoint() : __3dLight() constructor {
color = c_white;
intensity = 1;
radius = 10;
shadow_mapper = sh_d3d_shadow_depth;
shadow_map_size = 512;
shadow_map_views = array_create(6);
shadow_maps = array_create(6);
static submitSel = function(params = {}) {
shader_set(sh_d3d_wireframe);
preSubmitVertex(params);
shader_reset();
}
static submitShader = function(params = {}) { params.addLightPoint(self); }
static preSubmitVertex = function(params = {}) { #region
var _rot = new __rot3(0, 0, 0).lookAt(transform.position, params.camera.position);
var rot = matrix_build(0, 0, 0,
_rot.x, _rot.y, _rot.z,
1, 1, 1);
var sca = matrix_build(0, 0, 0,
0, 0, 0,
0.6, 0.6, 0.6);
var ran = matrix_build(0, 0, 0,
0, 0, 0,
radius * 2, radius * 2, radius * 2);
var pos = matrix_build(transform.position.x, transform.position.y, transform.position.z,
0, 0, 0,
1, 1, 1);
matrix_stack_push(pos);
matrix_stack_push(rot);
matrix_set(matrix_world, matrix_stack_top());
vertex_submit(VB_UI[0], pr_linestrip, -1);
matrix_stack_push(sca);
matrix_set(matrix_world, matrix_stack_top());
vertex_submit(VB_UI[0], pr_linestrip, -1);
matrix_stack_pop();
matrix_stack_push(ran);
matrix_set(matrix_world, matrix_stack_top());
vertex_submit(VB_UI[0], pr_linestrip, -1);
matrix_stack_pop();
matrix_stack_pop();
matrix_stack_pop();
matrix_set(matrix_world, matrix_build_identity());
} #endregion
static shadowProjectBegin = function(index = 0) { #region
//print($"Projecting cube face {index} to {shadow_maps[index]} with view {shadow_map_views[index]}")
surface_set_target(shadow_maps[index]);
draw_clear(c_black);
shader_set(shadow_mapper);
gpu_set_ztestenable(true);
camera_set_view_mat(shadow_map_camera, shadow_map_views[index]);
camera_set_proj_mat(shadow_map_camera, shadow_map_proj);
camera_apply(shadow_map_camera);
} #endregion
static shadowProjectEnd = function() { #region
shader_reset();
surface_reset_target();
camera_apply(0);
gpu_set_ztestenable(false);
} #endregion
static shadowProjectVertex = function(scene, objects) { #region
if(!shadow_active) return;
for( var i = 0; i < 6; i++ )
shadow_maps[i] = surface_verify(shadow_maps[i], shadow_map_size, shadow_map_size, surface_r32float);
var position = transform.position;
shadow_map_views = array_create(6);
shadow_map_views[0] = matrix_build_lookat(position.x, position.y, position.z, position.x + 1, position.y, position.z, 0, 0, -1);
shadow_map_views[1] = matrix_build_lookat(position.x, position.y, position.z, position.x - 1, position.y, position.z, 0, 0, -1);
shadow_map_views[2] = matrix_build_lookat(position.x, position.y, position.z, position.x, position.y + 1, position.z, 0, 0, -1);
shadow_map_views[3] = matrix_build_lookat(position.x, position.y, position.z, position.x, position.y - 1, position.z, 0, 0, -1);
shadow_map_views[4] = matrix_build_lookat(position.x, position.y, position.z, position.x, position.y, position.z + 1, 0, -1, 0);
shadow_map_views[5] = matrix_build_lookat(position.x, position.y, position.z, position.x, position.y, position.z - 1, 0, 1, 0);
shadow_map_view = array_merge( shadow_map_views[0], shadow_map_views[1], shadow_map_views[2], shadow_map_views[3], shadow_map_views[4], shadow_map_views[5] );
shadow_map_proj = matrix_build_projection_perspective_fov(90, 1, .01, radius);
for( var j = 0; j < 6; j++ ) { ///FUCK There's gotta be a better way to do this in GameMaker
shadowProjectBegin(j);
for( var i = 0, n = array_length(objects); i < n; i++ ) {
var _prev = objects[i];
if(_prev == noone) continue;
_prev.submit(scene, shadow_mapper);
}
shadowProjectEnd();
}
shadow_map = surface_verify(shadow_map, shadow_map_size * 2, shadow_map_size, surface_rgba32float);
surface_set_target(shadow_map);
draw_clear(c_black);
gpu_set_blendmode_ext(bm_one, bm_one);
draw_surface(shadow_maps[0], 0, 0);
draw_surface(shadow_maps[3], shadow_map_size, 0);
shader_set(sh_channel_R2G);
draw_surface(shadow_maps[1], 0, 0);
draw_surface(shadow_maps[4], shadow_map_size, 0);
shader_reset();
shader_set(sh_channel_R2B);
draw_surface(shadow_maps[2], 0, 0);
draw_surface(shadow_maps[5], shadow_map_size, 0);
shader_reset();
gpu_set_blendmode(bm_normal);
surface_reset_target();
} #endregion
}