Example #1
0
        void ProcessScanLine_GS(ScanLineData data, Vertex A, Vertex B, Vertex C, Vertex D, Color color, bool blin)
        {
            var pa = A.Position;
            var pb = B.Position;
            var pc = C.Position;
            var pd = D.Position;

            var gradient1 = pa.y != pb.y ? (data.currentY - pa.y) / (pb.y - pa.y) : 1;
            var gradient2 = pc.y != pd.y ? (data.currentY - pc.y) / (pd.y - pc.y) : 1;

            int sx = (int)Interpolate(pa.x, pb.x, gradient1);
            int ex = (int)Interpolate(pc.x, pd.x, gradient2);

            double z1 = Interpolate(pa.z, pb.z, gradient1);
            double z2 = Interpolate(pc.z, pd.z, gradient2);

            var sNoL = Interpolate(data.NoLa, data.NoLb, gradient1);
            var eNoL = Interpolate(data.NoLc, data.NoLd, gradient2);

            double sNoH = 0, eNoH = 0, sRoV = 0, eRoV = 0;

            if (blin)
            {
                sNoH = Interpolate(data.NoHa, data.NoHb, gradient1);
                eNoH = Interpolate(data.NoHc, data.NoHd, gradient2);
            }
            else
            {
                sRoV = Interpolate(data.RoVa, data.RoVb, gradient1);
                eRoV = Interpolate(data.RoVc, data.RoVd, gradient2);
            }


            for (var x = sx; x < ex; x++)
            {
                double gradient = (x - sx) / (double)(ex - sx);
                var    z = Interpolate(z1, z2, gradient);
                var    NoL = Interpolate(sNoL, eNoL, gradient);
                byte   r = 0, g = 0, b = 0;
                if (blin)
                {
                    var NoH = Interpolate(sNoH, eNoH, gradient);
                    r = Limit(kd * color.R * NoL + ks * color.R * NoH);
                    g = Limit(kd * color.R * NoL + ks * color.R * NoH);
                    b = Limit(kd * color.R * NoL + ks * color.R * NoH);
                }
                else
                {
                    var RoV = Interpolate(sRoV, eRoV, gradient);
                    r = Limit(kd * color.R * NoL + ks * color.R * RoV);
                    g = Limit(kd * color.R * NoL + ks * color.R * RoV);
                    b = Limit(kd * color.R * NoL + ks * color.R * RoV);
                }

                var shadedColor = Color.FromArgb(color.A, r, g, b);
                DrawPoint(new Vector3(x, data.currentY, z), shadedColor);
            }
        }
Example #2
0
        void ProcessScanLine_FS(ScanLineData data, Vector3 A, Vector3 B, Vector3 C, Vector3 D, Color color, bool blin)
        {
            var gradient1 = A.y != B.y ? (data.currentY - A.y) / (B.y - A.y) : 1;
            var gradient2 = C.y != D.y ? (data.currentY - C.y) / (D.y - C.y) : 1;

            int sx = (int)Interpolate(A.x, B.x, gradient1);
            int ex = (int)Interpolate(C.x, D.x, gradient2);

            double z1 = Interpolate(A.z, B.z, gradient1);
            double z2 = Interpolate(C.z, D.z, gradient2);

            for (var x = sx; x < ex; x++)
            {
                double gradient = (x - sx) / (double)(ex - sx);
                var    z = Interpolate(z1, z2, gradient);
                var    NoL = data.NoLa;
                var    RoV = data.RoVa;
                var    NoH = data.NoHa;
                byte   r = 0, g = 0, b = 0;

                if (blin)
                {
                    r = Limit(kd * color.R * NoL + ks * color.R * NoH);
                    g = Limit(kd * color.R * NoL + ks * color.R * NoH);
                    b = Limit(kd * color.R * NoL + ks * color.R * NoH);
                }
                else
                {
                    r = Limit(kd * color.R * NoL + ks * color.R * RoV);
                    g = Limit(kd * color.R * NoL + ks * color.R * RoV);
                    b = Limit(kd * color.R * NoL + ks * color.R * RoV);
                }

                var shadedColor = Color.FromArgb(color.A, r, g, b);

                DrawPoint(new Vector3(x, data.currentY, z), shadedColor);
            }
        }
