Open dkollmann opened 1 year ago
Thanks @dkollmann! I will take a look at this soon.
Also FYI if you try this code with Black & White, things will have a blue tint. This is because the water plane which should be rendered before all the other geometry, is rendered on top of it instead of behind the other geometry.
I made some fixes. Of course lpD3DMatrix has to be replaced, after getting the game camera properties from it. I added an option to disable the lighting which is needed when DdrawConvertHomogeneousW is true but DdrawConvertHomogeneousToWorld is false. At least for Black & White.
The force push was just an update on the commit comment.
For some reason when I add this DdrawConvertHomogeneousW = 1
line to the ini file I just get the following:
For some reason when I add this
DdrawConvertHomogeneousW = 1
line to the ini file I just get the following:
Ok, I figured this out. You have to set DdrawDisableLighting = 1
for Black & White.
My only last comment is that I prefer to create a struct and add it to the IDirect3DDeviceX.h
file rather than a whole new RednerData class for the DdrawConvertHomogeneous
settings/matrices. Since the code is in IDirect3DDeviceX.cpp
the settings should be in IDirect3DDeviceX.h
.
Other than that, I think this is about ready to merge.
Ah okay, I created the RenderData.h, because it was not possbile to include the device header in the DebugOverlay.cpp file.
I created the RenderData.h, because it was not possbile to include the device header in the DebugOverlay.cpp file.
DebugOverlay.h
already has #include "ddraw.h"
, which includes IDirect3DDeviceX.h
. So it is already covered.
Now DdrawConvertHomogeneousW
seems to be working great. However, I am not able to get DdrawConvertHomogeneousToWorld
working at all. I just get a black screen.
If possible, attach a few good looking screenshots (or even link a video) of the resulting rendering in RTX Remix!
These are my settings
DdrawOverrideWidth = 1920 DdrawOverrideHeight = 1080 DdrawOverrideRefreshRate = 60 DdrawOverrideStencilFormat = 80 DdrawConvertHomogeneousW = 1 DdrawConvertHomogeneousToWorld = 1 DdrawConvertHomogeneousToWorldUseGameCamera = 1 DdrawConvertHomogeneousToWorldFOV = 90 DdrawConvertHomogeneousToWorldNearPlane = 1 DdrawConvertHomogeneousToWorldFarPlane = 1000 DdrawConvertHomogeneousToWorldDepthOffset = 0.001 DdrawEnableMouseHook = 0 DdrawDisableLighting = 1
On my PC with the previous setings...
No RTX, the water plane which should be rendered first is just rendered alogn with the rest of the geometry. https://1drv.ms/v/s!As0-jjvsSN2xgft8Y6R-1Zsvta99uQ?e=453wxe
RTX, I ignore the water plane, so it is not rendered, since it does not serve the purpose of a raytraced surface anyway, since it is a plane facing the camera. https://1drv.ms/v/s!As0-jjvsSN2xgft9BREiXiT7RT6VAg?e=3t0yky
The RTX version is still quite experimental. I am fixing the issues one after another, but there is still work to do.
Ok, thanks! I figured it out. With the latest check-in this all you should need in your ini file. The rest should be set by default or auto-detected:
[Compatibility]
Dd7to9 = 1
[Dd7to9]
DdrawEnableMouseHook = 0
DdrawDisableLighting = 1
DdrawConvertHomogeneousW = 1
DdrawConvertHomogeneousToWorld = 1
DdrawConvertHomogeneousToWorldUseGameCamera = 1
With these settings and the latest build I am not seeing any issues. Try this build with only the included settings.
Latest build: dxwrapper.zip
Hmmm it works too well. Something seems off. Let me merge those changes into my branch and let me check.
RTX version crashes, with no explicit stencil format, but that is fine. DdrawOverrideStencilFormat = 80
Looks correct in blender though.
RTX version crashes, with no explicit stencil format, but that is fine. DdrawOverrideStencilFormat = 80
Sounds like a bug in RTX. The stencil format is set later. Maybe we should default to setting a stencil and then let the game override that, if needed?
I defaulted to no stencil because 2D DirectDraw games don't need it. But I don't think it will hurt to have a default one set. I prefer having less options and letting dxwrapper figure out things for the user.
Try this one and see if this has the same issue with RTX: dxwrapper.zip
I would not worry. To use RTX, you have to install all this as a mod anyway, so you also get the correct overrides and new assets.
I want to replace the water shader as well as the terrain shader. And add lights to the spells and so on.
Okay I found the issue. But still, not using DdrawConvertHomogeneousToWorldUseGameCamera currently yields the better results.
Maybe it would be better to just move the light, instead of transforming the geometry into insane values which then generate Z fighting. For the raytracing it should make no difference and the geometry we see is only the visible area anyway, so moving it around the world has no benefit.
Try this one and see if this has the same issue with RTX: dxwrapper.zip
Still crashes. Sorry. But as mentioned it does not matter, the user will get an installer anyway, and that will also install the dxwrapper.ini.
Also keep in mind that they just relased RTX Remix 0.2.0 like a week ago. It is still quite an experimental tool.
Still crashes. Sorry. [...] it does not matter, the user will get an installer anyway [...] they just relased RTX Remix 0.2.0 like a week ago. It is still quite an experimental tool.
Ok, no problem. Then I will not worry about it right now.
not using DdrawConvertHomogeneousToWorldUseGameCamera currently yields the better results.
Ok. What's the purpose of DdrawConvertHomogeneousToWorldUseGameCamera?
Maybe it would be better to just move the light, instead of transforming the geometry into insane values which then generate Z fighting.
I can't reproduce this issue. I'll wait until you have this resolved before merging the code.
Ok. What's the purpose of DdrawConvertHomogeneousToWorldUseGameCamera?
The idea is to transform the geometry back to its "original" world position, so it is correctly placed relative to other world geometry. So when I remove the 2D sky and replace it with a sky dome, so the raytracing has something it can actually hit, the game geometry will be correctly placed.
But it will probably be better to transform the sky dome instead into the homogenous space.
But still, not using DdrawConvertHomogeneousToWorldUseGameCamera
I think I fixed this issue. It should now be using the Game Camera. See check-in here: 44d43381e096a1fbff974f593ef68abc4d5c7efd
I can't reproduce this issue.
Now I can see the problem with the DdrawConvertHomogeneousToWorldUseGameCamera. It works fine as long as this option is disabled.
Shouldn't these lines be changed? FROM:
position = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
direction = DirectX::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
TO:
position = DirectX::XMVectorSet(view._41, view._42, view._43, view._44);
direction = DirectX::XMVectorSet(view._31, view._32, view._33, view._34);
Shouldn't these lines be changed?
The result of XMMatrixLookToLH should stay the same. So just using fixed values makes it easier for the compiler to optimize this and it simply represents what it does. A matrix which looks down the Z axis.
The result of XMMatrixLookToLH should stay the same.
Are you sure? The position
sent would be DirectX::XMVectorSet(-1.0f, 1.0f, 0.0f, 1.0f);
rather than DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
. Also, if we ever change the view
later than having it set by view
means it gets updated also. No need to manually change it later.
It seems like there may be more than just something wrong with DdrawConvertHomogeneousToWorldUseGameCamera
. I am seeing an issue in Dark Reign 2 when just using DdrawConvertHomogeneousToWorld
. The sky seems stretched
With DdrawConvertHomogeneousToWorld
enable:
How it is supposed to look:
I can also see it even when just DdrawConvertHomogeneousW
is enabled, but it is not quite as pronounced.
Okay, here are the things are are wrong here and why "position" is zero.
The result will be the same, but the code should be a bit clearer.
So what happens is...
I hope this all makes sense and is correct. Please take a look.
Not sure if it is related, but I noticed something curious with the reconstructed world space in Black & White.
The whole world is rotated by 24.4° degreees. But the thing is, if you look at the trees at the bottom left, they are straight, which implies that this is correct. I wonder why this is. Is this due to the angle of the reflection? In game, the camera is completely horizontal. I checked the original view matrix.
But I also noticed that the Y direction seems to be flipped. It is negative when looking up and positive when looking down.
Okay this seems to be a Black & White thing. No matter how I look att he view matrix, the angle only seems to be half of the actual angle. MAybe this is related to faking bent normals.
Hey Elisha, so I finally got around to take a closer look at this for Black & White. So for me, the practical difference between DdrawConvertHomogeneousToWorldUseGameCamera is that I use the original view matrix to remove the camera's tilt, so the world geometry comes out as horizontal. This way I can place a new water plane and it will always correctly align with the terrain. Of course this also means that the code became quite specialised for Black & White now and it might be a better option to remove DdrawConvertHomogeneousToWorldUseGameCamera, unless you see general value in this special case.
And just as a note, in the following code, yaw and pitch look like they should be the other way around, but this is indeed correct. Yaw is the rotation of X and pitch is the rotation of a vector around X.
Here is what I do now:
DirectX::XMVECTOR position, direction;
if (Config.DdrawConvertHomogeneousToWorldUseGameCamera)
{
// To reconstruct the 3D world, we need to know where the camera is and where it is looking
position = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
const float x = lpD3DMatrix->_11;
const float y = lpD3DMatrix->_12;
const float z = lpD3DMatrix->_13;
float pitch = std::atan2(y, z);
if(pitch < 0.0f && y * z > 0.0f) // check if y and z have the same sign
{
// handle flipping of the pitch. This is not because the camera is looking up.
pitch += DirectX::XM_PI;
}
float yaw = std::asin(x);
if(yaw < 0.0f)
{
yaw += DirectX::XM_2PI;
}
// mirror the transform
float pitchneg = -pitch;
float pitch_cos = std::cos(pitchneg);
float x2 = 0.0f; //std::cos(yaw) * pitch_cos;
float y2 = std::sin(pitchneg);
float z2 = /*std::sin(yaw) **/ pitch_cos;
direction = DirectX::XMVectorSet(x2, y2, z2, 0.0f);
ConvertHomogeneous.ToWorld_GameCameraYaw = yaw;
ConvertHomogeneous.ToWorld_GameCameraPitch = pitch;
}
else
{
position = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
direction = DirectX::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
}
@dkollmann, sorry for the delay in responding. I updated the code to match your branch. But I am wondering if there is an issue with DdrawConvertHomogeneousW
which is getting exacerbated in DdrawConvertHomogeneousToWorld
.
Could there be an issue because we are losing data in the DrawIndexedPrimitive()
when we overwrite data in lpVertices
?
The reason I ask is because I am still seeing distortion in the sky in Dark Reign 2 whenever DdrawConvertHomogeneousToWorld
is enabled, even if DdrawConvertHomogeneousToWorldUseGameCamera
is disabled. I also see distortion even if just DdrawConvertHomogeneousW
is enabled, though the distortion is much smaller in this last case.
Hey, I just wanted to say that I am still on this, but I changed my job and am moving to another country, so lately I am super busy.
@dkollmann, no problem. Take your time. I understand. Real life has to come first. Thanks for letting me know.
Because there are a lot of things added since this PR was created, I updated it to keep it in-sync with the master branch.
Keeping PR in-sync with master branch.
This is an update on the previous pull request https://github.com/elishacloud/dxwrapper/pull/188.