hzqst / MetaHookSv

MetaHook (https://github.com/nagist/metahook) porting for SvEngine (GoldSrc engine modified by Sven-Coop)
MIT License
147 stars 36 forks source link

[Renderer] Bug: Weird SVC_LIGHTSTYLE effect. #394

Closed lespaul64 closed 9 months ago

lespaul64 commented 9 months ago

I'm using this build https://github.com/hzqst/MetaHookSv/releases/tag/v20240201b and it gave me weird effect when send SVC_LIGHTSTYLE message via AmxModX. You can see the bug in this video https://youtu.be/BEIm6om6634?t=122.

The code i use to send SVC_LIGHTSTYLE:

SetLightStyle(id, const style[])
{
    message_begin(MSG_ONE, SVC_LIGHTSTYLE, _, id);
    write_byte(0); //other than 0 = no effect LOL
    write_string(style); //"#"=no light style
    message_end();
}

I use "#" to make super bright light on the entire map.

hzqst commented 9 months ago

Sending SVC_LIGHTSTYLE with "#" is technically an undefined behavior Letme expain the reason for you: The actual light style value that being transfered to lightmap generation procedure will be pre-processed by doing such calculation in the first place: Valve uses the ASCII code of '#' which is 23 as decimal, minus the ASCII code of a which is 97 as dec. and then the output value will get multiplied by 22 which will definitely gives you a negative number, which is (23-97)*22=-1628 as expected.

image

And the way Valve process the actual light style value (aka d_lightstylevalue) is pretty buggy: (This is the reversed-engineerd code of lightmap strength calculation prodecure) image e66d885f738b544ffd67c4de8cb4e2ec As you can see the negative value of d_lightstylevalue (-1628) got multipled by lightscale and gave you a super larger negative number (-68,530,176 in this scenario)

image

And then the super larger negative number got casted to an non-sense super-super-super large number of unsigned int which is 4,226,437,120 in case of overflowing/memory access violation in the later lightgamma-conversion table access pharse.

image

The 4,226,437,120 got right shifted by 14 turned out to be 257,961, and got clamp to 1023 which is pretty much what you saw "fullbright" in the vanilla GoldSrc engine.

It's technically/mathematically an non-sense value that happened to be "fullbright" which happened to "relies on Valve's buggy code to run" . It's definitely not what John Carmack want in the first place. The original intention of lightstyle is that a negative value of lightstyle input should be either be rendered as black (this is what I did exactly in the shader) or be completely refused as an invalid input. (btw John Carmack did a good job here and never generates such random non-sense output. it's Valve that ruined this calculation)

lespaul64 commented 9 months ago

Yeah you are right, i cannot use "#", i can only use "a" to "z". which mean: "a" = darkest "z" = brightest

di57inct commented 9 months ago

@hzqst weirdly enough, this was a good thing, as we could use it as a "nightvision" hack to apply fullbright to the map and eliminate almost all the shadows and dark areas without the performance-costly dlight, which is the only other option and could be used with limited radius.

hzqst commented 9 months ago

@hzqst weirdly enough, this was a good thing, as we could use it as a "nightvision" hack to apply fullbright to the map and eliminate almost all the shadows and dark areas without the performance-costly dlight, which is the only other option and could be used with limited radius.

I don't think it's anything but a good thing, like generating unwanted non-sense random color blocks everywhere: 315a3dc72f4f7e4ded00aa9df2c706be image

di57inct commented 9 months ago

Those random colors are from dlight which is no longer necessary if we used lightstyle #.