port EterLib/GrpShadowTexture verbatim; D3D top-left fill rule for the shadow target (unit C/D)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5be37b6363
commit
86e602cb32
@@ -642,14 +642,22 @@ private:
|
||||
const int y0 = std::max(0, int(std::floor(std::min({a.y, b.y, c.y}))));
|
||||
const int x1 = std::min(width - 1, int(std::ceil(std::max({a.x, b.x, c.x}))));
|
||||
const int y1 = std::min(height - 1, int(std::ceil(std::max({a.y, b.y, c.y}))));
|
||||
// D3D top-left fill rule: a pixel centre exactly on an edge is covered only when that edge
|
||||
// is a left edge (weight grows to the right) or a top edge (horizontal, weight grows downward).
|
||||
auto top_left = [area](const Point& p, const Point& q) {
|
||||
const float dx = (q.y - p.y) / area, dy = (p.x - q.x) / area;
|
||||
return dx > 0.0f || (dx == 0.0f && dy > 0.0f);
|
||||
};
|
||||
const bool tlA = top_left(b, c), tlB = top_left(c, a), tlC = top_left(a, b);
|
||||
auto covered = [](float w, bool tl) { return w > 0.0f || (w == 0.0f && tl); };
|
||||
for (int y = y0; y <= y1; ++y)
|
||||
for (int x = x0; x <= x1; ++x)
|
||||
{
|
||||
const float px = float(x) + 0.5f, py = float(y) + 0.5f;
|
||||
const float wa = edge(b, c, px, py) / area;
|
||||
const float wb = edge(c, a, px, py) / area;
|
||||
const float wc = 1.0f - wa - wb;
|
||||
if (wa < 0.0f || wb < 0.0f || wc < 0.0f) continue;
|
||||
const float wc = edge(a, b, px, py) / area;
|
||||
if (!covered(wa, tlA) || !covered(wb, tlB) || !covered(wc, tlC)) continue;
|
||||
const float z = wa * a.z + wb * b.z + wc * c.z;
|
||||
const size_t pixel = size_t(y) * width + x;
|
||||
if (z < 0.0f || z > 1.0f || z > m_offscreenDepth[pixel]) continue;
|
||||
|
||||
Reference in New Issue
Block a user