public static void Test()
        {
            Vector3D a = new Vector3D(1, 2, 1,1);
            Vector3D b = new Vector3D(5, 6, 0,1);
            Vector3D c = new Vector3D(1, 2, 3, 1);

            float r1 = Vector3D.Dot(a,b);
            Vector3D r2 = a - b;
            Vector3D r3 = Vector3D.Cross(a,b);
            Console.WriteLine("a dot b:{0}", r1);
            Console.WriteLine("a - b:({0},{1},{2},{3})", r2.x, r2.y, r2.z, r2.w);
            Console.WriteLine("a X b:({0},{1},{2},{3})", r3.x, r3.y, r3.z, r3.w);
            //
            Matrix4x4 mat1 = new Matrix4x4(1,2,3,4,
                                            1,2,3,4,
                                            1,2,3,4,
                                            0,0,0,1);
            Matrix4x4 mat2 = new Matrix4x4(1, 2, 3, 4,
                                            1, 2, 3, 4,
                                            1, 2, 3, 4,
                                            1, 2, 3, 4);
            Matrix4x4 mat3 = new Matrix4x4();
            mat3.Identity();
            Matrix4x4 mat4 = new Matrix4x4(1, 0, 0, 0,
                                           0, 1, 0, 0,
                                           0, 0, 1, 0,
                                           1, 2, 3, 1);

            Matrix4x4 mat5 = new Matrix4x4(1, 2, 3, 4,
                                           4, 3, 2, 1,
                                           0, -1, 2, 0,
                                           1, 6, 4, -2);
            Console.WriteLine("mat5   Determinate:" + mat5.Determinate());
            Console.WriteLine("mat5   GetAdjoint:");
            showMat(mat5.GetAdjoint());

            Console.WriteLine("mat5   Inverse:" );
            showMat(mat5.Inverse());

            Console.WriteLine("mat5 *  mat5 Inverse:");
            showMat(mat5 * mat5.Inverse());

            Console.WriteLine("mat2   Transpose:");
            showMat(mat2.Transpose());

            Matrix4x4 matr1 = mat1 * mat3;
            Console.WriteLine("mat1 * mat3:");
            showMat(matr1);
            Matrix4x4 matr2 = mat1 * mat2;
            Console.WriteLine("mat1 * mat2:");
            showMat(matr2);
            Vector3D r4 = a * mat1;
            Console.WriteLine("a * mat1:({0},{1},{2},{3})", r4.x, r4.y, r4.z, r4.w);

            Vector3D r5 = a * mat4;
            Console.WriteLine("a * mat4:({0},{1},{2},{3})", r5.x, r5.y, r5.z, r5.w);
        }
 public static void showMat(Matrix4x4 mat)
 {
     if (isEnable)
     {
         for (int i = 0; i < 4; i++)
         {
             Console.WriteLine("[{0},{1},{2},{3}]", mat[i, 0], mat[i, 1], mat[i, 2], mat[i, 3]);
         }
     }
 }
 /// <summary>
 /// 矩阵乘法
 /// </summary>
 /// <param name="lhs"></param>
 /// <param name="rhs"></param>
 /// <returns></returns>
 public static Matrix4x4 operator *(Matrix4x4 lhs, Matrix4x4 rhs)
 {
     Matrix4x4 nm = new Matrix4x4();
     nm.SetZero();
     for (int i = 0; i < 4; i++)
     {
         for (int j = 0; j < 4; j++)
         {
             for (int k = 0; k < 4; k++)
             {
                 nm._m[i, j] += lhs._m[i,k] * rhs._m[k, j];
             }
         }
     }
     return nm;
 }
예제 #4
0
        /// <summary>
        /// 投影变换,从相机空间到齐次剪裁空间
        /// </summary>
        /// <param name="p"></param>
        /// <param name="vertex"></param>
        private void SetProjectionTransform(Matrix4x4 p,ref Vertex vertex)
        {
            vertex.point = vertex.point * p;
            //得到齐次裁剪空间的点 v.point.w 中保存着原来的z(具体是z还是-z要看使用的投影矩阵,我们使用投影矩阵是让w中保存着z)

                //onePerZ 保存1/z,方便之后对1/z关于x’、y’插值得到1/z’
            vertex.onePerZ = 1 / vertex.point.w;
                //校正的推论: s/z、t/z和x’、y’也是线性关系。而我们之前知道1/z和x’、y’是线性关系。则我们得出新的思路:对1/z关于x’、y’插值得到1/z’,然后对s/z、t/z关于x’、y’进行插值得到s’/z’、t’/z’,然后用s’/z’和t’/z’分别除以1/z’,就得到了插值s’和t’
                //这里将需要插值的信息都乘以1/z 得到 s/z和t/z等,方便光栅化阶段进行插值
            vertex.u *= vertex.onePerZ;
            vertex.v *= vertex.onePerZ;
                //
            vertex.vcolor *= vertex.onePerZ;
            //
            vertex.lightingColor *= vertex.onePerZ;
        }
