blob: d478a3a268cca1a14860816a7ecc3c81894cf5d5 [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>
/// 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.
vec4 IPSample(sampler2D texture_sampler, vec2 coords, float y_coord_scale) {
if (y_coord_scale < 0.0) {
coords.y = 1.0 - coords.y;
}
return texture(texture_sampler, coords);
}
/// 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 `coods` 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);
}
// These values must correspond to the order of the items in the
// 'Entity::TileMode' enum class.
const float kTileModeClamp = 0;
const float kTileModeRepeat = 1;
const float kTileModeMirror = 2;
const float kTileModeDecal = 3;
/// 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 y_coord_scale,
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 IPSample(tex, IPVec2Tile(coords, x_tile_mode, y_tile_mode),
y_coord_scale);
}
/// 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 y_coord_scale,
float tile_mode) {
return IPSampleWithTileMode(tex, coords, y_coord_scale, tile_mode, 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.
/// The range of `coods` 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) {
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 IPSampleLinear(tex, IPVec2Tile(coords, x_tile_mode, y_tile_mode),
y_coord_scale, half_texel);
}
/// 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 `coods` 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) {
return IPSampleLinearWithTileMode(tex, coords, y_coord_scale, half_texel,
tile_mode, tile_mode);
}
#endif