Skip to content

HD models: no see-through specks on the Garand's sight and other custom guns - #1033

Merged
ccoventry merged 3 commits into
devfrom
fix/hd-model-mask-specks
Oct 25, 2026
Merged

ccoventry merged 3 commits into
devfrom
fix/hd-model-mask-specks

Conversation

@ccoventry

Copy link
Copy Markdown
Owner

Release note: Fixed: HD weapon skins no longer show tiny see-through dots that flickered on some custom guns, like the Garand's rear sight on the pre-Anniversary install.

What was wrong

PRE's custom dod\models\v_garand.mdl has a skin skin3_test.bmp (512x512) flagged masked, so palette index 255 is drawn see-through. In this skin, palette entry 255 is an ordinary near-black (2,2,2), not a key colour: whoever converted it to 256 colours let dark metal pixels land on it. That leaves 1,170 see-through blobs (corner neighbours counted as one), all of them noise, and no real hole. models_hd.py took the alpha straight from that mask, so each speck became a hole in the HD skin, and it blinked as the gun swayed against a bright floor. The same happens in PRE's custom Luger, M1 Carbine and scoped Kar skins (palette entry 255 = (4,4,4)).

Fix

models_hd.py: on skins used by a model held in hand (v_ or p_), see-through blobs of 8 px or fewer (corner neighbours count as one blob) are drawn solid in the HD file. Like every see-through pixel already, they take their nearest solid neighbour's colour. Real holes, like the stock Garand's 137 px peep sight, stay. test_models_hd.py covers the threshold, corner-joined blobs, the edge, real holes, and that only weapon skins change.

