From 9d803d1f19ae2c1969766512eb04623fe4beba77 Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Wed, 18 Dec 2024 09:05:57 +0100 Subject: [PATCH] Render in-game SDF sprites with a black outline SDF sprites are created with a pxrange of 8 (4 inside, 4 outside pixel range) and a size of 64x64. SDF are also now always grayscale and are mainly colored using the instruction color. For this we extended the texture loader to also handle grayscale images properly. Only PNG and TGA provide proper grayscale images. --- .../archive/data/texture/collapsed_arrow.png | Bin 915 -> 628 bytes .../archive/data/texture/expanded_arrow.png | Bin 942 -> 607 bytes korangar/archive/data/texture/filled_box.png | Bin 797 -> 703 bytes .../archive/data/texture/marker_effect.png | Bin 263368 -> 994 bytes .../archive/data/texture/marker_entity.png | Bin 273046 -> 1101 bytes .../archive/data/texture/marker_light.png | Bin 272162 -> 1316 bytes .../archive/data/texture/marker_object.png | Bin 263368 -> 1002 bytes .../archive/data/texture/marker_particle.png | Bin 263368 -> 1340 bytes .../archive/data/texture/marker_shadow.png | Bin 4886 -> 407 bytes .../archive/data/texture/marker_sound.png | Bin 263368 -> 1098 bytes .../archive/data/texture/unfilled_box.png | Bin 652 -> 612 bytes korangar/src/graphics/mod.rs | 4 +- .../passes/interface/shader/rectangle.wgsl | 4 +- .../interface/shader/rectangle_bindless.wgsl | 4 +- .../postprocessing/shader/rectangle.wgsl | 48 ++++++-- .../shader/rectangle_bindless.wgsl | 48 ++++++-- korangar/src/loaders/effect/mod.rs | 4 +- korangar/src/loaders/map/mod.rs | 4 +- korangar/src/loaders/mod.rs | 2 +- korangar/src/loaders/script/mod.rs | 6 +- korangar/src/loaders/texture/mod.rs | 114 ++++++++++++++++-- korangar/src/renderer/game_interface.rs | 19 ++- korangar/src/renderer/interface.rs | 10 +- korangar/src/world/particles/mod.rs | 10 +- 24 files changed, 218 insertions(+), 59 deletions(-) mode change 100755 => 100644 korangar/archive/data/texture/marker_effect.png mode change 100755 => 100644 korangar/archive/data/texture/marker_entity.png mode change 100755 => 100644 korangar/archive/data/texture/marker_light.png mode change 100755 => 100644 korangar/archive/data/texture/marker_object.png mode change 100755 => 100644 korangar/archive/data/texture/marker_particle.png mode change 100755 => 100644 korangar/archive/data/texture/marker_sound.png diff --git a/korangar/archive/data/texture/collapsed_arrow.png b/korangar/archive/data/texture/collapsed_arrow.png index 363d37408bf081c66bf3f30ee06035bc1cb9ac1b..cfa4cf4c268e45c52317b214d924e918ec6593e3 100755 GIT binary patch literal 628 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW(4IWRD z45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^>;_2(k{(?t{T}5-hnVu*E z17n1zi(`nz>DtTQ-cF7p>>ujya#kzq_00GfnWd35iFIq|o(tlcm#^oX>s9Dnz!VV_DsFYV%XP(PSJNJIxOv^K-8|q(Z)H+MEUE?$RQL=D3dt$MG9qW(P<3+Ewfg)}jKRr}AGFtKN5C@%~4Suq8P0Ee@Mhs+_8DBu zSl){=NN_A+UL|I&#JTTIO;h87l`IF6Y)-x2nfYSz49mT&mzPPqOktGR6`T6+$fPSQ zC8C>DUP@kQte#YIS6gcm$NU zt5Y&NBP>{I!1=4tb5fjW_`7Cn&ndy%dKTV3D($%|V7myo>zOmq#6bPX*+49u;JO|1-#v<(cb3=G~} zQ+te}AvZrIGp!Q0hPmDI;(;18;5L+G=B5^xB<2>N>oK!3F@#tWu~482sE5JR)z4*} HQ$iB}7fo;;SI1}~!2ZnqB`|$hdAc};RLrTpoEpyLD8c%`QTFIpDUKVB3ub6^ zxq5VV-kp2nZtVXUi)t~mw6cBop1+xU_j{}pPvlL@DfJvD&l*4DX5Gcm>UvZ)#=&7MMvE>5oMEPxMdwPcNfEp zqVn$=S~g`X{PN@fH|R02?X|1lrF4Knf~zej(U!qw(P6`lP7;Ys2_-o-PT~xcKQbt$ zba5}!y(W2zee=bgKd;EXJfvhCUo_*;qiCJY2Tr}Zwd;$l#DP5s5qb0CQfBm}rE7H^VIQuXijOKs*U-5|_ z%Xj|%y4*Qz{vV% z45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^>;_2(k{(?t{T~)A8fB7i} z21aL37sn8b(^DsSdmnZXar2+7bL1UYmX_U$9}EXuAH@BU{pYC8p%=rU=asf>HrG2B z7ICMmVMl-Eti5n#SH`6+XO}!`P1KvyU;LiuPvA~jc5a=Z<@Kd=|N82jcxvR7>Yn%B zPoiLzj_Uo*mBE?2lXptrWGc*6{2L{<-m}+LaEX3?{X4);WbrgMLL`Eg1Cs8 zvJd?aakudpth=!5@P@|efBsw&*e}=~C@wu=lkFzQJ4e}W_3bu$ApWSOka=IcIfoE) zV!)lQTdO>nIvb7uZ@SMS+N)_$u`2Algqwr${tX;86_0M`IIQGba78+eS$FpiufxLj zDG~wyn7v9*8VR(#n_{74ec-Oo3tOX=Ue$j#*D>nZ7ioQ&mH8YP!m1^%5hW>!C8<`) zMX5lF!N|bKMAy(r*U%!wz}(8%)XLCE+rYrez~Id_wZ|wLa`RI%(<*UmnA<%s9;iVB nZbM0CZfbE!Vr~Jt9&;;0bBHB#f*quQdKf%i{an^LB{Ts5KONr3 literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0V4M`-6XN>+|Nnpg{sBoi1H#2c zLX-hzAqv3yMhWVK03=lJi=T)AMp9czkY6wZgNcQem5q&^or8mulZ%U+n}>7%&fR70SEqj3N?OsQ_Zt+J#*p10!E{SOOh^LPg9;WQ#1I`nP`#bPyggLvlc)4 z+_Ej@^2-WN)v0T&Lyz3c6Knlqur-;j^yxISWhWx8{_c@hpT5s8?AS*EiH>j1?%SW0 zl|Nsx{B~BxJUvB62Cd*!V0v-&ba4!+m{WT>G@8kgq4gnix5s7$g+&VMlDfIHwn-!` zN+<_{Kl$u}H|)-zJGYglhqd-?{o3oZVWt4*hOKkI&5bo=cdFLBZ*L*O-`5v>@Z`!J%<0cP_kW1> zVhz7;uF`SG%d(*Sya9iI;7f&nU(W0axWpH*KL33YUrkNjN%s5ppZwx%-aiv>)rn|* TD=fbU7{v^pu6{1-oD!M<2xNib diff --git a/korangar/archive/data/texture/filled_box.png b/korangar/archive/data/texture/filled_box.png index 50a7cf392f8e55a4d3075d9be253d7c1b49fc621..ab6cbd6f8dbcdd0406ab6e9dda4a1d06787f434b 100644 GIT binary patch literal 703 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW(4IWRD z45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^>;_2(k{(?t{UDZrmRcIjt z1LI;(7sn8b({Cql^p;MPXrCXmPl99COP>i6&WCelo30+^DU$TsvM7nSWJO8F|Cwca zWv^1^n3Uy+wHsfU6UMUJO!1JbszlJ0Z076I`}jD`rgMLhf3bP*A33|anmzdp3L7VQ zu6`x_ujpE)`M#Og|7w1JcVntu-R%6Yar<^Pm zV`$a?=~vpUvo157(cWt)A}4m}? zGXI|wBh>5QzD04Vqo>&(?$4ZCM7Fpd<~_Rkd7I8$AO3ZBRG(~`Y$2XAE9lnkUHj|a z9oE;}pTqI_#m6H*R^NEjv9-S-+>rT2{UO_QmvAU zQh^kMk%5tkuAz~xp+$&+xs|c0m7$Tgfq|8Q!JBJpk5M$_=BH$)RpQn#w|ibZP=f~C mhLX(O)Z&uF+yZnx=2oUA5KA;ahSUP}FnGH9xvXDcN literal 797 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}OsL332^T2>ko^52yq}5>ks( zo*3;wHOR`4*${IvMUd^oFN;TIdwbbKV4#GR1o;IsNQX2p-Ff!^nI%oZQVforCw~7r z-r?Z;`O{+W=O_2SuwR*PXXjI}>Z9c3smFrktQ}VWY-9?Xw(DRhW8upk+fHwvB5Q3a zb82g_A7jz0MQeV1JsS9-UBXMfcH((QXl&+3LFwO9Y>${h56HcMsc- zKQik-F;-vjFm7qtP;~EHU7S*&tdgOa=%Xq3ou4~*rdX(EP4G(JByzs6(x9?azaxP` zf8wGDCgZEq6KZw_Jzc*d?37QS^BVI5PCq9ztUnvJyVyDU)i;J;%&VBzbO>r~v%FGn zU=&zw^hhGZ?xM()=!I;D_f6 z>Lj=N#!f5I*ElmZTm00n%M5oX&a01SS~I0|a%!?t{GW5r z3{P<7ebUGGsm*o!sbUW9oxkNm=WL75+GY{HM*8L7hdPJ0uB%z8*psTeTOwcjICu5G Z`=8>yQa%Q>R{~?0!PC{xWt~$(69BVL^m70J diff --git a/korangar/archive/data/texture/marker_effect.png b/korangar/archive/data/texture/marker_effect.png old mode 100755 new mode 100644 index 0aae07598100e533fc4e1eb4961be7b3546302c9..ca55078ef2640288045fb381da85531f48393256 GIT binary patch literal 994 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 To)8_H00000NkvXXu0mjf0i_ld literal 273046 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 U=IX0A0*PiBPn)TKMAts@e>K6FPyhe` diff --git a/korangar/archive/data/texture/marker_object.png b/korangar/archive/data/texture/marker_object.png old mode 100755 new mode 100644 index 61f85ea33f8b9b06ce7c4c7f12a20028a20595a4..8b9289abd105cb2499d77ded72b6a2942e28bcdf GIT binary patch literal 1002 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 T_n)6hr5i?{IO^dMXSDnuqny5Z diff --git a/korangar/archive/data/texture/marker_particle.png b/korangar/archive/data/texture/marker_particle.png old mode 100755 new mode 100644 index 0aae07598100e533fc4e1eb4961be7b3546302c9..edc0ed15e925a9b2ca1c4bfcd663ae0f138fc33d GIT binary patch literal 1340 zcmV-C1;hG@P)p|G$;0xRQV*&}bXYXqG&1eeKxbSb2$_sG2?>Fx7qf2*LLr z9uTlveXj(4=WL(F0RgM$LA)-aufP42?~;&!U8X*1)n-6co{xttq+phzi`Z3e1h8{e z7RO!8V4eFo!2Zv58z4WOtFkzx0qC*g#IMVB6Cm8@$D%4vI}WOkh|_ZHmo0!a+Z~QY zRURXdH|o?pWa%bA7{$r%aH`G#IkR#|;wXGxiJx}|3xY6=vm5{*&*Cr)0){pKFvb`Y z$|wK;Wt3oyG2Q_1&UxpYbpQa)I_JD|egnXnRckem9RNT#&PwamxGk5sEOHt|Ol=Hv z+lpb5%d)8t=CK!PNZiapiKe}aew;S}CXvPgc1st49=p1}bz<7q%J-0Aug92znZ>QH z+xy00T59aqS%eJMW$4W)4 zO}5#39H+a(sX8O@ft5oV$KjU0fC9#OlsS7Exf4T=CKNV$lK4u)RbH}e}_*(x?kWE<}V&>EkGi3GB z0#E?DI~A02y<1Hrz~)?3y@XwAPi7|IL&s4Q&|-$R(I;u)Q!!z z``lbfd`$DADs%3}5E(gSY1{(^2*W5zclr4PKoUG+Eq{_q5r2!nDL{twm?lve_J9E> zV?h`t`$x!*IcJPL84=1D<2=q%0DyfGg#lv}00SU|F(%}pA%tLz(6e8F5XOW&=AROR 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 Bu?zqJ literal 4886 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 F{vX{!DOCUf diff --git a/korangar/archive/data/texture/unfilled_box.png b/korangar/archive/data/texture/unfilled_box.png index 508a0c9bdcbda5a9f3b701776117348ad4fa0d8d..8198ba3d2480099d48ba7ed1766ccc6423e2e761 100644 GIT binary patch literal 612 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW(4IWRD z45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^>;_2(k{(?t{U0rh1A>S$n z21XB07sn8b({CpmdOHP5IQ08x3zT-G3$gXfhkIaA)B zdA>fpM*qIJ*}XHdk1y-XMmu?_&t(w*_?34-*juBHXzmBTA7>S^J`X>z>&(XJ8g?mhu^A^u}C1@`8;mIt0rO+8q;?%axXD*|*Cmxi#0 z1}@A#$-J6-l~AI_X0H7o5Y@RI- zFYNR6U9`7c{%xJErPIShscFmh&O7^2^5m`End!dl$HKT)+~zyZzl49YgVNn;^W$D; z2+sNN;ZhOXoNe}BxSlT$f50%KqpdV_uIwED&4D{jvk$Nvo>;Z%@v{CfU@)texJHzu zB$lLFB^RXvDF!10BNJUiBV9v_5Cd~7V^b?bBW(i%D+7Z!*VG=PXvob^$xN%ntzmBW sym+7n4Y&;@nYpROC5gEO=z1)zj7%Yx%ldS|Ni|0DuIxM)Z&yU zPdhQX(A0eT#dsd*HP@0LzhDOGkmjX3&;CENq$ya6!Ljqi?_b9|9DF~2TI~J&ESkUU9jfF2yZ+AF&%CG3vqBTFJeLWiZpI zo_=C|DjBSym9;WP@s;a`sIA|+B(F&CDtzv{b>>o5oiz3Dp@kL2ci1g-15WHWf4JDpTd*j4$qd~yCp;8y<$OOfUq77d@DcII zPgj|L_=P-9VK9?Ewf~;wzPopC{Ysg)l>d15f8jh6-iQ;I-&plDUk+XJmuV@lcC=tj SS2r*Y7(8A5T-G@yGywo4FqY&1 diff --git a/korangar/src/graphics/mod.rs b/korangar/src/graphics/mod.rs index ab1a7abb..81fc52d2 100644 --- a/korangar/src/graphics/mod.rs +++ b/korangar/src/graphics/mod.rs @@ -46,7 +46,7 @@ pub use self::texture::*; pub use self::vertices::*; use crate::graphics::sampler::{create_new_sampler, SamplerType}; use crate::interface::layout::ScreenSize; -use crate::loaders::TextureLoader; +use crate::loaders::{ImageType, TextureLoader}; use crate::NUMBER_OF_POINT_LIGHTS_WITH_SHADOWS; /// The size of a tile in pixel of the tile based light culling. @@ -377,7 +377,7 @@ impl GlobalContext { RgbaImage::from_raw(1, 1, vec![255, 255, 255, 255]).unwrap().as_raw(), false, )); - let walk_indicator_texture = texture_loader.get("grid.tga").unwrap(); + let walk_indicator_texture = texture_loader.get("grid.tga", ImageType::Color).unwrap(); let forward_textures = Self::create_forward_textures(device, forward_size, msaa); let picker_textures = Self::create_picker_textures(device, screen_size); let directional_shadow_map_texture = Self::create_directional_shadow_texture(device, directional_shadow_size); diff --git a/korangar/src/graphics/passes/interface/shader/rectangle.wgsl b/korangar/src/graphics/passes/interface/shader/rectangle.wgsl index fa918a7d..2a01ce7d 100644 --- a/korangar/src/graphics/passes/interface/shader/rectangle.wgsl +++ b/korangar/src/graphics/passes/interface/shader/rectangle.wgsl @@ -89,8 +89,8 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4 { switch (instance.rectangle_type) { case 1u: { // SDF - let pixel = textureSample(texture, linear_sampler, input.texture_coordinates); - color *= vec4(pixel.rgb, saturate((pixel.a - 0.5) * 2.0 / fwidth(pixel.a))); + let distance = textureSample(texture, linear_sampler, input.texture_coordinates).r; + color *= vec4(saturate((distance - 0.5) * 2.0 / fwidth(distance))); } case 2u: { // Sprite (linear filtering) diff --git a/korangar/src/graphics/passes/interface/shader/rectangle_bindless.wgsl b/korangar/src/graphics/passes/interface/shader/rectangle_bindless.wgsl index ee0b3afe..4948ff08 100644 --- a/korangar/src/graphics/passes/interface/shader/rectangle_bindless.wgsl +++ b/korangar/src/graphics/passes/interface/shader/rectangle_bindless.wgsl @@ -89,8 +89,8 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4 { switch (instance.rectangle_type) { case 1u: { // SDF - let pixel = textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates); - color *= vec4(pixel.rgb, saturate((pixel.a - 0.5) * 2.0 / fwidth(pixel.a))); + let distance = textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates).r; + color *= vec4(saturate((distance - 0.5) * 2.0 / fwidth(distance))); } case 2u: { // Sprite (linear filtering) diff --git a/korangar/src/graphics/passes/postprocessing/shader/rectangle.wgsl b/korangar/src/graphics/passes/postprocessing/shader/rectangle.wgsl index 9f27b5fe..1cda6112 100644 --- a/korangar/src/graphics/passes/postprocessing/shader/rectangle.wgsl +++ b/korangar/src/graphics/passes/postprocessing/shader/rectangle.wgsl @@ -38,29 +38,61 @@ fn vs_main( return output; } +/// The range of the SDF border defines the outline of an SDF. msdfgen calls this pxrange. +/// We normaly use pxrange of 8 px when creating 64x64 SDFs, which results in an out border of 4 px in texture space. +const BORDER_WIDTH: f32 = 0.5; +const EDGE_VALUE: f32 = 0.5; + @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { let instance = instance_data[input.instance_index]; + var color: vec4 = instance.color; + switch (instance.rectangle_type) { case 1u: { // SDF - let pixel = textureSample(texture, linear_sampler, input.texture_coordinates); - return vec4(pixel.rgb, saturate((pixel.a - 0.5) * 2.0 / fwidth(pixel.a))) * instance.color; + let distance = textureSample(texture, linear_sampler, input.texture_coordinates).r; + let aa_width = fwidth(distance); + + color *= vec4(step(EDGE_VALUE, distance)); + + // Outside outline + if (distance > EDGE_VALUE - BORDER_WIDTH && distance < EDGE_VALUE) { + let bias = 0.1; + let border_max = (EDGE_VALUE - BORDER_WIDTH) + bias; + + // Transition from transparent to black outline + let outer_alpha = smoothstep( + border_max, + border_max + aa_width, + distance + ); + color = vec4(0.0, 0.0, 0.0, outer_alpha); + } + // Inside outline + else if (distance >= EDGE_VALUE && distance < EDGE_VALUE + aa_width) { + // Transition from black outline to fill color + let inner_blend = smoothstep( + EDGE_VALUE, + EDGE_VALUE + aa_width, + distance + ); + color = mix(vec4(0.0, 0.0, 0.0, 1.0), instance.color, inner_blend); + } } case 2u: { // Sprite (linear filtering) - return textureSample(texture, linear_sampler, input.texture_coordinates) * instance.color; + color *= textureSample(texture, linear_sampler, input.texture_coordinates); } case 3u: { // Sprite (nearest filtering) - return textureSample(texture, nearest_sampler, input.texture_coordinates) * instance.color; - } - default: { - // Solid - return instance.color; + color *= textureSample(texture, nearest_sampler, input.texture_coordinates); } + default: {} } + + return color; } // Optimized version of the following truth table: diff --git a/korangar/src/graphics/passes/postprocessing/shader/rectangle_bindless.wgsl b/korangar/src/graphics/passes/postprocessing/shader/rectangle_bindless.wgsl index 2d105eb4..743be9eb 100644 --- a/korangar/src/graphics/passes/postprocessing/shader/rectangle_bindless.wgsl +++ b/korangar/src/graphics/passes/postprocessing/shader/rectangle_bindless.wgsl @@ -38,29 +38,61 @@ fn vs_main( return output; } +/// The range of the SDF border defines the outline of an SDF. msdfgen calls this pxrange. +/// We normaly use pxrange of 8 px when creating 64x64 SDFs, which results in an out border of 4 px in texture space. +const BORDER_WIDTH: f32 = 0.5; +const EDGE_VALUE: f32 = 0.5; + @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { let instance = instance_data[input.instance_index]; + var color: vec4 = instance.color; + switch (instance.rectangle_type) { case 1u: { // SDF - let pixel = textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates); - return vec4(pixel.rgb, saturate((pixel.a - 0.5) * 2.0 / fwidth(pixel.a))) * instance.color; + let distance = textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates).r; + let aa_width = fwidth(distance); + + color *= vec4(step(EDGE_VALUE, distance)); + + // Outside outline + if (distance > EDGE_VALUE - BORDER_WIDTH && distance < EDGE_VALUE) { + let bias = 0.1; + let border_max = (EDGE_VALUE - BORDER_WIDTH) + bias; + + // Transition from transparent to black outline + let outer_alpha = smoothstep( + border_max, + border_max + aa_width, + distance + ); + color = vec4(0.0, 0.0, 0.0, outer_alpha); + } + // Inside outline + else if (distance >= EDGE_VALUE && distance < EDGE_VALUE + aa_width) { + // Transition from black outline to fill color + let inner_blend = smoothstep( + EDGE_VALUE, + EDGE_VALUE + aa_width, + distance + ); + color = mix(vec4(0.0, 0.0, 0.0, 1.0), instance.color, inner_blend); + } } case 2u: { // Sprite (linear filtering) - return textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates) * instance.color; + color *= textureSample(textures[instance.texture_index], linear_sampler, input.texture_coordinates); } case 3u: { // Sprite (nearest filtering) - return textureSample(textures[instance.texture_index], nearest_sampler, input.texture_coordinates) * instance.color; - } - default: { - // Solid - return instance.color; + color *= textureSample(textures[instance.texture_index], nearest_sampler, input.texture_coordinates); } + default: {} } + + return color; } // Optimized version of the following truth table: diff --git a/korangar/src/loaders/effect/mod.rs b/korangar/src/loaders/effect/mod.rs index 0a1d4f44..ff11f313 100644 --- a/korangar/src/loaders/effect/mod.rs +++ b/korangar/src/loaders/effect/mod.rs @@ -12,7 +12,7 @@ use ragnarok_formats::version::InternalVersion; use wgpu::BlendFactor; use super::error::LoadError; -use super::TextureLoader; +use super::{ImageType, TextureLoader}; use crate::graphics::Color; use crate::loaders::GameFileLoader; use crate::world::{AnimationType, Effect, Frame, FrameType, Layer, MultiTexturePresent}; @@ -70,7 +70,7 @@ impl EffectLoader { .into_iter() .map(|name| { let path = format!("effect\\{}{}", prefix, name.name); - texture_loader.get(&path).unwrap() + texture_loader.get(&path, ImageType::Color).unwrap() }) .collect(), { diff --git a/korangar/src/loaders/map/mod.rs b/korangar/src/loaders/map/mod.rs index 84167c12..547512ac 100644 --- a/korangar/src/loaders/map/mod.rs +++ b/korangar/src/loaders/map/mod.rs @@ -22,7 +22,7 @@ pub use self::vertices::MAP_TILE_SIZE; use self::vertices::{generate_tile_vertices, ground_vertices}; use super::error::LoadError; use crate::graphics::{Buffer, ModelVertex, NativeModelVertex, Texture}; -use crate::loaders::{GameFileLoader, ModelLoader, TextureAtlasFactory, TextureLoader}; +use crate::loaders::{GameFileLoader, ImageType, ModelLoader, TextureAtlasFactory, TextureLoader}; use crate::world::{LightSourceKey, Model}; use crate::{EffectSourceExt, LightSourceExt, Map, Object, ObjectKey, SoundSourceExt}; @@ -121,7 +121,7 @@ impl MapLoader { let water_paths = get_water_texture_paths(water_type); water_paths .iter() - .map(|path| texture_loader.get(path).expect("Can't load water texture")) + .map(|path| texture_loader.get(path, ImageType::Color).expect("Can't load water texture")) .collect() }); diff --git a/korangar/src/loaders/mod.rs b/korangar/src/loaders/mod.rs index ddf0ccbe..4ddc5416 100644 --- a/korangar/src/loaders/mod.rs +++ b/korangar/src/loaders/mod.rs @@ -23,7 +23,7 @@ pub use self::model::*; pub use self::script::{ResourceMetadata, ScriptLoader}; pub use self::server::{load_client_info, ClientInfo, ServiceId}; pub use self::sprite::*; -pub use self::texture::{TextureAtlasFactory, TextureLoader}; +pub use self::texture::{ImageType, TextureAtlasFactory, TextureLoader}; pub const FALLBACK_BMP_FILE: &str = "missing.bmp"; pub const FALLBACK_JPEG_FILE: &str = "missing.jpg"; diff --git a/korangar/src/loaders/script/mod.rs b/korangar/src/loaders/script/mod.rs index 8c9f1d07..84b672dd 100644 --- a/korangar/src/loaders/script/mod.rs +++ b/korangar/src/loaders/script/mod.rs @@ -5,7 +5,7 @@ use korangar_util::FileLoader; use mlua::Lua; use ragnarok_packets::ItemId; -use super::TextureLoader; +use super::{ImageType, TextureLoader}; use crate::graphics::Texture; use crate::loaders::GameFileLoader; @@ -152,7 +152,7 @@ end let resource_name = self.get_item_resource_from_id(item.item_id, is_identified); let full_path = format!("À¯ÀúÀÎÅÍÆäÀ̽º\\item\\{resource_name}.bmp"); - let texture = texture_loader.get(&full_path).unwrap(); + let texture = texture_loader.get(&full_path, ImageType::Color).unwrap(); let name = self.get_item_name_from_id(item.item_id, is_identified); let metadata = ResourceMetadata { texture, name }; @@ -163,7 +163,7 @@ end pub fn load_market_item_metadata(&self, texture_loader: &TextureLoader, item: ShopItem) -> ShopItem { let resource_name = self.get_item_resource_from_id(item.item_id, true); let full_path = format!("À¯ÀúÀÎÅÍÆäÀ̽º\\item\\{resource_name}.bmp"); - let texture = texture_loader.get(&full_path).unwrap(); + let texture = texture_loader.get(&full_path, ImageType::Color).unwrap(); let name = self.get_item_name_from_id(item.item_id, true); let metadata = ResourceMetadata { texture, name }; diff --git a/korangar/src/loaders/texture/mod.rs b/korangar/src/loaders/texture/mod.rs index 350fee00..d10e073b 100644 --- a/korangar/src/loaders/texture/mod.rs +++ b/korangar/src/loaders/texture/mod.rs @@ -3,7 +3,7 @@ use std::num::{NonZeroU32, NonZeroUsize}; use std::sync::{Arc, Mutex}; use hashbrown::HashMap; -use image::{ImageBuffer, ImageFormat, ImageReader, Rgba, RgbaImage}; +use image::{GrayImage, ImageBuffer, ImageFormat, ImageReader, Rgba, RgbaImage}; #[cfg(feature = "debug")] use korangar_debug::logging::{print_debug, Colorize, Timer}; use korangar_util::color::contains_transparent_pixel; @@ -23,13 +23,19 @@ use crate::loaders::GameFileLoader; const MAX_CACHE_COUNT: u32 = 512; const MAX_CACHE_SIZE: usize = 512 * 1024 * 1024; +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub enum ImageType { + Color, + Grayscale, +} + pub struct TextureLoader { device: Arc, queue: Arc, game_file_loader: Arc, mip_map_render_context: MipMapRenderPassContext, lanczos3_drawer: Lanczos3Drawer, - cache: Mutex>>, + cache: Mutex>>, } impl TextureLoader { @@ -73,6 +79,30 @@ impl TextureLoader { Arc::new(texture) } + pub fn create_grayscale(&self, name: &str, image: GrayImage) -> Arc { + let texture = Texture::new_with_data( + &self.device, + &self.queue, + &TextureDescriptor { + label: Some(name), + size: Extent3d { + width: image.width(), + height: image.height(), + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::R8Unorm, + usage: TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }, + image.as_raw(), + false, + ); + Arc::new(texture) + } + fn create_with_mip_maps(&self, name: &str, image: RgbaImage, transparent: bool) -> Arc { let texture = Texture::new_with_data( &self.device, @@ -127,14 +157,23 @@ impl TextureLoader { Arc::new(texture) } - fn load(&self, path: &str) -> Result, LoadError> { - let (texture_data, transparent) = self.load_texture_data(path)?; - let texture = self.create(path, texture_data, transparent); + fn load(&self, path: &str, image_type: ImageType) -> Result, LoadError> { + let texture = match image_type { + ImageType::Color => { + let (texture_data, transparent) = self.load_texture_data(path)?; + self.create(path, texture_data, transparent) + } + ImageType::Grayscale => { + let texture_data = self.load_grayscale_texture_data(path)?; + self.create_grayscale(path, texture_data) + } + }; + self.cache .lock() .as_mut() .unwrap() - .insert(path.to_string(), texture.clone()) + .insert((path.to_string(), image_type), texture.clone()) .unwrap(); Ok(texture) } @@ -219,14 +258,71 @@ impl TextureLoader { Ok((image_buffer, transparent)) } - pub fn get(&self, path: &str) -> Result, LoadError> { + pub fn load_grayscale_texture_data(&self, path: &str) -> Result { + #[cfg(feature = "debug")] + let timer = Timer::new_dynamic(format!("load grayscale texture data from {}", path.magenta())); + + let image_format = match &path[path.len() - 4..] { + ".png" | ".PNG" => ImageFormat::Png, + ".tga" | ".TGA" => ImageFormat::Tga, + _ => { + #[cfg(feature = "debug")] + { + print_debug!("File with unknown image format found: {:?}", path); + print_debug!("Replacing with fallback"); + } + + return self.load_grayscale_texture_data(FALLBACK_PNG_FILE); + } + }; + + let file_data = match self.game_file_loader.get(&format!("data\\texture\\{path}")) { + Ok(file_data) => file_data, + Err(_error) => { + #[cfg(feature = "debug")] + { + print_debug!("Failed to load image: {:?}", _error); + print_debug!("Replacing with fallback"); + } + + return self.load_grayscale_texture_data(FALLBACK_PNG_FILE); + } + }; + let reader = ImageReader::with_format(Cursor::new(file_data), image_format); + + let image_buffer = match reader.decode() { + Ok(image) => image.to_luma8(), + Err(_error) => { + #[cfg(feature = "debug")] + { + print_debug!("Failed to decode image: {:?}", _error); + print_debug!("Replacing with fallback"); + } + + let fallback_path = match image_format { + ImageFormat::Png => FALLBACK_PNG_FILE, + ImageFormat::Tga => FALLBACK_TGA_FILE, + _ => unreachable!(), + }; + + return self.load_grayscale_texture_data(fallback_path); + } + }; + + #[cfg(feature = "debug")] + timer.stop(); + + Ok(image_buffer) + } + + pub fn get(&self, path: &str, image_type: ImageType) -> Result, LoadError> { let mut lock = self.cache.lock(); - match lock.as_mut().unwrap().get(path) { + match lock.as_mut().unwrap().get(&(path.into(), image_type)) { Some(texture) => Ok(texture.clone()), None => { // We need to drop to avoid a deadlock here. drop(lock); - self.load(path) + self.load(path, image_type) } } } diff --git a/korangar/src/renderer/game_interface.rs b/korangar/src/renderer/game_interface.rs index 3dffa6af..50c88367 100644 --- a/korangar/src/renderer/game_interface.rs +++ b/korangar/src/renderer/game_interface.rs @@ -8,7 +8,7 @@ use korangar_interface::application::FontSizeTrait; use crate::graphics::{Color, RectangleInstruction, Texture}; use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize}; -use crate::loaders::{FontSize, TextureLoader}; +use crate::loaders::{FontSize, ImageType, TextureLoader}; #[cfg(feature = "debug")] use crate::renderer::MarkerRenderer; use crate::renderer::SpriteRenderer; @@ -85,19 +85,19 @@ impl SpriteRenderer for GameInterfaceRenderer { impl GameInterfaceRenderer { pub fn new(window_size: ScreenSize, texture_loader: &TextureLoader) -> Self { let instructions = RefCell::new(Vec::new()); - let font_map_texture = texture_loader.get("font.png").unwrap(); + let font_map_texture = texture_loader.get("font.png", ImageType::Color).unwrap(); #[cfg(feature = "debug")] - let object_marker_texture = texture_loader.get("marker_object.png").unwrap(); + let object_marker_texture = texture_loader.get("marker_object.png", ImageType::Grayscale).unwrap(); #[cfg(feature = "debug")] - let light_source_marker_texture = texture_loader.get("marker_light.png").unwrap(); + let light_source_marker_texture = texture_loader.get("marker_light.png", ImageType::Grayscale).unwrap(); #[cfg(feature = "debug")] - let sound_source_marker_texture = texture_loader.get("marker_sound.png").unwrap(); + let sound_source_marker_texture = texture_loader.get("marker_sound.png", ImageType::Grayscale).unwrap(); #[cfg(feature = "debug")] - let effect_source_marker_texture = texture_loader.get("marker_effect.png").unwrap(); + let effect_source_marker_texture = texture_loader.get("marker_effect.png", ImageType::Grayscale).unwrap(); #[cfg(feature = "debug")] - let entity_marker_texture = texture_loader.get("marker_entity.png").unwrap(); + let entity_marker_texture = texture_loader.get("marker_entity.png", ImageType::Grayscale).unwrap(); #[cfg(feature = "debug")] - let shadow_marker_texture = texture_loader.get("marker_shadow.png").unwrap(); + let shadow_marker_texture = texture_loader.get("marker_shadow.png", ImageType::Grayscale).unwrap(); Self { instructions, @@ -266,13 +266,12 @@ impl MarkerRenderer for GameInterfaceRenderer { MarkerIdentifier::Shadow(..) => (&self.shadow_marker_texture, Color::rgb_u8(170, 170, 170)), }; - self.instructions.borrow_mut().push(RectangleInstruction::Sprite { + self.instructions.borrow_mut().push(RectangleInstruction::Sdf { screen_position, screen_size, color, texture_position: Vector2::new(0.0, 0.0), texture_size: Vector2::new(1.0, 1.0), - linear_filtering: true, texture: texture.clone(), }); } diff --git a/korangar/src/renderer/interface.rs b/korangar/src/renderer/interface.rs index ddf910e7..256cfbd6 100644 --- a/korangar/src/renderer/interface.rs +++ b/korangar/src/renderer/interface.rs @@ -8,7 +8,7 @@ use korangar_interface::application::Application; use crate::graphics::{Color, InterfaceRectangleInstruction, Texture}; use crate::interface::application::InterfaceSettings; use crate::interface::layout::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize}; -use crate::loaders::{FontLoader, GlyphInstruction, TextLayout, TextureLoader}; +use crate::loaders::{FontLoader, GlyphInstruction, ImageType, TextLayout, TextureLoader}; use crate::renderer::SpriteRenderer; /// Renders the interface provided by 'korangar_interface'. @@ -33,10 +33,10 @@ impl InterfaceRenderer { ) -> Self { let instructions = RefCell::new(Vec::default()); - let filled_box_texture = texture_loader.get("filled_box.png").unwrap(); - let unfilled_box_texture = texture_loader.get("unfilled_box.png").unwrap(); - let expanded_arrow_texture = texture_loader.get("expanded_arrow.png").unwrap(); - let collapsed_arrow_texture = texture_loader.get("collapsed_arrow.png").unwrap(); + let filled_box_texture = texture_loader.get("filled_box.png", ImageType::Grayscale).unwrap(); + let unfilled_box_texture = texture_loader.get("unfilled_box.png", ImageType::Grayscale).unwrap(); + let expanded_arrow_texture = texture_loader.get("expanded_arrow.png", ImageType::Grayscale).unwrap(); + let collapsed_arrow_texture = texture_loader.get("collapsed_arrow.png", ImageType::Grayscale).unwrap(); let interface_size = if high_quality_interface { window_size * 2.0 } else { window_size }; diff --git a/korangar/src/world/particles/mod.rs b/korangar/src/world/particles/mod.rs index d26bb289..fd9ab522 100644 --- a/korangar/src/world/particles/mod.rs +++ b/korangar/src/world/particles/mod.rs @@ -9,7 +9,7 @@ use rand::{thread_rng, Rng}; use crate::graphics::{Color, Texture}; use crate::interface::layout::{ScreenClip, ScreenPosition, ScreenSize}; -use crate::loaders::TextureLoader; +use crate::loaders::{ImageType, TextureLoader}; use crate::renderer::{GameInterfaceRenderer, SpriteRenderer}; use crate::world::Camera; use crate::{Entity, Map}; @@ -102,10 +102,10 @@ impl QuestIcon { + Vector3::new(0.0, 25.0, 0.0); // TODO: get height of the entity as offset let effect_id = quest_effect.effect as usize; let texture = texture_loader - .get(&format!( - "À¯ÀúÀÎÅÍÆäÀ̽º\\minimap\\quest_{}_{}.bmp", - effect_id, 1 /* 1 - 3 */ - )) + .get( + &format!("À¯ÀúÀÎÅÍÆäÀ̽º\\minimap\\quest_{}_{}.bmp", effect_id, 1), /* 1 - 3 */ + ImageType::Color, + ) .unwrap(); let color = match quest_effect.color { QuestColor::Yellow => Color::rgb_u8(200, 200, 30),