コード例 #1
0
ファイル: Device.cs プロジェクト: YESshowMeCode/MySoftRender
        /// <summary>
        /// 画一个点
        /// </summary>
        /// <param name="point"></param>
        /// <param name="c"></param>
        public void DrawPoint(Vector4 point, Color3 c)
        {
            if (point.X >= 0 && point.Y >= 0 && point.X <= Width && point.Y <= Height)
            {
                if (point.X == Width)
                {
                    point.X = point.X - 1;
                }
                if (point.Y == Height)
                {
                    point.Y = point.Y - 1;
                }

                Putpixel((int)point.X, (int)point.Y, point.Z, c);
            }
        }
コード例 #2
0
ファイル: Device.cs プロジェクト: YESshowMeCode/MySoftRender
        /// <summary>
        /// 绘画某个位置的像素
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="color"></param>
        public void Putpixel(int x, int y, float z, Color3 color)
        {
            int index = (x + y * Width);

            if (m_DepthBuffer[index] < z)
            {
                return;
            }

            m_DepthBuffer[index] = z;
            unsafe
            {
                byte *ptr = (byte *)(this.m_BmData.Scan0);
                byte *row = ptr + (y * this.m_BmData.Stride);
                row[x * 3]     = color.B;
                row[x * 3 + 1] = color.G;
                row[x * 3 + 2] = color.R;
            }
        }
コード例 #3
0
ファイル: Mesh.cs プロジェクト: YESshowMeCode/MySoftRender
        /// <summary>
        /// 实现了“基础光照模型”,在世界空间进行顶点光照处理
        /// </summary>
        /// <param name="position"></param>
        /// <param name="normal"></param>
        /// <param name="light"></param>
        /// <returns></returns>
        public Color3 GetLightColor(Vector4 position, Vector4 normal, Light light, Vector4 cameraPosition)
        {
            // 环境光
            Color3 ambient = light.Color * m_Material.AmbientStregth;
            //自发光
            Color3 emissive = m_Material.Emssive;
            // 漫反射
            Vector4 nor      = normal * m_Transform;
            Vector4 lightdir = (light.Position - position).Normalize();
            float   diff     = Math.Max(Vector4.Dot(normal.Normalize(), lightdir), 0);
            Color3  diffuse  = m_Material.Diffuse * diff;

            Vector4 viewDir  = (cameraPosition - position).Normalize();
            Vector4 h        = (viewDir + lightdir).Normalize();
            float   specular = (float)System.Math.Pow(Clamp(Vector4.Dot(h, normal)), m_Material.Shininess);

            Color3 specularColor = m_Material.Specular * specular * light.Color;//镜面高光

            return(ambient + diffuse + specularColor + emissive);
        }
コード例 #4
0
ファイル: Device.cs プロジェクト: YESshowMeCode/MySoftRender
        /// <summary>
        /// 画一条直线
        /// </summary>
        /// <param name="point0"></param>
        /// <param name="point1"></param>
        /// <param name="scene"></param>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        public void DrawLine(Vector4 point0, Vector4 point1, Scene scene, Vertex v1, Vertex v2)
        {
            int x0 = (int)point0.X;
            int y0 = (int)point0.Y;
            int x1 = (int)point1.X;
            int y1 = (int)point1.Y;

            int dx    = x1 - x0;
            int dy    = y1 - y0;
            int steps = Math.Max(Math.Abs(dx), Math.Abs(dy));

            if (steps == 0)
            {
                return;
            }

            float offsetX = (float)dx / (float)steps;
            float offsetY = (float)dy / (float)steps;

            float x = x0;
            float y = y0;

            Color3 vColor = new Color3(128, 128, 128);

            for (int i = 1; i <= steps; i++)
            {
                float dt = (float)(i) / (float)steps;
                vColor = MathUntily.Lerp(v1.Color, v2.Color, dt);
                float z = MathUntily.Lerp(point0.Z, point1.Z, dt);
                if (float.IsNaN(z))
                {
                    return;
                }

                DrawPoint(new Vector4((int)x, (int)y, z, 0), vColor);
                x += offsetX;
                y += offsetY;
            }
        }
