skia的学习与研究

news2025/3/4 22:48:09

最近再研究skia,特地发一篇文章来记录一下。Skia版本更新非常频繁,大概每四周就会创建一个新版本,此版本持续维护六周左右就会被标记为稳定分支
在这里插入图片描述

skia三套渲染:

  1. 无gpu硬件如嵌入式设备,使用CPU渲染,使用软光栅化(soft rasterizer)来处理图形渲染;
  2. 无gpu硬件但在win下,CPU渲染使用Win的Warp; Windows 高级光栅化平台 (WARP) 指南
  3. 有gpu硬件(独立显卡&集成显卡)使用GPU绘制;

文档链接:

官方文档:User Documentation | Skia
API文档: skia api
win下skia编译: Windows环境编译skia库_skia 编译-CSDN博客
skia图形后端:主要是依靠google自家开源的图形后端angle 来实现,现在angle主要是ANGLE 目前提供从 OpenGL ES 2.0、3.0 到
在这里插入图片描述

调试工具Fiddle:

Skia Fiddle 的工具,这是一个专门用于测试和演示 Skia 代码片段的 Web 工具。Skia Fiddle 允许开发者在浏览器中编写和运行 Skia 代码,查看绘图结果,并分享代码片段。 Skia Fiddle
fiddle 有案例教程named: Skia Fiddle

skia模块:

web端: 作为 Skia 的核心绘制接口,它提供了一系列绘制图形的方法,如绘制点、线、矩形、圆形、文本等。Skia 现在提供了一个 WebAssembly 构建版本, CanvasKit , 将 WebGL 上下文封装为一个 SkSurface;
SkCanvas:在 Android 开发中,自定义 View 时常常会使用 SkCanvas 来实现特定的图形绘制效果。
path:在图形绘制和处理中path在skia扮演着至关重要的角色。Path 允许你定义各种复杂的 2D 形状和轮廓,是实现高级图形效果和自定义绘图的基础,简单的几何形状,如直线、矩形、圆形、椭圆等;
SkPaint与SkPath区别:SkPaint 负责绘制属性和效果 ,绘制的颜色、透明度和绘制样式,SkPath 负责图形的形状和轮廓, 绘制的图形的轮廓,包括直线、曲线、矩形、圆形、椭圆等几何形状及其组合;
SkBitmap与skimage的区别:SkBitmap是光栅位图,包含实际的像素数据比如RGBA8888/RGB888/RGB565。它主要用于管理和操作位图数据,包括读取、写入和修改像素。SkImage 是一个只读操作,主要用于如图像显示渲染、纹理缓存。

关于Skia做三维:

首先skia是二维渲染引擎,里面根本就没有三维的概念!有的人问是否可以把它改造成也支持三维,但是最好不要这样做。不然工作量会非常大非常多。

  1. 先不说顶点着色器、曲面细分着色器、几何着色器、计算着色器(skia目标主要是二维,甚至还有软光栅,他的目标就是只支持二维的通用语跨平台跟三维的目标有差距外);
  2. skia没有材质系统/光照系统/camera,要自己实现一套材质系统/光照系统难度比较大工作量也很大,比如实现PBR的材质/光照/camera就很难。
  3. 3D资源模型的解析也无,对应的3D资源管理也没,3D的场景图或场景管理也没有;
  4. pipline也无,粒子系统、骨骼动画、物理系统、全部都没有只有;
    所以综上所述skia就是提供最基础的渲染跟直接裸写opengl的没区别,它就不适合3D

源码剖析:

深入理解Flutter的图形图像绘制原理——图形库skia剖析
内存管理: SkBudgeted

  • 当使用 SkBudgeted::kYes 时,Skia 会尝试在其内部的内存预算范围内进行操作,这意味着 Skia 会对创建和使用的资源(如图像、纹理、缓存等)进行管理,避免过度分配内存。
  • 避免内存溢出:在一些资源受限的环境中,如移动设备或嵌入式系统,内存是非常宝贵的资源。通过设置 SkBudgeted::kYes,Skia 可以根据预先设定的内存预算来决定是否创建新的资源,或者在必要时释放一些不再使用的资源,从而避免因内存使用过多导致的系统崩溃或性能下降。
  • Skia 会定期检查和清理不再使用的资源,以释放内存空间。当设置为 SkBudgeted::kYes 时,这种资源回收机制会更加积极主动。例如,对于一些已经不再需要的纹理或缓存,Skia 会及时将其释放,以确保内存使用保持在预算范围内

skia渲染属性一、

skia的坐标系:
Skia Coordinate Spaces | Skia
device与local坐标系: device与local坐标系从左上角的(0, 0)到右下角的(w, h)的范围, 默认情况下,本地和设备坐标系相同;片源着色器的坐标是local坐标。
修改local坐标系是直接使用canvas->translate/scale等;
修改着色器的坐标比如: SkGradientShader::MakeLinear函数的localMatrix;

