コード例 #1
0
        //从小到大输入
        private void RasterBottomTriangle(VertexOut v1, VertexOut v2, VertexOut v3, BaseShader shader)
        {
            VertexOut left   = v1;
            VertexOut right  = v2;
            VertexOut dest   = v3;
            float     weight = 0;
            VertexOut newLeft;
            VertexOut newRight;

            if (left.posProjective.x > right.posProjective.x)
            {
                VertexOut tmp = left;
                left  = right;
                right = tmp;
            }

            int dy = (int)dest.posProjective.y - (int)left.posProjective.y + 1;

            for (int i = 0; i < dy; i++)
            {
                if (dy != 0)
                {
                    weight = (float)i / dy;
                }
                newLeft  = LerpVertexOut(left, dest, weight);
                newRight = LerpVertexOut(right, dest, weight);
                newLeft.posProjective.y  = left.posProjective.y + i;
                newRight.posProjective.y = left.posProjective.y + i;
                ScanLinePerRow(newLeft, newRight, shader);
            }
        }
コード例 #2
0
        public void ProjectedMapRestore(VertexOut vertexOut)
        {
            float w = 1.0f / vertexOut.oneDivZ;

            vertexOut.posWorld.MultiplyNum(w);
            vertexOut.texcoord.MultiplyNum(w);
            vertexOut.color.MultiplyNum(w);
        }
コード例 #3
0
 //处理透视纹理映射
 public void ProjectedMap(VertexOut vertexOut)
 {
     //处理透视纹理映射
     vertexOut.oneDivZ = 1.0f / vertexOut.posProjective.w;
     vertexOut.posWorld.MultiplyNum(vertexOut.oneDivZ);
     vertexOut.texcoord.MultiplyNum(vertexOut.oneDivZ);
     vertexOut.color.MultiplyNum(vertexOut.oneDivZ);
 }
コード例 #4
0
 private void PerspectiveDivision(VertexOut vertexOut)
 {
     vertexOut.posProjective.x /= vertexOut.posProjective.w;
     vertexOut.posProjective.y /= vertexOut.posProjective.w;
     vertexOut.posProjective.z /= vertexOut.posProjective.w;
     vertexOut.posProjective.w  = 1;
     //[-1,1] to [0,1]
     vertexOut.posProjective.z = (vertexOut.posProjective.z + 1.0f) * 0.5f;
 }
コード例 #5
0
        //Bresenham画线法 用整数加减法代替浮点数加减法
        private void BresenhamLineRasterization(VertexOut from, VertexOut to)
        {
            int x = (int)from.posProjective.x;
            int y = (int)from.posProjective.y;

            int toX = (int)to.posProjective.x;
            int toY = (int)to.posProjective.y;

            int deltax = toX - x;
            int deltay = toY - y;

            int stepx = 1;
            int stepy = 1;

            if (deltax < 0)
            {
                stepx = -1;
            }
            if (deltay < 0)
            {
                stepy = -1;
            }

            int eps = 0;//误差累计

            deltax = Mathf.Abs(deltax);
            deltay = Mathf.Abs(deltay);

            if (deltax > deltay)
            {
                for (; x != toX; x += stepx)
                {
                    eps += deltay;
                    if ((eps << 1) >= deltax)
                    {
                        y   += stepy;
                        eps -= deltax;
                    }
                    backBuffer.DrawPixel(x, y, Color.White());
                }
            }
            else
            {
                for (; y != toY; y += stepy)
                {
                    eps += deltax;
                    if ((eps << 1) >= deltay)
                    {
                        x   += stepx;
                        eps -= deltay;
                    }
                    backBuffer.DrawPixel(x, y, Color.White());
                }
            }
        }
コード例 #6
0
        private VertexOut LerpVertexOut(VertexOut v1, VertexOut v2, float weight)
        {
            VertexOut vertexOut = new VertexOut();

            vertexOut.posProjective = Vector4D.Lerp(v1.posProjective, v2.posProjective, weight);
            vertexOut.posWorld      = Vector4D.Lerp(v1.posWorld, v2.posWorld, weight);
            vertexOut.color         = Color.Lefp(v1.color, v2.color, weight);
            vertexOut.normal        = Vector3D.Lerp(v1.normal, v2.normal, weight);
            vertexOut.texcoord      = Vector2D.Lerp(v1.texcoord, v2.texcoord, weight);
            vertexOut.oneDivZ       = (1 - weight) * v1.oneDivZ + weight * v2.oneDivZ;
            return(vertexOut);
        }