예제 #5
0
 /// <summary>
 /// 进行mv矩阵变换,从本地模型空间到世界空间,再到相机空间
 /// </summary>
 private void SetMVTransform(Matrix4x4 m, Matrix4x4 v,ref Vertex vertex)
 {
     vertex.point = vertex.point * m * v;
 }
예제 #6
0
        /// <summary>
        /// 实现了“基础光照模型”,在世界空间进行顶点光照处理
        /// </summary>
        /// <param name="v"></param>
        private void Lighting(Matrix4x4 m, Vector3D worldEyePositon ,ref Vertex v)
        {
            Vector3D worldPoint = v.point * m;//世界空间顶点位置
            Vector3D normal = v.normal * m.Inverse().Transpose();//模型空间法线乘以世界矩阵的逆转置得到世界空间法线
            normal = normal.Normalize();
            SoftRenderer.RenderData.Color emissiveColor = _mesh.material.emissive;//自发光
            SoftRenderer.RenderData.Color ambientColor = _ambientColor * _mesh.material.ka;//环境光

            Vector3D inLightDir = (_light.worldPosition - worldPoint).Normalize();
            float diffuse = Vector3D.Dot(normal, inLightDir);
            if(diffuse < 0)
            {
                diffuse = 0;
            }
            SoftRenderer.RenderData.Color diffuseColor = _mesh.material.diffuse * diffuse * _light.lightColor;//漫反射
            //
            Vector3D inViewDir = (worldEyePositon - worldPoint).Normalize();
            Vector3D h = (inViewDir + inLightDir).Normalize();
            float specular = 0;
            if(diffuse != 0)
            {//防止出现光源在物体背面产生高光的情况
                specular = (float)System.Math.Pow(MathUntil.Range(Vector3D.Dot(h, normal), 0, 1), _mesh.material.shininess);
            }
            SoftRenderer.RenderData.Color specularColor = _mesh.material.specular * specular * _light.lightColor;//镜面高光
            //
            v.lightingColor = emissiveColor + ambientColor + diffuseColor + specularColor;
        }
예제 #7
0
        /// <summary>
        /// 绘制三角形
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="mvp"></param>
        private void DrawTriangle(Vertex p1, Vertex p2, Vertex p3, Matrix4x4 m, Matrix4x4 v, Matrix4x4 p)
        {
            //--------------------几何阶段---------------------------
            if (_lightMode == LightMode.On)
            {//进行顶点光照
                Lighting(m, _camera.pos, ref p1);
                Lighting(m, _camera.pos, ref p2);
                Lighting(m, _camera.pos, ref p3);
            }

            //变换到相机空间
            SetMVTransform(m, v,ref p1);
            SetMVTransform(m, v, ref p2);
            SetMVTransform(m, v, ref p3);

            //在相机空间进行背面消隐
            if (BackFaceCulling(p1, p2, p3) == false)
            {
                return;
            }

            //变换到齐次剪裁空间
            SetProjectionTransform(p, ref p1);
            SetProjectionTransform(p, ref p2);
            SetProjectionTransform(p, ref p3);

            //裁剪
            if (Clip(p1) == false || Clip(p2) == false || Clip(p3) == false)
            {
                return;
            }

            //变换到屏幕坐标
            TransformToScreen(ref p1);
            TransformToScreen(ref p2);
            TransformToScreen(ref p3);

            //--------------------光栅化阶段---------------------------

            if(_currentMode == RenderMode.Wireframe)
            {//线框模式
                BresenhamDrawLine(p1, p2);
                BresenhamDrawLine(p2, p3);
                BresenhamDrawLine(p3, p1);
            }
            else
            {
                TriangleRasterization(p1, p2, p3);
            }
        }
예제 #8
0
 private void Draw(Matrix4x4 m, Matrix4x4 v, Matrix4x4 p)
 {
     _showTrisCount = 0;
     for (int i = 0; i + 2 < _mesh.vertices.Length; i += 3)
     {
         DrawTriangle(_mesh.vertices[i], _mesh.vertices[i + 1], _mesh.vertices[i + 2], m, v, p);
     }
     Console.WriteLine("显示的三角形数:"+ _showTrisCount);
 }
        /// <summary>
        /// 获取当前矩阵的伴随矩阵
        /// </summary>
        /// <returns></returns>
        public Matrix4x4 GetAdjoint()
        {
            int x,y;
            float[,] tempM = new float[3,3];
            Matrix4x4 result = new Matrix4x4();
            for (int i = 0; i < 4; i++)
            {
                 for (int j = 0; j < 4; j++)
                    {
                        for (int k = 0; k < 3; k++)
                        {
                            for (int t = 0; t < 3; ++t)
                            {
                                x = k >= i ? k + 1 : k;
                                y = t >= j ? t + 1 : t;

                                tempM[k,t] = _m[x,y];
                            }
                        }
                        result._m[i, j] = (float)System.Math.Pow(-1, (1 + j) + (1 + i)) * Determinate(tempM, 3);
                    }
            }
            return result.Transpose();
        }