Example #1
0
    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);
    }
Example #2
0
    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);
    }