|
1 | | -use bevy_asset::Handle; |
| 1 | +use bevy_asset::{Assets, Handle, RenderAssetUsages}; |
2 | 2 | use bevy_camera::visibility::Visibility; |
| 3 | +use bevy_color::{Color, ColorToComponents, Srgba}; |
3 | 4 | use bevy_ecs::prelude::*; |
4 | 5 | use bevy_image::Image; |
5 | 6 | use bevy_math::{Quat, UVec2}; |
6 | 7 | use bevy_reflect::prelude::*; |
7 | 8 | use bevy_transform::components::Transform; |
| 9 | +use wgpu_types::{ |
| 10 | + Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor, TextureViewDimension, |
| 11 | +}; |
8 | 12 |
|
9 | 13 | /// A marker component for a light probe, which is a cuboid region that provides |
10 | 14 | /// global illumination to all fragments inside it. |
@@ -96,6 +100,73 @@ pub struct EnvironmentMapLight { |
96 | 100 | pub affects_lightmapped_mesh_diffuse: bool, |
97 | 101 | } |
98 | 102 |
|
| 103 | +impl EnvironmentMapLight { |
| 104 | + /// An environment map with a uniform color, useful for uniform ambient lighting. |
| 105 | + pub fn solid_color(assets: &mut Assets<Image>, color: impl Into<Color>) -> Self { |
| 106 | + let color = color.into(); |
| 107 | + Self::hemispherical_gradient(assets, color, color, color) |
| 108 | + } |
| 109 | + |
| 110 | + /// An environment map with a hemispherical gradient, fading between the sky and ground colors |
| 111 | + /// at the horizon. Useful as a very simple 'sky'. |
| 112 | + pub fn hemispherical_gradient( |
| 113 | + assets: &mut Assets<Image>, |
| 114 | + top_color: impl Into<Color>, |
| 115 | + mid_color: impl Into<Color>, |
| 116 | + bottom_color: impl Into<Color>, |
| 117 | + ) -> Self { |
| 118 | + let handle = assets.add(Self::hemispherical_gradient_cubemap( |
| 119 | + top_color.into(), |
| 120 | + mid_color.into(), |
| 121 | + bottom_color.into(), |
| 122 | + )); |
| 123 | + |
| 124 | + Self { |
| 125 | + diffuse_map: handle.clone(), |
| 126 | + specular_map: handle, |
| 127 | + ..Default::default() |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + pub(crate) fn hemispherical_gradient_cubemap( |
| 132 | + top_color: Color, |
| 133 | + mid_color: Color, |
| 134 | + bottom_color: Color, |
| 135 | + ) -> Image { |
| 136 | + let top_color: Srgba = top_color.into(); |
| 137 | + let mid_color: Srgba = mid_color.into(); |
| 138 | + let bottom_color: Srgba = bottom_color.into(); |
| 139 | + Image { |
| 140 | + texture_view_descriptor: Some(TextureViewDescriptor { |
| 141 | + dimension: Some(TextureViewDimension::Cube), |
| 142 | + ..Default::default() |
| 143 | + }), |
| 144 | + ..Image::new( |
| 145 | + Extent3d { |
| 146 | + width: 1, |
| 147 | + height: 1, |
| 148 | + depth_or_array_layers: 6, |
| 149 | + }, |
| 150 | + TextureDimension::D2, |
| 151 | + [ |
| 152 | + mid_color, |
| 153 | + mid_color, |
| 154 | + top_color, |
| 155 | + bottom_color, |
| 156 | + mid_color, |
| 157 | + mid_color, |
| 158 | + ] |
| 159 | + .into_iter() |
| 160 | + .flat_map(|c| c.to_f32_array().map(half::f16::from_f32)) |
| 161 | + .flat_map(half::f16::to_le_bytes) |
| 162 | + .collect(), |
| 163 | + TextureFormat::Rgba16Float, |
| 164 | + RenderAssetUsages::RENDER_WORLD, |
| 165 | + ) |
| 166 | + } |
| 167 | + } |
| 168 | +} |
| 169 | + |
99 | 170 | impl Default for EnvironmentMapLight { |
100 | 171 | fn default() -> Self { |
101 | 172 | EnvironmentMapLight { |
|
0 commit comments