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); }
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); } } }