Open emoose opened 5 months ago
Have you take a look at the XBLA versions of the files? the file structure is very similar to PC version and some files are even interchangeable, it maybe a similar issue that the one with "lens_flare_offset.bin"?
For example the Shuttle Launch in the Milky Way ending: https://youtu.be/PdClIKIIduQ?si=CHWhny4yzvvIPSJC&t=290
I saw a YouTube comment that chalked up the character's off appearance to messed up UV maps in the C2C ending cut scenes. No idea if that's the case, but I figure I'd mention it if it gets you looking down a different track.
Made a tiny bit of progress with this, might have an idea whats wrong with it:
original:
semi-fixed:
Seems the model was setup to be back-face shaded, but the game is using the front-face shader with it, causing lit-up parts to be darkened and the dark parts lit up.
The game does have shaders to handle back-face shading, but some reason I guess some model parts aren't actually flagged to use it (but some like the mid-section are?)
Unfortunately forcing it to use that shader seems to flip the light direction as can be seen in the last pic, from O2SP footage on YT it looks like she's meant to be lit up there: https://youtu.be/Clu7hF2DZe4?t=8 (couldn't find any better capture...)
It could just be an issue with how I forced that shader though, maybe adding the flags to the model file would let game flip direction itself.
(E: or seeing as the mid-section is already using this shader & still has wrong light direction, maybe it's an issue with the shader itself :/)
...or maybe I have it backwards, game is using back-face shader on that mid-section part which makes the model look off, but if we force it to use the front-face shader like the rest of the model uses....
Now it has the right light direction too 🐱 Something still seems off about it though imo, wish there was a better capture of the 2SP ending to compare with.
Another compare with the change above
original:
fixed(?):
If anyone wants to test, use CE:
40DF04 (byte hex) -> 00
40DEF5 (byte hex) -> 20
Hoping char models might be the only things using this broken backface shading, and maybe we can just patch these bytes in Tweaks, but not really sure yet.
(E: those bits of cloth on her back do seem to get lit wrong after this change though, and maybe collar as well, maybe some parts are set to use the backface shading correctly but the mid-section got the flag by accident, same for Alberto too I suppose...)
That does certainly look better.
Pushed https://github.com/emoose/OutRun2006Tweaks/commit/32877c5d23f0ae4db7d7501de26351ddd22819ed which pretty much works like the above, hoping nothing else might be relying on those shaders though.
Sadly don't really think we could get those backface shaders working exactly like arcade, seems they relied on an Xbox specific register which D3D9 didn't include (Lindbergh seems like it might have added some pixel shader to emulate it but doesn't look like C2C has anything for that, too bad)
Did write some code earlier so this would only apply on character models, but after finding about that Xbox specific thing I figured pretty much all uses of it would be broken, so just made it apply on everything that uses it, hope I don't regret that lol.
E: ahh there are some stage shading changes too, what I saw it mostly seems improved, but haven't tried comparing many places yet
eg: Orig
New
Any idea if the same issue is causing this? https://github.com/emoose/OutRun2006Tweaks/issues/103
Oh wait, I think that actually fixed it! Or at the very least, improved it, have to compare with other ports to see how they look. That's another level marked under improved.
Do you know if this same issue is what's causing the transparency to be loaded in the wrong order on water surfaces?
Think that seam might be caused by there being no color / black void under the water, instead of any sky reflection, so the "reflection" of the hill meeting that black void then makes an obvious seam.
Comparing C2C with Xbox: Xbox
Looking at Xbox in renderdoc shows the sky being drawn in two passes, first pass draws the upper part of skybox sphere & second pass draws lower part, on C2C it seems only upper part gets drawn.
Tried comparing Sky_Disp
func between them and doesn't really seem to be any difference there, can't see anything that would stop the lower half from drawing.
The sky itself does have a model file, afaik it's OBJ_COURSE_OBJ_SKY_2A_SMT
on Xbox & obj_course_obj_sky_lake_pmt
in C2C, in there it looks like sky object only has 1 VtxGroup
defined in C2C while Xbox has 2, so could mean the actual lower sphere was just removed entirely from the skybox model for some reason :/
For now maybe we can change the void color to something closer to the sky, 89BD5C (4bytes) should be the hex RGBA for the void, setting that to something like 00385463 seems to help a little but there is still an obvious seam there...
Ah, I thought the black void was actually the bottom of the stage's 3D model peeking through as as silhouette.
If there's any other levels that have water reflections working fine it might be possible to switch the obj_course_obj_sky model file out, could probably change the sky texture back with texture replacement too, not sure if any levels do have it working properly though.
Hmm, maybe cloudy highlands? It seems to look okay from above, but when you go below you get a black void again. So the black void might just be better hidden here. The water texture is really low resolution though so it's kinda hard to tell if it's a seam.
Checked a couple levels but most of them had black void, but Tulip Garden doesn't oddly, copying obj_course_obj_sky_tuli_pmt.sz over obj_course_obj_sky_lake_pmt.sz does seem to work too:
There is still a kinda obvious seam shown with it though, but not as bad as it was:
Kinda seems there might be some blurring missing from it, or maybe the bloom shader would have handled that for us.
Some reason obj_course_obj_sky_lake_pmt doesn't dump with TextureExtract though while obj_course_obj_sky_tuli_pmt does, guess maybe lake sky uses the cube texture loader that I haven't hooked yet, but since tuli sky does extract that should mean sky for it could be replaced at least.
Oh I had upscaled versions in load folder which stopped lake from dumping, seems it dumps fine.
Yeah, the new water on Deep Lake now has super obvious tiling, so there's definitely something such as a blur layer missing from it. I'm guessing the answer is no, but is it possible to replace the model entirely with the proper fully-modeled one?
Probably not for a while, maybe we can do something with the Xbox sky model at some point though.
The tulip garden model mostly seems fine except some of the upper sky seems to leak under the water around edges of the map, guess maybe the sphere for the skybox is meant to be adjusted per-level or something.
The tiling in my pics could be because of the sloppy upscale textures I'm using, maybe wouldn't be too bad with vanilla ones.
So the water surface is supposed to be more bright and "reflective" as in the Tulip swap? Unfortunately as it is, the side effect is that the void becomes much more pronounced and distracting, but it's interesting that they can be swapped at all and sorta work still.
Eh that looks close to the same brightness as the Xbox ver to me, switching to tulip would only affect what gets drawn under the water, the water itself is part of the stage model afaik.
If I run xemu with the glow filter disabled, it's pretty close when using higher res:
Lowering to default res seems to help blur it, and also improves water too:
Wonder if maybe because water bumpmap is really low res (64x64) the game ends up drawing it more times, rather than stretching it? Maybe replacing bumpmap with a basic upscale could help. Didn't actually see the bumpmap getting dumped though, only seen it inside PIX so far. (E: ah nvm, looks like they're in obj_course_obj_common_pmt, there's a bunch of bumpmaps there for each frame of the water anim)
I updated my screenshot to show the comparison I meant. As for upscaling, I haven't tried it yet but I found these models for ESRGAN. It's for normals though, maybe it can be tweaked for bumps anyway in something like Chainner?
https://github.com/RunDevelopment/rundev-models/tree/main/normals
I tried replacing all the normal maps for the water with some high-res ones I found online (1024), but it doesn't affect the blur (or lack thereof). On another note, though, if I can get the looping sorted out (OR2 is 40 frames, but this is 120...) we'll probably have some nice looking water. Otherwise I'll try to find some animated water maps with a shorter loop.
I went and added a grid to each map to see how it tiles, but the resolution doesn't affect anything it seems. It gets scaled to fit the same area no matter the size.
Regarding the backface issue, is the Xbox register different to D3D9's VFACE?
On Xbox it uses oB0 output register which doesn't seem to exist on PC, seems vertex shader would set oD0 to front-face color and oB0 to backface, but since oB0 doesn't exist on PC it was just changed to overwrite the oD0 color again instead, causing the shading issues...
Don't really know too much about D3D9 shaders, GPT tells me in D3D9 vertex shaders don't actually have access to which face is being drawn, and only pixel shaders know about it, so guess for this to work the VS would have to somehow pass both front-face & back-face colors over to the pixel shader, and then the PS would check VFACE to decide which to draw?
Do have some things setup for reassembling/replacing vertex shaders (haven't looked into replacing pixel shaders yet but it's probably similar), but I'm not really sure how we could pack both colors into oD0 & then be able to extract them in the PS though...
FWIW here's front-face VSULT_DOUBLE_LAMBERT
shader (comments/constants from online arcade):
dp3 r5.x, -R_NORMAL, CV_LIGHT_DIRECTION // R5.x = normal dot light;
mul r2, R_DIFFUSE, CV_LIGHT_DIFFUSE
max r0, r5.x, c0 // if dot < 0 then dot = 0;
mul r1, r5.x, CV_HEMISPHERE_FACTOR0
add r1, r1, CV_HEMISPHERE_FACTOR1
mad r1, r1, r8, CV_MATERIAL_EMISSIVE
mul r1, r1, CV_R_DRANGE
mad oD0, r0, r2, r1
mov oD1, c0.x
and the VSULT_TWOSIDE_LAMBERT
backface:
// this should also include same code as VSULT_DOUBLE_LAMBERT, it does in Xbox/Lindbergh anyway
// but I guess since the result from that would just be overwritten it was removed
dp3 r5.x, R_NORMAL, CV_LIGHT_DIRECTION // R5.x = normal dot light; -- twoside version works on R_NORMAL instead of -R_NORMAL
mul r2, R_DIFFUSE, CV_LIGHT_DIFFUSE
mul r6, r5.x, CV_HEMISPHERE_FACTOR0
add r1, r6, CV_HEMISPHERE_FACTOR1
max r0, r5.x, c0 // if dot < 0 then dot = 0;
mad r1, r1, r8, CV_MATERIAL_EMISSIVE
mul r1, r1, CV_R_DRANGE
mad oD0, r0, r2, r1 // xbox assigns this to oB0 instead of oD0...
mov oD1, c0.x
(there's also specular versions of these shaders which set oD1, so we can't really use that :/)
E: interestingly the TwoSidedLighting sample from Xbox OG SDK has a shader that matches pretty close to those, even includes the same "if dot < 0 then dot = 0;" comment: https://github.com/xerohour/xbox_leak_may_2020/blob/fd00b4b3b2abb1ea6ef9ac64b755419741a3af00/xbox_leak_may_2020/xbox%20trunk/xbox/private/atg/samples/graphics/TwoSidedLighting/media/shaders/twosided.vsh#L55 Seems X360 SDK removed this sample though, maybe they wanted to focus on per-pixel lighting over per-vertex instead.
Is that the whole shader? I'm confused. Are there any other semantics or constants? What about the pixel shader, is that specific to this lighting shader or is it reused across several shaders? It seems like it's a mistake that they sent the backface shading through to oD0, as having the front side shading mirrored would make more sense IMO.
If I understand correctly, the Xbox has a whole seperate register for a backface colour? That's interesting.
pass both front-face & back-face colors over to the pixel shader, and then the PS would check VFACE to decide which to draw?
Yeah, that's correct. You can't really tell which is the front/backface from the vertex shader.
A few thoughts come to mind...
R_NORMAL
and -R_NORMAL
) and max
the result? It'd be wrong, but then both sides would be lit.
The ending cutscenes always looked weird to me, figured that's just how they always were but looks like other releases do actually look better: https://youtu.be/h2XfwaAmbWI?t=23
Wonder what's going wrong with it there, does anyone know if there's any footage of the Xbox/arcade endings?
E: looks like arcade does have better lighting, https://youtu.be/h2XfwaAmbWI?t=235 vs https://youtu.be/NuIG3LkmQUU?t=469, hm..
E2: tried looking into the ending anims too, looks like C2C is missing code for a lot of them, the confetti/flower particle effects have code to set them up but doesn't include the actual rendering code for some reason...
There is a "goldleaf" effect which is still included though and seems to share a lot with the confetti/flower code, maybe something could be worked with that.
The anims for the volcano/rocket I'm not really sure about, I think those get handled by
GoalRendition
functions, seems O2SP has three of those setup for PRIN/FLOR/EAST (guess two of those are the volcano/rocket levels but not really sure yet)C2C is also missing these goal rendition funcs entirely, I'm not 100% sure these are actually controlling those anims though since it looks like these are just used to play video files.. unless those ending anims are actually just videos playing in the background of the scene or something.
(the video player they use is some Criware thing, which is also what they use for audio in O2SP arcade as well, could maybe explain why Xbox JP brought back both looping BGM & these ending anims at the same time?)