mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Make gradients work as expected (flutter/engine#36140)
This commit is contained in:
parent
be6a4135d3
commit
ab5cbe1c52
@ -19,6 +19,18 @@ vec4 IPSample(sampler2D texture_sampler, vec2 coords, float y_coord_scale) {
|
||||
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;
|
||||
@ -81,4 +93,36 @@ vec4 IPSampleWithTileMode(sampler2D tex,
|
||||
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
|
||||
|
||||
@ -64,6 +64,8 @@ bool LinearGradientContents::Render(const ContentContext& renderer,
|
||||
gradient_info.texture_sampler_y_coord_scale =
|
||||
gradient_texture->GetYCoordScale();
|
||||
gradient_info.alpha = GetAlpha();
|
||||
gradient_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
|
||||
0.5 / gradient_texture->GetSize().height);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
|
||||
@ -63,6 +63,8 @@ bool RadialGradientContents::Render(const ContentContext& renderer,
|
||||
gradient_info.texture_sampler_y_coord_scale =
|
||||
gradient_texture->GetYCoordScale();
|
||||
gradient_info.alpha = GetAlpha();
|
||||
gradient_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
|
||||
0.5 / gradient_texture->GetSize().height);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
|
||||
@ -70,6 +70,8 @@ bool SweepGradientContents::Render(const ContentContext& renderer,
|
||||
gradient_texture->GetYCoordScale();
|
||||
gradient_info.tile_mode = static_cast<Scalar>(tile_mode_);
|
||||
gradient_info.alpha = GetAlpha();
|
||||
gradient_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
|
||||
0.5 / gradient_texture->GetSize().height);
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
|
||||
@ -12,6 +12,7 @@ uniform GradientInfo {
|
||||
float tile_mode;
|
||||
float texture_sampler_y_coord_scale;
|
||||
float alpha;
|
||||
vec2 half_texel;
|
||||
} gradient_info;
|
||||
|
||||
in vec2 v_position;
|
||||
@ -25,11 +26,11 @@ void main() {
|
||||
gradient_info.end_point - gradient_info.start_point
|
||||
);
|
||||
float t = dot / (len * len);
|
||||
frag_color = IPSampleWithTileMode(
|
||||
frag_color = IPSampleLinearWithTileMode(
|
||||
texture_sampler,
|
||||
vec2(t, 0.5),
|
||||
gradient_info.texture_sampler_y_coord_scale,
|
||||
gradient_info.tile_mode,
|
||||
gradient_info.half_texel,
|
||||
gradient_info.tile_mode);
|
||||
frag_color = vec4(frag_color.xyz * frag_color.a, frag_color.a) * gradient_info.alpha;
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ uniform GradientInfo {
|
||||
float tile_mode;
|
||||
float texture_sampler_y_coord_scale;
|
||||
float alpha;
|
||||
vec2 half_texel;
|
||||
} gradient_info;
|
||||
|
||||
in vec2 v_position;
|
||||
@ -21,11 +22,11 @@ out vec4 frag_color;
|
||||
void main() {
|
||||
float len = length(v_position - gradient_info.center);
|
||||
float t = len / gradient_info.radius;
|
||||
frag_color = IPSampleWithTileMode(
|
||||
frag_color = IPSampleLinearWithTileMode(
|
||||
texture_sampler,
|
||||
vec2(t, 0.5),
|
||||
gradient_info.texture_sampler_y_coord_scale,
|
||||
gradient_info.tile_mode,
|
||||
gradient_info.half_texel,
|
||||
gradient_info.tile_mode);
|
||||
frag_color = vec4(frag_color.xyz * frag_color.a, frag_color.a) * gradient_info.alpha;
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ uniform GradientInfo {
|
||||
float tile_mode;
|
||||
float texture_sampler_y_coord_scale;
|
||||
float alpha;
|
||||
vec2 half_texel;
|
||||
} gradient_info;
|
||||
|
||||
in vec2 v_position;
|
||||
@ -25,11 +26,11 @@ void main() {
|
||||
float angle = atan(-coord.y, -coord.x);
|
||||
|
||||
float t = (angle * k1Over2Pi + 0.5 + gradient_info.bias) * gradient_info.scale;
|
||||
frag_color = IPSampleWithTileMode(
|
||||
frag_color = IPSampleLinearWithTileMode(
|
||||
texture_sampler,
|
||||
vec2(t, 0.5),
|
||||
gradient_info.texture_sampler_y_coord_scale,
|
||||
gradient_info.tile_mode,
|
||||
gradient_info.half_texel,
|
||||
gradient_info.tile_mode);
|
||||
frag_color = vec4(frag_color.xyz * frag_color.a, frag_color.a) * gradient_info.alpha;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user