VaryingData GeometryProcessing(Vector3[] vertices, Matrix4x4 mvp) { var result = new VaryingData(); var count = vertices.Length; for (int i = 0; i < count; i++) { result.sv_position.Add(mvp * new Vector4(vertices[i].x, vertices[i].y, vertices[i].z, 1)); } return(result); }
FragmentData ClippingAndRasterization(VaryingData varyingData, int[] indexes) { var result = new FragmentData(); var count = indexes.Length; for (int i = 0; i < count; i += 3) { var index0 = indexes[i]; var index1 = indexes[i + 1]; var index2 = indexes[i + 2]; var v0 = new Vector4(varyingData.sv_position[index0].x, varyingData.sv_position[index0].y, varyingData.sv_position[index0].z, 1f) / varyingData.sv_position[index0].w; var v1 = new Vector4(varyingData.sv_position[index1].x, varyingData.sv_position[index1].y, varyingData.sv_position[index1].z, 1f) / varyingData.sv_position[index1].w; var v2 = new Vector4(varyingData.sv_position[index2].x, varyingData.sv_position[index2].y, varyingData.sv_position[index2].z, 1f) / varyingData.sv_position[index2].w; var area = EdgeFunction(v0, v1, v2); var xMin = Mathf.Max(Mathf.FloorToInt((Mathf.Min(v0.x, v1.x, v2.x) * 0.5f + 0.5f) / pixelSize.x), 0); var xMax = Mathf.Min(Mathf.CeilToInt((Mathf.Max(v0.x, v1.x, v2.x) * 0.5f + 0.5f) / pixelSize.x) + 1, width); var yMin = Mathf.Max(Mathf.FloorToInt((Mathf.Min(v0.y, v1.y, v2.y) * 0.5f + 0.5f) / pixelSize.y), 0); var yMax = Mathf.Min(Mathf.CeilToInt((Mathf.Max(v0.y, v1.y, v2.y) * 0.5f + 0.5f) / pixelSize.y) + 1, height); for (int x = xMin; x < xMax; x++) { for (int y = yMin; y < yMax; y++) { var p = new Vector2(x * pixelSize.x, y * pixelSize.y) + pixelSize * 0.5f; p = p * 2f - new Vector2(1f, 1f); var w0 = EdgeFunction(v1, v2, p); var w1 = EdgeFunction(v2, v0, p); var w2 = EdgeFunction(v0, v1, p); if (w0 < 0 || w1 < 0 || w2 < 0) { // triangle not contains the point continue; } w0 /= area; w1 /= area; w2 /= area; var interpolated_z = v0.z * w0 + v1.z * w1 + v2.z * w2; var interpolated_w = v0.w * w0 + v1.w * w1 + v2.w * w2; if (interpolated_z < 0f || interpolated_z > 1f) { // clip fragments outside the near/far planes continue; } // perspective correct interpolation // w0 = w0 * v0.w / interpolated_w; // w1 = w1 * v1.w / interpolated_w; // w2 = w2 * v2.w / interpolated_w; // var varying = varying0 * w0 + varying1 * w1 + varying2 * w2; var depth = interpolated_z; var index = y * width + x; result.index.Add(index); result.sv_depth.Add(depth); } } } return(result); }