Conversation
| fn degamma(v: Vec4) -> Vec4 { | ||
| decode_srgb(v.xyz).extend(v.w) | ||
| } | ||
|
|
||
| fn hsv_to_rgb(c: Vec3) -> Vec3 { | ||
| let K = Vec4::new(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); | ||
| let p = ((c.xxx + K.xyz).fract() * 6.0 - K.www).abs(); | ||
| c.z * lerp(K.xxx, (p - K.xxx).clamp(0.0, 1.0), c.y) | ||
| } |
There was a problem hiding this comment.
Looks like I copy 'n pasted swizzles inhere. Can remove.
There was a problem hiding this comment.
Looks like glam-rs will need Add<f32> and Sub<f32> implemented for it's vector types.
| @@ -0,0 +1,131 @@ | |||
| use lighting; | |||
|
|
|||
| bitflags! { | |||
There was a problem hiding this comment.
Would be quite nice to use this.
There was a problem hiding this comment.
can also try https://crates.io/crates/enumflags2, I find it even more ergonomic but it is a proc-macro instead so slower to build
| world_pos: Vec3, | ||
| opacity: Vec3, | ||
|
|
||
| #[flat] |
There was a problem hiding this comment.
Not sure what kind of shape these attributes will end up taking, but this is an example.
There was a problem hiding this comment.
Alternative syntax: #[spriv_attr(flat)] or something like this.
There was a problem hiding this comment.
as this is fragment shader input/layout it would likely have some attribute on the struct as as well including that name, so then this flat keyword ideally share namespace / part of the naming here also to make it explicit.
not too common to use though, but need to be supported
| constants: Constants, | ||
| inputs: Inputs, |
There was a problem hiding this comment.
Probably should talk about bindings in a new issue / PR.
| env_params: lighting::EnvParams, | ||
| view_params: lighting::ViewParams, |
There was a problem hiding this comment.
Would be nice to just use our own types here instead of what the GLSL thing does (raw vec4's).
There was a problem hiding this comment.
yup for sure, will be interesting what repr we will end up on the structs with, and if this top level struct has a repr here, can it also enforce (I hope so) that all the structs and types inside it also has it
| lighting::ark_light(surface_params, constants.view_params, constants.env_params).extend(input.opacity) | ||
| } else { | ||
| (input.diffuse_color.truncate() * input.diffuse_color.w()).extend(input.opacity) |
There was a problem hiding this comment.
These .extend and .truncate calls are kind of fine, but they do get tiresome after a while.
There was a problem hiding this comment.
it is rather cryptic of what does it even mean to truncate a diffuse color? may be other options than having an rgba color stored in a Vec4 with the glam naming here. the GLSL/HLSL swizzles and alias of rgba/xyzw is nice and more familar (just as the original code was diffuse_color.rgb which is very clear).
Could simply have diffuse_color.xyz() function in the math library instead of truncate here
There was a problem hiding this comment.
don't look the wording of .extend() either, also cryptic
| let scale = extract_conservative_scale_from_transform(object_to_world); | ||
| object_to_world = Mat4::from_mat3( | ||
| if spirv::view_index() == 0 { | ||
| global_uniforms.view_to_world.to_mat3() |
There was a problem hiding this comment.
I invented glam-rs functions to_mat3 and from_mat3 here.
| if instance.flags.contains(ALPHA_BLENDING_ENABLE | PREMULTIPLIED_ALPHA_ENABLE) { | ||
| if instance.flags.contains(PREMULTIPLIED_ALPHA_ENABLE) { |
There was a problem hiding this comment.
Somehow complex match patterns on bitflags! isn't ideal.
There was a problem hiding this comment.
think this is pretty fine though, somewhat cleaner and less error prone to read than the GLSL switch statement with bitwise logic in it me thinks.
and for other cases Rust's match will be really good
| diffuse_color.a = 1.0; | ||
| } | ||
|
|
||
| let position = if spirv::view_index() == 0 { |
There was a problem hiding this comment.
I figured we could have a bunch of these builtins in core::arch::spirv similar to how _mm_set_p1 for example lives in core::arch::x86_64
|
|
||
| position.set_y(-position.y()) | ||
|
|
||
| position |
There was a problem hiding this comment.
The GLSL function sets more interpolators then just position; we should find a way of setting this reliably between shader stages so that we can safely match then up. Potentially without all regular shader language magic around these.
|
From @h3r2tic
|
|
|
||
| #[vertex_shader] | ||
| fn main() -> Vec4 { | ||
| let instance = instance_data[spirv::instance_index()]; // gl_InstanceIndex |
There was a problem hiding this comment.
spirv::instance_index looks a bit weird -- as in, the namespace sounds weird. I would expect the instance_index to be in some draw context, not in a namespace related to the instruction set. It's almost as if having x86_64::current_thread
There was a problem hiding this comment.
agreed. probably should be a decorated parameter to the main function that you declare that you want to have the instance index. GLSL is not a good base here with loose globals, prefer the explicit inputs & outputs of HLSL and think that would fit better in explicit Rust land also
| let hsv = rgb_to_hsv(rgb); | ||
|
|
||
| let hsv = Vec3::new( | ||
| (hsv.x() + instance.hsv_transform_data.x()).fract(), |
There was a problem hiding this comment.
The .x() etc could probably become just .x. I believe glam uses methods since internally it uses SIMD types that we don't need on the GPU. With different vector types we can have just .x
There was a problem hiding this comment.
good point, that would be nice
There was a problem hiding this comment.
Not needing SIMD types isn't entirely true, unfortunately - NVIDIA still has massive performance losses when they non-SIMD types are used for loads and stores instead of the SIMD types.
Now, if we want that to impact our std-lib design is another question, because a load-store-vectorizer optimization pass can take care of that just as well.
There was a problem hiding this comment.
Not needing SIMD types isn't entirely true, unfortunately - NVIDIA still has massive performance losses when they non-SIMD types are used for loads and stores instead of the SIMD types
It is also possible to just map types to spir-v types. I have been doing that in rlsl, although reusing rusts simd types probably makes more sense.
It looks like this
#[spirv(Vec4)]
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec4<T> {
pub x: T,
pub y: T,
pub z: T,
pub w: T,
}There was a problem hiding this comment.
although reusing rusts simd types probably makes more sense.
Looked up the tracking issue for #[repr(simd)], looks like it's quite intense. Anyway, I believe the current WIP would automatically compile it to a spir-v SIMD type, I'm guessing it shows up as an Abi::Vector which just straight dumps to a spir-v vector (probably want to deopt in a couple cases that aren't supported eventually, but anyway, first draft)
| @@ -0,0 +1,131 @@ | |||
| use lighting; | |||
|
|
|||
| bitflags! { | |||
There was a problem hiding this comment.
can also try https://crates.io/crates/enumflags2, I find it even more ergonomic but it is a proc-macro instead so slower to build
| env_params: lighting::EnvParams, | ||
| view_params: lighting::ViewParams, |
There was a problem hiding this comment.
yup for sure, will be interesting what repr we will end up on the structs with, and if this top level struct has a repr here, can it also enforce (I hope so) that all the structs and types inside it also has it
| world_pos: Vec3, | ||
| opacity: Vec3, | ||
|
|
||
| #[flat] |
There was a problem hiding this comment.
as this is fragment shader input/layout it would likely have some attribute on the struct as as well including that name, so then this flat keyword ideally share namespace / part of the naming here also to make it explicit.
not too common to use though, but need to be supported
| lighting::ark_light(surface_params, constants.view_params, constants.env_params).extend(input.opacity) | ||
| } else { | ||
| (input.diffuse_color.truncate() * input.diffuse_color.w()).extend(input.opacity) |
There was a problem hiding this comment.
it is rather cryptic of what does it even mean to truncate a diffuse color? may be other options than having an rgba color stored in a Vec4 with the glam naming here. the GLSL/HLSL swizzles and alias of rgba/xyzw is nice and more familar (just as the original code was diffuse_color.rgb which is very clear).
Could simply have diffuse_color.xyz() function in the math library instead of truncate here
| lighting::ark_light(surface_params, constants.view_params, constants.env_params).extend(input.opacity) | ||
| } else { | ||
| (input.diffuse_color.truncate() * input.diffuse_color.w()).extend(input.opacity) |
There was a problem hiding this comment.
don't look the wording of .extend() either, also cryptic
|
|
||
| #[vertex_shader] | ||
| fn main() -> Vec4 { | ||
| let instance = instance_data[spirv::instance_index()]; // gl_InstanceIndex |
There was a problem hiding this comment.
agreed. probably should be a decorated parameter to the main function that you declare that you want to have the instance index. GLSL is not a good base here with loose globals, prefer the explicit inputs & outputs of HLSL and think that would fit better in explicit Rust land also
| if instance.flags.contains(BILLBOARD_ENABLE) { | ||
| let scale = extract_conservative_scale_from_transform(object_to_world); | ||
| object_to_world = Mat4::from_mat3( | ||
| if spirv::view_index() == 0 { |
There was a problem hiding this comment.
same here with spirv::view_index (gl_ViewIndex), think let's try doing it as an explicit function parameter/input instead
| if instance.flags.contains(ALPHA_BLENDING_ENABLE | PREMULTIPLIED_ALPHA_ENABLE) { | ||
| if instance.flags.contains(PREMULTIPLIED_ALPHA_ENABLE) { |
There was a problem hiding this comment.
think this is pretty fine though, somewhat cleaner and less error prone to read than the GLSL switch statement with bitwise logic in it me thinks.
and for other cases Rust's match will be really good
|
@repi your comments appear duplicated, any way to collapse them? |
|
Oh that is very odd, I think it happened somehow because I left comments in existing comments while I was doing my review, and GitHub somehow duplicates that, odd. Doesn't seem to be a way to remove it. I probably shouldn't have choosen "Request changes", but instead just "Add comments". Think it lists them as the changes I requested |
|
@Jasper-Bekkers think we could merge this in and file some follow up issues around the specific larger syntax discussions here? Then one can iterate further on it in future PRs |
|
Now that we have specific shaders to test with, we should probably close this issue and address ergonomics on a case-by-case basis. |
* subgroup: add trait VectorOrScalar, representing either a vector or a scalar type * subgroup: added all non-uniform subgroup operations * subgroup: remove all target_feature cfgs, replaced with docs * subgroup: added all subgroupBarrier*() functions from glsl * subgroup: added non group-op tests * subgroup: fixed asm for instructions taking GROUP_OP generic * subgroup: added tests for group-op instructions * gitignore: added rustc-ice* error reports * subgroup: added test for subgroup buildins * subgroup: make SubgroupMask a struct to prevent implicit casts to and from UVec4 * subgroup: fixed clippy lints * subgroup: drop the `non_uniform` from all subgroup functions, matching glsl * changelog: add subgroup intrinsics PR * subgroup: make VectorOrScalar trait match discussions in #1030 * cleanup: remove internal type F32x2 for glam::Vec2 --------- Co-authored-by: Firestar99 <4696087-firestar99@users.noreply.gitlab.com>
These are GLSL shaders we're using in Ark and versions converted into pseudo-rust.
I didn't touch on bindings yet, because I think that'll be something we can debate endlessly about.
This uses a
glam-rsinspired math library since it seems most likely that we'll use something like that.None of this compiles / builds, but it should give a bit of an overview of how these shaders will end up looking. I think many things can be improved so I'll go through and comment on a bunch of things.
Part of #4