Decisions

  • Weapon models only (v_, p_). All 200 unique masked skins in PRE's and POST's dod, dod_addon, dod_downloads and valve\models, map models included, were surveyed. 98 have 1-3 px holes, and on map models most of them are on purpose: gaps between leaves (trees and bushes), the frayed edges of torn flags, gaps in wire and camo nets, and the spring mesh in rustcar.mdl. A size-only rule would fill all of those. A colour rule ("fill a speck painted the same colour as its surroundings") also failed: it filled the rustcar's mesh gaps, whose key is black on dark metal. On weapon skins the data is clear-cut: the smallest real hole in any v_/p_ skin in either install is 21 px.
  • Threshold 8 px, not 3. With 3, 92% of the Garand's blobs go and 90 stay, in the 4-15 px range. With 8, 99% go (1,162 of 1,170), and 8 is still well under the 21 px smallest real weapon hole. The 8 that stay are 9-15 px.
  • The skin's edge counts as solid. 85 of the Garand's specks sit in its edge column, on the barrel. UVs never reach past the edge, so these are specks like any other. This also fills one 1 px corner pixel of the stock Luger's skin2_test.bmp, which is harmless.
  • Kill-feed icons (killfeed_icons.py) are untouched. PR Kill feed: an even layout where every weapon icon has the same height and nothing is cut off (#1022) #1023 changes that file. They were checked: d_garand (which draws part of v_garand.mdl), d_scopedkar, d_kar, d_luger and d_m1carbine were rendered on PRE with the current skins and with speck-filled ones, and every pixel came out the same. The icons have no pinholes.
  • No other open PR touches models_hd.py.

Survey: what this changes

All 314 v_/p_ models in PRE and POST (dod, dod_addon, dod_downloads, valve\models) have 28 unique masked skins, and 6 of them change:

Model Skin Specks filled (blobs) Pixels Blobs kept
PRE dod\v_luger.mdl (custom) skin1_test.bmp 512x512 4,097 6,319 145
PRE dod\v_luger.mdl (custom) skin2_test.bmp 512x512 2,551 4,805 139
PRE dod\v_scoped98k.mdl (custom) skin2_test.bmp 512x512 1,183 2,107 70
PRE dod\v_garand.mdl (custom) skin3_test.bmp 512x512 1,162 1,808 8
PRE dod\v_m1carbine.mdl (custom) skin4_test.bmp 512x512 665 1,238 78
POST dod\v_luger.mdl, HLTV_Models\v_luger.mdl (stock) skin2_test.bmp 256x256 1 (a corner pixel) 1 1 (the real 288 px hole)

The other 22 masked weapon skins are unchanged. They include the stock Garand, M1 Carbine and Luger skin1, and every PRE custom skin keyed with pure blue (30cal, 98k, BAR, Bren, Enfield, Greasegun, MG34, MG42, Sten, Bazooka, Panzerschreck, scoped FG42, mortar). Map models are not touched.

Test done

  • python -m unittest test_models_hd test_studiomodel in goldsrc-hooks/tools/hd: 13 pass. CI doesn't run these Python tests; that was already true for test_studiomodel.

  • Rebuilt the affected skins on this PC. First, 43 files were backed up to local\specks-backup\ (PRE: 6 skins x 7 styles, ultrasharp, plain, x4plus, generalv3, remacri, siax and blend; POST: 1 in ultrasharp). Then those files were removed and models_hd.py was run per style, plus build_all.py --types models blend. In the Garand's ultrasharp file, see-through pixels went from 7,608 to 376. PRE's partial custom styles (pbrify, ultrasharpv2, webphoto) don't hold these skins.

  • In game, PRE, Brain account, game_probe with the WSOD25 capture DLL, 1280x720. Demo: ktps8w4-element_gskill_armory_h2, element's POV with the Garand, around 7:13 on the demo bar, running past bright walls and the floor. There were three launches, 1 s of HLAE frames each:

    • before: the old speckled skins, put in models\overrides for that run and removed afterwards;
    • after: the rebuilt skins;
    • HD off: ds_hd_enabled 0.

    In before, a few light dots blink on the lower half of the rear sight. In after, none show over 10 frames. The texture's own scratches look the same in both. With HD off, the original model shows the same kind of dots. That comes from the custom model itself, not from HD, and this PR doesn't change it. The difference is small at 1280x720; the screenshot this started from was larger. Review sheet: local\review-images\specks\garand_rear_sight_before_after.png. The skin itself over white, before and after: garand_skin3_ultrasharp_{before,after}_on_white.png.

Your test

  1. In DoD Studio, delete the affected HD files so the build remakes them: in <PRE>\dod_addon\dodstudio_hd\models\<each style>\ delete skin3_test.bmp_5bd6747b.tga, skin1_test.bmp_95fc9010.tga, skin2_test.bmp_2803c465.tga, skin4_test.bmp_4729aab9.tga, skin2_test.bmp_15824d37.tga and skin2_test.bmp_3682be1c.tga. On this PC that's already done, and the old files are in local\specks-backup\.
  2. On the HD Textures page, under Build, tick your styles and model skins, then click Build. Files already built are skipped, so only the deleted ones are remade, in a minute or two. Blend is remade from x4plus and plain.
  3. On PRE, play ktps8w4-element_gskill_armory_h2 (element's POV, Garand) around 7:00 on the demo bar, while he runs with the Garand over the bright floor. The rear sight and receiver should show no light dots blinking as the gun sways.
  4. Optional: also look at the Luger, M1 Carbine and scoped Kar on PRE.

🤖 Generated with Claude Code

Some custom weapon skins (PRE's Garand, Luger, M1 Carbine, scoped Kar)
were converted to 256 colours with palette entry 255 left as an ordinary
near-black, so dark metal pixels on it are cut out; each became a 4x hole
that blinked as the gun swayed. On v_/p_ skins, see-through blobs of 8 px
or fewer are now drawn solid in their neighbours' colour. Map models keep
their small holes (leaf gaps, frayed flags, wire mesh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Review (night pass 2026-10-25)

Read: the whole diff (models_hd.py, test_models_hd.py). specks() labels the see-through mask with 8-connectivity and fills blobs of 8 px or fewer. Outside the skin counts as solid, so a blob on the edge is sized by its own pixels. Only skins a v_/p_ model uses go through it (held, keyed the same way as jobs). The colour fill was already done for every index-255 pixel, so the newly solid specks take their nearest solid neighbour's colour. No bugs found.

Ran: python -m unittest test_models_hd test_studiomodel gives 13 OK, and compileall is clean. I merged dev in (no conflicts), giving head 6132d9b5. CI is green.

One thing to know, not a blocker: C.built() only checks a file's size, so an HD skin someone already built isn't remade with the fix. Only a fresh build, or deleting the six files as your test step 1 says, picks it up. Other users' existing builds keep the specks until they rebuild. A version stamp like killfeed_icons.py's VERSION would force a rebuild, but that's a bigger change than this PR's plan. It can be a follow-up if wanted.

Verdict: ready to merge.

@ccoventry
ccoventry merged commit 174d4a0 into dev Oct 25, 2026
5 checks passed
@ccoventry
ccoventry deleted the fix/hd-model-mask-specks branch October 25, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant