Skip to content

Commit e3a0837

Browse files
authored
Added texture scrolling example (#154)
* Added texture scrolling example using texture transform 2d attribute and Defold provided time in shaders. * Updated the example to exclude custom texture transform attribute and use the default one instead. Reduced size of the images.
1 parent 6a88082 commit e3a0837

13 files changed

Lines changed: 375 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
path_settings {
2+
path: "**"
3+
profile: "Default"
4+
}
5+
profiles {
6+
name: "Default"
7+
platforms {
8+
os: OS_ID_GENERIC
9+
formats {
10+
format: TEXTURE_FORMAT_RGBA
11+
compression_level: BEST
12+
compression_type: COMPRESSION_TYPE_DEFAULT
13+
}
14+
mipmaps: false
15+
max_texture_size: 0
16+
premultiply_alpha: true
17+
}
18+
}
186 KB
Loading
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#version 140
2+
3+
in mediump vec2 var_texcoord0;
4+
in mediump mat3 var_texture_transform;
5+
in vec2 var_translation;
6+
7+
out vec4 out_fragColor;
8+
9+
uniform mediump sampler2D texture_sampler;
10+
uniform fs_uniforms
11+
{
12+
mediump vec4 tint;
13+
vec4 time;
14+
};
15+
16+
void main()
17+
{
18+
// Pre-multiply alpha since all runtime textures already are.
19+
vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
20+
21+
// Region origin in atlas UV space.
22+
vec2 atlas_pos = var_texture_transform[2].xy;
23+
24+
// Region size in atlas UV space.
25+
// The first two columns encode basis vectors; their lengths correspond to size.
26+
vec2 atlas_size = vec2(
27+
length(var_texture_transform[0].xy),
28+
length(var_texture_transform[1].xy)
29+
);
30+
31+
// Convert to local tile UV (0..1).
32+
vec2 localUV = (var_texcoord0 - atlas_pos) / atlas_size;
33+
34+
// Scroll in local UV space.
35+
localUV += (var_translation.xy) * time.x;
36+
37+
// Wrap inside tile.
38+
localUV = fract(localUV);
39+
40+
// Convert back to atlas space.
41+
vec2 finalUV = atlas_pos + localUV * atlas_size;
42+
43+
out_fragColor = texture(texture_sampler, finalUV) * tint_pm;
44+
45+
out_fragColor.a = 1.0;
46+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: "sprite"
2+
tags: "tile"
3+
vertex_program: "/assets/materials/scrolling.vp"
4+
fragment_program: "/assets/materials/scrolling.fp"
5+
vertex_constants {
6+
name: "view_proj"
7+
type: CONSTANT_TYPE_VIEWPROJ
8+
}
9+
fragment_constants {
10+
name: "tint"
11+
type: CONSTANT_TYPE_USER
12+
value {
13+
x: 1.0
14+
y: 1.0
15+
z: 1.0
16+
w: 1.0
17+
}
18+
}
19+
fragment_constants {
20+
name: "time"
21+
type: CONSTANT_TYPE_TIME
22+
}
23+
samplers {
24+
name: "texture_sampler"
25+
wrap_u: WRAP_MODE_CLAMP_TO_EDGE
26+
wrap_v: WRAP_MODE_CLAMP_TO_EDGE
27+
filter_min: FILTER_MODE_MIN_DEFAULT
28+
filter_mag: FILTER_MODE_MAG_DEFAULT
29+
}
30+
attributes {
31+
name: "translation"
32+
double_values {
33+
v: 0.0
34+
v: 0.0
35+
}
36+
vector_type: VECTOR_TYPE_VEC2
37+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#version 140
2+
3+
// Positions are in world space.
4+
in highp vec4 position;
5+
in mediump vec2 texcoord0;
6+
in mediump mat3 texture_transform_2d;
7+
in vec2 translation;
8+
9+
out mediump vec2 var_texcoord0;
10+
out mediump mat3 var_texture_transform;
11+
out vec2 var_translation;
12+
13+
uniform vs_uniforms
14+
{
15+
highp mat4 view_proj;
16+
};
17+
18+
void main()
19+
{
20+
gl_Position = view_proj * vec4(position.xyz, 1.0);
21+
var_texcoord0 = texcoord0;
22+
var_texture_transform = texture_transform_2d;
23+
var_translation = translation;
24+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
animations {
2+
id: "texture"
3+
images {
4+
image: "/assets/images/Texture.png"
5+
}
6+
playback: PLAYBACK_LOOP_FORWARD
7+
}
28.1 KB
Loading
27 KB
Loading
228 KB
Loading
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
tags: sprite
3+
title: Texture scrolling
4+
brief: This example shows how tint a sprite at run-time
5+
author: Defold Foundation
6+
scripts: materials/scrolling.vp, materials/scrolling.fp
7+
thumbnail: thumbnail.png
8+
---
9+
10+
# Texture scrolling
11+
12+
This example shows how to achieve **scrolling textures (UV scrolling)** in Defold without moving the sprite in world space. Instead, UVs are modified in the fragment shader. It works both with plain textures and with an **atlas**, and the scrolling is performed **inside the current atlas region**.
13+
14+
Since Defold 1.12.3 a new semantic type for Attributes is available named **"Texture Transform 2D"**, and it is used in this example.
15+
16+
Since Defold 1.12.3 also time is provided automatically to the shaders via Fragment Constant of type **"Time"**, and it is used in this example.
17+
18+
## Material Setup
19+
20+
1. Create a new material: `assets/materials/scrolling.material`, with these important things set:
21+
22+
- **Vertex attribute** `translation` (vec2)
23+
- Vector Type: `Vec2` (for 2D)
24+
- This is the UV scroll vector - defining direction and speed, meaning: `translation = (vx, vy)` where positive `vx` scrolls towards +U, and positive `vy` scrolls towards +V.
25+
26+
![Texture scrolling example](doc/material_translation.png)
27+
28+
- **Fragment constant** `time` of type `Time`
29+
- A material constant filled automatically by Defold.
30+
- In this example the fragment shader uses `time.x` as “time in seconds”, which is enough for simple scrolling.
31+
- Tint is left as is, as it's based on the built-in Sprite material.
32+
33+
![Texture scrolling example](doc/material_rest.png)
34+
35+
## Sprite setup
36+
37+
In `example/texture_scrolling.collection`, there are 4 sprites that all use the `scrolling.material` and mainly differ by the Vertex Attribute for **translation**, to achieve different direction and speed:
38+
39+
- `(0.1, 0.0)` – scroll to the right
40+
- `(0.1, -0.1)` – scroll diagonally (right + down)
41+
- `(-0.1, 0.1)` – scroll diagonally (left + up)
42+
- `(0.0, 0.1)` – scroll up
43+
44+
Notice, that visually it looks like the texture is moving in the **opposite** direction, because we are scrolling to the given direction the sampled texture.
45+
46+
To control per-sprite scroll speed/direction, **just change the `translation`** on that sprite in the editor (Vertex Attributes for Sprite components).
47+
48+
![Texture scrolling example](doc/setup.png)
49+
50+
## Shaders overview
51+
52+
- **Vertex shader** `assets/materials/scrolling.vp`
53+
- Transforms sprite vertices to clip space using `view_proj`.
54+
- Forwards `texcoord0`, `texture_transform_2d`, and `translation` to the fragment shader.
55+
56+
- **Fragment shader** `assets/materials/scrolling.fp`
57+
- Derives the atlas tile origin (`atlas_pos`) and size (`atlas_size`) from `texture_transform_2d`.
58+
- Converts atlas UV into local tile UV (0..1).
59+
- Applies scrolling using `localUV += translation * time.x`.
60+
- Wraps inside the tile with `fract(localUV)` to keep sampling within the region.
61+
- Converts back to atlas UV and samples `texture_sampler`.

0 commit comments

Comments
 (0)