Example #3
0
        public void DrawTriangle_GS(Vertex v1, Vertex v2, Vertex v3, Color color, double Time, Vector3 viewerPosition, bool blin = false)
        {
            if (v1.Position.y > v2.Position.y)
            {
                Swap(ref v1, ref v2);
            }

            if (v2.Position.y > v3.Position.y)
            {
                Swap(ref v2, ref v3);
            }

            if (v1.Position.y > v2.Position.y)
            {
                Swap(ref v1, ref v2);
            }

            var p1 = v1.Position;
            var p2 = v2.Position;
            var p3 = v3.Position;

            Vector3 lightPos = LP;

            double NoL1 = Compute_NoL(v1.WorldPosition, v1.Normal, lightPos);
            double NoL2 = Compute_NoL(v2.WorldPosition, v2.Normal, lightPos);
            double NoL3 = Compute_NoL(v3.WorldPosition, v3.Normal, lightPos);

            double RoV1 = 0, RoV2 = 0, RoV3 = 0;
            double NoH1 = 0, NoH2 = 0, NoH3 = 0;

            if (blin)
            {
                var H1 = Compute_H(v1.WorldPosition, viewerPosition, lightPos);
                var H2 = Compute_H(v2.WorldPosition, viewerPosition, lightPos);
                var H3 = Compute_H(v3.WorldPosition, viewerPosition, lightPos);

                H1.Normalize();
                H2.Normalize();
                H3.Normalize();

                var Nnorm1 = v1.Normal;
                var Nnorm2 = v2.Normal;
                var Nnorm3 = v3.Normal;

                Nnorm1.Normalize();
                Nnorm2.Normalize();
                Nnorm3.Normalize();

                NoH1 = Vector3.Dot(Nnorm1, H1);
                NoH2 = Vector3.Dot(Nnorm2, H2);
                NoH3 = Vector3.Dot(Nnorm3, H3);

                NoH1 = Math.Pow(NoH1, alpha);
                NoH2 = Math.Pow(NoH2, alpha);
                NoH3 = Math.Pow(NoH3, alpha);
            }
            else
            {
                var R1 = Compute_R(v1.WorldPosition, v1.Normal, lightPos);
                var R2 = Compute_R(v2.WorldPosition, v2.Normal, lightPos);
                var R3 = Compute_R(v3.WorldPosition, v3.Normal, lightPos);
                R1.Normalize();
                R2.Normalize();
                R3.Normalize();

                var V1 = viewerPosition - v1.WorldPosition;
                var V2 = viewerPosition - v2.WorldPosition;
                var V3 = viewerPosition - v3.WorldPosition;
                V1.Normalize();
                V2.Normalize();
                V3.Normalize();

                RoV1 = OverZero(Vector3.Dot(R1, V1));
                RoV2 = OverZero(Vector3.Dot(R2, V2));
                RoV3 = OverZero(Vector3.Dot(R3, V3));

                RoV1 = Math.Pow(RoV1, alpha);
                RoV2 = Math.Pow(RoV2, alpha);
                RoV3 = Math.Pow(RoV3, alpha);
            }

            var data = new ScanLineData {
            };

            double dP1P2, dP1P3;

            if (p2.y - p1.y > 0)
            {
                dP1P2 = (p2.x - p1.x) / (p2.y - p1.y);
            }
            else
            {
                dP1P2 = 0;
            }

            if (p3.y - p1.y > 0)
            {
                dP1P3 = (p3.x - p1.x) / (p3.y - p1.y);
            }
            else
            {
                dP1P3 = 0;
            }

            if (dP1P2 > dP1P3)
            {
                for (var y = (int)p1.y; y <= (int)p3.y; y++)
                {
                    data.currentY = y;
                    if (y < p2.y)
                    {
                        data.NoLa = NoL1;
                        data.NoLb = NoL3;
                        data.NoLc = NoL1;
                        data.NoLd = NoL2;
                        if (blin)
                        {
                            data.NoHa = NoH1;
                            data.NoHb = NoH3;
                            data.NoHc = NoH1;
                            data.NoHd = NoH2;
                        }
                        else
                        {
                            data.RoVa = RoV1;
                            data.RoVb = RoV3;
                            data.RoVc = RoV1;
                            data.RoVd = RoV2;
                        }

                        ProcessScanLine_GS(data, v1, v3, v1, v2, color, blin);
                    }
                    else
                    {
                        data.NoLa = NoL1;
                        data.NoLb = NoL3;
                        data.NoLc = NoL2;
                        data.NoLd = NoL3;
                        if (blin)
                        {
                            data.NoHa = NoH1;
                            data.NoHb = NoH3;
                            data.NoHc = NoH2;
                            data.NoHd = NoH3;
                        }
                        else
                        {
                            data.RoVa = RoV1;
                            data.RoVb = RoV3;
                            data.RoVc = RoV2;
                            data.RoVd = RoV3;
                        }

                        ProcessScanLine_GS(data, v1, v3, v2, v3, color, blin);
                    }
                }
            }
            else
            {
                for (var y = (int)p1.y; y <= (int)p3.y; y++)
                {
                    data.currentY = y;
                    if (y < p2.y)
                    {
                        data.NoLa = NoL1;
                        data.NoLb = NoL2;
                        data.NoLc = NoL1;
                        data.NoLd = NoL3;
                        if (blin)
                        {
                            data.NoHa = NoH1;
                            data.NoHb = NoH2;
                            data.NoHc = NoH1;
                            data.NoHd = NoH3;
                        }
                        else
                        {
                            data.RoVa = RoV1;
                            data.RoVb = RoV2;
                            data.RoVc = RoV1;
                            data.RoVd = RoV3;
                        }

                        ProcessScanLine_GS(data, v1, v2, v1, v3, color, blin);
                    }
                    else
                    {
                        data.NoLa = NoL2;
                        data.NoLb = NoL3;
                        data.NoLc = NoL1;
                        data.NoLd = NoL3;
                        if (blin)
                        {
                            data.NoHa = NoH1;
                            data.NoHb = NoH2;
                            data.NoHc = NoH1;
                            data.NoHd = NoH3;
                        }
                        else
                        {
                            data.RoVa = RoV1;
                            data.RoVb = RoV2;
                            data.RoVc = RoV1;
                            data.RoVd = RoV3;
                        }

                        ProcessScanLine_GS(data, v2, v3, v1, v3, color, blin);
                    }
                }
            }
        }
