Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Versioning](https://semver.org/spec/v2.0.0.html) for `libnopegl`.
- `ngl_get_viewport()` to get the viewport currently in use by the rendering
context
- `FontFace.index` parameter to select a different face in the font file
- `RadialBlur` node to apply a post processing radial blur effect to a scene

### Changed
- `Text.font_files` text-based parameter is replaced with `Text.font_faces` node
Expand Down
2 changes: 2 additions & 0 deletions libnopegl/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ lib_src = files(
'src/node_pathkey.c',
'src/node_program.c',
'src/node_quad.c',
'src/node_rblur.c',
'src/node_resourceprops.c',
'src/node_rotate.c',
'src/node_rotatequat.c',
Expand Down Expand Up @@ -675,6 +676,7 @@ shaders = {
'blur_downsample.frag': 'blur_downsample_frag.h',
'blur_upsample.frag': 'blur_upsample_frag.h',
'blur_interpolate.frag': 'blur_interpolate_frag.h',
'blur_radial_zoom.frag': 'blur_radial_zoom_frag.h',
'colorstats_init.comp': 'colorstats_init_comp.h',
'colorstats_sumscale.comp': 'colorstats_sumscale_comp.h',
'colorstats_waveform.comp': 'colorstats_waveform_comp.h',
Expand Down
33 changes: 33 additions & 0 deletions libnopegl/nodes.specs
Original file line number Diff line number Diff line change
Expand Up @@ -3360,6 +3360,39 @@
}
]
},
"RadialBlur": {
"file": "src/node_rblur.c",
"params": [
{
"name": "source",
"type": "node",
"node_types": ["Texture2D"],
"flags": ["nonull"],
"desc": "source to use for the blur"
},
{
"name": "destination",
"type": "node",
"node_types": ["Texture2D"],
"flags": ["nonull"],
"desc": "destination to use for the blur"
},
{
"name": "amount",
"type": "f32",
"default": 0.000000,
"flags": ["node"],
"desc": "amount of bluriness in the range [-1,1]"
},
{
"name": "center",
"type": "vec2",
"default": [0.000000,0.000000],
"flags": ["node"],
"desc": "center of the radial blur"
}
]
},
"RenderToTexture": {
"file": "src/node_rtt.c",
"params": [
Expand Down
68 changes: 68 additions & 0 deletions libnopegl/src/glsl/blur_radial_zoom.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2023-2024 Matthieu Bouron <[email protected]>
* Copyright 2023-2024 Nope Forge
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#include helper_srgb.glsl

void main()
{
vec2 size = vec2(textureSize(tex, 0));
vec2 direction = (tex_coord - center) * size;
vec2 step = normalize(direction) / size;
float radius = length(direction) * amount;
int radius_i = int(ceil(radius));

/*
* Use the 3-sigma rule to approximate sigma, see:
* - https://en.wikipedia.org/wiki/Talk%3AGaussian_blur#Radius_again
* - https://en.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7_rule
*/
float sigma = radius / 3.0;

/*
* Fast approximation of the gaussian function using the incremental gaussian
* algorithm adapted from GPU Gem 3.
*/
float g0 = 1.0;
float g1 = sigma > 1e-4 ? exp(-1.0 / (2.0 * sigma * sigma)) : 0.0;
float g2 = g1 * g1;

vec4 color = vec4(0.0);
float total_weight = 0.0;

int nb_samples = max(radius_i, 2);
for (int i = 0; i < nb_samples; i = i + 2) {
/* Take advantage of hw filtering to reduce the number of texture fetches */
float w1 = g0;
g0 *= g1;
g1 *= g2;
float w2 = g0;
g0 *= g1;
g1 *= g2;
float w = w1 + w1;
vec2 offset = ((float(i) * w1 + (float(i) + 1.0) * w2) / w) * step;
vec4 value = texture(tex, tex_coord - offset);
color += vec4(ngli_srgb2linear(value.rgb), value.a) * w;
total_weight += w;
}
color /= total_weight;
ngl_out_color = vec4(ngli_linear2srgb(color.rgb), color.a);
}
1 change: 1 addition & 0 deletions libnopegl/src/glsl/helper_misc_utils.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ float ngli_aa(float x) { return ngli_sat(x / fwidth(x) + 0.5); }
const vec3 ngli_luma_weights = vec3(.2126, .7152, .0722); // BT.709
const float ngli_pi = 3.14159265358979323846;
const float ngli_tau = 6.28318530717958647692;
const float ngli_inv_sqrt_tau = 0.3989422804014327;
Loading