### Compile libplacebo example Source: https://libplacebo.org/basic-rendering Command to compile the basic logging example using pkg-config. ```bash $ gcc example.c -o example `pkg-config --cflags --libs libplacebo` ``` -------------------------------- ### Initialize and run a libplacebo rendering loop Source: https://libplacebo.org/basic-rendering This example initializes the libplacebo API, sets up an OpenGL-based GPU instance, and manages a windowed rendering loop using GLFW. ```c #include #include #include #include const char * const title = "libplacebo demo"; int width = 800; int height = 600; GLFWwindow *window; pl_log pllog; pl_opengl opengl; pl_swapchain swchain; static bool make_current(void *priv); static void release_current(void *priv); static void resize_cb(GLFWwindow *win, int new_w, int new_h) { width = new_w; height = new_h; pl_swapchain_resize(swchain, &width, &height); } static void render_frame(struct pl_swapchain_frame frame) { pl_gpu gpu = opengl->gpu; pl_tex_clear(gpu, frame.fbo, (float[4]){ 1.0, 0.5, 0.0, 1.0 }); } int main() { pllog = pl_log_create(PL_API_VER, pl_log_params( .log_cb = pl_log_color, .log_level = PL_LOG_INFO, )); if (!glfwInit()) return 1; window = glfwCreateWindow(width, height, title, NULL, NULL); if (!window) return 1; opengl = pl_opengl_create(pllog, pl_opengl_params( .get_proc_addr = glfwGetProcAddress, .allow_software = true, // allow software rasterers .debug = true, // enable error reporting .make_current = make_current, .release_current = release_current, )); swchain = pl_opengl_create_swapchain(opengl, pl_opengl_swapchain_params( .swap_buffers = (void (*)(void *)) glfwSwapBuffers, .priv = window, )); if (!swchain) return 2; if (!pl_swapchain_resize(swchain, &width, &height)) return 2; glfwSetFramebufferSizeCallback(window, resize_cb); while (!glfwWindowShouldClose(window)) { struct pl_swapchain_frame frame; while (!pl_swapchain_start_frame(swchain, &frame)) glfwWaitEvents(); render_frame(frame); if (!pl_swapchain_submit_frame(swchain)) break; pl_swapchain_swap_buffers(swchain); glfwPollEvents(); } pl_swapchain_destroy(&swchain); pl_opengl_destroy(&opengl); glfwDestroyWindow(window); glfwTerminate(); pl_log_destroy(&pllog); return 0; } static bool make_current(void *priv) { glfwMakeContextCurrent(window); return true; } static void release_current(void *priv) { glfwMakeContextCurrent(NULL); } ``` -------------------------------- ### Compile GLFW and libplacebo example Source: https://libplacebo.org/basic-rendering Command to compile the windowing example with both GLFW and libplacebo dependencies. ```bash $ gcc example.c -o example `pkg-config --cflags --libs glfw3 libplacebo` ``` -------------------------------- ### Apply Sigmoid Shader Transformation Source: https://libplacebo.org/glsl This example demonstrates applying a sigmoid transformation to color values using specializable shader constants. The transformation ensures the output passes through (0,0) and (1,1). ```glsl void pl_shader_sigmoidize(pl_shader sh, const struct pl_sigmoid_params *params) { if (!sh_require(sh, PL_SHADER_SIG_COLOR, 0, 0)) return; params = PL_DEF(params, &pl_sigmoid_default_params); float center = PL_DEF(params->center, 0.75); float slope = PL_DEF(params->slope, 6.5); // This function needs to go through (0,0) and (1,1), so we compute the // values at 1 and 0, and then scale/shift them, respectively. float offset = 1.0 / (1 + expf(slope * center)); float scale = 1.0 / (1 + expf(slope * (center - 1))) - offset; GLSL("color = clamp(color, 0.0, 1.0); \n" "color = vec4(\" $\") - vec4(\" $\") * \n" " log(vec4(1.0) / (color * vec4(\" $\") + vec4(\" $\")) \n" " - vec4(1.0)); \n", SH_FLOAT(center), SH_FLOAT(1.0 / slope), SH_FLOAT(scale), SH_FLOAT(offset))); } ``` -------------------------------- ### Apply Clipping Logic with Dynamic Variables Source: https://libplacebo.org/glsl This example shows how to implement clipping logic using dynamic shader variables. It checks for out-of-bounds color values and updates clipping flags based on input thresholds. ```glsl if (params->show_clipping) { const float eps = 1e-6f; GLSL("bool clip_hi, clip_lo; \n" "clip_hi = any(greaterThan(color.rgb, vec3(\" $\"))); \n" "clip_lo = any(lessThan(color.rgb, vec3(\" $\"))); \n" "clip_hi = clip_hi || ipt.x > \" $\"; \n" "clip_lo = clip_lo || ipt.x < \" $\"; \n", SH_FLOAT_DYN(pl_hdr_rescale(PL_HDR_PQ, PL_HDR_NORM, tone.input_max) + eps), SH_FLOAT(pl_hdr_rescale(PL_HDR_PQ, PL_HDR_NORM, tone.input_min) - eps), SH_FLOAT_DYN(tone.input_max + eps), SH_FLOAT(tone.input_min - eps))); } ``` -------------------------------- ### Example pl_frame_mix struct Source: https://libplacebo.org/renderer This struct describes the current state of a vsync for frame mixing. It requires collecting relevant frames, determining their relative distances to the vsync, and normalizing timestamps. The vsync duration is also a critical parameter. ```c (struct pl_frame_mix) { .num_frames = 6, .frames = (const struct pl_frame *[]) { /* frame 0 */ /* frame 1 */ /* ... */ /* frame 5 */ }, .signatures = (uint64_t[]) { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5 // }, .timestamps = (float[]) { -2.4, -1.4, -0.4, 0.6, 1.6, 2.6, // }, .vsync_duration = 0.4, // 24 fps video on 60 fps display } ``` -------------------------------- ### Example Shader with SAVE Directive Source: https://libplacebo.org/custom-shaders This shader binds both luma and chroma, resizes the luma plane to match chroma's dimensions, and saves the result as a new texture named LUMA_LOWRES. It demonstrates how to use the SAVE directive to create intermediate textures for processing. ```glsl //!HOOK CHROMA //!BIND CHROMA //!BIND LUMA //!SAVE LUMA_LOWRES //!WIDTH CHROMA.w //!HEIGHT CHROMA.h vec4 hook() { return LUMA_texOff(0); } ``` -------------------------------- ### Initialize a GLFW window Source: https://libplacebo.org/basic-rendering Sets up a basic windowing environment using GLFW alongside libplacebo logging. ```c // ... #include const char * const title = "libplacebo demo"; int width = 800; int height = 600; GLFWwindow *window; int main() { pllog = pl_log_create(PL_API_VER, pl_log_params( .log_level = PL_LOG_INFO, )); if (!glfwInit()) return 1; window = glfwCreateWindow(width, height, title, NULL, NULL); if (!window) return 1; while (!glfwWindowShouldClose(window)) { glfwWaitEvents(); } glfwDestroyWindow(window); glfwTerminate(); pl_log_destroy(&pllog); return 0; } ``` -------------------------------- ### Unrolled Loops with @for Source: https://libplacebo.org/glsl Employ '@for' directives for unrolled loops. A local variable '@x' represents the current loop index, starting from 0. ```glsl int offset = ${const int: params->kernel_width / 2}; float sum = 0.0; @for (x < params->kernel_width) sum += textureLodOffset($luma, $pos, 0.0, int(@sum - offset)).r; ``` ```glsl float weight = /* ... */; vec4 color = textureLod($tex, $pos, 0.0); @for (c : params->component_mask) sum[@c] += weight * color[@c]; ``` ```glsl @for (i < 10) { float weight = /* ... */; @if @(i < 5) weight = -weight; sum += weight * texture(...); @} ``` -------------------------------- ### Create and manage a pl_swapchain Source: https://libplacebo.org/basic-rendering Initializes a swapchain for an OpenGL GPU and handles window resizing and buffer swapping. ```c // ... pl_swapchain swchain; static void resize_cb(GLFWwindow *win, int new_w, int new_h) { width = new_w; height = new_h; pl_swapchain_resize(swchain, &width, &height); } int main() { // ... if (!opengl) return 2; swchain = pl_opengl_create_swapchain(opengl, pl_opengl_swapchain_params( .swap_buffers = (void (*)(void *)) glfwSwapBuffers, .priv = window, )); if (!swchain) return 2; // if (!pl_swapchain_resize(swchain, &width, &height)) return 2; glfwSetFramebufferSizeCallback(window, resize_cb); while (!glfwWindowShouldClose(window)) { pl_swapchain_swap_buffers(swchain); glfwPollEvents(); // } pl_swapchain_destroy(&swchain); pl_opengl_destroy(&opengl); glfwDestroyWindow(window); glfwTerminate(); pl_log_destroy(&pllog); return 0; } ``` -------------------------------- ### Initialize pl_opengl GPU context Source: https://libplacebo.org/basic-rendering Creates a pl_opengl instance using GLFW for context management. Requires valid make_current and release_current callbacks. ```c // ... pl_opengl opengl; static bool make_current(void *priv); static void release_current(void *priv); int main() { // ... window = glfwCreateWindow(width, height, title, NULL, NULL); if (!window) return 1; opengl = pl_opengl_create(pllog, pl_opengl_params( .get_proc_addr = glfwGetProcAddress, .allow_software = true, // allow software rasterers .debug = true, // enable error reporting .make_current = make_current, // .release_current = release_current, )); if (!opengl) return 2; while (!glfwWindowShouldClose(window)) { glfwWaitEvents(); } pl_opengl_destroy(&opengl); glfwDestroyWindow(window); glfwTerminate(); pl_log_destroy(&pllog); return 0; } static bool make_current(void *priv) { glfwMakeContextCurrent(window); return true; } static void release_current(void *priv) { glfwMakeContextCurrent(NULL); } ``` -------------------------------- ### Render frames with pl_swapchain Source: https://libplacebo.org/basic-rendering Implements a render loop using pl_swapchain_start_frame and pl_swapchain_submit_frame to clear the framebuffer. ```c // ... static void render_frame(struct pl_swapchain_frame frame) { pl_gpu gpu = opengl->gpu; pl_tex_clear(gpu, frame.fbo, (float[4]){ 1.0, 0.5, 0.0, 1.0 }); } int main() { // ... while (!glfwWindowShouldClose(window)) { struct pl_swapchain_frame frame; while (!pl_swapchain_start_frame(swchain, &frame)) glfwWaitEvents(); // render_frame(frame); if (!pl_swapchain_submit_frame(swchain)) break; // pl_swapchain_swap_buffers(swchain); glfwPollEvents(); } // ... } ``` -------------------------------- ### Global Preset Configuration Source: https://libplacebo.org/options Allows overriding all options with predefined presets for different performance and quality needs. ```APIDOC ## Global preset ### `preset=` Override all options from all sections by the values from the given preset. The following presets are available: * `default`: Default settings, tuned to provide a balance of performance and quality. Should be fine on almost all systems. * `fast`: Disable all advanced rendering, equivalent to passing `no` to every option. Increases performance on very slow / old integrated GPUs. * `high_quality`: Reset all structs to their `high_quality` presets (where available), set the upscaler to `ewa_lanczossharp`, and enable `deband=yes`. Suitable for use on machines with a discrete GPU. ``` -------------------------------- ### Define Enum Parameter for Colorspace Source: https://libplacebo.org/custom-shaders Use `TYPE ENUM int` to define an enumeration parameter. The possible values are listed, and these names become available as `#define` macros within the shader and in RPN expressions. This example shows how to select a color matrix based on the enum value. ```glsl #!PARAM csp //!DESC Colorspace //!TYPE ENUM int BT709 BT2020 DCIP3 //!HOOK MAIN //!BIND HOOKED const mat3 matrices[3] = { mat3(...), // BT709 mat3(...), // BT2020 mat3(...), // DCIP3 }; #define MAT matrices[csp] // ... ``` -------------------------------- ### Create a pl_log object Source: https://libplacebo.org/basic-rendering Initializes a logging object using the required API version and parameter macro. ```c #include pl_log pllog; int main() { pllog = pl_log_create(PL_API_VER, pl_log_params( .log_cb = pl_log_color, .log_level = PL_LOG_INFO, )); // ... pl_log_destroy(&pllog); return 0; } ``` -------------------------------- ### Render a frame to the swapchain Source: https://libplacebo.org/renderer Converts a swapchain frame to a target frame and executes the rendering process. ```c bool render_frame(const struct pl_frame *image, const struct pl_swapchain_frame *swframe) { struct pl_frame target; pl_frame_from_swapchain(&target, swframe); return pl_render_image(renderer, image, target, &pl_render_default_params); } ``` -------------------------------- ### Initialize and destroy pl_renderer Source: https://libplacebo.org/renderer Basic lifecycle management for the renderer instance. ```c pl_renderer renderer; init() { renderer = pl_renderer_create(pllog, gpu); if (!renderer) goto error; // ... } uninit() { pl_renderer_destroy(&renderer); } ``` -------------------------------- ### Implement Debanding Iterations Source: https://libplacebo.org/glsl Demonstrates the use of GLSL macro loops to generate shader code for debanding, mixing literal constants and dynamic identifiers. ```C for (int i = 1; i <= params->iterations; i++) { GLSL(// Compute a random angle and distance "d = \"$\".xy * vec2(%d.0 * \"$\", %f); \n" // "d = d.x * vec2(cos(d.y), sin(d.y)); \n" // Sample at quarter-turn intervals around the source pixel "avg = T(0.0); \n" "avg += GET(+d.x, +d.y); \n" "avg += GET(-d.x, +d.y); \n" "avg += GET(-d.x, -d.y); \n" "avg += GET(+d.x, -d.y); \n" "avg *= 0.25; \n" // Compare the (normalized) average against the pixel "diff = abs(res - avg); \n" "bound = T(\"$\" / %d.0); \n", prng, i, radius, M_PI * 2, threshold, i); if (num_comps > 1) { GLSL("res = mix(avg, res, greaterThan(diff, bound)); \n"); } else { GLSL("res = mix(avg, res, diff > bound); \n"); } } ``` -------------------------------- ### Tone Mapping Debug Options Source: https://libplacebo.org/options Debugging and visualization options for tone and gamut mapping. ```APIDOC ## Debug Options ### Parameters - **force_tone_mapping_lut** (string, yes|no) - Optional - Force use of full tone-mapping LUT. Defaults to no. - **visualize_lut** (string, yes|no) - Optional - Visualize color mapping LUTs. Defaults to no. ``` -------------------------------- ### LUT Visualization Options Source: https://libplacebo.org/options Controls for visualizing the Look-Up Table (LUT) and gamut during rendering. ```APIDOC ## Visualization Options ### `visualize_lut_x0`, `visualize_lut_y0`, `visualize_lut_x1`, `visualize_lut_y1` Controls where to draw the LUt visualization, relative to the rendered video. Defaults to `0.0` for `x0`/`y0`, and `1.0` for `x1`/`y1`. ### `visualize_hue=`, `visualize_theta=` Controls the rotation of the gamut 3DLUT visualization. The `hue` parameter rotates the gamut through hue space (around the `I` axis), while the `theta` parameter vertically rotates the cross section (around the `C` axis), in radians. Defaults to `0.0` for both. ### `show_clipping=` Graphically highlight hard-clipped pixels during tone-mapping (i.e. pixels that exceed the claimed source luminance range). Defaults to `no`. ``` -------------------------------- ### Tone Mapping Configuration Parameters Source: https://libplacebo.org/options Configuration parameters for controlling tone mapping curves, knee points, and contrast recovery. ```APIDOC ## Tone Mapping Configuration ### Parameters - **knee_adaptation** (float, 0.0-1.0) - Optional - Ratio between source and target average in PQ space. Defaults to 0.4. - **knee_minimum** (float, 0.0-0.5) - Optional - Minimum knee point as percentage of PQ range. Defaults to 0.1. - **knee_maximum** (float, 0.5-1.0) - Optional - Maximum knee point as percentage of PQ range. Defaults to 0.8. - **knee_default** (float, 0.0-1.0) - Optional - Default knee point without metadata. Defaults to 0.4. - **knee_offset** (float, 0.5-2.0) - Optional - Knee point offset for bt2390. Defaults to 1.0. - **slope_tuning** (float, 0.0-10.0) - Optional - Spline slope tuning coefficient. Defaults to 1.5. - **slope_offset** (float, 0.0-1.0) - Optional - Spline slope offset. Defaults to 0.2. - **spline_contrast** (float, 0.0-1.5) - Optional - Contrast setting for spline function. Defaults to 0.5. - **reinhard_contrast** (float, 0.0-1.0) - Optional - Local contrast coefficient at display peak. Defaults to 0.5. - **linear_knee** (float, 0.0-1.0) - Optional - Knee point for legacy functions. Defaults to 0.3. - **exposure** (float, 0.0-10.0) - Optional - Linear exposure/gain for linear methods. Defaults to 1.0. - **inverse_tone_mapping** (string, yes|no) - Optional - Enable inverse tone mapping. Defaults to no. - **tone_map_metadata** (string, any|none|hdr10|hdr10plus|cie_y) - Optional - Data source for tone mapping. Defaults to any. - **tone_lut_size** (integer, 0-4096) - Optional - Tone mapping LUT size. Defaults to 256. - **contrast_recovery** (float, 0.0-2.0) - Optional - HDR contrast recovery strength. Defaults to 0.0. - **contrast_smoothness** (float, 1.0-32.0) - Optional - HDR contrast recovery lowpass kernel size. Defaults to 3.5. ``` -------------------------------- ### Apply pixel offset with OFFSET directive Source: https://libplacebo.org/custom-shaders Demonstrates shifting the sampled region by a constant pixel amount and propagating the shift to the main scaler. ```glsl //!HOOK LUMA //!BIND HOOKED //!OFFSET 100.5 100.5 vec4 hook() { // Constant offset by N pixels towards the bottom right return HOOKED_texOff(-vec2(100.5)); } ``` -------------------------------- ### 3DLUT Gamut Mapping Parameters Source: https://libplacebo.org/options Parameters for configuring the size and interpolation method of 3DLUTs used for gamut mapping. ```APIDOC ## 3DLUT Gamut Mapping Parameters ### `lut3d_size_I`, `lut3d_size_C`, `lut3d_size_h` - **Type**: integer - **Range**: 0 to 1024 - **Description**: Gamut mapping 3DLUT size for channels I, C, and h respectively. Setting a dimension to `0` picks the default value. - **Defaults**: I: 48, C: 32, h: 256 ### `lut3d_tricubic` - **Type**: boolean (yes|no) - **Description**: Use higher quality, but slower, tricubic interpolation for gamut mapping 3DLUTs. May substantially improve the 3DLUT gamut mapping accuracy, in particular at smaller 3DLUT sizes. Shouldn't have much effect at the default size. - **Default**: no ``` -------------------------------- ### Manage shader cache for pl_renderer Source: https://libplacebo.org/renderer Persist and restore compiled shader programs to avoid costly recompilation on startup. ```c static uint8_t *load_saved_cache(); static void store_saved_cache(uint8_t *cache, size_t bytes); void init() { renderer = pl_renderer_create(pllog, gpu); if (!renderer) goto error; uint8_t *cache = load_saved_cache(); if (cache) { pl_renderer_load(renderer, cache); free(cache); } // ... } void uninit() { size_t cache_bytes = pl_renderer_save(renderer, NULL); uint8_t *cache = malloc(cache_bytes); if (cache) { pl_renderer_save(renderer, cache); store_saved_cache(cache, cache_bytes); free(cache); } pl_renderer_destroy(&renderer); } ``` -------------------------------- ### Miscellaneous Renderer Settings Source: https://libplacebo.org/options Configure general renderer settings including error diffusion, color mapping, and background clearing. ```APIDOC ## Miscellaneous renderer settings ### `error_diffusion=` Enables error diffusion dithering. Error diffusion is a very slow and memory intensive method of dithering without the use of a fixed dither pattern. If set, this will be used instead of `dither_method` whenever possible. It's highly recommended to use this only for still images, not moving video. Defaults to `none`. The following options are available: * `simple`: Simple error diffusion (fast) * `false-fs`: False Floyd-Steinberg kernel (fast) * `sierra-lite`: Sierra Lite kernel (slow) * `floyd-steinberg`: Floyd-Steinberg kernel (slow) * `atkinson`: Atkinson kernel (slow) * `jarvis-judice-ninke`: Jarvis, Judice & Ninke kernel (very slow) * `stucki`: Stucki kernel (very slow) * `burkes`: Burkes kernel (very slow) * `sierra-2`: Two-row Sierra (very slow) * `sierra-3`: Three-row Sierra (very slow) ### `lut_type=` Overrides the color mapping LUT type. Defaults to `unknown`. The following options are available: * `unknown`: Unknown LUT type, try and guess from metadata * `native`: LUT is applied to raw image contents * `normalized`: LUT is applied to normalized (HDR) RGB values * `conversion`: LUT fully replaces color conversion step Note There is no way to load LUTs via the options mechanism, so this option only has an effect if the LUT is loaded via external means. ### `background_r=<0.0..1.0>`, `background_g=<0.0..1.0>`, `background_b=<0.0..1.0>` If the image being rendered does not span the entire size of the target, it will be cleared explicitly using this background color (RGB). Defaults to `0.0` for all. ### `background_transparency=<0.0..1.0>` The (inverted) alpha value of the background clear color. Defaults to `0.0`. ### `skip_target_clearing=` If set, skips clearing the background backbuffer entirely. Defaults to `no`. Note This is automatically skipped if the image to be rendered would completely cover the backbuffer. ``` -------------------------------- ### Define Specializable Shader Constants Source: https://libplacebo.org/glsl Use these functions to define tunable parameters that change infrequently. They generate specialization constants on supported platforms or fall back to literal shader #defines. ```c ident_t sh_const_int(pl_shader sh, const char *name, int val); ident_t sh_const_uint(pl_shader sh, const char *name, unsigned int val); ident_t sh_const_float(pl_shader sh, const char *name, float val); #define SH_INT(val) sh_const_int(sh, "const", val) #define SH_UINT(val) sh_const_uint(sh, "const", val) #define SH_FLOAT(val) sh_const_float(sh, "const", val) ``` -------------------------------- ### Define Uniform and Storage Buffers Source: https://libplacebo.org/custom-shaders Defines a uniform buffer 'buf_uniform' with float variables and a storage buffer 'buf_storage' with a vec2 and an array of 32 integers. The initial data for the uniform buffer is provided. ```shader //!BUFFER buf_uniform //!VAR float foo //!VAR float bar 0000000000000000 //!BUFFER buf_storage //!VAR vec2 bat //!VAR int big[32]; //!STORAGE ``` -------------------------------- ### Dithering Options Source: https://libplacebo.org/options Parameters to control the dithering process for color quantization and artifact reduction. ```APIDOC ## Dithering These options affect the way colors are dithered before output. Dithering is always required to avoid introducing banding artefacts as a result of quantization to a lower bit depth output texture. ### `dither=` Enables dithering. Defaults to `yes`. ### `dither_preset=` Overrides the value of all options in this section by their default values from the given preset. ### `dither_method=` Chooses the dithering method to use. Defaults to `blue`. The following methods are available: * `blue`: Dither with blue noise. Very high quality, but requires the use of a LUT. Warning Computing a blue noise texture with a large size can be very slow, however this only needs to be performed once. Even so, using this with a `dither_lut_size` greater than `6` is generally ill-advised. * `ordered_lut`: Dither with an ordered (bayer) dither matrix, using a LUT. Low quality, and since this also uses a LUT, there's generally no advantage to picking this instead of `blue`. It's mainly there for testing. * `ordered`: The same as `ordered`, but uses fixed function math instead of a LUT. This is faster, but only supports a fixed dither matrix size of 16x16 (equivalent to `dither_lut_size=4`). * `white`: Dither with white noise. This does not require a LUT and is fairly cheap to compute. Unlike the other modes it doesn't show any repeating patterns either spatially or temporally, but the downside is that this is visually fairly jarring due to the presence of low frequencies in the noise spectrum. ### `dither_lut_size=<1..8>` For the dither methods which require the use of a LUT (`blue`, `ordered_lut`), this controls the size of the LUT (base 2). Defaults to `6`. ### `dither_temporal=` Enables temporal dithering. This reduces the persistence of dithering artifacts by perturbing the dithering matrix per frame. Defaults to `no`. Warning This can cause nasty aliasing artifacts on some LCD screens. ``` -------------------------------- ### Initialize and Uninitialize pl_queue Source: https://libplacebo.org/renderer Initializes and destroys the `pl_queue` helper for managing frames. Ensure `gpu` is a valid graphics processing unit handle. ```c #include pl_queue queue; void init() { queue = pl_queue_create(gpu); } void uninit() { pl_queue_destroy(&queue); // ... } ``` -------------------------------- ### Shader Parameter Definition Source: https://libplacebo.org/custom-shaders Defines how to declare parameters for shaders, including types like DEFINE and ENUM, and their usage within shader code. ```APIDOC ## Shader Parameter Definition ### Description Defines parameters for shaders using the `!PARAM` syntax. Parameters can be scalars, enums, or preprocessor defines, influencing shader compilation and runtime behavior. ### Parameters - **!PARAM** (string) - Required - The name of the parameter. - **!DESC** (string) - Optional - A description of the parameter. - **!TYPE** (string) - Required - The type of the parameter (e.g., int, float, uint, ENUM, DEFINE). - **!MINIMUM** (number) - Optional - The minimum value for numeric parameters. - **!MAXIMUM** (number) - Optional - The maximum value for numeric parameters. ### Usage Examples #### Preprocessor Define ``` //!PARAM taps //!DESC Smoothing taps //!TYPE DEFINE //!MINIMUM 0 //!MAXIMUM 5 ``` #### Enumeration Parameter ``` //!PARAM csp //!DESC Colorspace //!TYPE ENUM int BT709 BT2020 DCIP3 ``` ``` -------------------------------- ### Sigmoidization Configuration Source: https://libplacebo.org/options Options for sigmoidization to reduce ringing artifacts during upscaling. ```APIDOC ## Sigmoidization Configuration ### Parameters - **sigmoid** (yes|no) - Optional - Enables sigmoidization. Defaults to yes. - **sigmoid_preset** (string) - Optional - Overrides options with preset values. - **sigmoid_center** (0.0..1.0) - Optional - Bias of the sigmoid curve. Defaults to 0.75. - **sigmoid_slope** (1.0..20.0) - Optional - Steepness of the sigmoid curve. Defaults to 6.5. ``` -------------------------------- ### Gamut Expansion Source: https://libplacebo.org/options Configuration option to enable or disable gamut expansion. ```APIDOC ## Gamut Expansion ### `gamut_expansion` - **Type**: boolean (yes|no) - **Description**: If enabled, allows the gamut mapping function to expand the gamut, in cases where the target gamut exceeds that of the source. If disabled, the source gamut will never be enlarged, even when using a gamut mapping function capable of bidirectional mapping. - **Default**: no ``` -------------------------------- ### Define Tunable Float Parameter Source: https://libplacebo.org/custom-shaders Defines a tunable float parameter named 'contrast' with a description, type, and min/max bounds. The default value is set to 1.0. ```shader //!PARAM contrast //!DESC Gain to apply to image brightness //!TYPE float //!MINIMUM 0.0 //!MAXIMUM 100.0 1.0 ``` -------------------------------- ### Scaling Options Source: https://libplacebo.org/options Configuration for image upscaling and downscaling filters, including plane-specific and temporal interpolation settings. ```APIDOC ## Scaling ### `upscaler=` Sets the filter used for upscaling. Defaults to `lanczos`. Pass `upscaler=help` to see a full list of filters. The most relevant options, roughly ordered from fastest to slowest: * `none`: No filter, only use basic GPU texture sampling * `nearest`: Nearest-neighbour (box) sampling (very fast) * `bilinear`: Bilinear sampling (very fast) * `oversample`: Aspect-ratio preserving nearest neighbour sampling (very fast) * `bicubic`: Bicubic interpolation (fast) * `gaussian`: Gaussian smoothing (fast) * `catmull_rom`: Catmull-Rom cubic spline * `lanczos`: Lanczos reconstruction * `ewa_lanczos`: EWA Lanczos ("Jinc") reconstruction (slow) * `ewa_lanczossharp`: Sharpened version of `ewa_lanczos` (slow) * `ewa_lanczos4sharpest`: Very sharp version of `ewa_lanczos`, with anti-ringing (very slow) ### `downscaler=` Sets the filter used for downscaling. Defaults to `hermite`. Pass `downscaler=help` to see a full list of filters. The most relevant options, roughly ordered from fastest to slowest: * `none`: Use the same filter as specified for `upscaler` * `box`: Box averaging (very fast) * `hermite`: Hermite-weighted averaging (fast) * `bilinear`: Bilinear (triangle) averaging (fast) * `bicubic`: Bicubic interpolation (fast) * `gaussian`: Gaussian smoothing (fast) * `catmull_rom`: Catmull-Rom cubic spline * `mitchell`: Mitchell-Netravalia cubic spline * `lanczos`: Lanczos reconstruction ### `plane_upscaler=`, `plane_downscaler=` Override the filter used for upscaling/downscaling planes, e.g. chroma/alpha. If set to `none`, use the same setting as `upscaler` and `downscaler`, respectively. Defaults to `none` for both. ### `frame_mixer=` Sets the filter used for frame mixing (temporal interpolation). Defaults to `oversample`. Pass `frame_mixer=help` to see a full list of filters. The most relevant options, roughly ordered from fastest to slowest: * `none`: Disable frame mixing, show nearest frame to target PTS * `oversample`: Oversampling, only mix "edge" frames while preserving FPS * `hermite`: Hermite-weighted frame mixing * `linear`: Linear frame mixing * `cubic`: Cubic B-spline frame mixing ### `antiringing_strength=<0.0..1.0>` Antiringing strength to use for all filters. A value of `0.0` disables antiringing, and a value of `1.0` enables full-strength antiringing. Defaults to `0.0`. Note Specific filter presets may override this option. ``` -------------------------------- ### Output Blending Options Source: https://libplacebo.org/options Settings to control how the rendered image is blended onto the output framebuffer. ```APIDOC ## Output Blending These options affect the way the image is blended onto the output framebuffer. ### `blend=` Enables output blending. Defaults to `no`. ### `blend_preset=` Overrides the value of all options in this section by their default values from the given preset. Currently, the only preset is `alpha_overlay`, which corresponds to normal alpha blending. ### `blend_src_rgb`, `blend_src_alpha`, `blend_dst_rgb`, `blend_dst_alpha` Choose the blending mode for each component. Defaults to `zero` for all. The following modes are available: * `zero`: Component will be unused. * `one`: Component will be added at full strength. * `alpha`: Component will be multiplied by the source alpha value. * `one_minus_alpha`: Component will be multiplied by 1 minus the source alpha. ``` -------------------------------- ### Distortion Configuration Source: https://libplacebo.org/options Configure settings to distort or transform the output image. ```APIDOC ## Distortion The settings in this section can be used to distort/transform the output image. ### `distort=` Enables distortion. Defaults to `no`. ### `distort_preset=` Overrides the value of all options in this section by their default values from the given preset. ### `distort_scale_x`, `distort_scale_y` Scale the image in the X/Y dimension by an arbitrary factor. Corresponds to the main diagonal of the transformation matrix. Defaults to `1.0` for both. ### `distort_shear_x`, `distort_shear_y` Adds the X/Y dimension onto the Y/X dimension (respectively), scaled by an arbitrary amount. Corresponds to the anti-diagonal of the 2x2 transformation matrix. Defaults to `0.0` for both. ### `distort_offset_x`, `distort_offset_y` Offsets the X/Y dimensions by an arbitrary offset, relative to the image size. Corresponds to the bottom row of a 3x3 affine transformation matrix. Defaults to `0.0` for both. ### `distort_unscaled=` If enabled, the texture is placed inside the center of the canvas without scaling. Otherwise, it is effectively stretched to the canvas size. Defaults to `no`. Note This option has no effect when using `pl_renderer`. ### `distort_constrain=` If enabled, the transformation is automatically scaled down and shifted to ensure that the resulting image fits inside the output canvas. Defaults to `no`. ### `distort_bicubic=` If enabled, use bicubic interpolation rather than faster bilinear interpolation. Higher quality but slower. Defaults to `no`. ### `distort_addreess_mode=` Specifies the texture address mode to use when sampling out of bounds. Defaults to `clamp`. ### `distort_alpha_mode=` If set to something other than `none`, all out-of-bounds accesses will instead be treated as transparent, according to the given alpha mode. ``` -------------------------------- ### Shader Directives Overview Source: https://libplacebo.org/custom-shaders Directives used to define shader execution points, texture access, and output management. ```APIDOC ## HOOK ### Description A HOOK directive determines when a shader stage is run within the processing pipeline. It is only possible to intercept the image at fixed hook points. ### Hook Points - RGB, LUMA, CHROMA, ALPHA, XYZ, CHROMA_SCALED, ALPHA_SCALED, NATIVE, MAIN, LINEAR, SIGMOID, PREKERNEL, POSTKERNEL, SCALED, PREOUTPUT, OUTPUT ## BIND ### Description The BIND directive makes a texture available for use in the shader. This can be a hook point, a custom texture, or a saved texture. ### Macros - NAME_raw: Raw texture sampler - NAME_pos: Texel coordinates - NAME_size: Texture size - NAME_tex(vec2 pos): Wrapper for texture sampling - NAME_texOff(vec2 offset): Access adjacent pixels ## SAVE ### Description Overrides the default behavior of capturing output back into the hooked texture, allowing the result to be saved as a new named texture. ### Request Example //!HOOK CHROMA //!BIND CHROMA //!BIND LUMA //!SAVE LUMA_LOWRES //!WIDTH CHROMA.w //!HEIGHT CHROMA.h vec4 hook() { return LUMA_texOff(0); } ``` -------------------------------- ### HDR Peak Detection Configuration Source: https://libplacebo.org/options Options for HDR peak detection to improve tone-mapping. ```APIDOC ## HDR Peak Detection Configuration ### Parameters - **peak_detect** (yes|no) - Optional - Enables HDR peak detection. Defaults to yes. - **peak_detection_preset** (default|high_quality) - Optional - Overrides options with preset values. ``` -------------------------------- ### Custom Scaler Configuration Source: https://libplacebo.org/options Defines how to configure custom filter kernels for scaling operations. ```APIDOC ### Custom scalers Custom filter kernels can be created by setting the filter to `custom`, in addition to setting the respective options, replacing `` by the corresponding scaler (`upscaler`, `downscaler`, etc.) #### `_preset=` Overrides the value of all options in this section by their default values from the given filter preset. #### `_kernel=`, `_window=` Choose the filter kernel and window function, rspectively. Pass `help` to get a full list of filter kernels. Defaults to `none`. #### `_radius=<0.0..16.0>` Override the filter kernel radius. Has no effect if the filter kernel is not resizeable. Defaults to `0.0`, meaning "no override". #### `_clamp=<0.0..1.0>` Represents an extra weighting/clamping coefficient for negative weights. A value of `0.0` represents no clamping. A value of `1.0` represents full clamping, i.e. all negative lobes will be removed. Defaults to `0.0`. #### `_blur=<0.0..100.0>` Additional blur coefficient. This effectively stretches the kernel, without changing the effective radius of the filter radius. Setting this to a value of `0.0` is equivalent to disabling it. Values significantly below `1.0` may seriously degrade the visual output, and should be used with care. Defaults to `0.0`. #### `_taper=<0.0..1.0>` Additional taper coefficient. This essentially flattens the function's center. The values within `[-taper, taper]` will return `1.0`, with the actual function being squished into the remainder of `[taper, radius]`. Defaults to `0.0`. #### `_antiring=<0.0..1.0>` Antiringing override for this filter. Defaults to `0.0`, which infers the value from `antiringing_strength`. ``` -------------------------------- ### Define Dynamic Shader Variables Source: https://libplacebo.org/glsl Use these functions for variables expected to change very frequently. They are sent as elements of a uniform buffer or directly as push constants. ```c ident_t sh_var_int(pl_shader sh, const char *name, int val, bool dynamic); ident_t sh_var_uint(pl_shader sh, const char *name, unsigned int val, bool dynamic); ident_t sh_var_float(pl_shader sh, const char *name, float val, bool dynamic); #define SH_INT_DYN(val) sh_var_int(sh, "const", val, true) #define SH_UINT_DYN(val) sh_var_uint(sh, "const", val, true) #define SH_FLOAT_DYN(val) sh_var_float(sh, "const", val, true) ``` -------------------------------- ### Conditionally execute shader with WHEN directive Source: https://libplacebo.org/custom-shaders Uses a parameter-based expression to determine if a shader stage should execute. ```glsl //!PARAM strength //!TYPE float //!MINIMUM 0 1.0 //!HOOK MAIN //!BIND HOOKED //!WHEN intensity 0 > //!DESC do something based on 'intensity' ... ``` -------------------------------- ### Color Adjustment Configuration Source: https://libplacebo.org/options Options to alter the appearance of video through color decoding adjustments. ```APIDOC ## Color Adjustment Configuration ### Parameters - **color_adjustment** (yes|no) - Optional - Enables color adjustment. Defaults to yes. - **brightness** (-1.0..1.0) - Optional - Luminance bias. Defaults to 0.0. - **contrast** (0.0..100.0) - Optional - Luminance gain. Defaults to 1.0. - **saturation** (0.0..100.0) - Optional - Chromaticity gain. Defaults to 1.0. - **hue** (angle) - Optional - Hue shift in radians. Defaults to 0.0. - **gamma** (0.0..100.0) - Optional - Gamma lift. Defaults to 1.0. - **temperature** (-1.143..5.286) - Optional - Color temperature shift. Defaults to 0.0. ``` -------------------------------- ### Deinterlacing Configuration Source: https://libplacebo.org/options Configure settings for deinterlacing frames. Note that this requires passing extra metadata to link frames. ```APIDOC ## Deinterlacing Configures the settings used to deinterlace frames, if required. Note The use of these options requires the caller to pass extra metadata to incoming frames to link them together / mark them as fields. ### `deinterlace=` Enables deinterlacing. Defaults to `no`. ### `deinterlace_preset=` Overrides the value of all options in this section by their default values from the given preset. ### `deinterlace_algo=` Chooses the algorithm to use for deinterlacing. Defaults to `yadif`. The following algorithms are available: * `weave`: No-op deinterlacing, just sample the weaved frame un-touched. * `bob`: Naive bob deinterlacing. Doubles the field lines vertically. * `yadif`: "Yet another deinterlacing filter". Deinterlacer with temporal and spatial information. Based on FFmpeg's Yadif filter algorithm, but adapted slightly for the GPU. * `bwdif`: "Bob weaver deinterlacing filter". Motion-adaptive deinterlacer based on yadif, with the use of w3fdif and cubic interpolation algorithms. ### `deinterlace_skip_spatial=` Skip the spatial interlacing check for `yadif`. Defaults to `no`. ```