Example #4
0
        public void DrawTriangle_FS(Vertex v1, Vertex v2, Vertex v3, Color color, double Time, Vector3 viewerPosition, bool blin = false)
        {
            if (v1.Position.y > v2.Position.y)
            {
                Swap(ref v1, ref v2);
            }

            if (v2.Position.y > v3.Position.y)
            {
                Swap(ref v2, ref v3);
            }

            if (v1.Position.y > v2.Position.y)
            {
                Swap(ref v1, ref v2);
            }

            var p1 = v1.Position;
            var p2 = v2.Position;
            var p3 = v3.Position;

            Vector3 vnFace      = (v1.Normal + v2.Normal + v3.Normal) / 3;
            Vector3 centerPoint = (v1.WorldPosition + v2.WorldPosition + v3.WorldPosition) / 3;
            Vector3 lightPos    = LP;

            double NoL = Compute_NoL(centerPoint, vnFace, lightPos);

            double NoH = 0, RoV = 0;

            if (blin)
            {
                var H = Compute_H(v1.WorldPosition, viewerPosition, lightPos);
                H.Normalize();
                var Nnorm1 = v1.Normal;
                Nnorm1.Normalize();
                NoH = Vector3.Dot(Nnorm1, H);
                NoH = Math.Pow(NoH, alpha);
            }
            else
            {
                var R = Compute_R(centerPoint, vnFace, lightPos);
                R.Normalize();
                var V = viewerPosition - centerPoint;
                V.Normalize();
                RoV = OverZero(Vector3.Dot(R, V));
                RoV = Math.Pow(RoV, alpha);
            }

            var data = new ScanLineData {
                NoLa = NoL, RoVa = RoV, NoHa = NoH
            };

            double dP1P2, dP1P3;

            if (p2.y - p1.y > 0)
            {
                dP1P2 = (p2.x - p1.x) / (p2.y - p1.y);
            }
            else
            {
                dP1P2 = 0;
            }

            if (p3.y - p1.y > 0)
            {
                dP1P3 = (p3.x - p1.x) / (p3.y - p1.y);
            }
            else
            {
                dP1P3 = 0;
            }

            if (dP1P2 > dP1P3)
            {
                for (var y = (int)p1.y; y <= (int)p3.y; y++)
                {
                    data.currentY = y;
                    if (y < p2.y)
                    {
                        ProcessScanLine_FS(data, p1, p3, p1, p2, color, blin);
                    }
                    else
                    {
                        ProcessScanLine_FS(data, p1, p3, p2, p3, color, blin);
                    }
                }
            }
            else
            {
                for (var y = (int)p1.y; y <= (int)p3.y; y++)
                {
                    data.currentY = y;
                    if (y < p2.y)
                    {
                        ProcessScanLine_FS(data, p1, p2, p1, p3, color, blin);
                    }
                    else
                    {
                        ProcessScanLine_FS(data, p2, p3, p1, p3, color, blin);
                    }
                }
            }
        }