色彩空间:
skia : Skia Color Management | Skia
以D50 XYZ颜色空间为中间者、在任意两个颜色空间之间做转换,
在这里插入图片描述

alpha预乘:
在 Skia 管线里,每个 SkShader 都会返回预乘Alpha的颜色,如果从一个非预乘的SkImage(例如常见的 PNG 格式图像)开始,将其转换为SkImageShader并进行求值,得到的颜色值是经过预乘处理的,即[RA, GA, B*A, A] ,而不是原本未预乘的[R, G, B, A];

线性与非线性颜色空间转换:
toLinearSrgb 和 fromLinearSrgb 函数用于在 sRGB 和线性 sRGB 颜色空间之间进行转换;

// sRGB 颜色空间转换为线性 RGB 采用分段函数,分为线性和非线性两部分
// 当 sRGB 颜色值较小时(小于等于 0.04045),采用线性转换公式 C_linear = C_srgb / 12.92
// 当 sRGB 颜色值较大时(大于 0.04045),采用非线性转换公式 C_linear = ((C_srgb + 0.055) / (1 + 0.055)) ^ 2.4
// 其中 0.04045 是线性和非线性转换的分界点
// 12.92 是通过计算 (1 + 0.055) / (0.04045 ^ (1 / 2.4)) 得到,保证线性和非线性转换在分界点处连续
// 0.055 是 sRGB 非线性转换公式中的偏移常量
// 2.4 是 sRGB 非线性转换公式中的伽马值
vec3 toLinearSrgb(vec3 srgb) {
    const float a = 0.055;  // sRGB 非线性转换公式中的偏移常量
    return mix(
        srgb / 12.92,  // 线性转换部分
        pow((srgb + a) / (1.0 + a), vec3(2.4)),  // 非线性转换部分
        step(0.04045, srgb)  // 根据 srgb 值是否大于 0.04045 选择线性或非线性转换
    );
}


// 将线性 RGB 颜色转换为 sRGB 颜色
// 从线性 RGB 转换回 sRGB 同样采用分段函数
// 当线性 RGB 颜色值较小时(小于等于 0.0031308),采用线性转换公式 C_srgb = C_linear * 12.92
// 当线性 RGB 颜色值较大时(大于 0.0031308),采用非线性转换公式 C_srgb = (1 + 0.055) * (C_linear ^ (1 / 2.4)) - 0.055
// 0.0031308 是线性和非线性转换的分界点,通过将线性和非线性转换公式在分界点处相等计算得到
// 12.92、0.055 和 2.4 的含义与 toLinearSrgb 函数中相同
vec3 fromLinearSrgb(vec3 linear) {
    const float a = 0.055;  // sRGB 非线性转换公式中的偏移常量
    return mix(
        linear * 12.92,  // 线性转换部分
        (1.0 + a) * pow(linear, vec3(1.0 / 2.4)) - a,  // 非线性转换部分
        step(0.0031308, linear)  // 根据 linear 值是否大于 0.0031308 选择线性或非线性转换
    );
}