コード例 #7
0
        private void EdgeWalkingFillRasterization(VertexOut v1, VertexOut v2, VertexOut v3, BaseShader shader)
        {
            //先把三个点按y从小到大排序
            VertexOut[] targets = { v1, v2, v3 };
            VertexOut   tmp;

            if (targets[0].posProjective.y > targets[1].posProjective.y)
            {
                tmp        = targets[0];
                targets[0] = targets[1];
                targets[1] = tmp;
            }
            if (targets[0].posProjective.y > targets[2].posProjective.y)
            {
                tmp        = targets[0];
                targets[0] = targets[2];
                targets[2] = tmp;
            }
            if (targets[1].posProjective.y > targets[2].posProjective.y)
            {
                tmp        = targets[1];
                targets[1] = targets[2];
                targets[2] = tmp;
            }

            if ((int)targets[0].posProjective.y == (int)targets[1].posProjective.y)
            {
                //下三角形
                RasterBottomTriangle(targets[0], targets[1], targets[2], shader);
            }
            else if ((int)targets[1].posProjective.y == (int)targets[2].posProjective.y)
            {
                //上三角形
                RasterTopTriangle(targets[0], targets[1], targets[2], shader);
            }
            else
            {
                //需要分割为上三角形下三角形
                float weight = (targets[1].posProjective.y - targets[0].posProjective.y)
                               / (targets[2].posProjective.y - targets[0].posProjective.y);

                VertexOut vertexOutNew = LerpVertexOut(targets[0], targets[2], weight);
                vertexOutNew.posProjective.y = targets[1].posProjective.y;

                RasterTopTriangle(targets[0], vertexOutNew, targets[1], shader);
                RasterBottomTriangle(vertexOutNew, targets[1], targets[2], shader);
            }
        }
コード例 #8
0
        public override VertexOut VertexShader(Vertex vertexIn)
        {
            VertexOut vertexOut = new VertexOut();

            vertexOut.posWorld      = Matrix4x4.MultiplyVector4D(modelMatrix, vertexIn.position);
            vertexOut.posProjective = Matrix4x4.MultiplyVector4D(viewMatrix, vertexOut.posWorld);
            vertexOut.posProjective = Matrix4x4.MultiplyVector4D(projectedMatrix, vertexOut.posProjective);

            vertexOut.color  = vertexIn.color.Copy();
            vertexOut.normal = vertexIn.normal.Copy();

            vertexOut.normal   = Matrix4x4.MultiplyVector4D(modelMatrixInverse, vertexOut.normal.ToVector4D()).ToVector3D();
            vertexOut.texcoord = vertexIn.texcoord.Copy();

            //vertexOut.oneDivZ = 1.0f / vertexOut.posProjective.w;
            //vertexOut.posWorld.MultiplyNum(vertexOut.oneDivZ);
            //vertexOut.texcoord.MultiplyNum(vertexOut.oneDivZ);
            //vertexOut.color.MultiplyNum(vertexOut.oneDivZ);

            return(vertexOut);
        }
コード例 #9
0
        public override Color FragmentShader(VertexOut vertexIn)
        {
            Color color = texture.Sample(vertexIn.texcoord.x, vertexIn.texcoord.y);

            //Color color = Color.Red();
            if (light != null)
            {
                if (light.GetType() == typeof(DirectionalLight))
                {
                    color = color * ((DirectionalLight)light).Lighting(
                        ambientColor,
                        diffuseColor,
                        specularColor,
                        vertexIn.posWorld.ToVector3D(),
                        vertexIn.normal,
                        Vector3D.Minus(eyePos, vertexIn.posWorld));
                    color.a = 1;
                }
            }
            //return vertexIn.color;
            return(color);
        }
コード例 #10
0
        //按列逐行扫描
        private void ScanLinePerRow(VertexOut left, VertexOut right, BaseShader shader)
        {
            VertexOut current;
            int       length = (int)right.posProjective.x - (int)left.posProjective.x;

            if (length == 0)
            {
                return;
            }
            for (int i = 0; i <= length; i++)
            {
                float weight = (float)i / length;
                current = LerpVertexOut(left, right, weight);

                if (shader.ZTest == true)
                {
                    if (current.posProjective.z >= 0.5f &&
                        current.posProjective.z > backBuffer.GetDepth((int)current.posProjective.x, (int)current.posProjective.y))
                    {
                        continue;
                    }
                }

                if (shader.ZWrite == true)
                {
                    backBuffer.DrawDepth((int)current.posProjective.x, (int)current.posProjective.y, current.posProjective.z);
                }

                current.posProjective.x = left.posProjective.x + i;
                current.posProjective.y = left.posProjective.y;

                //透视纹理处理
                shader.ProjectedMapRestore(current);

                //片段着色
                backBuffer.DrawPixel((int)current.posProjective.x, (int)current.posProjective.y, shader.FragmentShader(current));
            }
        }
コード例 #11
0
 public virtual Color FragmentShader(VertexOut vertexIn)
 {
     return(null);
 }