Skip to content

Commit

Permalink
Merge pull request qmlbook#94 from qmlbook/convert-ch09-10
Browse files Browse the repository at this point in the history
Convert ch09 10
  • Loading branch information
e8johan authored Sep 21, 2021
2 parents f5c07df + 06d1720 commit e872a07
Show file tree
Hide file tree
Showing 159 changed files with 1,215 additions and 1,907 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,6 @@ examples.tar.gz
# Python
.venv
__pycache__

# Qt Shaders
*.qsb
40 changes: 20 additions & 20 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,36 +168,36 @@ function ch11Sidebar() {

function ch10Sidebar() {
return {
title: "OpenGL Shaders",
path: '/ch10-shaders/shader-effects',
title: "Effects (Qt6 - Draft)",
path: '/ch10-effects/effects',
collapsable: false,
children: [
'/ch10-shaders/shader-effects',
'/ch10-shaders/opengl-shaders',
'/ch10-shaders/shader-elements',
'/ch10-shaders/fragment-shaders',
'/ch10-shaders/wave-effect',
'/ch10-shaders/vertex-shader',
'/ch10-shaders/curtain-effect',
'/ch10-shaders/effect-library',
'/ch10-effects/effects',
'/ch10-effects/particles',
'/ch10-effects/simple-simulation',
'/ch10-effects/particle-parameters',
'/ch10-effects/directed-particles',
'/ch10-effects/affecting-particles',
'/ch10-effects/particle-groups',
'/ch10-effects/particle-painters',
'/ch10-effects/opengl-shaders',
'/ch10-effects/shader-elements',
'/ch10-effects/fragment-shaders',
'/ch10-effects/wave-effect',
'/ch10-effects/vertex-shader',
'/ch10-effects/curtain-effect',
'/ch10-effects/summary',
]
}
}

function ch09Sidebar() {
return {
title: "Particles",
path: '/ch09-particles/particle-simulation',
title: "Shapes (Qt6 - Placeholder)",
path: '/ch09-shapes/placeholder',
collapsable: false,
children: [
'/ch09-particles/particle-simulation',
'/ch09-particles/concept',
'/ch09-particles/simple-simulation',
'/ch09-particles/particle-parameters',
'/ch09-particles/directed-particles',
'/ch09-particles/affecting-particles',
'/ch09-particles/particle-groups',
'/ch09-particles/summary',
'/ch09-shapes/placeholder',
]
}
}
Expand Down
6 changes: 0 additions & 6 deletions docs/ch09-particles/particle-simulation.md

This file was deleted.

19 changes: 0 additions & 19 deletions docs/ch09-particles/src/particles/particles.qmlproject

This file was deleted.

3 changes: 0 additions & 3 deletions docs/ch09-particles/summary.md

This file was deleted.

3 changes: 3 additions & 0 deletions docs/ch09-shapes/placeholder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Placeholder

This is a placeholder for a chapter on QML Shapes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Particles are emitted by the emitter. After a particle was emitted it can’t be

Each type of affector affects particles in a different way:


* `Age` - alter where the particle is in its life-cycle
* `Attractor` - attract particles towards a specific point
* `Friction` - slows down movement proportional to the particle’s current velocity
Expand All @@ -16,128 +15,60 @@ Each type of affector affects particles in a different way:

## Age

Allows particle to age faster. the *lifeLeft* property specified how much life a particle should have left.

```qml
Age {
anchors.horizontalCenter: parent.horizontalCenter
width: 240; height: 120
system: particleSystem
advancePosition: true
lifeLeft: 1200
once: true
Tracer {}
}
```

In the example, we shorten the life of the upper particles once when they reach the age of affector to 1200 msec. As we have set the *advancePosition* to true, we see the particle appearing again on a position when the particle has 1200 msecs left to live.
Allows particle to age faster. the `lifeLeft` property specified how much life a particle should have left.

<<< @/docs/ch10-effects/src/particles/age.qml#M1

In the example, we shorten the life of the upper particles once when they reach the age of affector to 1200 msec. As we have set the `advancePosition` to true, we see the particle appearing again on a position when the particle has 1200 msecs left to live.

![image](./assets/age.png)

## Attractor

The attractor attracts particles towards a specific point. The point is specified using `pointX` and `pointY`, which is relative to the attractor geometry. The strength specifies the force of attraction. In our example we let particles travel from left to right. The attractor is placed on the top and half of the particles travel through the attractor. Affector only affect particles while they are in their bounding box. This split allows us to see the normal stream and the affected stream simultaneous.

```qml
Attractor {
anchors.horizontalCenter: parent.horizontalCenter
width: 160; height: 120
system: particleSystem
pointX: 0
pointY: 0
strength: 1.0
Tracer {}
}
```
<<< @/docs/ch10-effects/src/particles/attractor.qml#M1

It’s easy to see that the upper half of the particles are affected by the attracted to the top. The attraction point is set to top-left (0/0 point) of the attractor with a force of 1.0.



![image](./assets/attractor.png)

## Friction

The friction affector slows down particles by a factor until a certain threshold is reached.

```qml
Friction {
anchors.horizontalCenter: parent.horizontalCenter
width: 240; height: 120
system: particleSystem
factor : 0.8
threshold: 25
Tracer {}
}
```
<<< @/docs/ch10-effects/src/particles/friction.qml#M1

In the upper friction area, the particles are slowed down by a factor of 0.8 until the particle reaches 25 pixels per seconds velocity. The threshold act’s like a filter. Particles traveling above the threshold velocity are slowed down by the given factor.



![image](./assets/friction.png)

## Gravity

The gravity affector applies an acceleration In the example we stream the particles from the bottom to the top using an angle direction. The right side is unaffected, where on the left a gravity effect is applied. The gravity is angled to 90 degrees (bottom-direction) with a magnitude of 50.

```qml
Gravity {
width: 240; height: 240
system: particleSystem
magnitude: 50
angle: 90
Tracer {}
}
```
<<< @/docs/ch10-effects/src/particles/gravity.qml#M1

Particles on the left side try to climb up, but the steady applied acceleration towards the bottom drags them into the direction of the gravity.



![image](./assets/gravity.png)

## Turbulence

The turbulence affector applies a *chaos* map of force vectors to the particles. The chaos map is defined by a noise image, which can be defined with the *noiseSource* property. The strength defines how strong the vector will be applied to the particle movements.

```qml
Turbulence {
anchors.horizontalCenter: parent.horizontalCenter
width: 240; height: 120
system: particleSystem
strength: 100
Tracer {}
}
```
<<< @/docs/ch10-effects/src/particles/turbulence.qml#M1

In the upper area of the example, particles are influenced by the turbulence. Their movement is more erratic. The amount of erratic deviation from the original path is defined by the strength.



![image](./assets/turbulence.png)

## Wander

The wander manipulates the trajectory. With the property *affectedParameter* can be specified which parameter (velocity, position or acceleration) is affector by the wander. The *pace* property specifies the maximum of attribute changes per second. The yVariance and yVariance specify the influence on x and y component of the particle trajectory.

```qml
Wander {
anchors.horizontalCenter: parent.horizontalCenter
width: 240; height: 120
system: particleSystem
affectedParameter: Wander.Position
pace: 200
yVariance: 240
Tracer {}
}
```
<<< @/docs/ch10-effects/src/particles/wander.qml#M1

In the top wander affector particles are shuffled around by random trajectory changes. In this case, the position is changed 200 times per second in the y-direction.



![image](./assets/wander.png)

File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
35 changes: 35 additions & 0 deletions docs/ch10-effects/curtain-effect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Curtain Effect

In the last example for custom shader effects, I would like to bring you the curtain effect. This effect was published first in May 2011 as part of [Qt labs for shader effects](http://labs.qt.nokia.com/2011/05/03/qml-shadereffectitem-on-qgraphicsview/).

![image](./assets/curtain.png)

At that time I really loved these effects and the curtain effect was my favorite out of them. I just love how the curtain opens and hide the background object.

For this chapter, the effect has been adapted for Qt 6. It has also been slghtly simplifed to make it a better showcase.

The curtain image is called `fabric.png`. The effect then uses a vertex shader to swing the curtain forth and back and a fragment shader to apply shadows to show how the fabric folds.

The diagram below shows how the shader works. The waves are computed through a sin curve with 7 periods (7\*PI=21.99…). The other part is the swinging. The `topWidht` of the curtain is animated when the curtain is opened or closed. The `bottomWidth` follows the `topWidth` using a `SpringAnimation`. This creates the effect of the bottom part of the curtain swinging freely. The calulated `swing` component is the strengh of the swing based on the y-component of the vertexes.

![image](./assets/curtain_diagram.png)

The curtain effect is implemed in the `CurtainEffect.qml` file where the fabric image act as the texture source. In the QML code, the `mesh` property is adjusted to make sure that the number of vertixes is increased to give a smoother result.

<<< @/docs/ch10-effects/src/effects/curtain/CurtainEffect.qml#M1

The vertex shader, shown below, reshapes the curtain based on the `topWidth` and `bottomWidth` properies, extrapolating the shift based on the y-coordinate. It also calculates the `shade` value, which is used in the fragment shader. The `shade` property is passed through an additional output in `location` 1.

<<< @/docs/ch10-effects/src/effects/curtain/curtain.vert#M1

In the fragment shader below, the `shade` is picked up as an input in `location` 1 and is then used to calculate the `fragColor`, which is used to draw the pixel in question.

<<< @/docs/ch10-effects/src/effects/curtain/curtain.frag#M1

The combination of QML animations and passing variables from the vertex shader to the fragment shader demonstrates how QML and shaders can be used together to build complex, animated, effects.

The effect itself is used from the `curtaindemo.qml` file shown below.

<<< @/docs/ch10-effects/src/effects/curtain/curtaindemo.qml#M1

The curtain is opened through a custom `open` property on the curtain effect. We use a `MouseArea` to trigger the opening and closing of the curtain when the user clicks or taps the area.
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@ We have seen particles can rotate. But particles can also have a trajectory. The

There are different vector spaces available to define the velocity or acceleration of a particle:


* `AngleDirection` - a direction that varies in angle


* `PointDirection` - a direction that varies in x and y components


* `TargetDirection` - a direction towards the target point



![image](./assets/particle_directions.png)

Let’s try to move the particles over from the left to the right side of our scene by using the velocity directions.
Expand Down Expand Up @@ -44,30 +37,11 @@ velocity: AngleDirection {
}
```



![image](./assets/angledirection.png)

Here is the full source code, with an average lifetime set to 6.4 seconds. We set the emitter width and height to 1px. This means all particles are emitted at the same location and from thereon travel based on our given trajectory.

```qml
Emitter {
id: emitter
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 1; height: 1
system: particleSystem
lifeSpan: 6400
lifeSpanVariation: 400
size: 32
velocity: AngleDirection {
angle: 0
angleVariation: 15
magnitude: 100
magnitudeVariation: 50
}
}
```
<<< @/docs/ch10-effects/src/particles/angledirection.qml#M1

So what is then the acceleration doing? The acceleration adds an acceleration vector to each particle, which changes the velocity vector over time. For example, let’s make a trajectory like an arc of stars. For this we change our velocity direction to -45 degree and remove the variations, to better visualize a coherent arc:

Expand All @@ -89,36 +63,13 @@ acceleration: AngleDirection {

The result is an arc going from the center-left to the bottom right.



![image](./assets/angledirection2.png)

The values are discovered by try-and-error.

Here is the full code of our emitter.

```qml
Emitter {
id: emitter
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 1; height: 1
system: particleSystem
emitRate: 10
lifeSpan: 6400
lifeSpanVariation: 400
size: 32
velocity: AngleDirection {
angle: -45
angleVariation: 0
magnitude: 100
}
acceleration: AngleDirection {
angle: 90
magnitude: 25
}
}
```
<<< @/docs/ch10-effects/src/particles/angledirection2.qml#M1

In the next example we would like that the particles again travel from left to right but this time we use the `PointDirection` vector space.

Expand All @@ -143,8 +94,6 @@ velocity: PointDirection {

The result should be particles traveling in a 15-degree cone from right to left.



![image](./assets/pointdirection.png)

Now coming to our last contender, the `TargetDirection`. The target direction allows us to specify a target point as an x and y coordinate relative to the emitter or an item. When an item has specified the center of the item will become the target point. You can achieve the 15-degree cone by specifying a target variation of 1/6 th of the x target:
Expand All @@ -166,7 +115,4 @@ I spare you the image as it looks the same as the previous one, instead, I have

In the following image, the red and the green circle specify each a target item for the target direction of the velocity respective the acceleration property. Each target direction has the same parameters. Here the question: Who is responsible for velocity and who is for acceleration?



![image](./assets/directionquest.png)

Loading

0 comments on commit e872a07

Please sign in to comment.