-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Allow fragment shader to access vertex position #14334
Comments
Why can't you use the Adding this to bevy would need to be optional because that would be a lot of wasted bandwidth for most games. The issue is I'm not sure how that would be implemented to let users control that. |
There is only 1 field that needs to be added to struct VertexOutput {
...
@location(2) local_position: vec4<f32>,
... |
Even better:
#ifdef VERTEX_POSITIONS
out.world_position = vertex.position;
let position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4<f32>(vertex.position, 1.0));
out.position = position_world_to_clip(position.xyz);
#endif If users want the old intended value for the let old_version_world_position = mesh_functions::mesh_position_local_to_world(world_from_local, in.world_position); |
It's still 128 bit more per vertices and it would not be used by the vast majority of people. I have no idea if that actually would make a noticeable performance impact. A PR implementing it would need benchmark numbers to be approved.
That's not better, that's worse because now the world_position isn't the world_position and the much more common use case of the world_position that is already used by every mesh using the StandardMaterial would break. |
I think it probably makes sense to include the world to local matrix so the fragment world position (or any world position/direction) can be cheaply converted to local space. Part of it is already included: bevy/crates/bevy_pbr/src/render/mesh.rs Line 264 in 160bcc7
|
Linking this as another possible general solution that would allow access to whatever in the vertex shader to forward to fragment. #13373 |
What problem does this solve or what need does it fill?
When writing a fragment shader for a material that needs the position of the point relative to the mesh origin.
For example, I'm writing a shader for Earth material. The mesh is destructible, so vertex is not only limited to surface vertices, but also to vertices of subterranean holes and crevices due to mesh destruction. So, fragments that is below the planet radius is using some procedural function to create a color similar to a lava.
What solution would you like?
bevy_pbr::forward_io::Vertex::position
into one of the fields forbevy_pbr::forward_io::VertexOutput.local_position
.bevy_pbr::mesh_types::MeshTypes::world_from_local
, name it:inv_world_from_local
orlocal_from_world
.Either 1 or 2 will suffice for obtaining the mesh local position.
What alternative(s) have you considered?
Currently, I wrote a custom struct to hold an output of the vertex shader to include
local_position
like so:Then I can use the
local_position
in the fragment shader to give a color of the fragment based on its position relative to the object mesh.If an
inverse_world_from_local
is included inVertexOutput
calculating thelocal_position
would simply be:In cases, where there is no access to vertex shader, ie: Meshlet material
I use a rather expensive
inverse_mat4(world_from_local)
function to get the inverse of theworld_from_local
. Then getting thelocal_position
would then just be:The code for
inverse_mat4
is very expensive, and it is calculated for each fragment.Additional context
destruct.mp4
The text was updated successfully, but these errors were encountered: