Exemplo n.º 1
0
        public static Vertex2D BuildVertex2D(Vertex vertex, Matrix4 transMat, Vector3 cameraPos, List <IPosLight> lights, int w, int h)
        {
            Vertex2D   result = default(Vertex2D);
            SoftDevice device = SoftDevice.Default;

            if (null == device)
            {
                return(result);
            }
            // 将3d坐标投影到2d空间;
            result = ProjectToScreen(vertex.position, transMat, (float)w, (float)h);
            // 顶点光照;
            LightUtil.ApplyVertexLightings(lights, cameraPos, vertex.worldPosition, vertex.worldNormal, ref result);
            // 填充顶点信息;
            result.FillRenderData(vertex.uv0, vertex.color, device.PerspectiveCorrection);
            return(result);
        }
Exemplo n.º 2
0
        private static void _PixelPragma(Texture tex, int y,
                                         Vertex2D pa, Vertex2D pb, Vertex2D pc, Vertex2D pd, AddPixelHandler handler)
        {
            // 计算y位置上横向扫描线的起始和结束;
            SoftDevice device = SoftDevice.Default;

            if (null == device)
            {
                return;
            }
            HorizonScanLine scanLine = default(HorizonScanLine);

            if (!HorizonScanLine.InterpolateWithVertex2D(y, pa, pb, pc, pd, LightUtil.enableLightings, ref scanLine))
            {
                return;
            }
            int leftX  = scanLine.left;
            int rightX = scanLine.right;

            // 有可能出现pb.x > pd.x的情况,这里做下容错;
            if (leftX > rightX)
            {
                scanLine.SwapLeftRight();
            }
            // 开始横向扫描生成像素点;
            bool    usePerZ      = device.PerspectiveCorrection;
            float   invxLength   = scanLine.InvLength;
            Vector2 uv           = Vector2.zero;
            Color   surfaceColor = Color.Zero;

            for (var x = leftX; x < rightX; x++)
            {
                float gradient = (float)(x - leftX) * invxLength;
                if (gradient < 0)
                {
                    gradient = 0;
                }
                else if (gradient > 1)
                {
                    gradient = 1;
                }
                float z = scanLine.leftZ + (scanLine.rightZ - scanLine.leftZ) * gradient;
                // 提前做ztest;
                if (!device.ZTest(x, y, z))
                {
                    continue;
                }
                float invZ = 0f;
                if (z <= MathUtil.Epsilon && z >= -MathUtil.Epsilon)
                {
                    invZ = 1f;
                }
                else
                {
                    invZ = 1f / z;
                }
                // 纹理映射;
                if (MaterialManager.enableTextures)
                {
                    if (null != tex)
                    {
                        uv = scanLine.leftUV + (scanLine.rightUV - scanLine.leftUV) * gradient;
                        // 这里使用透视修正后,离的足够近也会出问题;
                        if (usePerZ)
                        {
                            surfaceColor = tex.GetColor(uv.x * invZ, uv.y * invZ);
                        }
                        else
                        {
                            surfaceColor = tex.GetColor(uv.x, uv.y);
                        }
                    }
                }
                else
                {
                    surfaceColor = scanLine.leftColor + (scanLine.rightColor - scanLine.leftColor) * gradient;
                }
                if (LightUtil.enableLightings)
                {
                    Color diffuse = MathUtil.Interpolate(scanLine.leftDiffuse, scanLine.rightDiffuse, gradient);
                    if (usePerZ)
                    {
                        diffuse *= invZ;
                    }
                    surfaceColor = Color.Multiply(surfaceColor, diffuse);
                }
                if (null != handler)
                {
                    handler(x, y, z, surfaceColor);
                }
            }
        }