@@ -158,6 +158,67 @@ void Rasterizer::RasterizeTo(const Vertex& v0, const Vertex& v1, const Vertex& v
158158 }
159159}
160160
161+ void Rasterizer::RasterizeTo (const VertexSoA& soa, size_t i0, size_t i1, size_t i2,
162+ int x0, int y0, int x1, int y1,
163+ std::vector<Fragment>& out) {
164+ // 读取三顶点的屏幕空间位置
165+ const Vector4f& p0 = soa.pos_screen [i0];
166+ const Vector4f& p1 = soa.pos_screen [i1];
167+ const Vector4f& p2 = soa.pos_screen [i2];
168+
169+ Vector2f a = Vector2f (p0.x , p0.y );
170+ Vector2f b = Vector2f (p1.x , p1.y );
171+ Vector2f c = Vector2f (p2.x , p2.y );
172+
173+ Vector2f bboxMin = Vector2f{std::min ({a.x , b.x , c.x }), std::min ({a.y , b.y , c.y })};
174+ Vector2f bboxMax = Vector2f{std::max ({a.x , b.x , c.x }), std::max ({a.y , b.y , c.y })};
175+
176+ // Clamp 到屏幕尺寸
177+ float minx = std::max (0 .0f , bboxMin.x );
178+ float miny = std::max (0 .0f , bboxMin.y );
179+ float maxx = std::min (float (width_ - 1 ), bboxMax.x );
180+ float maxy = std::min (float (height_ - 1 ), bboxMax.y );
181+
182+ // 与外部提供的裁剪区域相交(半开区间) -> 闭区间扫描
183+ int sx = std::max (x0, int (std::floor (minx)));
184+ int sy = std::max (y0, int (std::floor (miny)));
185+ int ex = std::min (x1 - 1 , int (std::floor (maxx)));
186+ int ey = std::min (y1 - 1 , int (std::floor (maxy)));
187+ if (sx > ex || sy > ey) return ;
188+
189+ // 透视矫正插值依赖 w
190+ float w0_inv = p0.w ;
191+ float w1_inv = p1.w ;
192+ float w2_inv = p2.w ;
193+
194+ for (int x = sx; x <= ex; ++x) {
195+ for (int y = sy; y <= ey; ++y) {
196+ auto [is_inside, bary] = GetBarycentricCoord (
197+ Vector3f (p0.x , p0.y , p0.z ), Vector3f (p1.x , p1.y , p1.z ), Vector3f (p2.x , p2.y , p2.z ),
198+ Vector3f (static_cast <float >(x), static_cast <float >(y), 0 ));
199+ if (!is_inside) continue ;
200+
201+ float w_inv_interp = Interpolate (w0_inv, w1_inv, w2_inv, bary);
202+ Vector3f cb (
203+ bary.x * w0_inv / w_inv_interp,
204+ bary.y * w1_inv / w_inv_interp,
205+ bary.z * w2_inv / w_inv_interp);
206+
207+ float z = Interpolate (p0.z , p1.z , p2.z , cb);
208+
209+ Fragment frag;
210+ frag.screen_coord = {x, y};
211+ frag.normal = Interpolate (soa.normal [i0], soa.normal [i1], soa.normal [i2], cb);
212+ frag.uv = Interpolate (soa.uv [i0], soa.uv [i1], soa.uv [i2], cb);
213+ frag.color = InterpolateColor (soa.color [i0], soa.color [i1], soa.color [i2], cb);
214+ frag.depth = z;
215+ // material 指针由调用方填写
216+
217+ out.push_back (frag);
218+ }
219+ }
220+ }
221+
161222std::pair<bool , Vector3f> Rasterizer::GetBarycentricCoord (const Vector3f& p0,
162223 const Vector3f& p1,
163224 const Vector3f& p2,
0 commit comments