Skip to content

Commit

Permalink
feat!: Allow for custom shaders and materials (#3384)
Browse files Browse the repository at this point in the history
Allows for custom materials and shaders.
  • Loading branch information
wolfenrain authored Dec 14, 2024
1 parent f940d3f commit ae73181
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class SpatialMaterial extends Material {
this.roughness = 0.6,
}) : albedoTexture = albedoTexture ?? Texture.standard,
super(
vertexShader: Shader(
name: 'TextureVertex',
vertexShader: Shader.vertex(
asset:
'packages/flame_3d/assets/shaders/spatial_material.shaderbundle',
slots: [
UniformSlot.value('VertexInfo', {
'model',
Expand All @@ -26,8 +27,9 @@ class SpatialMaterial extends Material {
),
],
),
fragmentShader: Shader(
name: 'TextureFragment',
fragmentShader: Shader.fragment(
asset:
'packages/flame_3d/assets/shaders/spatial_material.shaderbundle',
slots: [
UniformSlot.sampler('albedoTexture'),
UniformSlot.value('Material', {
Expand Down
52 changes: 30 additions & 22 deletions packages/flame_3d/lib/src/resources/shader/shader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,53 @@ import 'package:flame_3d/graphics.dart';
import 'package:flame_3d/resources.dart';
import 'package:flutter_gpu/gpu.dart' as gpu;

/// {@template shader}
/// {@template shader_resource}
///
/// {@endtemplate}
class ShaderResource extends Resource<gpu.Shader> {
final Shader shader;
/// {@macro shader_resource}
factory ShaderResource.createFromAsset({
required String asset,
required String shaderName,
required List<UniformSlot> slots,
}) {
final library = gpu.ShaderLibrary.fromAsset(asset)!;

/// {@macro shader}
ShaderResource(
super.resource, {
required String name,
List<UniformSlot> slots = const [],
}) : shader = Shader(name: name, slots: slots) {
for (final slot in slots) {
slot.resource = resource.getUniformSlot(slot.name);
final shader = library[shaderName];
if (shader == null) {
throw StateError('Shader "$shaderName" not found in library "$asset"');
}
return ShaderResource._(shader, slots: slots);
}

factory ShaderResource.create({
required String name,
required List<UniformSlot> slots,
ShaderResource._(
super.resource, {
List<UniformSlot> slots = const [],
}) {
final shader = _library[name];
if (shader == null) {
throw StateError('Shader "$name" not found in library');
for (final slot in slots) {
slot.resource = resource.getUniformSlot(slot.name);
}
return ShaderResource(shader, name: name, slots: slots);
}

static final _library = gpu.ShaderLibrary.fromAsset(
'packages/flame_3d/assets/shaders/spatial_material.shaderbundle',
)!;
}

class Shader {
final String asset;
final String name;
final List<UniformSlot> slots;
final Map<String, UniformInstance> instances = {};

Shader({
required this.asset,
required this.name,
required this.slots,
});

Shader.vertex({required String asset, required List<UniformSlot> slots})
: this(asset: asset, name: 'TextureVertex', slots: slots);

Shader.fragment({required String asset, required List<UniformSlot> slots})
: this(asset: asset, name: 'TextureFragment', slots: slots);

/// Set a [Texture] at the given [key] on the buffer.
void setTexture(String key, Texture texture) => _setTypedValue(key, texture);

Expand Down Expand Up @@ -140,6 +144,10 @@ class Shader {
}

ShaderResource compile() {
return ShaderResource.create(name: name, slots: slots);
return ShaderResource.createFromAsset(
asset: asset,
shaderName: name,
slots: slots,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ void main() {

Shader _createShader(List<UniformSlot> slots) {
return Shader(
asset: 'none',
name: '-test-',
slots: slots,
);
Expand Down

0 comments on commit ae73181

Please sign in to comment.