blob: 56be817085db3e9bfdd663d18b3a52d321fcb8ea [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TEXTURE_GLSL_
#define TEXTURE_GLSL_
#include <impeller/branching.glsl>
#include <impeller/conversions.glsl>
#include <impeller/tile_mode.glsl>
#include <impeller/types.glsl>
/// Sample from a texture.
///
/// If `y_coord_scale` < 0.0, the Y coordinate is flipped. This is useful
/// for Impeller graphics backends that use a flipped framebuffer coordinate
/// space.
///
/// A negative mip bias is applied to improve the sharpness of scaled down
/// images when mip sampling is enabled. See `kDefaultMipBias` for more detail.
vec4 IPSample(sampler2D texture_sampler, vec2 coords, float y_coord_scale) {
return texture(texture_sampler, IPRemapCoords(coords, y_coord_scale),
kDefaultMipBias);
}
/// Sample from a texture.
///
/// If `y_coord_scale` < 0.0, the Y coordinate is flipped. This is useful
/// for Impeller graphics backends that use a flipped framebuffer coordinate
/// space.
/// The range of `coords` will be mapped from [0, 1] to [half_texel, 1 -
/// half_texel]
vec4 IPSampleLinear(sampler2D texture_sampler,
vec2 coords,
float y_coord_scale,
vec2 half_texel) {
coords.x = mix(half_texel.x, 1 - half_texel.x, coords.x);
coords.y = mix(half_texel.y, 1 - half_texel.y, coords.y);
return IPSample(texture_sampler, coords, y_coord_scale);
}
/// Remap a float using a tiling mode.
///
/// When `tile_mode` is `kTileModeDecal`, no tiling is applied and `t` is
/// returned. In all other cases, a value between 0 and 1 is returned by tiling
/// `t`.
/// When `t` is between [0 to 1), the original unchanged `t` is always returned.
float IPFloatTile(float t, float tile_mode) {
if (tile_mode == kTileModeClamp) {
t = clamp(t, 0.0, 1.0);
} else if (tile_mode == kTileModeRepeat) {
t = fract(t);
} else if (tile_mode == kTileModeMirror) {
float t1 = t - 1;
float t2 = t1 - 2 * floor(t1 * 0.5) - 1;
t = abs(t2);
}
return t;
}
/// Remap a vec2 using a tiling mode.
///
/// Runs each component of the vec2 through `IPFloatTile`.
vec2 IPVec2Tile(vec2 coords, float x_tile_mode, float y_tile_mode) {
return vec2(IPFloatTile(coords.x, x_tile_mode),
IPFloatTile(coords.y, y_tile_mode));
}
/// Sample a texture, emulating a specific tile mode.
///
/// This is useful for Impeller graphics backend that don't have native support
/// for Decal.
vec4 IPSampleWithTileMode(sampler2D tex,
vec2 coords,
float x_tile_mode,
float y_tile_mode) {
if (x_tile_mode == kTileModeDecal && (coords.x < 0 || coords.x >= 1) ||
y_tile_mode == kTileModeDecal && (coords.y < 0 || coords.y >= 1)) {
return vec4(0);
}
return texture(tex, coords, kDefaultMipBias);
}
const float16_t kTileModeDecalHf = 3.0hf;
/// Sample a texture, emulating a specific tile mode.
///
/// This is useful for Impeller graphics backend that don't have native support
/// for Decal.
f16vec4 IPHalfSampleWithTileMode(f16sampler2D tex,
vec2 coords,
float16_t x_tile_mode,
float16_t y_tile_mode) {
if (x_tile_mode == kTileModeDecalHf && (coords.x < 0.0 || coords.x >= 1.0) ||
y_tile_mode == kTileModeDecalHf && (coords.y < 0.0 || coords.y >= 1.0)) {
return f16vec4(0.0hf);
}
return texture(tex, coords, kDefaultMipBiasHalf);
}
/// Sample a texture, emulating a specific tile mode.
///
/// This is useful for Impeller graphics backend that don't have native support
/// for Decal.
/// The range of `coords` will be mapped from [0, 1] to [half_texel, 1 -
/// half_texel]
vec4 IPSampleLinearWithTileMode(sampler2D tex,
vec2 coords,
float y_coord_scale,
vec2 half_texel,
float x_tile_mode,
float y_tile_mode,
vec4 decal_border_color) {
if (x_tile_mode == kTileModeDecal && (coords.x < 0 || coords.x >= 1) ||
y_tile_mode == kTileModeDecal && (coords.y < 0 || coords.y >= 1)) {
return decal_border_color;
}
return IPSampleLinear(tex, IPVec2Tile(coords, x_tile_mode, y_tile_mode),
y_coord_scale, half_texel);
}
/// Sample a texture with decal tile mode.
vec4 IPSampleDecal(sampler2D texture_sampler, vec2 coords) {
if (any(lessThan(coords, vec2(0))) ||
any(greaterThanEqual(coords, vec2(1)))) {
return vec4(0);
}
return texture(texture_sampler, coords, kDefaultMipBias);
}
/// Sample a texture with decal tile mode.
f16vec4 IPHalfSampleDecal(f16sampler2D texture_sampler, vec2 coords) {
if (any(lessThan(coords, vec2(0))) ||
any(greaterThanEqual(coords, vec2(1)))) {
return f16vec4(0.0);
}
return texture(texture_sampler, coords, kDefaultMipBiasHalf);
}
/// Sample a texture, emulating a specific tile mode.
///
/// This is useful for Impeller graphics backend that don't have native support
/// for Decal.
/// The range of `coords` will be mapped from [0, 1] to [half_texel, 1 -
/// half_texel]
vec4 IPSampleLinearWithTileMode(sampler2D tex,
vec2 coords,
float y_coord_scale,
vec2 half_texel,
float tile_mode,
vec4 decal_border_color) {
return IPSampleLinearWithTileMode(tex, coords, y_coord_scale, half_texel,
tile_mode, tile_mode, decal_border_color);
}
#endif