mirror of
https://github.com/bevyengine/bevy
synced 2025-03-02 06:17:18 +00:00
Add transmission, thickness and diffuse transmission textures
This commit is contained in:
parent
08e7416b7f
commit
272b696d78
4 changed files with 99 additions and 3 deletions
|
@ -157,6 +157,23 @@ pub struct StandardMaterial {
|
|||
/// mesh shapes without having to fine tune the thickness, consider using the [`NotTransmittedShadowReceiver`](crate::light::NotTransmittedShadowReceiver) component.
|
||||
pub diffuse_transmission: f32,
|
||||
|
||||
/// A map that modulates diffuse transmission via its **A channel**. Multiplied by [`StandardMaterial::diffuse_transmission`]
|
||||
/// to obtain the final result.
|
||||
///
|
||||
/// **Important:** The [`StandardMaterial::diffuse_transmission`] property must be set to a value higher than 0.0,
|
||||
/// or this texture won't have any effect.
|
||||
///
|
||||
/// **Note:** Due to how channels are mapped, you can more efficiently use a single shared texture image
|
||||
/// for configuring the following:
|
||||
///
|
||||
/// - R - `transmission_texture`
|
||||
/// - G - `thickness_texture`
|
||||
/// - B - _unused_
|
||||
/// - A - `diffuse_transmission_texture`
|
||||
#[texture(17)]
|
||||
#[sampler(18)]
|
||||
pub diffuse_transmission_texture: Option<Handle<Image>>,
|
||||
|
||||
/// The amount of light transmitted _specularly_ through the material (i.e. via refraction)
|
||||
///
|
||||
/// Implemented as a relatively expensive screen-space effect that allows ocluded objects to be seen through the material, while
|
||||
|
@ -171,6 +188,23 @@ pub struct StandardMaterial {
|
|||
/// **Note:** Typically used in conjunction with [`StandardMaterial::thickness`] and [`StandardMaterial::ior`].
|
||||
pub transmission: f32,
|
||||
|
||||
/// A map that modulates specular transmission via its **R channel**. Multiplied by [`StandardMaterial::transmission`]
|
||||
/// to obtain the final result.
|
||||
///
|
||||
/// **Important:** The [`StandardMaterial::transmission`] property must be set to a value higher than 0.0,
|
||||
/// or this texture won't have any effect.
|
||||
///
|
||||
/// **Note:** Due to how channels are mapped, you can more efficiently use a single shared texture image
|
||||
/// for configuring the following:
|
||||
///
|
||||
/// - R - `transmission_texture`
|
||||
/// - G - `thickness_texture`
|
||||
/// - B - _unused_
|
||||
/// - A - `diffuse_transmission_texture`
|
||||
#[texture(13)]
|
||||
#[sampler(14)]
|
||||
pub transmission_texture: Option<Handle<Image>>,
|
||||
|
||||
/// Thickness of the volume beneath the material surface.
|
||||
///
|
||||
/// When set to `0.0` (the default) the material appears as an infinitely-thin film,
|
||||
|
@ -182,6 +216,23 @@ pub struct StandardMaterial {
|
|||
/// [`StandardMaterial::diffuse_transmission`].
|
||||
pub thickness: f32,
|
||||
|
||||
/// A map that modulates thickness via its G channel. Multiplied by [`StandardMaterial::thickness`]
|
||||
/// to obtain the final result.
|
||||
///
|
||||
/// **Important:** The [`StandardMaterial::thickness`] property must be set to a value higher than 0.0,
|
||||
/// or this texture won't have any effect.
|
||||
///
|
||||
/// **Note:** Due to how channels are mapped, you can more efficiently use a single shared texture image
|
||||
/// for configuring the following:
|
||||
///
|
||||
/// - R - `transmission_texture`
|
||||
/// - G - `thickness_texture`
|
||||
/// - B - _unused_
|
||||
/// - A - `diffuse_transmission_texture`
|
||||
#[texture(15)]
|
||||
#[sampler(16)]
|
||||
pub thickness_texture: Option<Handle<Image>>,
|
||||
|
||||
/// The index of refraction of the material
|
||||
///
|
||||
/// | Material | Index of Refraction |
|
||||
|
@ -403,8 +454,11 @@ impl Default for StandardMaterial {
|
|||
// <https://google.github.io/filament/Material%20Properties.pdf>
|
||||
reflectance: 0.5,
|
||||
diffuse_transmission: 0.0,
|
||||
diffuse_transmission_texture: None,
|
||||
transmission: 0.0,
|
||||
transmission_texture: None,
|
||||
thickness: 0.0,
|
||||
thickness_texture: None,
|
||||
ior: 1.5,
|
||||
occlusion_texture: None,
|
||||
normal_map_texture: None,
|
||||
|
@ -462,6 +516,9 @@ bitflags::bitflags! {
|
|||
const FLIP_NORMAL_MAP_Y = (1 << 7);
|
||||
const FOG_ENABLED = (1 << 8);
|
||||
const DEPTH_MAP = (1 << 9); // Used for parallax mapping
|
||||
const TRANSMISSION_TEXTURE = (1 << 10);
|
||||
const THICKNESS_TEXTURE = (1 << 11);
|
||||
const DIFFUSE_TRANSMISSION_TEXTURE = (1 << 12);
|
||||
const ALPHA_MODE_RESERVED_BITS = (Self::ALPHA_MODE_MASK_BITS << Self::ALPHA_MODE_SHIFT_BITS); // ← Bitmask reserving bits for the `AlphaMode`
|
||||
const ALPHA_MODE_OPAQUE = (0 << Self::ALPHA_MODE_SHIFT_BITS); // ← Values are just sequential values bitshifted into
|
||||
const ALPHA_MODE_MASK = (1 << Self::ALPHA_MODE_SHIFT_BITS); // the bitmask, and can range from 0 to 7.
|
||||
|
@ -548,6 +605,15 @@ impl AsBindGroupShaderType<StandardMaterialUniform> for StandardMaterial {
|
|||
if self.depth_map.is_some() {
|
||||
flags |= StandardMaterialFlags::DEPTH_MAP;
|
||||
}
|
||||
if self.transmission_texture.is_some() {
|
||||
flags |= StandardMaterialFlags::TRANSMISSION_TEXTURE;
|
||||
}
|
||||
if self.thickness_texture.is_some() {
|
||||
flags |= StandardMaterialFlags::THICKNESS_TEXTURE;
|
||||
}
|
||||
if self.diffuse_transmission_texture.is_some() {
|
||||
flags |= StandardMaterialFlags::DIFFUSE_TRANSMISSION_TEXTURE;
|
||||
}
|
||||
let has_normal_map = self.normal_map_texture.is_some();
|
||||
if has_normal_map {
|
||||
if let Some(texture) = images.get(self.normal_map_texture.as_ref().unwrap()) {
|
||||
|
|
|
@ -63,9 +63,6 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
|||
|
||||
pbr_input.material.base_color = output_color;
|
||||
pbr_input.material.reflectance = material.reflectance;
|
||||
pbr_input.material.diffuse_transmission = material.diffuse_transmission;
|
||||
pbr_input.material.transmission = material.transmission;
|
||||
pbr_input.material.thickness = material.thickness;
|
||||
pbr_input.material.ior = material.ior;
|
||||
pbr_input.material.flags = material.flags;
|
||||
pbr_input.material.alpha_cutoff = material.alpha_cutoff;
|
||||
|
@ -92,6 +89,24 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
|||
pbr_input.material.metallic = metallic;
|
||||
pbr_input.material.perceptual_roughness = perceptual_roughness;
|
||||
|
||||
var transmission: f32 = material.transmission;
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_TRANSMISSION_TEXTURE_BIT) != 0u) {
|
||||
transmission *= textureSample(transmission_texture, transmission_sampler, uv).r;
|
||||
}
|
||||
pbr_input.material.transmission = transmission;
|
||||
|
||||
var thickness: f32 = material.thickness;
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_THICKNESS_TEXTURE_BIT) != 0u) {
|
||||
thickness *= textureSample(thickness_texture, thickness_sampler, uv).g;
|
||||
}
|
||||
pbr_input.material.thickness = thickness;
|
||||
|
||||
var diffuse_transmission = material.diffuse_transmission;
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_DIFFUSE_TRANSMISSION_TEXTURE_BIT) != 0u) {
|
||||
diffuse_transmission *= textureSample(diffuse_transmission_texture, diffuse_transmission_sampler, uv).a;
|
||||
}
|
||||
pbr_input.material.diffuse_transmission = diffuse_transmission;
|
||||
|
||||
var occlusion: f32 = 1.0;
|
||||
#ifdef VERTEX_UVS
|
||||
if ((material.flags & STANDARD_MATERIAL_FLAGS_OCCLUSION_TEXTURE_BIT) != 0u) {
|
||||
|
|
|
@ -28,3 +28,15 @@ var normal_map_sampler: sampler;
|
|||
var depth_map_texture: texture_2d<f32>;
|
||||
@group(1) @binding(12)
|
||||
var depth_map_sampler: sampler;
|
||||
@group(1) @binding(13)
|
||||
var transmission_texture: texture_2d<f32>;
|
||||
@group(1) @binding(14)
|
||||
var transmission_sampler: sampler;
|
||||
@group(1) @binding(15)
|
||||
var thickness_texture: texture_2d<f32>;
|
||||
@group(1) @binding(16)
|
||||
var thickness_sampler: sampler;
|
||||
@group(1) @binding(17)
|
||||
var diffuse_transmission_texture: texture_2d<f32>;
|
||||
@group(1) @binding(18)
|
||||
var diffuse_transmission_sampler: sampler;
|
||||
|
|
|
@ -28,6 +28,9 @@ const STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP: u32 = 64u;
|
|||
const STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y: u32 = 128u;
|
||||
const STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT: u32 = 256u;
|
||||
const STANDARD_MATERIAL_FLAGS_DEPTH_MAP_BIT: u32 = 512u;
|
||||
const STANDARD_MATERIAL_FLAGS_TRANSMISSION_TEXTURE_BIT: u32 = 1024u;
|
||||
const STANDARD_MATERIAL_FLAGS_THICKNESS_TEXTURE_BIT: u32 = 2048u;
|
||||
const STANDARD_MATERIAL_FLAGS_DIFFUSE_TRANSMISSION_TEXTURE_BIT: u32 = 4096u;
|
||||
const STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS: u32 = 3758096384u; // (0b111u32 << 29)
|
||||
const STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE: u32 = 0u; // (0u32 << 29)
|
||||
const STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK: u32 = 536870912u; // (1u32 << 29)
|
||||
|
|
Loading…
Add table
Reference in a new issue