blender混合:
SkPaint Overview | Skia Skia 使用默认的 SkBlendMode::kSrcOver`进行混合;跟opengl的混合模式一样 混合 - LearnOpenGL CN

skia的shader-SKSL

sksl资料:
SKSL教程
验证sksl
sksl debug

sksl简介:
skia的shader使用的是sksl,sksl是skia自定义的shader语法,底层由angle实现图形后端RHI;SKSL只开放了片源着色器!sksl与glsl很类似但是特别要住于他俩的区别, 由于:使用GLSL语言,您正在编程GPU管线的阶段。使用SKSL,您正在编程SKIA这个2D图形引擎的管道的阶段(引擎图形后端封装一层)。

SkSL 效果是 Skia 管道的一部分。当你发出画布绘图操作指令时,Skia(通常)会组装一个单一的 GPU 片段着色器来完成所有必要的工作。这个色器通常包括几个部分。例如,它可能包括:

  • 评估一个像素是否在被绘制的形状内部或外部(或者在边界上,在这种情况下可能会应用抗锯齿)。
  • 评估一个像素是否在剪裁区域的内部或外部(同样,对于边界像素可能会有抗锯齿逻辑)。
  • SkPaint 上的 SkShader 的逻辑。SkShader 实际上可以是一个对象树(由于 SkShaders::Blend 和下面描述的其他特性)。
  • 类似的 SkColorFilter 逻辑(它也可以是一个树结构,由于 SkColorFilters::Compose、SkColorFilters::Blend 和下面描述的特性)。
  • 混合代码(对于某些 SkBlendModes,或者通过 SkPaint::setBlender 指定的自定义混合)。
  • 颜色空间转换代码,作为 Skia 颜色管理的一部分。

即使 SkPaint 在 SkShader、SkColorFilter 或 SkBlender 字段中有一个复杂的对象树,仍然只有一个 GPU 片源着色器。该树中的每个节点都会创建一个函数。剪裁代码和几何代码各自创建一个函数。混合代码可能会创建一个函数。总体片段着色器然后调用所有这些函数(这些函数可能会调用其他函数,例如在 SkShader 树的情况下)。(号称很优化的HSR技术、函数复用、内联函数、预计算或缓存 减少overdraw但是我感觉有点吹过头了吧,不过除非二维的比较什么…)

清空:
SkCanvas 的 canvas->clear(SK_ColorGRAY);作用清除画布:clear 方法会清除画布上的所有内容。填充颜色:clear 方法会用指定的颜色填充整个画布。跟 glClear(GL_COLOR_BUFFER_BIT)类似!

原始图像着色器:
在SkImage::makeRawShader 采样计算是属于线性空间如果后续需要绘制到屏幕上需要伽马矫正或需要进行颜色空间的变换的。所以makeRawShader主要是用于对存储法线、粗糙度、oa、高度图或恰好存储在图像中的任何其他纯数学数据的图像。它的工作方式与常规图像着色器(包括过滤和平铺)类似,但有一些主要区别:

  • 不应用色彩空间转换(忽略图像的色彩空间)。
  • alpha 类型为 kUnpremul 的图像不会自动预乘。
  • 不支持双三次滤波(Bicubic filtering)调用makeRawShader时请求双三次过滤将返回nullptr 。

sksl renderTaget(FBO)
sksl 采样二维纹理SkSL_EvaluatingImageShader
sksl调用另一个render pass,动态组合着色器片段
sksl坐标系:
在这里插入图片描述

参考资料:

漫谈史上最强Skia 2D渲染引擎(少谈优点,多谈缺点)
深入理解Flutter的图形图像绘制原理——图形库skia剖析
[总结] 漫谈HDR和色彩管理(二)颜色空间 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2309695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络编程 day01

网络编程 day01 0. 网络编程课程介绍1. 认识网络1.网络发展史2.局域网与广域网局域网(LAN)广域网(Wan) 3.光猫4.路由器5.交换机与路由器6.网线 2. IP1. 基本概念2. 网络号/主机号(二级划分)3. IP地址分类整…

vscode通过ssh远程连接(linux系统)不能跳转问题

1.问题描述 unbantu中的vscode能够通过函数跳转到函数定义,而windows通过ssh连接unbantu的vscode却无法跳转 2.原因: 主要原因是这里缺少插件,这里是unbantu给主机的服务器,与ubantu本地vscode插件相互独立,能否跳转…

unity pico开发 五 UI交互

文章目录 添加画布添加交互组件取消传送射线对UI的控制解决按扳机键会传送的冲突按下按键呼出菜单,并让菜单出现在头的前方 添加画布 创建一个新画布,添加一个Button,将画布改为world space,然后缩放改为0.001,调整到…

软开经验总结

文章目录 软开经验总结一、二次开发时候操作步骤二、logger的作用!!!三、git使用 软开经验总结 一、二次开发时候操作步骤 改 SDK 和 language level改 maven 配置改数据库 注意Mysql 版本 差别是否过大!!&#xff0…

QT 中的元对象系统(三):QObject深入理解

目录 1.简介 2.特性 2.1.对象树与内存管理 2.2.信号与槽机制 2.3.事件处理 2.4.属性系统 2.4.1.Q_PROPERTY配置的属性 2.4.2.动态属性 2.4.3.实现原理 2.5.国际化支持 2.6. 定时器支持 3.类设计(q和d指针) 4.总结 1.简介 QObject这个 class 是 QT 对象模型的核心&…

二、QT和驱动模块实现智能家居-----问题汇总1

1、文件地址改变后必须在QT下更改地址 2、指定了QT内Kits下的Sysroot头文件地址,但是还是找不到头文件: 3、提示无法执行QT程序:先干掉之前的QT程序 ps //查看程序PIDkill -9 PID 4、无法执行QT程序 1)未设置环境变量 …

Golang的数据库分库分表

# Golang的数据库分库分表 什么是数据库分库分表 数据库分库分表是指将单一的数据库拆分成多个库,每个库中包含多张表,以提高数据库的性能和可伸缩性。通常在大型应用中,单一的数据库往往无法满足高并发和海量数据的需求,因此需要…

NModbus 连接到Modbus服务器(Modbus TCP)

1、在项目中通过NuGet添加NModbus,在界面中添加一个Button。 using NModbus.Device; using NModbus; using System.Net.Sockets; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Docu…

基于vue3和flask开发的前后端管理系统(一):项目启动准备

准备工作 我们需要准备以下工具 vue3:构建前端 tailwind css:样式库vite:快速构建vue项目pinia :vue3 的事件管理器 flask:后端代码Mysql:数据库 heidisql:数据库图形化界面 vscode&#xff1…

单例模式(线程案例)

单例模式可以分为两种:1.饿汉模式 2.懒汉模式 一.饿汉模式 //饿汉模式👇 class MySingleTon{//因为这是一个静态成员变量,在类加载的时候,就创建了private static MySingleTon mySingleTon new MySingleTon();//创建一个静…

通过多线程分别获取高分辨率和低分辨率的H264码流

目录 一.RV1126 VI采集摄像头数据并同时获取高分辨率码流和低分辨率码流流程 ​编辑 1.1初始化VI模块: 1.2初始化RGA模块: 1.3初始化高分辨率VENC编码器、 低分辨率VENC编码器: 1.4 VI绑定高分辨率VENC编码器,VI绑定RGA模块…

智慧农业中光谱相机对土壤成分的无损检测应用‌

可浏览之前发布的一篇文章:光谱相机在农业中的具体应用案例 一、土壤成分定量分析 ‌养分检测‌ 光谱相机通过捕捉土壤反射的特定波长光线,可精准检测氮、磷、钾等主要养分含量,以及有机质和水分比例。例如,不同养分对近红外波段…

DNS 详细过程 与 ICMP

🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 DNS (Domain Name System) 快速了解🦋 DNS 背景🦋 域名简介🦋 真实地址查询 —— DNS🎀 域名的层级关系&am…

学到什么记什么(25.3.3)

Upload-labs 今日重新做了一下文件上传漏洞&#xff0c;这里第一题之前采用直接抓包改后缀名.jpg为.php&#xff0c;再写入一句话<?php phpinfo();?>然后放行&#xff0c;得到图片地址&#xff08;可复制&#xff09;&#xff0c;本来直接访问图片地址即可得到敏感信息…

阿里云服务器部署项目笔记 实操 centos7.9

阿里云服务器部署项目笔记 实操 centos7.9 springboot vue elementUImysqlredis 相关的redis,mysql,nginx镜像,jdk 通过网盘分享的文件&#xff1a;docker镜像 链接: https://pan.baidu.com/s/15VwcWBP4Jy07xADuvylgQw?pwdm2g9 提取码: m2g9 配置环境 连接云服务器 安装…

win32汇编环境,窗口程序中使控件子类化的示例一

;运行效果 ;win32汇编环境,窗口程序中使编辑框控件子类化的示例一 ;窗口子类化&#xff0c;就是把某种控件&#xff0c;自已再打造一遍&#xff0c;加入自已的功能。比如弄个特殊形状的按钮&#xff0c;或只能输入特殊字符的编辑框 ;当然&#xff0c;一般来说&#xff0c;这都是…

多镜头视频生成、机器人抓取、扩散模型个性化 | Big Model weekly第58期

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 01 GLM-4-Voice: Towards Intelligent and Human-Like End-to-End Spoken Chatbot 本文介绍了一种名为GLM-4-Voice的智能且类人化的端到端语音聊天机器人。它支持中文和英文&#xff0c;能够进行实时语音对话&a…

第十四届蓝桥杯:(二分算法)字串简写

这道题我们的做法是开两个vector&#xff0c;分别把a和b字符的下标存进去&#xff0c;然后遍历a字符&#xff0c;我们要求长度必须大于等于k&#xff0c;我们可以画个图&#xff0c;也就是说b的下标减a的下标必须大于等于k-1 也就是b的下标必须大于等于a的下标k-1 我们用二分找…

制服小程序的“滑手”:禁用页面左右滑动全攻略

哈哈&#xff0c;看来你已经很聪明地发现了小程序中左右滑动的“顽皮”行为&#xff01;&#x1f604; 没错&#xff0c;我们可以通过设置 disableScroll 属性来“管教”它&#xff0c;同时结合 CSS 样式让页面既禁得住横向“乱跑”&#xff0c;又能顺畅地上下滚动。你的方案已…

webstorm的Live Edit插件配合chrome扩展程序JetBrains IDE Support实现实时预览html效果

前言 我们平时在前端网页修改好代码要点击刷新再去看修改的效果&#xff0c;这样比较麻烦&#xff0c;那么很多软件都提供了实时预览的功能&#xff0c;我们一边编辑代码一边可以看到效果。下面说的是webstorm。 1 Live Edit 首先我们需要在webstorm的settings里安装插件Live …