meetric1/GMod-Seamless-Portals

Black skybox (potential fix included)

Closed this issue · 2 comments

I have theorized a possible fix for the black sky effect. I took a look at the Render Order and saw that PreDrawSkybox is never called if the EyePos is outside of the world bounds, which lines up perfectly with the effect being experienced here. I tested this myself using this simple code:

local drewSkybox = false
hook.Add("RenderScene", "skybox_override", function()
     drewSkybox = false
end )

hook.Add("PreDrawSkyBox", "skybox_override", function()
     drewSkybox = true
end )

This works and allows drewSkybox to be read accurately for any hook occuring after PreDrawSkyBox, theoretically allowing the emulation of a skybox to be drawn if and only if it has failed to previously. The main problem with this is that none of the skybox methods will be called, obviously, so it cannot be done at the exact same time it normally would. I think that PreDrawOpaqueRenderables, asserting that the first two arguments are false, is probably the best bet. However if it doesn't cause any issues, drawing inside of NeedsDepthPass or SetupWorldFog using the cam library might be better. I'm quite against this approach but it may be necessary to make it work.

What would this "emulation" I speak of be? My initial thought was to re-implement how Source handles 3D skyboxes in LUA, and I was somewhat successful. The emulated 3D skybox render was always just a little bit off from the real deal, and I couldn't do anything about it, nor do I think anyone would be able to. In addition, the 2D skybox did not then always get rendered reliably inside of the emulated 3D skybox, which isn't acceptable given that the black skybox is most easily triggered by upward facing portals, where there is little likelihood of any 3D skybox geometry existing.

So: here's what I'm trying now. Just do only the 2D skybox, and maybe revisit 3D skyboxes if I can manage that. It would be a matter of finding out the cubemap textures for the current map's skybox, and then rendering the faces of the cube some arbitrary distance from the current camera any time after monitors are drawn, but before the world is drawn. According to this image on the wiki, the skybox texture name is stored in a keyvalue inside of the world entity, but I could not for the life of me find it inside of Garry's Mod (tried lua_run PrintTable(game.GetWorld():GetKeyValues())). However it is given that the default skybox is sky_day01_01, so I would work with that. The different faces of a given skybox texture are found in materials/skybox/name_BK.vtf, materials/skybox/name_DN.vtf, etc. This is not going to draw the env_sun if one exists, maybe we can figure that out.

If I am able to do this on my own then I will simply create a PR and reference this issue.

quite an interesting read… thank you for putting effort into solving this issue. I had another weird idea in order to render the 3D skybox by using similar stencil code to the portals and rendering a massive box in the sky, but your idea sounds cheaper to do since you wouldn’t be calling renderview 2 times every frame

Fixed by #13. Good job on being faster than me