From 6aa530daea811f7db28778e2dc32839aa15bcd4e Mon Sep 17 00:00:00 2001 From: Sven Balzer <4653051+Kyuusokuna@users.noreply.github.com> Date: Mon, 3 Aug 2026 13:32:20 +0200 Subject: [PATCH] rename basic shader to character add character shadow make animation play twice as fast when sprinting --- CMakeLists.txt | 3 +- src/main.cpp | 27 ++- src/renderer.h | 3 +- src/renderer_sdlgpu.c | 163 +++++++++++++++++- src/renderer_wgpu.c | 127 +++++++++++++- .../spirv/{basic.spv => character.spv} | Bin src/shaders/spirv/character_shadow.spv | Bin 0 -> 2636 bytes .../src/{basic.slang => character.slang} | 0 src/shaders/src/character_shadow.slang | 75 ++++++++ .../wgsl/{basic.wgsl => character.wgsl} | 0 src/shaders/wgsl/character_shadow.wgsl | 88 ++++++++++ 11 files changed, 475 insertions(+), 11 deletions(-) rename src/shaders/spirv/{basic.spv => character.spv} (100%) create mode 100644 src/shaders/spirv/character_shadow.spv rename src/shaders/src/{basic.slang => character.slang} (100%) create mode 100644 src/shaders/src/character_shadow.slang rename src/shaders/wgsl/{basic.wgsl => character.wgsl} (100%) create mode 100644 src/shaders/wgsl/character_shadow.wgsl diff --git a/CMakeLists.txt b/CMakeLists.txt index 236c4c6..2cee8f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,8 @@ function(add_shader name) set(SHADERS_WGSL ${SHADERS_WGSL} "${CMAKE_CURRENT_SOURCE_DIR}/src/shaders/wgsl/${name}.wgsl" PARENT_SCOPE) endfunction() -add_shader(basic) +add_shader(character) +add_shader(character_shadow) add_shader(world) add_shader(grid) diff --git a/src/main.cpp b/src/main.cpp index 7943cba..8d8ac2c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ static SDL_Window *window; static R_Texture framebuffer; static R_Texture player_texture; +static R_Texture character_shadow_texture; static R_Texture tile_textures_atlas; static R_Texture tile_textures_atlas_imgui; @@ -915,6 +916,12 @@ static bool init_resources() { return false; } + character_shadow_texture = create_texture("characters/shadow.png"); + if (!character_shadow_texture) { + log_error("Failed to create shader texture."); + return false; + } + if (!recreate_tile_textures()) { log_error("Failed to create tile textures."); return false; @@ -1438,7 +1445,7 @@ static void update_state_game() { const bool *keyboard_state = SDL_GetKeyboardState(NULL); if (player.is_moving) { - player.animation_time += delta_time; + player.animation_time += delta_time * (keyboard_state[SDL_SCANCODE_LSHIFT] ? 2 : 1); vec2 leftover_movement = vec2(player.target_position) - player.visual_position; vec2 movement = clamp(min(vec2(0, 0), leftover_movement), normalize(leftover_movement) * (delta_t * character_speed * (keyboard_state[SDL_SCANCODE_LSHIFT] ? 2.0f : 1.0f)), max(vec2(0, 0), leftover_movement)); @@ -1478,7 +1485,8 @@ static void render_game() { { ZoneScopedN("player_instance_buffer"); - Uint64 variation_index = (player.animation_time / (100 * SDL_NS_PER_MS)) % 4; + Uint64 ns_per_variation = (1.0f / (character_speed * 2)) * SDL_NS_PER_SECOND; + Uint64 variation_index = (player.animation_time / (ns_per_variation)) % 4; player_instance.pos = player.visual_position; player_instance.sprite_selection = variation_index << 16 | player.direction; @@ -1555,7 +1563,20 @@ static void render_game() { { ZoneScopedN("Draw Player"); - renderer_frame_set_shader(R_SHADER_BASIC); + renderer_frame_set_shader(R_SHADER_CHARACTER_SHADOW); + renderer_frame_draw(vertex_buffer, index_buffer, player_instance_buffer, 6, 1, &(R_Draw_Resources){ + .vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer }, + + .num_vertex_uniform_buffers = 1, + + .fragment_sampled_textures = (R_Texture[]){ character_shadow_texture }, + .fragment_uniform_buffers = (R_Buffer[]){ tint_color_buffer }, + + .num_fragment_sampled_textures = 1, + .num_fragment_uniform_buffers = 1, + }); + + renderer_frame_set_shader(R_SHADER_CHARACTER); renderer_frame_draw(vertex_buffer, index_buffer, player_instance_buffer, 6, 1, &(R_Draw_Resources){ .vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer }, diff --git a/src/renderer.h b/src/renderer.h index 8524782..c355242 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -8,7 +8,8 @@ extern "C" { #endif // __cplusplus typedef enum : Uint32 { - R_SHADER_BASIC, + R_SHADER_CHARACTER, + R_SHADER_CHARACTER_SHADOW, R_SHADER_WORLD, R_SHADER_GRID, R_SHADER_COUNT, diff --git a/src/renderer_sdlgpu.c b/src/renderer_sdlgpu.c index 9971dc6..09baace 100644 --- a/src/renderer_sdlgpu.c +++ b/src/renderer_sdlgpu.c @@ -409,9 +409,9 @@ bool renderer_init(SDL_Window *window_) { }); // Shaders - { // Basic + { // Character const Uint8 shader_source[] = { - #embed "shaders/spirv/basic.spv" + #embed "shaders/spirv/character.spv" }; SDL_GPUShader *vertex_shader = SDL_CreateGPUShader(device, &(SDL_GPUShaderCreateInfo){ @@ -445,7 +445,164 @@ bool renderer_init(SDL_Window *window_) { SDL_PropertiesID properties = SDL_CreateProperties(); SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER basic"); - shaders[R_SHADER_BASIC] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){ + shaders[R_SHADER_CHARACTER] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){ + .vertex_shader = vertex_shader, + .fragment_shader = fragment_shader, + + .vertex_input_state = { + .vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){ + { + .slot = 0, + .pitch = 20, + .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX, + + .instance_step_rate = 0, + }, + { + .slot = 1, + .pitch = 12, + .input_rate = SDL_GPU_VERTEXINPUTRATE_INSTANCE, + + .instance_step_rate = 0, + }, + }, + .num_vertex_buffers = 2, + + .vertex_attributes = (SDL_GPUVertexAttribute[]){ + { + .location = 0, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, + .offset = 0, + }, + { + .location = 1, + .buffer_slot = 0, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, + .offset = 12, + }, + { + .location = 2, + .buffer_slot = 1, + .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, + .offset = 0, + }, + { + .location = 3, + .buffer_slot = 1, + .format = SDL_GPU_VERTEXELEMENTFORMAT_UINT, + .offset = 8, + }, + }, + .num_vertex_attributes = 4, + }, + + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_BACK, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + + .depth_bias_constant_factor = 0.0f, + .depth_bias_clamp = 0.0f, + .depth_bias_slope_factor = 0.0f, + + .enable_depth_bias = false, + .enable_depth_clip = false, + }, + + .multisample_state = { + .sample_count = SDL_GPU_SAMPLECOUNT_8, + .sample_mask = 0, + .enable_mask = 0, + + .enable_alpha_to_coverage = false, + }, + + .depth_stencil_state = { + .compare_op = SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, + + .back_stencil_state = { .fail_op = SDL_GPU_STENCILOP_INVALID, .pass_op = SDL_GPU_STENCILOP_INVALID, .depth_fail_op = SDL_GPU_STENCILOP_INVALID, .compare_op = SDL_GPU_COMPAREOP_INVALID, }, + .front_stencil_state = { .fail_op = SDL_GPU_STENCILOP_INVALID, .pass_op = SDL_GPU_STENCILOP_INVALID, .depth_fail_op = SDL_GPU_STENCILOP_INVALID, .compare_op = SDL_GPU_COMPAREOP_INVALID, }, + + .compare_mask = 0, + .write_mask = 0, + + .enable_depth_test = false, + .enable_depth_write = false, + .enable_stencil_test = false, + }, + + .target_info = { + .color_target_descriptions = (SDL_GPUColorTargetDescription[]){ + { + .format = texture_formats[surface.format], + .blend_state = { + .src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA, + .dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + .color_blend_op = SDL_GPU_BLENDOP_ADD, + + .src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA, + .dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + .alpha_blend_op = SDL_GPU_BLENDOP_ADD, + + .color_write_mask = 0, + + .enable_blend = true, + .enable_color_write_mask = false, + }, + } + }, + + .num_color_targets = 1, + + .depth_stencil_format = SDL_GPU_TEXTUREFORMAT_INVALID, + .has_depth_stencil_target = false, + }, + }); + SDL_DestroyProperties(properties); + SDL_ReleaseGPUShader(device, vertex_shader); + SDL_ReleaseGPUShader(device, fragment_shader); + } + + { // Character Shadow + const Uint8 shader_source[] = { + #embed "shaders/spirv/character_shadow.spv" + }; + + SDL_GPUShader *vertex_shader = SDL_CreateGPUShader(device, &(SDL_GPUShaderCreateInfo){ + .code_size = sizeof(shader_source), + .code = shader_source, + .entrypoint = "main_vertex", + + .format = SDL_GPU_SHADERFORMAT_SPIRV, + .stage = SDL_GPU_SHADERSTAGE_VERTEX, + + .num_samplers = 0, + .num_storage_textures = 0, + .num_storage_buffers = 0, + .num_uniform_buffers = 1, + }); + + SDL_GPUShader *fragment_shader = SDL_CreateGPUShader(device, &(SDL_GPUShaderCreateInfo){ + .code_size = sizeof(shader_source), + .code = shader_source, + .entrypoint = "main_fragment", + + .format = SDL_GPU_SHADERFORMAT_SPIRV, + .stage = SDL_GPU_SHADERSTAGE_FRAGMENT, + + .num_samplers = 1, + .num_storage_textures = 0, + .num_storage_buffers = 0, + .num_uniform_buffers = 1, + }); + + SDL_PropertiesID properties = SDL_CreateProperties(); + SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER basic"); + + shaders[R_SHADER_CHARACTER_SHADOW] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){ .vertex_shader = vertex_shader, .fragment_shader = fragment_shader, diff --git a/src/renderer_wgpu.c b/src/renderer_wgpu.c index 93c4511..4b4ef6d 100644 --- a/src/renderer_wgpu.c +++ b/src/renderer_wgpu.c @@ -673,9 +673,9 @@ bool renderer_init(SDL_Window *window_) { }; // Shaders - { // Basic + { // Character const char shader_source[] = { - #embed "shaders/wgsl/basic.wgsl" + #embed "shaders/wgsl/character.wgsl" }; WGPUShaderModule shader = wgpuDeviceCreateShaderModule(device, &(WGPUShaderModuleDescriptor){ @@ -686,7 +686,128 @@ bool renderer_init(SDL_Window *window_) { .label = { .data = "basic shader", .length = WGPU_STRLEN } }); - shaders[R_SHADER_BASIC] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){ + shaders[R_SHADER_CHARACTER] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){ + .label = { .data = "basic render_pipeline", .length = WGPU_STRLEN }, + + .layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){ + .label = { .data = "basic pipeline_layout", .length = WGPU_STRLEN }, + .bindGroupLayoutCount = 4, + .bindGroupLayouts = (WGPUBindGroupLayout[]){ + wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){ + .entryCount = 0, + .entries = (WGPUBindGroupLayoutEntry[]){ + + }, + }), + wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){ + .entryCount = 1, + .entries = (WGPUBindGroupLayoutEntry[]){ + { .binding = 0, .visibility = WGPUShaderStage_Vertex, .buffer = { .type = WGPUBufferBindingType_Uniform } }, + }, + }), + wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){ + .entryCount = 2, + .entries = (WGPUBindGroupLayoutEntry[]){ + { .binding = 0, .visibility = WGPUShaderStage_Fragment, .texture = { .sampleType = WGPUTextureSampleType_Float, .viewDimension = WGPUTextureViewDimension_2D } }, + { .binding = 1, .visibility = WGPUShaderStage_Fragment, .sampler = { .type = WGPUSamplerBindingType_Filtering } }, + }, + }), + wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){ + .entryCount = 1, + .entries = (WGPUBindGroupLayoutEntry[]){ + { .binding = 0, .visibility = WGPUShaderStage_Fragment, .buffer = { .type = WGPUBufferBindingType_Uniform } }, + }, + }), + }, + }), + + .vertex = { + .module = shader, + .entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN }, + .constantCount = 0, + .constants = NULL, + .bufferCount = 2, + .buffers = (WGPUVertexBufferLayout[]){ + { + .stepMode = WGPUVertexStepMode_Vertex, + .arrayStride = 20, + .attributeCount = 2, + .attributes = (WGPUVertexAttribute[]){ + { + .format = WGPUVertexFormat_Float32x3, + .offset = 0, + .shaderLocation = 0, + }, + { + .format = WGPUVertexFormat_Float32x2, + .offset = 12, + .shaderLocation = 1, + }, + }, + }, + { + .stepMode = WGPUVertexStepMode_Instance, + .arrayStride = 12, + .attributeCount = 2, + .attributes = (WGPUVertexAttribute[]){ + { + .format = WGPUVertexFormat_Float32x2, + .offset = 0, + .shaderLocation = 2, + }, + { + .format = WGPUVertexFormat_Uint32, + .offset = 8, + .shaderLocation = 3, + }, + }, + }, + }, + }, + + .primitive = { + .topology = WGPUPrimitiveTopology_TriangleList, + .stripIndexFormat = WGPUIndexFormat_Undefined, + .frontFace = WGPUFrontFace_CCW, + .cullMode = WGPUCullMode_Back, + .unclippedDepth = false, + }, + + .depthStencil = NULL, + + .multisample = { + .count = 4, + .mask = ~0u, + .alphaToCoverageEnabled = false, + }, + + .fragment = &(WGPUFragmentState){ + .module = shader, + .entryPoint = { .data = "main_fragment", .length = WGPU_STRLEN }, + .constantCount = 0, + .constants = NULL, + .targetCount = 1, + .targets = &color_target_state, + }, + }); + + wgpuShaderModuleRelease(shader); + } + + { // Character Shadow + const char shader_source[] = { + #embed "shaders/wgsl/character_shadow.wgsl" + }; + + WGPUShaderModule shader = wgpuDeviceCreateShaderModule(device, &(WGPUShaderModuleDescriptor){ + .nextInChain = (WGPUChainedStruct *)&(WGPUShaderSourceWGSL){ + .chain = { .next = NULL, .sType = WGPUSType_ShaderSourceWGSL }, + .code = { .data = shader_source, .length = SDL_arraysize(shader_source) }, + }, + .label = { .data = "basic shader", .length = WGPU_STRLEN } + }); + + shaders[R_SHADER_CHARACTER_SHADOW] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){ .label = { .data = "basic render_pipeline", .length = WGPU_STRLEN }, .layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){ diff --git a/src/shaders/spirv/basic.spv b/src/shaders/spirv/character.spv similarity index 100% rename from src/shaders/spirv/basic.spv rename to src/shaders/spirv/character.spv diff --git a/src/shaders/spirv/character_shadow.spv b/src/shaders/spirv/character_shadow.spv new file mode 100644 index 0000000000000000000000000000000000000000..3238c17ad4216975b5dddd3ff0887abeb46d5837 GIT binary patch literal 2636 zcmZvc+iP4^6o+>*nX##@tw`@uQlk)Q7`&vl_L9`6s8pM@5A|)BCX+IfnG;V>()y+p z!KZ+aYSpR_1^)prs1z^Y9r`Dfq9E$KFM{89&faBOy23Ae-S*n+cBVEweoqKPA%uzW z5C5h6!*F;ao?7k=jc|!`_QdHE&GW@#bLzljh~d6a^C)j`!Alwjy>_?XTI=LR=VEvs z`9-h;>;?~lEnzf_aL$9$cPVe5>vj4C@>TE>*h*~eBnMY3qnk^eKVxg26nyU4p2k1j1|?P79ja%#F&aI;bR z7^l_hb$Vwzxdqq5hH#W~t=qZKTFJAQI}1fO>&F<{HXUFS8+B%Q}z147EqLfLsKJ9A}go@JKyU;bI5%1h(bfo|lM z&K()_aTm4%V>*X@KuYpM@aawWuG+}T?hX#-Xs-ul`#cy=*?1{u`oe&8RJ5o2hf4XinVsA}3~x^6vzM%$ zvpU~C!fD>>l#fL@*`GtUPVZ}fA1v}E8E-McgTJN$!`7buQBzvUia0S zm95u(O|tRa*L2@{+)qh=^K;(@<6TAeeyZ;Vyz>=9Sj_!zaFF_q>s`q^{~|fJWBk`| z8?ZiQXRs4kUy}F0Ti;2hqJ12AM@YtBk9~d^Ub}hBqjQdr0`<}odojn>h~x_3pKM@C?50<}`3#6Tq4ebIt(u zZ{g$J<3OD;rs<;dJRW&xY0v&6gF_(od>)-t1NQtBr}Ok%`vlmV)Z;Vo?m&|NfY(Ra zz5W5X6N||1{f|+1j{MyBpQ6qh?4|qvbJTP2ja0t@zeIiV`8E33yX5m5yn6fZy#EB= zGbbtO|AN<7yZ7yjIjc`I`ZUVwB>mnXKjVG|tXrQ=@vYC{F9CN%d(wXq^&6x9I`tUi zdX(RcF~3CCSN*2AuV29%)1B154$_`{4ey(kPnFj-Wc4>ds^c4YYZ$B}z40<}Ce texture1 : register(t0, space2); + +[vk::binding(0, 3)] ConstantBuffer tint : register(b0, space3); + +[shader("pixel")] +FragmentShaderOutput main_fragment(VertexShaderOutput input) { + var output: FragmentShaderOutput; + + output.color = pixel_art_sample(texture1, input.uv); + output.color = float4(output.color.rgb * tint.rgb, output.color.a); + + return output; +} + +void GetDimensions(Sampler2D texture, out float width, out float height) { + __target_switch { + case wgsl: { + texture.__getTexture().GetDimensions(width, height); + } break; + default: { + texture.GetDimensions(width, height); + } break; + } +} + +float4 pixel_art_sample(Sampler2D input_texture, float2 input_uv) { + var dimensions : float2; + GetDimensions(input_texture, dimensions.x, dimensions.y); + + let texture_uv = input_uv * dimensions.xy; + let sample_uv = (floor(texture_uv) + min(fract(texture_uv) / fwidth(texture_uv), float2(1.0, 1.0)) - 0.5) / dimensions.xy; + + return input_texture.Sample(sample_uv); +} diff --git a/src/shaders/wgsl/basic.wgsl b/src/shaders/wgsl/character.wgsl similarity index 100% rename from src/shaders/wgsl/basic.wgsl rename to src/shaders/wgsl/character.wgsl diff --git a/src/shaders/wgsl/character_shadow.wgsl b/src/shaders/wgsl/character_shadow.wgsl new file mode 100644 index 0000000..8f27fe6 --- /dev/null +++ b/src/shaders/wgsl/character_shadow.wgsl @@ -0,0 +1,88 @@ +struct _MatrixStorage_float4x4_ColMajorstd140_0 +{ + @align(16) data_0 : array, i32(4)>, +}; + +@binding(0) @group(1) var view_projection_matrix_0 : _MatrixStorage_float4x4_ColMajorstd140_0; +@binding(0) @group(2) var texture1_texture_0 : texture_2d; + +@binding(1) @group(2) var texture1_sampler_0 : sampler; + +@binding(0) @group(3) var tint_0 : vec3; +struct VertexShaderOutput_0 +{ + @builtin(position) pos_0 : vec4, + @location(0) uv_0 : vec2, +}; + +struct vertexInput_0 +{ + @location(0) pos_1 : vec3, + @location(1) uv_1 : vec2, + @location(2) world_pos_0 : vec2, +}; + +struct VertexShaderInput_0 +{ + vertex_index_0 : u32, + pos_2 : vec3, + uv_2 : vec2, + world_pos_1 : vec2, +}; + +@vertex +fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_1 : u32) -> VertexShaderOutput_0 +{ + var _S2 : VertexShaderInput_0; + _S2.vertex_index_0 = vertex_index_1; + _S2.pos_2 = _S1.pos_1; + _S2.uv_2 = _S1.uv_1; + _S2.world_pos_1 = _S1.world_pos_0; + var _S3 : vec2 = _S2.pos_2.xy * vec2(0.5f); + _S2.pos_2.x = _S3.x; + _S2.pos_2.y = _S3.y; + var output_0 : VertexShaderOutput_0; + output_0.pos_0 = (((mat4x4(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4(_S2.world_pos_1 + _S2.pos_2.xy, 0.0f, 1.0f)))); + output_0.uv_0 = _S2.uv_2; + return output_0; +} + +fn GetDimensions_0( texture_texture_0 : texture_2d, texture_sampler_0 : sampler, width_0 : ptr, height_0 : ptr) +{ + {var dim = textureDimensions((texture_texture_0));(((*width_0))) = f32(dim.x);(((*height_0))) = f32(dim.y);}; + return; +} + +fn pixel_art_sample_0( input_texture_texture_0 : texture_2d, input_texture_sampler_0 : sampler, input_uv_0 : vec2) -> vec4 +{ + var dimensions_0 : vec2; + var _S4 : f32 = dimensions_0[i32(0)]; + var _S5 : f32 = dimensions_0[i32(1)]; + GetDimensions_0(input_texture_texture_0, input_texture_sampler_0, &(_S4), &(_S5)); + dimensions_0[i32(0)] = _S4; + dimensions_0[i32(1)] = _S5; + var _S6 : vec2 = input_uv_0 * dimensions_0.xy; + var _S7 : vec2 = (floor(_S6) + min(fract(_S6) / (fwidth((_S6))), vec2(1.0f, 1.0f)) - vec2(0.5f)) / dimensions_0.xy; + ; + return (textureSample((input_texture_texture_0), (input_texture_sampler_0), (_S7))); +} + +struct FragmentShaderOutput_0 +{ + @location(0) color_0 : vec4, +}; + +struct pixelInput_0 +{ + @location(0) uv_3 : vec2, +}; + +@fragment +fn main_fragment( _S8 : pixelInput_0, @builtin(position) pos_3 : vec4) -> FragmentShaderOutput_0 +{ + var output_1 : FragmentShaderOutput_0; + var _S9 : vec4 = pixel_art_sample_0(texture1_texture_0, texture1_sampler_0, _S8.uv_3); + output_1.color_0 = vec4(_S9.xyz * tint_0.xyz, _S9.w); + return output_1; +} +