Scirra / Construct-bugs

Public bug report submissions for Construct 3 and Construct Animate. Please read the guidelines then click the 'Issues' tab to get started.
https://www.construct.net
107 stars 83 forks source link

depth writing in wgsl #7875

Closed F3der1co closed 8 months ago

F3der1co commented 8 months ago

Problem description

Since the amazing addition of the direct 3d rendering option for shaders I have now created a bunch of 3d shaders. But while it's super easy with webgl2, I'm not sure how to port them over to webgpu, as it seems like depth writing is not as easy/supported.

Maybe I am doing something wrong in the wgsl shader and I need to do something with the output or input struct, but not sure.

Attach a .c3p

project: debugDepth.zip

simple alpha discard shader: debugShader.zip

Steps to reproduce

  1. run preview with webGPU

Observed result

can't write to the depth output, error in the console

Expected result

being able to write to the depth output

More details

I understand that this is an undocumented feature, but being able to write to the depth output is crucial for 3d shaders, particularly with any transparency (you automatically get some transparency just by using none nearest filtering). In the end if this is not supported I'll lock my 3d projects to webgl2 only, which wouldn't be great, but still acceptable.

Possible solution could be a different output and input structs, so we can do i.e. %%FRAGMENTOUTPUT3D_STRUCT%% (also could be a solution for the fragment position, see Mikal fragment lighting proposal)

Affected browsers/platforms:

First affected release:

System details

View details PASTE HERE
AshleyScirra commented 8 months ago

Writing to gl_FragDepth is not something we've ever intended to be supported by third-party shaders. Construct is primarily a 2D engine and the uses for this are limited in 2D. WebGL usually just lets you do whatever, but WebGPU is much stricter and requires things like pipelines to be correctly configured for shader programs depending on whether they want to reference the frag_depth builtin, and it also tends to be fussy about it (e.g. you cannot specify that you are going to use something and then not use it, nor vice versa), whereas WebGL is permissive. With this issue, it puts us in a difficult position: either we have to do potentially complicated work to support something that we did not want to support in the first place and the engine was not originally designed to support, or we leave it unsupported and then there is a porting problem for some people's projects. We are not taking WebGL away though, so those projects can continue to use WebGL rendering for the time being. I think this falls in to the category of a feature request as the original use of writing to fragment depth is not officially supported, so it should be filed to the suggestions tracker.

FWIW, I think people overestimate how feasible it is to add 3D features. There seems to be a never-ending string of "but if you just add this one last little thing, then we can do cool 3D stuff..." which will continue forever until we implement a full 3D engine!

F3der1co commented 8 months ago

Ok, I filled a suggestion. I'm crossing my fingers it can be added! https://github.com/Scirra/Construct-feature-requests/issues/164

Also as a side node, the engine getting a continuous flow of 3d additions is not the worst idea either, t's not like 3d in c3 should ever be considered "finished" imho. But I do understand that there are some very tough barriers like 3d layout editor and a proper 3d renderer are unlikely to ever happen due to the scope and disruption they can cause to the rest of the engine.

MikalDev commented 8 months ago

My question on whether this is a bug or feature request is if the webgpu effect render supports the direct-3d render option, do we not need to replicate the default webgpu fragment shader and do the the transparency based write depth function? If we do not do that, will our render have issues with transparency and depth?

This is the last operation of the default shader:

output.color = c * input.fragColor; ${useFragDepth ? "output.fragDepth = select(input.fragPos.z, 1.0, output.color.a == 0.0);" : ""} return output;

NickR-Git commented 8 months ago

Writing to gl_FragDepth is not something we've ever intended to be supported by third-party shaders. Construct is primarily a 2D engine and the uses for this are limited in 2D. WebGL usually just lets you do whatever, but WebGPU is much stricter and requires things like pipelines to be correctly configured for shader programs depending on whether they want to reference the frag_depth builtin, and it also tends to be fussy about it (e.g. you cannot specify that you are going to use something and then not use it, nor vice versa), whereas WebGL is permissive. With this issue, it puts us in a difficult position: either we have to do potentially complicated work to support something that we did not want to support in the first place and the engine was not originally designed to support, or we leave it unsupported and then there is a porting problem for some people's projects. We are not taking WebGL away though, so those projects can continue to use WebGL rendering for the time being. I think this falls in to the category of a feature request as the original use of writing to fragment depth is not officially supported, so it should be filed to the suggestions tracker.

FWIW, I think people overestimate how feasible it is to add 3D features. There seems to be a never-ending string of "but if you just add this one last little thing, then we can do cool 3D stuff..." which will continue forever until we implement a full 3D engine!

It sure seems that others are happy to take up the mantle of adding 3D support where it makes sense, and they've added a lot of functionality declared difficult or impossible by the Scirra development team - and it would appear that actually isn't the case, as there is now (3rd-party) support for rotating 3D shapes, sprites, etc.

Fixing inconsistencies between officially supported renderers, whatever the reason, seems like it falls under standard basic development practices.

AshleyScirra commented 8 months ago

My question on whether this is a bug or feature request is if the webgpu effect render supports the direct-3d render option, do we not need to replicate the default webgpu fragment shader and do the the transparency based write depth function?

I would not look at the built-in shaders. They have special handling and the effect compositor is largely a separate rendering path. So you will probably just get confused if you look at other built-in shaders.

Effects should ignore the fragment color. It has no purpose in effect shaders. Currently modifying the fragment depth in effect shaders is not supported.

MikalDev commented 8 months ago

If we use a direct-3d rendering shader in webgpu, will there be a different visual behavior with color transparency and depth buffering compared to the webgl2 version of the same effect (e.g. if webgl2 version has the code to have transparent colors not impact the depth buffer)?

If has the same result (however it is done), that is great and what we would want in the end.

F3der1co commented 8 months ago

@AshleyScirra I just realized it actually is a documented feature, so I think there is a strong argument that this is a "bug". image