Created
March 28, 2023 14:34
-
-
Save prime31/c0b07abb8d53f2053a1a688ba2251fee to your computer and use it in GitHub Desktop.
Bevy Material Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import bevy_pbr::mesh_view_bindings | |
#import bevy_pbr::mesh_bindings | |
#import bevy_pbr::pbr_types | |
#import bevy_pbr::utils | |
#import bevy_pbr::clustered_forward | |
#import bevy_pbr::lighting | |
#import bevy_pbr::shadows | |
#import bevy_pbr::pbr_functions | |
@group(1) @binding(0) | |
var texture: texture_2d<f32>; | |
@group(1) @binding(1) | |
var texture_sampler: sampler; | |
struct FragmentInput { | |
@builtin(front_facing) is_front: bool, | |
@builtin(position) frag_coord: vec4<f32>, | |
#import bevy_pbr::mesh_vertex_output | |
}; | |
let TAU: f32 = 6.28318530717958647692528676655900577; | |
fn dir_to_equirectangular(dir: vec3<f32>) -> vec2<f32> { | |
let x = atan2(dir.z, dir.x) / (2.0 * PI) + 0.5; // 0-1 | |
let y = acos(dir.y) / PI; // 0-1 | |
return vec2<f32>(x, y); | |
} | |
fn refract(I: vec3<f32>, N: vec3<f32>, eta: f32) -> vec3<f32> { | |
let k = max((1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))), 0.0); | |
return eta * I - (eta * dot(N, I) + sqrt(k)) * N; | |
} | |
@fragment | |
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> { | |
var N = normalize(in.world_normal); | |
var V = normalize(view.world_position.xyz - in.world_position.xyz); | |
var NdotV = max(dot(N, V), 0.0001); | |
var fresnel = clamp(1.0 - NdotV, 0.0, 1.0); | |
fresnel = pow(fresnel, 5.0) * 2.0; | |
let glow = pow(NdotV, 10.0) * 50.0; | |
var col = vec3(0.0, 0.0, 0.0); | |
col = mix(col, vec3(0.5, 0.1, 0.0), glow); | |
let bump_coords = dir_to_equirectangular(N * vec3(1.0, -0.5, 1.0) - vec3(0.0, 0.5, 0.0)); | |
let bump = textureSample(texture, texture_sampler, bump_coords).r; | |
var reflect_coords = dir_to_equirectangular(reflect(-V, N)); | |
let reflection = textureSample(texture, texture_sampler, reflect_coords).rgb; | |
var refract_coords = dir_to_equirectangular(refract(-V, N + bump * 2.0, 1.0/1.52)); | |
let refraction = textureSample(texture, texture_sampler, refract_coords).rgb; | |
col = (col * refraction) + reflection * (fresnel + 0.05); | |
return tone_mapping(vec4(col, 1.0)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(AsBindGroup, TypeUuid, Debug, Clone, Reflect)] | |
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e1"] | |
pub struct GlowyMaterial { | |
#[texture(0)] | |
#[sampler(1)] | |
pub env_texture: Option<Handle<Image>>, | |
} | |
impl Material for GlowyMaterial { | |
fn fragment_shader() -> ShaderRef { | |
"shaders/glowy.wgsl".into() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() { | |
App::new() | |
.add_plugins(DefaultPlugins.set(AssetPlugin { | |
watch_for_changes: true, // for shader hot reload | |
..Default::default() | |
})) | |
.add_plugin(MaterialPlugin::<GlowyMaterial>::default()) | |
.add_plugin(bevy_inspector_egui::quick::AssetInspectorPlugin::<GlowyMaterial>::default()) // egui material inspector | |
.add_startup_system(setup) | |
.run(); | |
} | |
fn setup( | |
mut commands: Commands, | |
mut meshes: ResMut<Assets<Mesh>>, | |
mut glowy_materials: ResMut<Assets<GlowyMaterial>>, | |
asset_server: Res<AssetServer>, | |
) { | |
let env_texture = asset_server.load("textures/colosseum.hdr"); | |
let glowy_material = glowy_materials.add(GlowyMaterial { | |
env_texture: Some(env_texture), | |
}); | |
commands.spawn(MaterialMeshBundle { | |
mesh: meshes.add(Mesh::from(shape::UVSphere { | |
radius: 0.5, | |
..default() | |
})), | |
material: glowy_material.clone(), | |
transform: Transform::from_xyz(0.0, 1.5, 0.0), | |
..default() | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment