Repository navigation
Vulkan: draw decals, and draw them like OpenGL does - #7879
Open
dustinspace217 wants to merge 3 commits into
Open
dustinspace217 wants to merge 3 commits into
dustinspace217 wants to merge 3 commits into
Conversation
The Vulkan shader input mask had one bit per listed attribute, so the pipeline dropped the MATRIX4 attributes at locations 9-11 and the decal vertex shader read three of its four instance-matrix columns from unbound inputs. No decal was ever drawn in Vulkan. The mask now covers four locations for VATTRIB_MODEL_MATRIX. It is built by shader_vertex_input_mask() in shader_types so both Vulkan call sites share it and a unit test covers it without a Vulkan build. Fixes scp-fs2open#7866
The decal pipeline config set the shader type but not the flags, so the decal shader variant was always compiled without USE_NORMAL_MAP and fell back to screen-space derivative normals for angle rejection. Far more of the decal volume passed the angle test than in OpenGL, which lit the decals brighter and wider. The pipeline now takes the flags the material reports, as the other draw paths already do.
…idth check Pin the full mask per shader type instead of the presence of the matrix bits, so an expansion of any other attribute fails; pin that a decal without a normal map is the one that reads the scene normal buffer; add a compile-time bound on the mask width; trim two comments.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Decals now render on Vulkan, matching OpenGL. Two one-line causes: the shader input mask dropped three of four per-instance matrix columns, and the decal pipeline lacked the material's shader flags. The mask now comes from one helper,
shader_vertex_input_mask()inshader_types.Why?
On Vulkan, decals from Lua or a weapon's
$Impact Decal:never showed up, while the same table lit the ship in OpenGL. Fixes #7866.How?
The Vulkan pipeline keeps one bit per vertex attribute a shader type lists, and the decal shader lists
VATTRIB_MODEL_MATRIXonce. A mat4 takes four locations (8 to 11), so three columns read unbound inputs and decals landed nowhere on screen. The helper gives the matrix four bits for both Vulkan call sites. OpenGL binds by name and is unchanged.Vulkan decals then drew two to fifteen times brighter and wider than OpenGL's: the variant without
USE_NORMAL_MAPfell back to screen-space derivative normals for angle rejection. The decal pipeline config now takes the material's flags, like the other draw paths.Testing?
Linux, headless, Release and Debug with fatal warnings. Vulkan on NVIDIA, OpenGL on Mesa's software renderer. Base b477dd5 vs this branch, MediaVPs 5.0.2, SM1-01, 1280x720, plus a two-table mod: a decal (
$Decal: vkdecaltest,+Diffuse: beamglow1,+Glow: beamglow1) and an$On Mission Start:hook giving every ship a ship-sized one (def:create(radius, radius, -1, -1, ship, ship.Class.Model:getDetailRoot())).Before, only OpenGL lit the ships. After, both do, and halo brightness at three ships stays inside OpenGL's range over four frames each. Without the mod, frames match the base build within run scatter. Frame times are flat: Vulkan 11.9 ms with decals on both builds, OpenGL 45.6 vs 45.4 ms. Decals draw under MSAA 4x, a normal-mapped decal draws on both renderers, and the Debug build's validation layer reports the same pre-existing messages with and without decals, none from the decal pass. Three new unit tests cover the input mask per shader type (old code: mask 257, locations 9 to 11 missing), the matrix locations and the decal flag polarity. Both suites pass in Release and Debug.
Anything Else?
The Vulkan decal fragment shader samples all three maps through one
sampler2DArraybinding, so a glow or normal bitmap different from the diffuse reads the diffuse. With athruster01glow, OpenGL shows a bluish halo, Vulkan the old white one. That path was unreachable until now. I left it for a separate PR. Written with Claude Code; the investigation, review and testing ran on my machine.