fix: D3D12 sphere - enable depth write, fix texture UV seam tearing and orientation

- Enable depth write mask (D3D12_DEPTH_WRITE_MASK_ALL) to fix rendering artifacts
- Change texture address mode from Wrap to Clamp to fix UV seam tearing
- Remove V coordinate flip in shader to fix upside-down texture
- Add ground truth screenshot (GT.ppm) for testing
This commit is contained in:
2026-03-22 18:41:11 +08:00
parent 6c92164a03
commit 7d1362a41e
3 changed files with 30 additions and 25 deletions

View File

@@ -28,5 +28,5 @@ VSOut MainVS(Vertex v) {
} }
float4 MainPS(VSOut i) : SV_TARGET { float4 MainPS(VSOut i) : SV_TARGET {
return gDiffuseTexture.Sample(gSampler, i.texcoord.xy); return gDiffuseTexture.Sample(gSampler, float2(i.texcoord.x, i.texcoord.y));
} }

View File

@@ -3,6 +3,7 @@
#include <dxgi1_4.h> #include <dxgi1_4.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define _USE_MATH_DEFINES
#include <math.h> #include <math.h>
#include <stdarg.h> #include <stdarg.h>
#include <string> #include <string>
@@ -172,24 +173,26 @@ void GenerateSphere(std::vector<Vertex>& vertices, std::vector<UINT32>& indices,
vertices.clear(); vertices.clear();
indices.clear(); indices.clear();
for (int lat = 0; lat <= segments; lat++) { segments = (segments < 3) ? 3 : segments;
float theta = lat * 3.14159f / segments;
float sinTheta = sinf(theta);
float cosTheta = cosf(theta);
for (int lon = 0; lon <= segments; lon++) { for (int lat = 0; lat <= segments; ++lat) {
float phi = lon * 2.0f * 3.14159f / segments; float phi = static_cast<float>(M_PI) * lat / segments;
float sinPhi = sinf(phi); float sinPhi = sinf(phi);
float cosPhi = cosf(phi); float cosPhi = cosf(phi);
for (int lon = 0; lon <= segments; ++lon) {
float theta = static_cast<float>(2 * M_PI) * lon / segments;
float sinTheta = sinf(theta);
float cosTheta = cosf(theta);
Vertex v; Vertex v;
v.pos[0] = radius * sinTheta * cosPhi; v.pos[0] = radius * sinPhi * cosTheta;
v.pos[1] = radius * cosTheta; v.pos[1] = radius * cosPhi;
v.pos[2] = radius * sinTheta * sinPhi; v.pos[2] = radius * sinPhi * sinTheta;
v.pos[3] = 1.0f; v.pos[3] = 1.0f;
v.texcoord[0] = (float)lon / segments; v.texcoord[0] = static_cast<float>(lon) / segments;
v.texcoord[1] = (float)lat / segments; v.texcoord[1] = static_cast<float>(lat) / segments;
v.texcoord[2] = 0.0f; v.texcoord[2] = 0.0f;
v.texcoord[3] = 0.0f; v.texcoord[3] = 0.0f;
@@ -197,18 +200,20 @@ void GenerateSphere(std::vector<Vertex>& vertices, std::vector<UINT32>& indices,
} }
} }
for (int lat = 0; lat < segments; lat++) { for (int lat = 0; lat < segments; ++lat) {
for (int lon = 0; lon < segments; lon++) { for (int lon = 0; lon < segments; ++lon) {
int first = lat * (segments + 1) + lon; UINT32 topLeft = lat * (segments + 1) + lon;
int second = first + segments + 1; UINT32 topRight = topLeft + 1;
UINT32 bottomLeft = (lat + 1) * (segments + 1) + lon;
UINT32 bottomRight = bottomLeft + 1;
indices.push_back(first); indices.push_back(topLeft);
indices.push_back(second); indices.push_back(bottomLeft);
indices.push_back(first + 1); indices.push_back(topRight);
indices.push_back(second); indices.push_back(topRight);
indices.push_back(second + 1); indices.push_back(bottomLeft);
indices.push_back(first + 1); indices.push_back(bottomRight);
} }
} }
} }
@@ -367,7 +372,7 @@ bool InitD3D12() {
psoDesc.RasterizerState.FrontCounterClockwise = FALSE; psoDesc.RasterizerState.FrontCounterClockwise = FALSE;
psoDesc.RasterizerState.DepthClipEnable = TRUE; psoDesc.RasterizerState.DepthClipEnable = TRUE;
psoDesc.DepthStencilState.DepthEnable = TRUE; psoDesc.DepthStencilState.DepthEnable = TRUE;
psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
psoDesc.BlendState.RenderTarget[0].BlendEnable = FALSE; psoDesc.BlendState.RenderTarget[0].BlendEnable = FALSE;
psoDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; psoDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE;