nmfisher / flutter_filament

3D rendering layer for Flutter/Filament
Other
44 stars 7 forks source link

Type and position of addLight has no effect #23

Open Hannnes1 opened 1 month ago

Hannnes1 commented 1 month ago

When adding a light with FilamentControllerFFI.addLight, it seems like the position parameters has no effect.

For example

filamentController.addLight(1, 6000, 10000, 0, 0, 0, 0, 0, -1, true);

Produces exactly the same output as

filamentController.addLight(1, 1500, 100000, 10000, 10000, 10000, 0, 0, -1, true);

I also tried to change the position afterwards, but I can't get that to work either:

final _lightId = await filamentController.addLight(1, 1500, 100000, 0, 0, 0, 0, 0, -1, true);

await filamentController.setPosition(_lightId, -1000, 0, 0);

I also have issues with setting the light type. The documentation mentions five different lights (that i assume correlates to an int of 0 to 4), but only light 0 and 1 (SUN and DIRECTIONAL?) produces any light at all.

Despite the above, the color, intensity and direction works as expected.

For reference, this is the code that I tested with. The issue is most visible with a large, shiny objects. I have tested on both the develop and feature/instancing (that branch had the most resent commit).

import 'package:flutter/material.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament/filament_controller_ffi.dart';
import 'package:flutter_filament/widgets/filament_widget.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TestPage(),
    );
  }
}

class TestPage extends StatefulWidget {
  const TestPage({super.key});

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  final FilamentController _filamentController = FilamentControllerFFI();

  @override
  void initState() {
    super.initState();

    Future(() async {
      await Future.delayed(const Duration(milliseconds: 100));

      await _filamentController.createViewer();

      await _filamentController.setRendering(true);

      final modelId = await _filamentController.loadGlb('assets/1.glb');

      await _filamentController.setPosition(modelId, 0, 0, -2);

      // Change parameters here to see the issue.
      await _filamentController.addLight(1, 6000, 100000, 0, 0, 0, 0, 0, -1, true);
    });
  }

  @override
  void dispose() {
    super.dispose();

    _filamentController.destroy();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Stack(
        children: [
          const Positioned.fill(
            child: ColoredBox(
              color: Colors.blueGrey,
            ),
          ),
          Positioned.fill(
            top: 100,
            bottom: 100,
            child: FilamentWidget(
              controller: _filamentController,
            ),
          ),
        ],
      ),
    );
  }
}
nmfisher commented 1 month ago

Directional lights in Filament (Light::Type::SUN and Light::Type::DIRECTIONAL) only have a direction, not a position.

https://github.com/google/filament/blob/main/filament/include/filament/LightManager.h

(there's no fall-off, so the position would be redundant)

Point/spot lights will recognize the specified position, however one constant source of frustration for me is the difference in lux calculations between Filament and Blender which means you really need to correct the camera exposure, but that doesn't look like your problem).

Which asset/platform are you using? Can you at least see your object with an indirect light source?

Hannnes1 commented 1 month ago

Okay, that makes sense.

I have tried with a few different assets, on both Android and iOS. The default cube in blender should be enough to see the issue though.

I probably don't understand the lightning in filament completely, but I thought this code (the rest is the same as above) would at least show me something overexposed

...
      final modelId = await _filamentController.loadGlb('assets/cube.glb');

      await _filamentController.setPosition(modelId, 0, 0, -5);

      await _filamentController.addLight(3, 6000, 100000000000, 0, 0, 0, 0, 0, 0, true);
...

But all I see is a black cube

9C1AE452-277B-452B-84C6-78A6E83FA86A

nmfisher commented 1 month ago

Does the cube have a material assigned in Blender?

Hannnes1 commented 1 month ago

It does. I have tried with a few different materials, both reflective and not. Here is the model from the image above: https://drive.google.com/file/d/1DYxsaRniAr8rdyfC1Q8q8fg0X-V7fJXo/view?usp=sharing

nmfisher commented 1 month ago

OK, it looks like I've broken something. Let me investigate.

nmfisher commented 1 month ago

A spot light with position to (0,1,0) and direction to (0,-1,0) works on MacOS/iOS: Screenshot 2024-03-26 at 12 20 19 AM IMG_17C61DD4AB9E-1

I have pushed quite a few changes, but the only one relevant to the lighting is adding a transform (so we can manipulate with the gizmo), and I don't think that should make a difference.

Maybe try the example project on iOS and see if it works? I have merged everything into develop, but this won't work on Android/Windows as I need to compile the gizmo material. There are unfortunately quite a few Dart import changes required, I had to restructure everything to get a handle, basically you should now just import package:flutter_filament/flutter_filament.dart.

(in your comment above you used a direction of (0,0,0) which might cause issues, make sure you're pointing in an actual direction)

Hannnes1 commented 1 month ago

The example project works for me on iOS now as well. Still not seeing any light in my other project, it doesn't seem like it is due to this package at least.

I will keep playing around with it to see if I can figure it out.

Hannnes1 commented 2 weeks ago

Hi, Sorry for taking so long to update this. I had to prioritize some other stuff.

I think I'm doing something wrong, because I still can't get anything other than sun or directional light to work.

I just tested the code below on the latest commit on develop. If I haven't misunderstood the coordinate system, I should have a light placed slightly above the cube, pointing down. I have attached some screenshots below.

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

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TestPage(),
    );
  }
}

class TestPage extends StatefulWidget {
  const TestPage({super.key});

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  final FilamentController _filamentController = FilamentControllerFFI();

  int count = 0;

  @override
  void initState() {
    super.initState();

    Future(() async {
      await Future.delayed(const Duration(milliseconds: 100));

      await _filamentController.createViewer();

      await _filamentController.setRendering(true);

      final modelId = await _filamentController.loadGlb('assets/cube.glb');

      await _filamentController.setPosition(modelId, 0, 0, -6);

      await _filamentController.setRotation(modelId, 0.5, 1, 0, 0);

      // Change parameters here to see the issue.
      await _filamentController.addLight(3, 6000, 8000000, 0, 1, -6, 0, -1, 0, true);
    });
  }

  @override
  void dispose() {
    super.dispose();

    _filamentController.destroy();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
            child: Stack(
              children: [
                const Positioned.fill(
                  child: ColoredBox(
                    color: Colors.blueGrey,
                  ),
                ),
                Positioned.fill(
                  top: 120.0 + count,
                  bottom: 100,
                  child: FilamentWidget(
                    controller: _filamentController,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Here is the material in Blender: Screenshot 2024-04-30 at 12 49 44

Directional light (await _filamentController.addLight(1, 6000, 8000000, 0, 1, -6, 0, -1, 0, true);): Screenshot 2024-04-30 at 12 51 54

Spot light (await _filamentController.addLight(3, 6000, 8000000, 0, 1, -6, 0, -1, 0, true);): Screenshot 2024-04-30 at 12 53 38

Appreciate your help!

nmfisher commented 2 weeks ago

No problem at all and thanks again for submitting this issue. I confirm I can reproduce it (on macOS). If I manually set the position of the light, I can at least get it to appear:

...
var light = await _filamentController!
          .addLight(2, 6000, 10000000, 0, 0, 0, 0, -1, 0, true);
await _filamentController!.setPosition(light, 0, 1.2, -6);

I suspect that the initial position specified when creating a light is actually separate from its transform, so if it's not created at (0,0,0) then we either need to invert this before applying the transform, or don't allow creating lights with an initial position. I'll take a closer look.

Hannnes1 commented 2 weeks ago

Great, thanks! I will try your workaround when I'm back in office tomorrow. If that works, I'm happy for now :)

Hannnes1 commented 2 weeks ago

That worked, thank you. It seems like part of the problem before has been the short distance that the light reaches. After some experimenting it seems like the light fades away at 1 unit.

So if I had a cube with the size 2x2x2 placed at 0,0,-6, a spotlight with the direction 0,0,-1 has to be between 0,0,-4 and 0,0,-3 to be visible (no matter the intensity). Is that intentional, and is it possible to change?

Hope my description is understandable. I can see if I can make a video otherwise.

nmfisher commented 2 weeks ago

It is possible to adjust the fall-off/attenuation radius, but I didn't expose this on the Flutter/Dart side. I'll add this to the list of improvements.

Hannnes1 commented 2 weeks ago

Alright, good to know. Thanks!