Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate Far Cry water reflections #5

Closed
mirh opened this issue Aug 11, 2017 · 34 comments
Closed

Investigate Far Cry water reflections #5

mirh opened this issue Aug 11, 2017 · 34 comments

Comments

@mirh
Copy link

mirh commented Aug 11, 2017

thread

@elishacloud
Copy link
Owner

Interesting. I am not quite sure what could be causing this issue but I will check it out. Seems easy enough to reproduce.

@CookiePLMonster
Copy link

Any news on this? Might investigate it at some point soon, since I got the game just for this.

@elishacloud
Copy link
Owner

@CookiePLMonster, I have not had much time to look into this issue. I also purchased the game from GOG because of this. Initially I thought the issue was related to shaders, but so far I have not found any issues with the shaders. Though I will admit I have not ruled them out yet. If you get a chance to look into this let me know what you find out.

@CookiePLMonster
Copy link

CookiePLMonster commented Mar 24, 2018

My experience with FC has been terrible so far - not sure if it depends on particular detail settings but I have been facing constant crashes (we're talking 90 seconds of gameplay TOPS), frame drops (down to 8FPS, no joke)... other than that, Alt-Tab consistently leaves my game in a locked up state, mouse cursor leaves smudges in main menu...

I'll try playing around with this a bit more. I have never seen people complain about those specific issues so maybe detail settings are broken (game auto-defaults to minimum details for me, which makes me think they probably broke a VRAM check by making it signed, so my 8GB VRAM GPU shows as -2GB instead of 4GB for this 32-bit game). I haven't checked the 64-bit version yet either.

I also thought the water issue would be related to shaders, however - have you compared pix frames between XP and non-XP?

@elishacloud
Copy link
Owner

I have not had any problems with FC so far (other than the reflection issue). I am running at the highest setting for every graphic option. My graphics card only has 3GBs of VRAM. I am using a GeForce GTX 780.

I have not tried running PIX yet to compare frames. I have mainly focused on the PixelShaders using my d3d9 wrapper.

@CookiePLMonster
Copy link

CookiePLMonster commented Mar 24, 2018 via email

@elishacloud
Copy link
Owner

When I enable vsync I get some stuttering and screen tearing.

@elishacloud
Copy link
Owner

Not sure if you have see this guide, but it has some interesting details on Far Cry, especially page 8.

r_Quality_Reflection [0,1] - 0=Off, 1=On. If turned on allows reflection of all surrounding objects in the water. This decreases FPS in areas with water but increases realism.

Also looking at the Shaders\Cache\CGVShaders folder tells me that this may be handled by a VertexShader not a PixelShader.

@CookiePLMonster
Copy link

CookiePLMonster commented Mar 25, 2018 via email

@mirh
Copy link
Author

mirh commented Mar 25, 2018

Maybe first try to figure out why you are so special to crash every minute or so /s

@CookiePLMonster
Copy link

CookiePLMonster commented Mar 25, 2018 via email

@CookiePLMonster
Copy link

This is worrying... I gave it another try today and none of the issues I had manifest themselves now... I should maybe check if Steam shader cache hides them.

@mirh
Copy link
Author

mirh commented Mar 26, 2018

Pretty extremely sure steam cache has nothing to do with older games.
...
Maybe W10 did update something?

@CookiePLMonster
Copy link

CookiePLMonster commented Mar 29, 2018 via email

@CookiePLMonster
Copy link

CookiePLMonster commented Mar 31, 2018

So, so far... I have no idea what is going on. This has to be the weirdest issue I ever got to debug, since "wrong" PIX frames capturted on Windows 10... display correctly on Windows XP!

For example, water reflection on Win10 looks like this:
ref102

But the same frame looks like this on XP:
refxp2

Both have the same draws and both show correct mesh postVS and preVS, but on Win10 I don't even see those pixels in pixel history - not even as rejected by depth/alpha/stencil test.

It's weird. I thought maybe pixel shader is busted, but even that should output something (at least I should be able to see output in pixel history). Rocks on this screen are rendered with this PS:

    ps_1_1
    def c2, 0.5, 0.5, 0.5, 1
    tex t0
    tex t1
    tex t2
    mul r0.xyz, t0, v0.w
  + mov r0.w, v0.z
    mul_x2 r0.xyz, r0, c0
    lrp r1.xyz, r0.w, t1, c2
    mul_x2 r0.xyz, r0, r1
  + mov r0.w, v1.z
    lrp r1.xyz, r0.w, t2, c2
  + mul r0.w, t0, v0
    mul_x2 r0.xyz, r0, r1

// approximately 9 instruction slots used (3 texture, 6 arithmetic)

EDIT:
I know those screens look so absurd so it looks like April Fools, but I can confirm that tomorrow ^^

@CookiePLMonster
Copy link

far cry screenshot 2018 04 01 - 15 50 52 55

@mirh
Copy link
Author

mirh commented Apr 1, 2018

And then GOG shouldn't throw money at you..

@CookiePLMonster
Copy link

CookiePLMonster commented Apr 3, 2018

OK, so as here
CookiePLMonster/SilentPatchFarCry@fb79e57

I implemented a fix by saving clip planes and lazily setting active ones before each draw call. This fix is fully reliable (and generic), but it's definitely too broad...

Basing on hours of testing and trial and error by now it's not exactly "draw calls invalidate clip planes" like I thought (and like the fix suggests) - planes get corrupted/invalidated by something else, but I can't quite make out what.

I tried caching SetClipPlane values and letting them to D3D directly (as opposed to just caching and setting lazily) and re-submitting them from SetVertexShader and/or SetVertexShaderConstants - but that does not fix the issue fully. Most of the geometry is fine, but looks like the first batch of geometries drawn after enabling clip planes is still missing.

This is definitely a bug and it may not be as obvious as I initially thought - but thankfully current fix is reliable, albeit maybe too broad. However, 1 extra D3D call for each clipped draw call is really a non-issue.

EDIT:
I'm not sure if @crosire would be interested in this issue, but it may also concern d3d8to9 (because now using d3d9 makes it "vulnerable" to the issue) and ReShade... plus maybe also some NVidia-fu =)

@elishacloud
Copy link
Owner

Nice! Works flawlessly for me. Would be interesting to figure out why clip planes are getting corrupted.

@mirh
Copy link
Author

mirh commented Apr 4, 2018

Mh.. Guess like that would require some hefty disassembly?
@UCyborg @Marcinosoft maybe you are interested in this.

@CookiePLMonster
Copy link

For me, this looks like some optimization/precomputation being applied to those (maybe calculating clipping space?) which does not carry for subsequent draws - notice not all draws are busted (trees reflect fine), so it's not like planes are corrupted for all calls.

I re-retested last night again - if I remove lazy setting entirely and re-apply planes from those functions:

  • SetVertexShader
  • SetVertexShaderConstantF
  • SetPixelShader
  • SetPixelShaderConstantF
  • SetTransform

I get better results - geometry is mostly there, but with some holes which in my case appear/dissapear depending on camera angle and placement (different order of draws? different shaders used?).

I gave up trying to come up with a less "heavy" fix (though admitedly, 1 extra D3D call for each draw call per enabled clip plane is nothing, as most of the time clip planes are disabled anyway) for one important reason - even if I ended up fixing it by re-submitting planes from X functions, I can't say for sure it would be exhaustive - more calls may every well also be causing issues. Besides, current fix was tested with all three GPU vendors and confirmed working flawlessly.

@elishacloud
Copy link
Owner

I am not sure if they has anything to do with it, but I was looking up the Microsoft documentation and according to this site calling Clear() with NULL "will clear the entire viewport".

I notice that once in each frame immediately after the game calls SetViewport() it calls Clear(), removing the viewport that was just called. Why would the game set a viewport and then immediately clear it before the viewport was ever used?

Is it possible that Clear() works differently on Windows 8/10 than the game expects?

farcry_clear

@CookiePLMonster
Copy link

It could be... but I'm pretty sure they set viewport and then clear it so they clear the entire image - leaving viewport as smaller and then clearing would probably clear only a part of the image...

By the way, have you been able to get VSync to work? I can't get it on Win7 nor Win10.

@CookiePLMonster
Copy link

Interesting quirk: clip planes can be disabled via system.cfg by adding this:
d3d9_ClipPlanes = "0"

@elishacloud
Copy link
Owner

@CookiePLMonster, no I have not been able to get VSync to work for me. I am also using Win10.

Also, disabling the clip planes solved the initial reflection issue but also caused a whole bunch of new "artifacts" in the water.

@CookiePLMonster
Copy link

CookiePLMonster commented Apr 8, 2018

Sure, it makes perfect sense - they use clip planes to cull underwater geometry so it doesn't end up rendered in a reflection map. Disabling clip planes makes them reflect.

About VSync, by now I'm pretty sure it's totally broken so I hooked up some custom code for that.

This issue can be closed now, I guess? Your fix is in place and mine is releasing tomorrow-ish.

@elishacloud
Copy link
Owner

About VSync, by now I'm pretty sure it's totally broken so I hooked up some custom code for that.

Nice! Great work!

@mirh
Copy link
Author

mirh commented Apr 8, 2018

This issue can be closed now, I guess?

I guess like it depends on whehter one simply wants "fixes" or even "documentation" of them.

@elishacloud
Copy link
Owner

I added a wiki for the Far Cry fix.

Note: I did not fix VSync yet, but can add an option for that later. @CookiePLMonster fix is better since he actually checks the status of the VSync option. I plan on just adding a VSync option to dxwrapper.

Closing the issue.

@CookiePLMonster
Copy link

CookiePLMonster commented Apr 9, 2018

Though on the flip side, I like your SetRenderState more - even though I can't imagine any cases where it would report failure (with valid parameters), it doesn't hurt accounting for it like you did in your fix!

On semi-unrelated note, do you think it's worth submitting identical PRs for d3d8to9 and ReShade? I would say it makes sense, especially since the fix is very cheap and I literally can't imagine any cases where it introduces regressions.

@elishacloud
Copy link
Owner

@CookiePLMonster, the vsync issue with Far Cry could be related to the issue here.

@CookiePLMonster
Copy link

Doubt it - if I recall correctly, FC never requested anything else but immediate interval. If it requested a default one though then you are probably right.

BTW. I am not 100% sure if it's an universal Win10 issue, since my current experiments with CRC Extreme showed that by default the game used a default presentation interval, yet I am 100% sure vsync worked.

@elishacloud
Copy link
Owner

Yep. You are right. It looks like the the Far Cry vsync fix changed it from 'immediate' to 'one'.

@holybagpipes
Copy link

@elishacloud Sorry for necro-ing this thread but I've tried the fix for the reflections and it tends to crash quite a bit. This is with the GOG release and the 64-bit addon since the wrapper doesn't seem to work with the 64-bit version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants