diff --git a/packages/flame_3d/assets/shaders/spatial_material.shaderbundle b/packages/flame_3d/assets/shaders/spatial_material.shaderbundle index 66ac3b75cc6..3129875f793 100644 Binary files a/packages/flame_3d/assets/shaders/spatial_material.shaderbundle and b/packages/flame_3d/assets/shaders/spatial_material.shaderbundle differ diff --git a/packages/flame_3d/lib/src/resources/light/light.dart b/packages/flame_3d/lib/src/resources/light/light.dart index b6b584ed2b8..94284daec4b 100644 --- a/packages/flame_3d/lib/src/resources/light/light.dart +++ b/packages/flame_3d/lib/src/resources/light/light.dart @@ -23,8 +23,8 @@ class Light extends Resource { void createResource() {} void apply(int index, Shader shader) { - shader.setVector3('Light$index.position', transform.position); - shader.setColor('Light$index.color', source.color); - shader.setFloat('Light$index.intensity', source.intensity); + shader.setVector3('Light[$index].position', transform.position); + shader.setColor('Light[$index].color', source.color); + shader.setFloat('Light[$index].intensity', source.intensity); } } diff --git a/packages/flame_3d/lib/src/resources/light/lighting_info.dart b/packages/flame_3d/lib/src/resources/light/lighting_info.dart index b0eab1546f5..d8e801d215b 100644 --- a/packages/flame_3d/lib/src/resources/light/lighting_info.dart +++ b/packages/flame_3d/lib/src/resources/light/lighting_info.dart @@ -16,9 +16,8 @@ class LightingInfo { void _applyPointLights(Shader shader) { final pointLights = lights.where((e) => e.source is PointLight); final numLights = pointLights.length; - if (numLights > 3) { - // temporary, until we support dynamic arrays - throw Exception('At most 3 point lights are allowed'); + if (numLights > maxLights) { + throw Exception('At most $maxLights point lights are allowed'); } shader.setUint('LightsInfo.numLights', numLights); @@ -39,10 +38,13 @@ class LightingInfo { } static List shaderSlots = [ + UniformSlot.array('Light', {'position', 'color', 'intensity'}), UniformSlot.value('AmbientLight', {'color', 'intensity'}), UniformSlot.value('LightsInfo', {'numLights'}), - UniformSlot.value('Light0', {'position', 'color', 'intensity'}), - UniformSlot.value('Light1', {'position', 'color', 'intensity'}), - UniformSlot.value('Light2', {'position', 'color', 'intensity'}), ]; + + /// The maximum number of point lights supported by the shader. + /// Since we use fixed-length arrays in the shader, we cannot support an + /// arbitrary number of lights. + static const maxLights = 8; } diff --git a/packages/flame_3d/shaders/spatial_material.frag b/packages/flame_3d/shaders/spatial_material.frag index 0d99815e66f..f3172905d79 100644 --- a/packages/flame_3d/shaders/spatial_material.frag +++ b/packages/flame_3d/shaders/spatial_material.frag @@ -2,7 +2,7 @@ // implementation based on https://learnopengl.com/PBR/Lighting -// #define NUM_LIGHTS 8 +#define MAX_LIGHTS 8 #define PI 3.14159265359 #define EPSILON 0.0001 @@ -23,7 +23,13 @@ uniform Material { float roughness; } material; -// light info +// lighting info + +uniform Light { + vec3 position; + vec4 color; + float intensity; +} lights[MAX_LIGHTS]; uniform AmbientLight { vec4 color; @@ -34,30 +40,6 @@ uniform LightsInfo { uint numLights; } lightsInfo; -// uniform Light { -// vec3 position; -// vec3 color; -// float intensity; -// } lights[NUM_LIGHTS]; - -uniform Light0 { - vec3 position; - vec4 color; - float intensity; -} light0; - -uniform Light1 { - vec3 position; - vec4 color; - float intensity; -} light1; - -uniform Light2 { - vec3 position; - vec4 color; - float intensity; -} light2; - // camera info uniform Camera { @@ -150,28 +132,12 @@ void main() { vec3 lo = vec3(0.0); - if (lightsInfo.numLights > 0) { - vec3 light0Pos = light0.position; - vec3 light0Color = light0.color.rgb; - float light0Intensity = light0.intensity; - - lo += processLight(light0Pos, light0Color, light0Intensity, baseColor, normal, viewDir, diffuse); - } - - if (lightsInfo.numLights > 1) { - vec3 light1Pos = light1.position; - vec3 light1Color = light1.color.rgb; - float light1Intensity = light1.intensity; - - lo += processLight(light1Pos, light1Color, light1Intensity, baseColor, normal, viewDir, diffuse); - } - - if (lightsInfo.numLights > 2) { - vec3 light2Pos = light2.position; - vec3 light2Color = light2.color.rgb; - float light2Intensity = light2.intensity; + for (uint i = 0; i < lightsInfo.numLights; i++) { + vec3 lightPos = lights[i].position.xyz; + vec3 lightColor = lights[i].color.rgb; + float lightIntensity = lights[i].intensity; - lo += processLight(light2Pos, light2Color, light2Intensity, baseColor, normal, viewDir, diffuse); + lo += processLight(lightPos, lightColor, lightIntensity, baseColor, normal, viewDir, diffuse); } vec3 color = ambient + lo; @@ -180,4 +146,4 @@ void main() { color = pow(color, vec3(1.0 / 2.2)); outColor = vec4(color, 1.0); -} \ No newline at end of file +}