From cff9194721a38053ce7640b00ad42e33af601634 Mon Sep 17 00:00:00 2001 From: Katajisto Date: Thu, 30 Oct 2025 23:12:16 +0200 Subject: [PATCH] create billboard rendering pipeline --- src/main.jai | 1 + src/rendering/backend.jai | 6 + src/rendering/backend_sokol.jai | 27 ++ src/rendering/helpers.jai | 6 + src/rendering/pipelines.jai | 58 +++ src/rendering/tasks.jai | 12 +- src/shaders/jai/shader_billboard.jai | 506 +++++++++++++++++++++++++++ src/shaders/shader_billboard.glsl | 48 +++ 8 files changed, 662 insertions(+), 2 deletions(-) create mode 100644 src/shaders/jai/shader_billboard.jai create mode 100644 src/shaders/shader_billboard.glsl diff --git a/src/main.jai b/src/main.jai index 9e853d0..880b55b 100644 --- a/src/main.jai +++ b/src/main.jai @@ -11,6 +11,7 @@ MEM_DEBUG :: false; #import "Hash"; #import "Simple_Package_Reader"; +String :: #import "String"; Jaison :: #import "Jaison"; stbi :: #import "stb_image"; diff --git a/src/rendering/backend.jai b/src/rendering/backend.jai index ffbabb9..ca0b26e 100644 --- a/src/rendering/backend.jai +++ b/src/rendering/backend.jai @@ -21,6 +21,7 @@ Render_Command_Type :: enum { UPDATE_TRIXELS; DRAW_TRIXELS; SET_LIGHT; + DRAW_BILLBOARD; } Render_Command :: struct { @@ -60,6 +61,11 @@ Render_Command_Update_Trixels :: struct { colMultipliers : *[16][16][16]Vector3; } +Render_Command_Draw_Billboard :: struct { + #as using c : Render_Command; + c.type = .DRAW_BILLBOARD; +} + Render_Command_Draw_Trixels :: struct { #as using c : Render_Command; c.type = .DRAW_TRIXELS; diff --git a/src/rendering/backend_sokol.jai b/src/rendering/backend_sokol.jai index 0db5906..93506be 100644 --- a/src/rendering/backend_sokol.jai +++ b/src/rendering/backend_sokol.jai @@ -40,6 +40,8 @@ backend_handle_command :: (cmd: *Render_Command) { case .SET_LIGHT; set_light_command := cast(*Render_Command_Set_Light)cmd; current_world_config = set_light_command.worldConfig; + case .DRAW_BILLBOARD; + backend_draw_billboard(); } } @@ -223,6 +225,31 @@ backend_draw_ground :: (wc: *World_Config) { sg_draw(0, 6, 2); } +backend_draw_billboard :: () { + mvp := create_viewproj(*camera); + vs_params : Billboard_Vs_Params; + anim := table_find_pointer(*g_animations, "player_idle"); + if anim { + gPipelines.billboard.bind.images[0] = anim.sheet; + num := cast(s32)(get_time() / 0.1) % anim.frames.count; + frame := anim.frames[num]; + vs_params.uvs = Vector4.{ + cast(float) frame.x / cast(float)anim.sheet_w, + cast(float) frame.y / cast(float)anim.sheet_h, + cast(float) frame.w / cast(float)anim.sheet_w, + cast(float) frame.h / cast(float)anim.sheet_h, + }.component; + vs_params.size = Vector2.{cast(float)(frame.w / 16), cast(float)(frame.h / 16)}.component; + vs_params.cam = camera.position.component; + } + vs_params.mvp = mvp.floats; + vs_params.offset = Vector3.{10, 1, 5.5}.component; + sg_apply_pipeline(gPipelines.billboard.pipeline); + sg_apply_bindings(*gPipelines.billboard.bind); + sg_apply_uniforms(UB_billboard_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params)) })); + sg_draw(0, 6, 1); +} + backend_draw_ground_gbuf :: (wc: *World_Config) { mvp := create_viewproj(*camera); view := create_lookat(*camera); diff --git a/src/rendering/helpers.jai b/src/rendering/helpers.jai index 5102dc4..9660729 100644 --- a/src/rendering/helpers.jai +++ b/src/rendering/helpers.jai @@ -15,6 +15,7 @@ fill_uniform_with_engine_data :: (uniform: *$A, enginedata: *$B) { create_world_rendering_tasks :: (world: *World) { create_sky_rendering_task(*world.conf); create_set_light_rendering_task(*world.conf); + create_billboard_rendering_task(); for world.positions { if it.positions.count < 1 then continue; triletask := Rendering_Task_Trile.{}; @@ -47,6 +48,11 @@ create_ground_rendering_task :: (world: *World) { add_rendering_task(groundtask); } +create_billboard_rendering_task :: () { + billboardtask := Rendering_Task_Billboard.{type = .BILLBOARD }; + add_rendering_task(billboardtask); +} + create_set_cam_rendering_task :: (cam: Camera, planeHeight: float) { camtask := Rendering_Task_Set_Camera.{type = .SET_CAMERA, camera = cam, planeHeight = planeHeight}; add_rendering_task(camtask); diff --git a/src/rendering/pipelines.jai b/src/rendering/pipelines.jai index 9afd5f9..07b33de 100644 --- a/src/rendering/pipelines.jai +++ b/src/rendering/pipelines.jai @@ -63,6 +63,8 @@ gPipelines : struct { op : Pipeline_Binding; mix : Pipeline_Binding; + + billboard : Pipeline_Binding; // Renders the SSAO texture using things from the gbuffer pass. ssao: Pipeline_Binding; @@ -139,6 +141,7 @@ create_pipelines :: () { create_ssao_pipeline(); create_op_pipeline(); create_mix_pipeline(); + create_billboard_pipeline(); create_shadowmap_image(); create_final_image(); @@ -761,6 +764,61 @@ create_op_pipeline :: () { } +create_billboard_pipeline :: () { + pipeline: sg_pipeline_desc; + shader_desc := billboard_shader_desc(sg_query_backend()); + pipeline.shader = sg_make_shader(*shader_desc); + pipeline.layout.buffers[0].stride = 4*3; + + pipeline.layout.attrs[ATTR_billboard_position] = .{ format = .FLOAT3, buffer_index = 0 }; + pipeline.index_type = .UINT16; + pipeline.depth = .{ + write_enabled = true, + compare = .LESS_EQUAL, + pixel_format = .DEPTH + }; + + color_state := sg_color_target_state.{ + pixel_format = .RGBA32F, + blend = .{ + enabled = true, + src_factor_rgb = .SRC_ALPHA, + dst_factor_rgb = .ONE_MINUS_SRC_ALPHA + } + }; + + vertices: [4]Vector3 = .[ + .{ 0.0, 0.0, 0.0}, + .{ 1.0, 0.0, 0.0}, + .{ 1.0, 1.0, 0.0}, + .{ 0.0, 1.0, 0.0}, + ]; + + indices: [6]u16 = .[ + 0, 1, 2, + 0, 2, 3, + ]; + + + pipeline.color_count = 1; + pipeline.colors[0] = color_state; + + gPipelines.billboard.pipeline = sg_make_pipeline(*pipeline); + + ibuffer := sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 6 * 2 } }; + vbuffer := sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 4 * 3 * 4 } }; + + gPipelines.billboard.bind.index_buffer = sg_make_buffer(*ibuffer); + gPipelines.billboard.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer); + + gPipelines.billboard.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{ + wrap_u = .CLAMP_TO_EDGE, + wrap_v = .CLAMP_TO_EDGE, + min_filter = .NEAREST, + mag_filter = .NEAREST, + })); +} + // Takes in 2-3 textures, and mixes them. create_mix_pipeline :: () { platconf := get_plat_conf(); diff --git a/src/rendering/tasks.jai b/src/rendering/tasks.jai index 69fb03a..cae9f8c 100644 --- a/src/rendering/tasks.jai +++ b/src/rendering/tasks.jai @@ -8,8 +8,8 @@ Rendering_Task_Type :: enum { SET_LIGHT; TRILE; // We need to add an ability to invalidate buffer instead of updating it constantly. Also probably have a buffer for static world triles and one for moving ones. TRIXELS; - SPRITE; - PARTICLES; + BILLBOARD; + PARTICLES; }; Rendering_Task :: struct { @@ -39,6 +39,11 @@ Rendering_Task_Ground :: struct { world : *World; } +Rendering_Task_Billboard :: struct { + #as using t : Rendering_Task; + t.type = .BILLBOARD; +} + Rendering_Task_Trile :: struct { #as using t : Rendering_Task; t.type = .TRILE; @@ -115,6 +120,9 @@ tasks_to_commands :: () { commandDrawGround.worldConfig = *(cast(*Rendering_Task_Ground)it).world.conf; array_add(*render_command_buckets.main, commandDrawGround); array_add(*render_command_buckets.gbuffer, commandDrawGround); + case .BILLBOARD; + commandDrawBillboard := New(Render_Command_Draw_Billboard,, temp); + array_add(*render_command_buckets.main, commandDrawBillboard); case .SET_CAMERA; task := (cast(*Rendering_Task_Set_Camera)it); command := New(Render_Command_Set_Camera,, temp); diff --git a/src/shaders/jai/shader_billboard.jai b/src/shaders/jai/shader_billboard.jai new file mode 100644 index 0000000..ddeac52 --- /dev/null +++ b/src/shaders/jai/shader_billboard.jai @@ -0,0 +1,506 @@ +/* + #version:1# (machine generated, don't edit!) + + Generated by sokol-shdc (https://github.com/floooh/sokol-tools) + + Cmdline: + sokol-shdc -i shader_billboard.glsl -o ./jai/shader_billboard.jai -l glsl430:glsl300es:metal_macos -f sokol_jai + + Overview: + ========= + Shader program: 'billboard': + Get shader desc: billboard_shader_desc(sg_query_backend()) + Vertex Shader: vs_billboard + Fragment Shader: fs_billboard + Attributes: + ATTR_billboard_position => 0 + Bindings: + Uniform block 'billboard_vs_params': + Jai struct: Billboard_Vs_Params + Bind slot: UB_billboard_vs_params => 0 + Image 'sprite': + Image type: ._2D + Sample type: .FLOAT + Multisampled: false + Bind slot: IMG_sprite => 0 + Sampler 'spritesmp': + Type: .FILTERING + Bind slot: SMP_spritesmp => 0 +*/ +ATTR_billboard_position :: 0; +UB_billboard_vs_params :: 0; +IMG_sprite :: 0; +SMP_spritesmp :: 0; +Billboard_Vs_Params :: struct { + mvp: [16]float; + uvs: [4]float; + offset: [3]float; + _: [4]u8; + size: [2]float; + _: [8]u8; + cam: [3]float; + _: [4]u8; +}; +/* + #version 430 + + uniform vec4 billboard_vs_params[8]; + layout(location = 0) in vec3 position; + layout(location = 0) out vec2 uv_in; + + void main() + { + vec3 _53 = billboard_vs_params[5].xyz - billboard_vs_params[7].xyz; + _53.y = 0.0; + gl_Position = mat4(billboard_vs_params[0], billboard_vs_params[1], billboard_vs_params[2], billboard_vs_params[3]) * vec4((billboard_vs_params[5].xyz + (normalize(cross(vec3(0.0, 1.0, 0.0), normalize(_53))) * ((position.x - 0.5) * billboard_vs_params[6].x))) + (vec3(0.0, 1.0, 0.0) * (position.y * billboard_vs_params[6].y)), 1.0); + uv_in = vec2(billboard_vs_params[4].x + (position.x * billboard_vs_params[4].z), billboard_vs_params[4].y + (position.y * billboard_vs_params[4].w)); + } + +*/ +vs_billboard_source_glsl430 := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x33,0x30,0x0a,0x0a,0x75,0x6e, + 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x62,0x69,0x6c,0x6c,0x62, + 0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x38, + 0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69, + 0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x33,0x20, + 0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74, + 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x6f, + 0x75,0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x5f,0x69,0x6e,0x3b,0x0a,0x0a, + 0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x35,0x33,0x20,0x3d,0x20,0x62,0x69,0x6c, + 0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73, + 0x5b,0x35,0x5d,0x2e,0x78,0x79,0x7a,0x20,0x2d,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f, + 0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x37,0x5d, + 0x2e,0x78,0x79,0x7a,0x3b,0x0a,0x20,0x20,0x20,0x20,0x5f,0x35,0x33,0x2e,0x79,0x20, + 0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f, + 0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x62,0x69, + 0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d, + 0x73,0x5b,0x30,0x5d,0x2c,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f, + 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x62,0x69, + 0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d, + 0x73,0x5b,0x32,0x5d,0x2c,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f, + 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33,0x5d,0x29,0x20,0x2a,0x20, + 0x76,0x65,0x63,0x34,0x28,0x28,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f, + 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x35,0x5d,0x2e,0x78,0x79,0x7a, + 0x20,0x2b,0x20,0x28,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65,0x28,0x63,0x72, + 0x6f,0x73,0x73,0x28,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e, + 0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x2c,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69, + 0x7a,0x65,0x28,0x5f,0x35,0x33,0x29,0x29,0x29,0x20,0x2a,0x20,0x28,0x28,0x70,0x6f, + 0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x78,0x20,0x2d,0x20,0x30,0x2e,0x35,0x29,0x20, + 0x2a,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70, + 0x61,0x72,0x61,0x6d,0x73,0x5b,0x36,0x5d,0x2e,0x78,0x29,0x29,0x29,0x20,0x2b,0x20, + 0x28,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x2c,0x20, + 0x30,0x2e,0x30,0x29,0x20,0x2a,0x20,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e, + 0x2e,0x79,0x20,0x2a,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76, + 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x36,0x5d,0x2e,0x79,0x29,0x29,0x2c, + 0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x5f,0x69,0x6e, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72, + 0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x2e,0x78, + 0x20,0x2b,0x20,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x78,0x20,0x2a, + 0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61, + 0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x2e,0x7a,0x29,0x2c,0x20,0x62,0x69,0x6c,0x6c, + 0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b, + 0x34,0x5d,0x2e,0x79,0x20,0x2b,0x20,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e, + 0x2e,0x79,0x20,0x2a,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76, + 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x2e,0x77,0x29,0x29,0x3b, + 0x0a,0x7d,0x0a,0x0a,0x00, +]; +/* + #version 430 + + layout(binding = 16) uniform sampler2D sprite_spritesmp; + + layout(location = 0) in vec2 uv_in; + layout(location = 0) out vec4 color; + + void main() + { + vec2 _12 = uv_in; + _12.y = 1.0 - _12.y; + vec4 _35 = texture(sprite_spritesmp, _12); + if (_35.w < 0.00999999977648258209228515625) + { + discard; + } + color = vec4(_35.xyz * 0.300000011920928955078125, 1.0); + } + +*/ +fs_billboard_source_glsl430 := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x33,0x30,0x0a,0x0a,0x6c,0x61, + 0x79,0x6f,0x75,0x74,0x28,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x20,0x3d,0x20,0x31, + 0x36,0x29,0x20,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x73,0x61,0x6d,0x70,0x6c, + 0x65,0x72,0x32,0x44,0x20,0x73,0x70,0x72,0x69,0x74,0x65,0x5f,0x73,0x70,0x72,0x69, + 0x74,0x65,0x73,0x6d,0x70,0x3b,0x0a,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c, + 0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,0x20, + 0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x5f,0x69,0x6e,0x3b,0x0a,0x6c,0x61,0x79,0x6f, + 0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29, + 0x20,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b, + 0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x32,0x20,0x3d,0x20,0x75, + 0x76,0x5f,0x69,0x6e,0x3b,0x0a,0x20,0x20,0x20,0x20,0x5f,0x31,0x32,0x2e,0x79,0x20, + 0x3d,0x20,0x31,0x2e,0x30,0x20,0x2d,0x20,0x5f,0x31,0x32,0x2e,0x79,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x34,0x20,0x5f,0x33,0x35,0x20,0x3d,0x20,0x74,0x65, + 0x78,0x74,0x75,0x72,0x65,0x28,0x73,0x70,0x72,0x69,0x74,0x65,0x5f,0x73,0x70,0x72, + 0x69,0x74,0x65,0x73,0x6d,0x70,0x2c,0x20,0x5f,0x31,0x32,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x33,0x35,0x2e,0x77,0x20,0x3c,0x20,0x30,0x2e, + 0x30,0x30,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x37,0x36,0x34,0x38,0x32,0x35, + 0x38,0x32,0x30,0x39,0x32,0x32,0x38,0x35,0x31,0x35,0x36,0x32,0x35,0x29,0x0a,0x20, + 0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x69,0x73, + 0x63,0x61,0x72,0x64,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20, + 0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x33,0x35, + 0x2e,0x78,0x79,0x7a,0x20,0x2a,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30, + 0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32, + 0x35,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, +]; +/* + #version 300 es + + uniform vec4 billboard_vs_params[8]; + layout(location = 0) in vec3 position; + out vec2 uv_in; + + void main() + { + vec3 _53 = billboard_vs_params[5].xyz - billboard_vs_params[7].xyz; + _53.y = 0.0; + gl_Position = mat4(billboard_vs_params[0], billboard_vs_params[1], billboard_vs_params[2], billboard_vs_params[3]) * vec4((billboard_vs_params[5].xyz + (normalize(cross(vec3(0.0, 1.0, 0.0), normalize(_53))) * ((position.x - 0.5) * billboard_vs_params[6].x))) + (vec3(0.0, 1.0, 0.0) * (position.y * billboard_vs_params[6].y)), 1.0); + uv_in = vec2(billboard_vs_params[4].x + (position.x * billboard_vs_params[4].z), billboard_vs_params[4].y + (position.y * billboard_vs_params[4].w)); + } + +*/ +vs_billboard_source_glsl300es := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a, + 0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x62,0x69, + 0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d, + 0x73,0x5b,0x38,0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63, + 0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x6f,0x75,0x74, + 0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x5f,0x69,0x6e,0x3b,0x0a,0x0a,0x76,0x6f, + 0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20, + 0x76,0x65,0x63,0x33,0x20,0x5f,0x35,0x33,0x20,0x3d,0x20,0x62,0x69,0x6c,0x6c,0x62, + 0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x35, + 0x5d,0x2e,0x78,0x79,0x7a,0x20,0x2d,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72, + 0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x37,0x5d,0x2e,0x78, + 0x79,0x7a,0x3b,0x0a,0x20,0x20,0x20,0x20,0x5f,0x35,0x33,0x2e,0x79,0x20,0x3d,0x20, + 0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69, + 0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x62,0x69,0x6c,0x6c, + 0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b, + 0x30,0x5d,0x2c,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73, + 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x62,0x69,0x6c,0x6c, + 0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b, + 0x32,0x5d,0x2c,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73, + 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33,0x5d,0x29,0x20,0x2a,0x20,0x76,0x65, + 0x63,0x34,0x28,0x28,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73, + 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x35,0x5d,0x2e,0x78,0x79,0x7a,0x20,0x2b, + 0x20,0x28,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65,0x28,0x63,0x72,0x6f,0x73, + 0x73,0x28,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x2c, + 0x20,0x30,0x2e,0x30,0x29,0x2c,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65, + 0x28,0x5f,0x35,0x33,0x29,0x29,0x29,0x20,0x2a,0x20,0x28,0x28,0x70,0x6f,0x73,0x69, + 0x74,0x69,0x6f,0x6e,0x2e,0x78,0x20,0x2d,0x20,0x30,0x2e,0x35,0x29,0x20,0x2a,0x20, + 0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72, + 0x61,0x6d,0x73,0x5b,0x36,0x5d,0x2e,0x78,0x29,0x29,0x29,0x20,0x2b,0x20,0x28,0x76, + 0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e, + 0x30,0x29,0x20,0x2a,0x20,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x79, + 0x20,0x2a,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f, + 0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x36,0x5d,0x2e,0x79,0x29,0x29,0x2c,0x20,0x31, + 0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x5f,0x69,0x6e,0x20,0x3d, + 0x20,0x76,0x65,0x63,0x32,0x28,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f, + 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x2e,0x78,0x20,0x2b, + 0x20,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x78,0x20,0x2a,0x20,0x62, + 0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61, + 0x6d,0x73,0x5b,0x34,0x5d,0x2e,0x7a,0x29,0x2c,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f, + 0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d, + 0x2e,0x79,0x20,0x2b,0x20,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x79, + 0x20,0x2a,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f, + 0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x2e,0x77,0x29,0x29,0x3b,0x0a,0x7d, + 0x0a,0x0a,0x00, +]; +/* + #version 300 es + precision mediump float; + precision highp int; + + uniform highp sampler2D sprite_spritesmp; + + in highp vec2 uv_in; + layout(location = 0) out highp vec4 color; + + void main() + { + highp vec2 _12 = uv_in; + _12.y = 1.0 - _12.y; + highp vec4 _35 = texture(sprite_spritesmp, _12); + if (_35.w < 0.00999999977648258209228515625) + { + discard; + } + color = vec4(_35.xyz * 0.300000011920928955078125, 1.0); + } + +*/ +fs_billboard_source_glsl300es := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a, + 0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x20,0x6d,0x65,0x64,0x69,0x75,0x6d, + 0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x3b,0x0a,0x70,0x72,0x65,0x63,0x69,0x73,0x69, + 0x6f,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x69,0x6e,0x74,0x3b,0x0a,0x0a,0x75, + 0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x73,0x61,0x6d, + 0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x73,0x70,0x72,0x69,0x74,0x65,0x5f,0x73,0x70, + 0x72,0x69,0x74,0x65,0x73,0x6d,0x70,0x3b,0x0a,0x0a,0x69,0x6e,0x20,0x68,0x69,0x67, + 0x68,0x70,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x5f,0x69,0x6e,0x3b,0x0a,0x6c, + 0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d, + 0x20,0x30,0x29,0x20,0x6f,0x75,0x74,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65, + 0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20, + 0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x68,0x69,0x67, + 0x68,0x70,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x32,0x20,0x3d,0x20,0x75,0x76, + 0x5f,0x69,0x6e,0x3b,0x0a,0x20,0x20,0x20,0x20,0x5f,0x31,0x32,0x2e,0x79,0x20,0x3d, + 0x20,0x31,0x2e,0x30,0x20,0x2d,0x20,0x5f,0x31,0x32,0x2e,0x79,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x34,0x20,0x5f,0x33,0x35, + 0x20,0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x73,0x70,0x72,0x69,0x74, + 0x65,0x5f,0x73,0x70,0x72,0x69,0x74,0x65,0x73,0x6d,0x70,0x2c,0x20,0x5f,0x31,0x32, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x33,0x35,0x2e,0x77, + 0x20,0x3c,0x20,0x30,0x2e,0x30,0x30,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x37, + 0x36,0x34,0x38,0x32,0x35,0x38,0x32,0x30,0x39,0x32,0x32,0x38,0x35,0x31,0x35,0x36, + 0x32,0x35,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x64,0x69,0x73,0x63,0x61,0x72,0x64,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d, + 0x0a,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x34,0x28,0x5f,0x33,0x35,0x2e,0x78,0x79,0x7a,0x20,0x2a,0x20,0x30,0x2e,0x33,0x30, + 0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35, + 0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x7d,0x0a, + 0x0a,0x00, +]; +/* + #include + #include + + using namespace metal; + + struct billboard_vs_params + { + float4x4 mvp; + float4 uvs; + float3 offset; + float2 size; + float3 cam; + }; + + struct main0_out + { + float2 uv_in [[user(locn0)]]; + float4 gl_Position [[position]]; + }; + + struct main0_in + { + float3 position [[attribute(0)]]; + }; + + vertex main0_out main0(main0_in in [[stage_in]], constant billboard_vs_params& _24 [[buffer(0)]]) + { + main0_out out = {}; + float3 _53 = _24.offset - _24.cam; + _53.y = 0.0; + out.gl_Position = _24.mvp * float4((_24.offset + (fast::normalize(cross(float3(0.0, 1.0, 0.0), fast::normalize(_53))) * ((in.position.x - 0.5) * _24.size.x))) + (float3(0.0, 1.0, 0.0) * (in.position.y * _24.size.y)), 1.0); + out.uv_in = float2(_24.uvs.x + (in.position.x * _24.uvs.z), _24.uvs.y + (in.position.y * _24.uvs.w)); + return out; + } + +*/ +vs_billboard_source_metal_macos := u8.[ + 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f, + 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65, + 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a, + 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20, + 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x62, + 0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61, + 0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78, + 0x34,0x20,0x6d,0x76,0x70,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x34,0x20,0x75,0x76,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x33,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c, + 0x6f,0x61,0x74,0x32,0x20,0x73,0x69,0x7a,0x65,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x33,0x20,0x63,0x61,0x6d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73, + 0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x5f, + 0x69,0x6e,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,0x29, + 0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x67, + 0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x70,0x6f,0x73, + 0x69,0x74,0x69,0x6f,0x6e,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72, + 0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x33,0x20,0x70,0x6f,0x73,0x69,0x74,0x69, + 0x6f,0x6e,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x30, + 0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x76,0x65,0x72,0x74,0x65,0x78,0x20, + 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28, + 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74, + 0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x61, + 0x6e,0x74,0x20,0x62,0x69,0x6c,0x6c,0x62,0x6f,0x61,0x72,0x64,0x5f,0x76,0x73,0x5f, + 0x70,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x32,0x34,0x20,0x5b,0x5b,0x62,0x75, + 0x66,0x66,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d, + 0x20,0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x33,0x20, + 0x5f,0x35,0x33,0x20,0x3d,0x20,0x5f,0x32,0x34,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74, + 0x20,0x2d,0x20,0x5f,0x32,0x34,0x2e,0x63,0x61,0x6d,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x5f,0x35,0x33,0x2e,0x79,0x20,0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x6f,0x75,0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e, + 0x20,0x3d,0x20,0x5f,0x32,0x34,0x2e,0x6d,0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x34,0x28,0x28,0x5f,0x32,0x34,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x20, + 0x2b,0x20,0x28,0x66,0x61,0x73,0x74,0x3a,0x3a,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69, + 0x7a,0x65,0x28,0x63,0x72,0x6f,0x73,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x33,0x28, + 0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x2c,0x20, + 0x66,0x61,0x73,0x74,0x3a,0x3a,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65,0x28, + 0x5f,0x35,0x33,0x29,0x29,0x29,0x20,0x2a,0x20,0x28,0x28,0x69,0x6e,0x2e,0x70,0x6f, + 0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x78,0x20,0x2d,0x20,0x30,0x2e,0x35,0x29,0x20, + 0x2a,0x20,0x5f,0x32,0x34,0x2e,0x73,0x69,0x7a,0x65,0x2e,0x78,0x29,0x29,0x29,0x20, + 0x2b,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x31, + 0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x20,0x2a,0x20,0x28,0x69,0x6e,0x2e,0x70, + 0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x79,0x20,0x2a,0x20,0x5f,0x32,0x34,0x2e, + 0x73,0x69,0x7a,0x65,0x2e,0x79,0x29,0x29,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x75,0x76,0x5f,0x69,0x6e,0x20,0x3d,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x32,0x28,0x5f,0x32,0x34,0x2e,0x75,0x76,0x73,0x2e,0x78, + 0x20,0x2b,0x20,0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e, + 0x78,0x20,0x2a,0x20,0x5f,0x32,0x34,0x2e,0x75,0x76,0x73,0x2e,0x7a,0x29,0x2c,0x20, + 0x5f,0x32,0x34,0x2e,0x75,0x76,0x73,0x2e,0x79,0x20,0x2b,0x20,0x28,0x69,0x6e,0x2e, + 0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2e,0x79,0x20,0x2a,0x20,0x5f,0x32,0x34, + 0x2e,0x75,0x76,0x73,0x2e,0x77,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65, + 0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, +]; +/* + #include + #include + + using namespace metal; + + struct main0_out + { + float4 color [[color(0)]]; + }; + + struct main0_in + { + float2 uv_in [[user(locn0)]]; + }; + + fragment main0_out main0(main0_in in [[stage_in]], texture2d sprite [[texture(0)]], sampler spritesmp [[sampler(0)]]) + { + main0_out out = {}; + float4 _27 = sprite.sample(spritesmp, in.uv_in); + if (_27.w < 0.00999999977648258209228515625) + { + discard_fragment(); + } + out.color = float4(_27.xyz * 0.300000011920928955078125, 1.0); + return out; + } + +*/ +fs_billboard_source_metal_macos := u8.[ + 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f, + 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65, + 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a, + 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20, + 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d, + 0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x63,0x6f, + 0x6c,0x6f,0x72,0x28,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74, + 0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x5f,0x69,0x6e, + 0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d, + 0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x20,0x6d, + 0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d, + 0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61, + 0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65, + 0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,0x3e,0x20,0x73,0x70,0x72,0x69,0x74,0x65, + 0x20,0x5b,0x5b,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x30,0x29,0x5d,0x5d,0x2c, + 0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x20,0x73,0x70,0x72,0x69,0x74,0x65,0x73, + 0x6d,0x70,0x20,0x5b,0x5b,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x28,0x30,0x29,0x5d, + 0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f, + 0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,0x32,0x37,0x20,0x3d,0x20,0x73,0x70, + 0x72,0x69,0x74,0x65,0x2e,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x73,0x70,0x72,0x69, + 0x74,0x65,0x73,0x6d,0x70,0x2c,0x20,0x69,0x6e,0x2e,0x75,0x76,0x5f,0x69,0x6e,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x32,0x37,0x2e,0x77,0x20, + 0x3c,0x20,0x30,0x2e,0x30,0x30,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x37,0x36, + 0x34,0x38,0x32,0x35,0x38,0x32,0x30,0x39,0x32,0x32,0x38,0x35,0x31,0x35,0x36,0x32, + 0x35,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x64,0x69,0x73,0x63,0x61,0x72,0x64,0x5f,0x66,0x72,0x61,0x67,0x6d,0x65,0x6e, + 0x74,0x28,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x6f, + 0x75,0x74,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x34,0x28,0x5f,0x32,0x37,0x2e,0x78,0x79,0x7a,0x20,0x2a,0x20,0x30,0x2e,0x33,0x30, + 0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35, + 0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a, + 0x0a,0x00, +]; +billboard_shader_desc :: (backend: sg_backend) -> sg_shader_desc { + desc: sg_shader_desc; + desc.label = "billboard_shader"; + if backend == { + case .GLCORE; + desc.vertex_func.source = xx *vs_billboard_source_glsl430; + desc.vertex_func.entry = "main"; + desc.fragment_func.source = xx *fs_billboard_source_glsl430; + desc.fragment_func.entry = "main"; + desc.attrs[0].base_type = .FLOAT; + desc.attrs[0].glsl_name = "position"; + desc.uniform_blocks[0].stage = .VERTEX; + desc.uniform_blocks[0].layout = .STD140; + desc.uniform_blocks[0].size = 128; + desc.uniform_blocks[0].glsl_uniforms[0].type = .FLOAT4; + desc.uniform_blocks[0].glsl_uniforms[0].array_count = 8; + desc.uniform_blocks[0].glsl_uniforms[0].glsl_name = "billboard_vs_params"; + desc.images[0].stage = .FRAGMENT; + desc.images[0].multisampled = false; + desc.images[0].image_type = ._2D; + desc.images[0].sample_type = .FLOAT; + desc.samplers[0].stage = .FRAGMENT; + desc.samplers[0].sampler_type = .FILTERING; + desc.image_sampler_pairs[0].stage = .FRAGMENT; + desc.image_sampler_pairs[0].image_slot = 0; + desc.image_sampler_pairs[0].sampler_slot = 0; + desc.image_sampler_pairs[0].glsl_name = "sprite_spritesmp"; + case .GLES3; + desc.vertex_func.source = xx *vs_billboard_source_glsl300es; + desc.vertex_func.entry = "main"; + desc.fragment_func.source = xx *fs_billboard_source_glsl300es; + desc.fragment_func.entry = "main"; + desc.attrs[0].base_type = .FLOAT; + desc.attrs[0].glsl_name = "position"; + desc.uniform_blocks[0].stage = .VERTEX; + desc.uniform_blocks[0].layout = .STD140; + desc.uniform_blocks[0].size = 128; + desc.uniform_blocks[0].glsl_uniforms[0].type = .FLOAT4; + desc.uniform_blocks[0].glsl_uniforms[0].array_count = 8; + desc.uniform_blocks[0].glsl_uniforms[0].glsl_name = "billboard_vs_params"; + desc.images[0].stage = .FRAGMENT; + desc.images[0].multisampled = false; + desc.images[0].image_type = ._2D; + desc.images[0].sample_type = .FLOAT; + desc.samplers[0].stage = .FRAGMENT; + desc.samplers[0].sampler_type = .FILTERING; + desc.image_sampler_pairs[0].stage = .FRAGMENT; + desc.image_sampler_pairs[0].image_slot = 0; + desc.image_sampler_pairs[0].sampler_slot = 0; + desc.image_sampler_pairs[0].glsl_name = "sprite_spritesmp"; + case .METAL_MACOS; + desc.vertex_func.source = xx *vs_billboard_source_metal_macos; + desc.vertex_func.entry = "main0"; + desc.fragment_func.source = xx *fs_billboard_source_metal_macos; + desc.fragment_func.entry = "main0"; + desc.attrs[0].base_type = .FLOAT; + desc.uniform_blocks[0].stage = .VERTEX; + desc.uniform_blocks[0].layout = .STD140; + desc.uniform_blocks[0].size = 128; + desc.uniform_blocks[0].msl_buffer_n = 0; + desc.images[0].stage = .FRAGMENT; + desc.images[0].multisampled = false; + desc.images[0].image_type = ._2D; + desc.images[0].sample_type = .FLOAT; + desc.images[0].msl_texture_n = 0; + desc.samplers[0].stage = .FRAGMENT; + desc.samplers[0].sampler_type = .FILTERING; + desc.samplers[0].msl_sampler_n = 0; + desc.image_sampler_pairs[0].stage = .FRAGMENT; + desc.image_sampler_pairs[0].image_slot = 0; + desc.image_sampler_pairs[0].sampler_slot = 0; + } + return desc; +} diff --git a/src/shaders/shader_billboard.glsl b/src/shaders/shader_billboard.glsl new file mode 100644 index 0000000..5adf675 --- /dev/null +++ b/src/shaders/shader_billboard.glsl @@ -0,0 +1,48 @@ +@vs vs_billboard + +in vec3 position; + +layout(binding=0) uniform billboard_vs_params { + mat4 mvp; + vec4 uvs; + vec3 offset; + vec2 size; + vec3 cam; +}; + +out vec2 uv_in; + +void main() { + vec3 local_pos = vec3((position.x - 0.5) * size.x, (position.y) * size.y, position.z); + vec3 world_up = vec3(0.0, 1.0, 0.0); + vec3 look_dir = offset - cam; + look_dir.y = 0.0; + look_dir = normalize(look_dir); + vec3 world_right = normalize(cross(world_up, look_dir)); + vec3 world_pos = offset + (world_right * local_pos.x) + (world_up * local_pos.y); + gl_Position = mvp * vec4(world_pos, 1.0); + uv_in = vec2(uvs.x + position.x * uvs.z, uvs.y + position.y * uvs.w); +} +@end + +@fs fs_billboard + +in vec2 uv_in; +out vec4 color; + +layout(binding = 0) uniform texture2D sprite; +layout(binding = 0) uniform sampler spritesmp; + +void main() { + vec2 uv = uv_in; + #if SOKOL_GLSL + uv.y = 1.0 - uv.y; + #endif + vec4 sampled = texture(sampler2D(sprite, spritesmp), uv); + if(sampled.a < 0.01) discard; + color = vec4(sampled.rgb * 0.3, 1.0); +} + +@end + +@program billboard vs_billboard fs_billboard