本文已参加【新人创作礼】活动,一起开启掘金创作之路。
📒博客首页:何名取 的个人主页 - 文章 - 掘金 (juejin.cn)
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❤️期待一起交流!
🙏作者水平很有限,如果发现错误,求告知,多谢!
🌺有问题可私信交流!!!
CustomParticle
前言
CustomParticle自定义渲染器是ParticlePainter粒子渲染器中的一员,之前已经介绍过它的兄弟ImageParticle图片渲染器了,本节来介绍一下CustomParticle自定义渲染器。
简介
CustomParticle自定义渲染器用于指定着色器来绘制粒子。这里的指定着色器指的是OpenGL里的着色器,意味着可以直接使用OpenGL着色器的一些特性。下面是CustomParticle自定义渲染器的属性列表:
属性 | 类型 | 描述 |
---|---|---|
fragmentShader | string | 这个属性保存片段着色器的GLSL源代码。默认的着色器期望从顶点着色器传递纹理坐标为“可变highp vec2 qt_TexCoord0”,它从名为“source”的sampler2D采样。 |
vertexShader | string | 这个属性保存顶点着色器的GLSL源代码。默认的着色器将纹理坐标传递给片段着色器“highp vec2 qt_TexCoord0”。 |
着色器是使用一种叫GLSL的类C语言写成的。GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。
着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。每个着色器的入口点都是main函数,在这个函数中我们处理所有的输入变量,并将结果输出到输出变量中。
这两个属性都可以将GLSL的代码进行使用,不同之处在于片段着色器和顶点着色器的使用。
使用
本节将创建一个自定义粒子渲染器,其作用是将输入的图片原子化分解,分解出的原子是以另一张图片做为原子的形式。本节中将要分解的图片设置为一个心型🧡,原子化的图片使用小颗粒的图片。以下代码是CustomParticle自定义渲染器部分的代码。其中GLSL的代码不做介绍了。
CustomParticle {
system: sys
anchors.fill: parent
property real maxWidth: root.width
property real maxHeight: root.height
ShaderEffectSource {
id: pictureSource
sourceItem: picture
hideSource: false
}
Image {
id: picture
anchors.fill: parent
source: "qrc:/heart.png"
fillMode: Image.PreserveAspectFit
}
ShaderEffectSource {
id: particleSource
sourceItem: particle
hideSource: true
}
Image {
id: particle
source: "qrc:///particleresources/fuzzydot.png"
}
//! [vertex]
vertexShader:"
uniform highp float maxWidth;
uniform highp float maxHeight;
varying highp vec2 fTex2;
varying lowp float fFade;
uniform lowp float qt_Opacity;
void main() {
fTex2 = vec2(qt_ParticlePos.x, qt_ParticlePos.y);
//Uncomment this next line for each particle to use full texture, instead of the solid color at the center of the particle.
//fTex2 = fTex2 + ((- qt_ParticleData.z / 2. + qt_ParticleData.z) * qt_ParticleTex); //Adjusts size so it's like a chunk of image.
fTex2 = fTex2 / vec2(maxWidth, maxHeight);
highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;
fFade = min(t*4., (1.-t*t)*.75) * qt_Opacity;
defaultMain();
}
"
//! [vertex]
property variant particleTexture: particleSource
property variant pictureTexture: pictureSource
//! [fragment]
fragmentShader: "
uniform sampler2D particleTexture;
uniform sampler2D pictureTexture;
varying highp vec2 qt_TexCoord0;
varying highp vec2 fTex2;
varying lowp float fFade;
void main() {
gl_FragColor = texture2D(pictureTexture, fTex2) * texture2D(particleTexture, qt_TexCoord0).w * fFade;
}"
//! [fragment]
}
效果展示
这里我将粒子效果做成了鼠标点击才会运行的状态,开始界面展示要分解的图形,每次点击鼠标就发将图片分解成粒子发射出去。