コード例 #5
0
ファイル: Clip.cs プロジェクト: YESshowMeCode/MySoftRender
        /// <summary>
        /// 求交点, 返回的pos是裁剪空间下坐标
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <param name="face"></param>
        /// <param name="wMin"></param>
        /// <param name="wMax"></param>
        /// <returns></returns>
        Vertex Intersect(Vertex v1, Vertex v2, FaceTypes face, Vector4 wMin, Vector4 wMax)
        {
            Vertex  vertex = new Vertex();
            float   k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0, k6 = 0;
            Vector4 p1 = v1.ClipPosition;
            Vector4 p2 = v2.ClipPosition;

            if (p1.X != p2.X)
            {
                k1 = (wMin.X - p1.X) / (p2.X - p1.X); k2 = (wMax.X - p1.X) / (p2.X - p1.X);
            }
            else
            {
                k1 = k2 = 1;
            }
            if (p1.Y != p2.Y)
            {
                k3 = (wMin.Y - p1.Y) / (p2.Y - p1.Y); k4 = (wMax.Y - p1.Y) / (p2.Y - p1.Y);
            }
            else
            {
                k3 = k4 = 1;
            }
            if (p1.Z != p2.Z)
            {
                k5 = (wMin.Z - p1.Z) / (p2.Z - p1.Z); k6 = (wMax.Z - p1.Z) / (p2.Z - p1.Z);
            }
            else
            {
                k5 = k6 = 1;
            }

            Vector4 clipPos = new Vector4();
            Vector4 pos     = new Vector4();
            Color3  col     = new Color3(0, 0, 0);
            Vector4 normal  = new Vector4();
            Vector2 uv      = new Vector2();

            switch (face)
            {
            case FaceTypes.LEFT:
                clipPos.X = wMin.X;
                clipPos.Y = p1.Y + (p2.Y - p1.Y) * k1;
                clipPos.Z = p1.Z + (p2.Z - p1.Z) * k1;
                clipPos.W = p1.W + (p2.W - p1.W) * k1;
                col       = MathUntily.Lerp(v1.Color, v2.Color, k1);
                normal    = MathUntily.Lerp(v1.Normal, v2.Normal, k1);
                pos       = MathUntily.Lerp(v1.Position, v2.Position, k1);
                uv        = MathUntily.Lerp(v1.UV, v2.UV, k1);
                break;

            case FaceTypes.RIGHT:
                clipPos.X = wMax.X;
                clipPos.Y = p1.Y + (p2.Y - p1.Y) * k2;
                clipPos.Z = p1.Z + (p2.Z - p1.Z) * k2;
                clipPos.W = p1.W + (p2.W - p1.W) * k2;
                col       = MathUntily.Lerp(v1.Color, v2.Color, k2);
                normal    = MathUntily.Lerp(v1.Normal, v2.Normal, k2);
                pos       = MathUntily.Lerp(v1.Position, v2.Position, k2);
                uv        = MathUntily.Lerp(v1.UV, v2.UV, k2);
                break;

            case FaceTypes.BUTTOM:
                clipPos.Y = wMin.Y;
                clipPos.X = p1.X + (p2.X - p1.X) * k3;
                clipPos.Z = p1.Z + (p2.Z - p1.Z) * k3;
                clipPos.W = p1.W + (p2.W - p1.W) * k3;
                col       = MathUntily.Lerp(v1.Color, v2.Color, k3);
                normal    = MathUntily.Lerp(v1.Normal, v2.Normal, k3);
                pos       = MathUntily.Lerp(v1.Position, v2.Position, k3);
                uv        = MathUntily.Lerp(v1.UV, v2.UV, k3);
                break;

            case FaceTypes.TOP:
                clipPos.Y = wMax.Y;
                clipPos.X = p1.X + (p2.X - p1.X) * k4;
                clipPos.Z = p1.Z + (p2.Z - p1.Z) * k4;
                clipPos.W = p1.W + (p2.W - p1.W) * k4;
                col       = MathUntily.Lerp(v1.Color, v2.Color, k4);
                normal    = MathUntily.Lerp(v1.Normal, v2.Normal, k4);
                pos       = MathUntily.Lerp(v1.Position, v2.Position, k4);
                uv        = MathUntily.Lerp(v1.UV, v2.UV, k4);
                break;

            case FaceTypes.NEAR:
                clipPos.Z = wMin.Z;
                clipPos.X = p1.X + (p2.X - p1.X) * k5;
                clipPos.Y = p1.Y + (p2.Y - p1.Y) * k5;
                clipPos.W = p1.W + (p2.W - p1.W) * k5;
                col       = MathUntily.Lerp(v1.Color, v2.Color, k5);
                normal    = MathUntily.Lerp(v1.Normal, v2.Normal, k5);
                pos       = MathUntily.Lerp(v1.Position, v2.Position, k5);
                uv        = MathUntily.Lerp(v1.UV, v2.UV, k5);
                break;

            case FaceTypes.FAR:
                clipPos.Z = wMax.Z;
                clipPos.X = p1.X + (p2.X - p1.X) * k6;
                clipPos.Y = p1.Y + (p2.Y - p1.Y) * k6;
                clipPos.W = p1.W + (p2.W - p1.W) * k6;
                col       = MathUntily.Lerp(v1.Color, v2.Color, k6);
                normal    = MathUntily.Lerp(v1.Normal, v2.Normal, k6);
                pos       = MathUntily.Lerp(v1.Position, v2.Position, k6);
                uv        = MathUntily.Lerp(v1.UV, v2.UV, k6);
                break;
            }

            vertex.Position       = pos;
            vertex.ClipPosition   = clipPos;
            vertex.ScreenPosition = this.m_Device.ViewPort(clipPos);
            vertex.Normal         = normal;
            vertex.UV             = uv;
            vertex.Color          = col;
            return(vertex);
        }