Skip to content

[Impeller] Sampling textures seem to have a black background sometimes #115031

@jonahwilliams

Description

@jonahwilliams

When the following application is run on Skia, we get the following expected output:

When running this on impeller, this shows with a black rectangle:

If I comment out the Text widgets in the Column, this renders correctly:

Adding other colors to the resulting output works correctly in all cases, so the problem seems to be with the texture.

main.dart

import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter_shaders/flutter_shaders.dart';

void main() {
  runApp(const MyApp());
}

final transform = Matrix4.identity().storage;

class MyApp extends StatelessWidget {
  const MyApp({super.key});


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: RepaintBoundary(
          child: ShaderBuilder(
            (BuildContext context, FragmentShader shader, Widget? child) {
              return AnimatedSampler(
                (ui.Image image, Size size, Offset offset, ui.Canvas canvas) {
                  canvas.translate(offset.dx, offset.dy);
                  var sampler = ImageShader(image, TileMode.clamp, TileMode.clamp, transform);
                  shader.setFloat(0, size.width);
                  shader.setFloat(1, size.height);
                  shader.setSampler(0, sampler);
                  canvas.translate(offset.dx, offset.dy);
                  canvas.drawRect(Offset.zero & size, Paint()..shader = shader);
                },
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      const Text(
                        'You have pushed the button this many times:',
                      ),
                      Text(
                        '$_counter',
                        style: Theme.of(context).textTheme.headlineMedium,
                      ),
                    ],
                  ),
                );
            },
            assetKey: 'shaders/sampler.frag',
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

shaders/sampler.frag

precision highp float;

#include <flutter/runtime_effect.glsl>

layout(location = 0) uniform vec2 size;
layout(location = 1) uniform sampler2D uTexture;

out vec4 fragColor;

void main() {
  vec2 uv = FlutterFragCoord() / size;
  fragColor = texture(uTexture, uv);
}

pubspec.yaml

name: foo_bar_shaders
description: A new Flutter project.

environment:
  sdk: '>=2.19.0-374.0.dev <3.0.0'

dependencies:
  flutter:
    sdk: flutter
  flutter_shaders: ^0.0.1
  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

flutter:
  shaders:
    - shaders/blur.frag
    - shaders/sampler.frag

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions