mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 15:30:35 +00:00
More D3D hackery: Take inverted Z in proj matrix into account.
Also, *2 breaks it for no good reason so don't do that.
This commit is contained in:
parent
9bf5d40084
commit
08b340f423
@ -483,11 +483,15 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
|
||||
float viewZScale = gstate.getViewportZScale();
|
||||
float viewZCenter = gstate.getViewportZCenter();
|
||||
|
||||
// Adjust for D3D projection matrix. We got squashed up to only 0-1, so we multiply
|
||||
// the scale factor by 2, and add an offset.
|
||||
// Given the way we do the rounding, the integer part of the offset is probably mostly irrelevant as we cancel
|
||||
// it afterwards anyway.
|
||||
viewZScale *= 2.0f;
|
||||
// It seems that we should adjust for D3D projection matrix. We got squashed up to only 0-1, so we divide
|
||||
// the scale factor by 2, and add an offset. But, this doesn't work! I get near-perfect results not doing it.
|
||||
// viewZScale *= 2.0f;
|
||||
|
||||
// Need to take the possibly inverted proj matrix into account.
|
||||
if (gstate_c.vpDepth < 0.0)
|
||||
viewZScale *= -1.0f;
|
||||
viewZCenter -= 32767.5f;
|
||||
float viewZInvScale;
|
||||
if (viewZScale != 0.0) {
|
||||
|
@ -742,16 +742,16 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
||||
vpWidth *= renderWidthFactor;
|
||||
vpHeight *= renderHeightFactor;
|
||||
|
||||
float zScale = gstate.getViewportZScale() / 65535.0f;
|
||||
float zCenter = gstate.getViewportZCenter() / 65535.0f;
|
||||
float zScale = gstate.getViewportZScale();
|
||||
float zCenter = gstate.getViewportZCenter();
|
||||
|
||||
// Note - We lose the sign of the zscale here. But we keep it in gstate_c.vpDepth.
|
||||
// That variable is only check for sign later so the multiplication by 2 isn't really necessary.
|
||||
|
||||
// It's unclear why we need this Z offset of 1 to match OpenGL, but this checks out in multiple games.
|
||||
float depthRangeMin = zCenter - fabsf(zScale) - 0.5f/65535.0f;
|
||||
float depthRangeMax = zCenter + fabsf(zScale) - 0.5f/65535.0f;
|
||||
gstate_c.vpDepth = zScale * 2;
|
||||
// It's unclear why we need this Z offset to match OpenGL, but this checks out in multiple games.
|
||||
float depthRangeMin = (zCenter - fabsf(zScale)) * (1.0f / 65535.0f);
|
||||
float depthRangeMax = (zCenter + fabsf(zScale)) * (1.0f / 65535.0f);
|
||||
gstate_c.vpDepth = zScale * (2.0f / 65335.0f);
|
||||
|
||||
// D3D doesn't like viewports partially outside the target, so we
|
||||
// apply the viewport partially in the shader.
|
||||
|
@ -288,10 +288,10 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) {
|
||||
|
||||
if (!gstate.isModeThrough()) {
|
||||
// Apply the projection and viewport to get the Z buffer value, floor to integer, undo the viewport and projection.
|
||||
// Not completely sure this is 100% right under DX9 as the Z range is different...
|
||||
// The Z range in D3D is different but we compensate for that using parameters.
|
||||
WRITE(p, "\nfloat4 depthRoundZVP(float4 v) {\n");
|
||||
WRITE(p, " float z = v.z / v.w;\n");
|
||||
WRITE(p, " z = z * u_depthRange.x + u_depthRange.y;\n");
|
||||
WRITE(p, " z = (z * u_depthRange.x + u_depthRange.y);\n");
|
||||
WRITE(p, " z = floor(z);\n");
|
||||
WRITE(p, " z = (z - u_depthRange.z) * u_depthRange.w;\n");
|
||||
WRITE(p, " return float4(v.x, v.y, z * v.w, v.w);\n");
|
||||
|
Loading…
Reference in New Issue
Block a user