Flutter自定义着色器插件flutter_shaders的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter自定义着色器插件flutter_shaders的使用

flutter_shaders简介

flutter_shaders 是一个用于简化Flutter中FragmentProgram API使用的工具包。通过这个插件,开发者可以更方便地在Flutter应用中集成和使用自定义着色器(shaders),从而实现复杂的图形效果。

可用的着色器

该插件自带了一些预定义的着色器,可以直接在项目中引用。例如:

  • Pixelation:像素化效果,将提供的采样器缩减为MxN样本。它可以通过AnimatedSampler widget来使用。

为了在你的应用程序中包含这些着色器,你需要在pubspec.yaml文件中声明它们。以Pixelation着色器为例,在pubspec.yaml添加如下内容:

flutter:
  shaders:
    - packages/flutter_shaders/shaders/pixelation.frag

这行配置告诉Flutter从指定路径加载着色器代码。

示例代码解析

下面是一个完整的示例demo,展示了如何在Flutter应用中使用flutter_shaders创建一个带有自定义着色器效果的应用程序。

main.dart

// 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.

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

void main() async {
  // 加载着色器程序
  final ui.FragmentProgram program = await ui.FragmentProgram.fromAsset('shaders/inkwell.frag');
  
  // 启动应用程序
  runApp(MyApp(program: program));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key, required this.program});

  final ui.FragmentProgram program;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        splashFactory: ShaderInkFeatureFactory(program, (
          shader, {
          required double animation,
          required Color color,
          required Offset position,
          required Size referenceBoxSize,
          required double targetRadius,
          required TextDirection textDirection,
        }) {
          shader.setFloatUniforms((uniforms) => uniforms
            ..setFloat(animation)
            ..setColor(color, premultiply: true)
            ..setFloat(targetRadius)
            ..setOffset(position));
        }),
      ),
      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: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

解释

  1. 导入必要的库:首先导入了dart:uiflutter_shaders库。
  2. 异步加载着色器:在main()函数中,我们异步加载了一个名为inkwell.frag的着色器文件,并将其传递给MyApp构造函数。
  3. 创建MaterialApp:在MyApp类中,设置了主题并指定了一个自定义的splashFactory,它接收一个ui.FragmentProgram对象作为参数。这里使用了ShaderInkFeatureFactory工厂方法来生成带有自定义着色器效果的水波纹动画。
  4. 设置UI布局:最后,在MyHomePage中构建了一个简单的用户界面,包括一个计数器和一个浮动按钮。每次点击按钮时,计数器加一,并触发重新绘制。

以上就是关于flutter_shaders的基本使用说明及示例代码。你可以根据自己的需求修改着色器逻辑或添加更多类型的着色器到你的Flutter项目中。


更多关于Flutter自定义着色器插件flutter_shaders的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义着色器插件flutter_shaders的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中使用自定义着色器插件flutter_shaders可以极大地增强图形渲染能力。以下是一个基本的示例,展示了如何在Flutter项目中集成和使用flutter_shaders

步骤1:添加依赖

首先,在你的pubspec.yaml文件中添加flutter_shaders依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_shaders: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

步骤2:创建自定义着色器

接下来,你需要编写自定义的GLSL(OpenGL Shading Language)着色器代码。假设我们有一个简单的顶点着色器vertex_shader.glsl和一个片段着色器fragment_shader.glsl

vertex_shader.glsl

#version 300 es
precision mediump float;

in vec4 a_position;
in vec2 a_texCoord;

uniform mat4 u_matrix;

out vec2 v_texCoord;

void main() {
  gl_Position = u_matrix * a_position;
  v_texCoord = a_texCoord;
}

fragment_shader.glsl

#version 300 es
precision mediump float;

in vec2 v_texCoord;

uniform sampler2D u_texture;
uniform vec4 u_color;

out vec4 outColor;

void main() {
  vec4 texColor = texture(u_texture, v_texCoord);
  outColor = texColor * u_color;
}

步骤3:编写Flutter代码加载和使用着色器

在你的Flutter项目中,创建一个新的Dart文件,例如custom_shader.dart,并在其中编写代码以加载和使用这些着色器。

custom_shader.dart

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

class CustomShaderWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 加载自定义着色器
    final vertexShader = ShaderProgram.fromFiles('vertex_shader.glsl', 'fragment_shader.glsl');

    // 创建材质
    final material = Material(
      shader: ShaderMaterial(
        shaderProgram: vertexShader,
        uniforms: {
          'u_matrix': Matrix4.identity(), // 这里可以根据需要进行变换
          'u_texture': TextureUniform.fromImage(Image.asset('assets/your_image.png').image), // 替换为你的图像资源
          'u_color': Color(0xFF00FF00).toVector4(), // 绿色
        },
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Shader Example'),
      ),
      body: Center(
        child: CustomPaint(
          painter: CustomShaderPainter(material),
          size: Size(300, 300), // 根据需要调整大小
        ),
      ),
    );
  }
}

class CustomShaderPainter extends CustomPainter {
  final Material material;

  CustomShaderPainter(this.material);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..shader = material.createShader(size);
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false; // 除非你的着色器需要动态更新,否则通常返回false
  }
}

步骤4:在应用程序中使用自定义着色器小部件

最后,在你的main.dart文件中使用CustomShaderWidget

main.dart

import 'package:flutter/material.dart';
import 'custom_shader.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Custom Shader Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CustomShaderWidget(),
    );
  }
}

注意事项

  1. 确保你的GLSL文件已经正确放置在项目的资源目录中,并且在pubspec.yaml中正确引用。
  2. 图像资源(如assets/your_image.png)也需要在pubspec.yaml中进行声明。
  3. 这是一个基本示例,实际应用中可能需要根据具体需求调整着色器代码和Flutter代码。

通过上述步骤,你应该能够在Flutter应用中成功集成和使用自定义着色器。

回到顶部