Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automatic depth/shadow shaders for arbitrary materials #5896

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,26 @@ description = "A shader that uses the GLSL shading language"
category = "Shaders"
wasm = true

[[example]]
name = "shader_material_override"
path = "examples/shader/shader_material_override.rs"

[package.metadata.example.shader_material_override]
name = "Material with core function override"
description = "A shader that overrides a core pbr function for a material"
category = "Shaders"
wasm = true

[[example]]
name = "pbr_global_override"
path = "examples/shader/pbr_global_override.rs"

[package.metadata.example.pbr_global_override]
name = "core function default override"
description = "a global override for pbr functions for all materials"
category = "Shaders"
wasm = true

[[example]]
name = "shader_instancing"
path = "examples/shader/shader_instancing.rs"
Expand Down
15 changes: 6 additions & 9 deletions assets/shaders/animate_shader.wgsl
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
#import bevy_pbr::mesh_types
#import bevy_pbr::mesh_view_bindings

@group(1) @binding(0)
var<uniform> mesh: Mesh;

// NOTE: Bindings must come before functions that use them!
#import bevy_pbr::mesh_bindings
#import bevy_pbr::mesh_functions

struct Vertex {
Expand All @@ -21,7 +15,10 @@ struct VertexOutput {
@vertex
fn vertex(vertex: Vertex) -> VertexOutput {
var out: VertexOutput;
out.clip_position = mesh_position_local_to_clip(mesh.model, vec4<f32>(vertex.position, 1.0));
out.clip_position = bevy_pbr::mesh_functions::mesh_position_local_to_clip(
bevy_pbr::mesh_bindings::mesh.model,
vec4<f32>(vertex.position, 1.0)
);
out.uv = vertex.uv;
return out;
}
Expand All @@ -30,7 +27,7 @@ fn vertex(vertex: Vertex) -> VertexOutput {
struct Time {
time_since_startup: f32,
};
@group(2) @binding(0)
@group(1) @binding(0)
var<uniform> time: Time;


Expand Down
51 changes: 21 additions & 30 deletions assets/shaders/array_texture.wgsl
Original file line number Diff line number Diff line change
@@ -1,55 +1,46 @@
#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::mesh_vertex_output
#import bevy_pbr::pbr_functions
#import bevy_pbr::mesh_view_bindings

@group(1) @binding(0)
var my_array_texture: texture_2d_array<f32>;
@group(1) @binding(1)
var my_array_texture_sampler: sampler;

struct FragmentInput {
@builtin(front_facing) is_front: bool,
@builtin(position) frag_coord: vec4<f32>,
#import bevy_pbr::mesh_vertex_output
};

@fragment
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
let layer = i32(in.world_position.x) & 0x3;
fn fragment(
@builtin(front_facing) is_front: bool,
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
) -> @location(0) vec4<f32> {
let layer = i32(mesh.world_position.x) & 0x3;

// Prepare a 'processed' StandardMaterial by sampling all textures to resolve
// the material members
var pbr_input: PbrInput = pbr_input_new();
var pbr_input: bevy_pbr::pbr_functions::PbrInput = bevy_pbr::pbr_functions::pbr_input_new();

pbr_input.material.base_color = textureSample(my_array_texture, my_array_texture_sampler, in.uv, layer);
pbr_input.material.base_color = textureSample(my_array_texture, my_array_texture_sampler, mesh.uv, layer);
#ifdef VERTEX_COLORS
pbr_input.material.base_color = pbr_input.material.base_color * in.color;
pbr_input.material.base_color = pbr_input.material.base_color * mesh.color;
#endif

pbr_input.frag_coord = in.frag_coord;
pbr_input.world_position = in.world_position;
pbr_input.world_normal = in.world_normal;
pbr_input.frag_coord = mesh.clip_position;
pbr_input.world_position = mesh.world_position;
pbr_input.world_normal = mesh.world_normal;

pbr_input.is_orthographic = view.projection[3].w == 1.0;
pbr_input.is_orthographic = bevy_pbr::mesh_view_bindings::view.projection[3].w == 1.0;

pbr_input.N = prepare_normal(
pbr_input.N = bevy_pbr::pbr_functions::prepare_normal(
pbr_input.material.flags,
in.world_normal,
mesh.world_normal,
#ifdef VERTEX_TANGENTS
#ifdef STANDARDMATERIAL_NORMAL_MAP
in.world_tangent,
mesh.world_tangent,
#endif
#endif
in.uv,
in.is_front,
mesh.uv,
is_front,
);
pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic);
pbr_input.V = bevy_pbr::pbr_functions::calculate_view(mesh.world_position, pbr_input.is_orthographic);

return tone_mapping(pbr(pbr_input));
return bevy_pbr::pbr_functions::tone_mapping(bevy_pbr::pbr_functions::pbr(pbr_input));
}
6 changes: 3 additions & 3 deletions assets/shaders/cubemap_unlit.wgsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import bevy_pbr::mesh_view_bindings
#import bevy_pbr::mesh_vertex_output

#ifdef CUBEMAP_ARRAY
@group(1) @binding(0)
Expand All @@ -13,9 +13,9 @@ var base_color_sampler: sampler;

@fragment
fn fragment(
#import bevy_pbr::mesh_vertex_output
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
) -> @location(0) vec4<f32> {
let fragment_position_view_lh = world_position.xyz * vec3<f32>(1.0, 1.0, -1.0);
let fragment_position_view_lh = mesh.world_position.xyz * vec3<f32>(1.0, 1.0, -1.0);
return textureSample(
base_color_texture,
base_color_sampler,
Expand Down
4 changes: 3 additions & 1 deletion assets/shaders/custom_material.frag
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ layout(set = 1, binding = 0) uniform CustomMaterial {
layout(set = 1, binding = 1) uniform texture2D CustomMaterial_texture;
layout(set = 1, binding = 2) uniform sampler CustomMaterial_sampler;

// wgsl modules can be imported and used in glsl
#import bevy_pbr::pbr_functions as PbrFuncs

void main() {
o_Target = Color * texture(sampler2D(CustomMaterial_texture,CustomMaterial_sampler), v_Uv);
o_Target = PbrFuncs::tone_mapping(Color * texture(sampler2D(CustomMaterial_texture,CustomMaterial_sampler), v_Uv));
}
6 changes: 4 additions & 2 deletions assets/shaders/custom_material.wgsl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#import bevy_pbr::mesh_vertex_output

struct CustomMaterial {
color: vec4<f32>,
};
Expand All @@ -11,7 +13,7 @@ var base_color_sampler: sampler;

@fragment
fn fragment(
#import bevy_pbr::mesh_vertex_output
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
) -> @location(0) vec4<f32> {
return material.color * textureSample(base_color_texture, base_color_sampler, uv);
return material.color * textureSample(base_color_texture, base_color_sampler, mesh.uv);
}
7 changes: 4 additions & 3 deletions assets/shaders/custom_material_chromatic_aberration.wgsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import bevy_pbr::mesh_view_bindings
#import bevy_pbr::mesh_vertex_output

@group(1) @binding(0)
var texture: texture_2d<f32>;
Expand All @@ -8,11 +9,11 @@ var our_sampler: sampler;

@fragment
fn fragment(
@builtin(position) position: vec4<f32>,
#import bevy_sprite::mesh2d_vertex_output
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput
) -> @location(0) vec4<f32> {
let view = bevy_pbr::mesh_view_bindings::view;
// Get screen position with coordinates from 0 to 1
let uv = position.xy / vec2<f32>(view.width, view.height);
let uv = mesh.clip_position.xy / vec2<f32>(view.width, view.height);
let offset_strength = 0.02;

// Sample each color channel with an arbitrary shift
Expand Down
35 changes: 35 additions & 0 deletions assets/shaders/custom_material_override.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#import bevy_pbr::lighting
#import bevy_pbr::mesh_view_types
#import bevy_pbr::mesh_vertex_output
#import bevy_pbr::fragment

fn quantize_steps() -> f32 {
return 2.0;
}

override fn bevy_pbr::lighting::point_light (
world_position: vec3<f32>,
light: bevy_pbr::mesh_view_types::PointLight,
roughness: f32,
NdotV: f32,
N: vec3<f32>,
V: vec3<f32>,
R: vec3<f32>,
F0: vec3<f32>,
diffuseColor: vec3<f32>
) -> vec3<f32> {
// call original function
let original =
bevy_pbr::lighting::point_light(world_position, light, roughness, NdotV, N, V, R, F0, diffuseColor);
// quantize
let quantized = vec3<u32>(original * quantize_steps() + 0.5);
return clamp(vec3<f32>(quantized) / quantize_steps(), vec3<f32>(0.0), vec3<f32>(1.0));
}

@fragment
fn fragment(
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
@builtin(front_facing) is_front: bool,
) -> @location(0) vec4<f32> {
return bevy_pbr::fragment::fragment(mesh, is_front);
}
7 changes: 4 additions & 3 deletions assets/shaders/custom_material_screenspace_texture.wgsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import bevy_pbr::mesh_view_bindings
#import bevy_pbr::mesh_vertex_output

@group(1) @binding(0)
var texture: texture_2d<f32>;
Expand All @@ -7,10 +8,10 @@ var texture_sampler: sampler;

@fragment
fn fragment(
@builtin(position) position: vec4<f32>,
#import bevy_pbr::mesh_vertex_output
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
) -> @location(0) vec4<f32> {
let uv = position.xy / vec2<f32>(view.width, view.height);
let view = bevy_pbr::mesh_view_bindings::view;
let uv = mesh.clip_position.xy / vec2<f32>(view.width, view.height);
let color = textureSample(texture, texture_sampler, uv);
return color;
}
10 changes: 5 additions & 5 deletions assets/shaders/custom_vertex_attribute.wgsl
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#import bevy_pbr::mesh_view_bindings
#import bevy_pbr::mesh_bindings
#import bevy_pbr::mesh_functions

struct CustomMaterial {
color: vec4<f32>,
};
@group(1) @binding(0)
var<uniform> material: CustomMaterial;

// NOTE: Bindings must come before functions that use them!
#import bevy_pbr::mesh_functions

struct Vertex {
@location(0) position: vec3<f32>,
@location(1) blend_color: vec4<f32>,
Expand All @@ -23,7 +20,10 @@ struct VertexOutput {
@vertex
fn vertex(vertex: Vertex) -> VertexOutput {
var out: VertexOutput;
out.clip_position = mesh_position_local_to_clip(mesh.model, vec4<f32>(vertex.position, 1.0));
out.clip_position = bevy_pbr::mesh_functions::mesh_position_local_to_clip(
bevy_pbr::mesh_bindings::mesh.model,
vec4<f32>(vertex.position, 1.0)
);
out.blend_color = vertex.blend_color;
return out;
}
Expand Down
43 changes: 43 additions & 0 deletions assets/shaders/global_light_override.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#define_import_path quantize_lights

#import bevy_pbr::lighting
#import bevy_pbr::mesh_view_types

fn quantize_steps() -> f32 {
return 2.0;
}

override fn bevy_pbr::lighting::point_light(
world_position: vec3<f32>,
light: bevy_pbr::mesh_view_types::PointLight,
roughness: f32,
NdotV: f32,
N: vec3<f32>,
V: vec3<f32>,
R: vec3<f32>,
F0: vec3<f32>,
diffuseColor: vec3<f32>
) -> vec3<f32> {
// call original function
let original = bevy_pbr::lighting::point_light(world_position, light, roughness, NdotV, N, V, R, F0, diffuseColor);
// quantize
let quantized = vec3<u32>(original * quantize_steps() + 0.5);
return clamp(vec3<f32>(quantized) / quantize_steps(), vec3<f32>(0.0), vec3<f32>(1.0));
}

override fn bevy_pbr::lighting::directional_light(
light: bevy_pbr::mesh_view_types::DirectionalLight,
roughness: f32,
NdotV: f32,
normal: vec3<f32>,
view: vec3<f32>,
R: vec3<f32>,
F0: vec3<f32>,
diffuseColor: vec3<f32>
) -> vec3<f32> {
// call original function
let original = bevy_pbr::lighting::directional_light(light, roughness, NdotV, normal, view, R, F0, diffuseColor);
// quantize
let quantized = vec3<u32>(original * quantize_steps() + 0.5);
return clamp(vec3<f32>(quantized) / quantize_steps(), vec3<f32>(0.0), vec3<f32>(1.0));
}
13 changes: 5 additions & 8 deletions assets/shaders/instancing.wgsl
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
#import bevy_pbr::mesh_types
#import bevy_pbr::mesh_view_bindings

@group(1) @binding(0)
var<uniform> mesh: Mesh;

// NOTE: Bindings must come before functions that use them!
#import bevy_pbr::mesh_functions
#import bevy_pbr::mesh_bindings

struct Vertex {
@location(0) position: vec3<f32>,
Expand All @@ -25,7 +19,10 @@ struct VertexOutput {
fn vertex(vertex: Vertex) -> VertexOutput {
let position = vertex.position * vertex.i_pos_scale.w + vertex.i_pos_scale.xyz;
var out: VertexOutput;
out.clip_position = mesh_position_local_to_clip(mesh.model, vec4<f32>(position, 1.0));
out.clip_position = bevy_pbr::mesh_functions::mesh_position_local_to_clip(
bevy_pbr::mesh_bindings::mesh.model,
vec4<f32>(position, 1.0)
);
out.color = vertex.i_color;
return out;
}
Expand Down
4 changes: 3 additions & 1 deletion assets/shaders/line_material.wgsl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#import bevy_pbr::mesh_vertex_output

struct LineMaterial {
color: vec4<f32>,
};
Expand All @@ -7,7 +9,7 @@ var<uniform> material: LineMaterial;

@fragment
fn fragment(
#import bevy_pbr::mesh_vertex_output
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
) -> @location(0) vec4<f32> {
return material.color;
}
4 changes: 3 additions & 1 deletion assets/shaders/shader_defs.wgsl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#import bevy_pbr::mesh_vertex_output

struct CustomMaterial {
color: vec4<f32>,
};
Expand All @@ -7,7 +9,7 @@ var<uniform> material: CustomMaterial;

@fragment
fn fragment(
#import bevy_pbr::mesh_vertex_output
mesh: bevy_pbr::mesh_vertex_output::MeshVertexOutput,
) -> @location(0) vec4<f32> {
#ifdef IS_RED
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
Expand Down
Loading