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

client generated normals: why flat? #1605

Closed
gstanlo opened this issue May 3, 2019 · 10 comments
Closed

client generated normals: why flat? #1605

gstanlo opened this issue May 3, 2019 · 10 comments

Comments

@gstanlo
Copy link

gstanlo commented May 3, 2019

I saw #1376 but it doesn't seem to have a resolution.

client implementations should calculate flat normals.

This must surely mean smooth normals generated by treating triangles as flat, right? To get a faceted mesh with constant normals across its triangles, any vertices that are shared by multiple triangles would need to be split up.

@emackey
Copy link
Member

emackey commented May 4, 2019

Great question! I've wondered about this too. Seems like true "flat-shading" normals would require changes to the mesh, splitting shared verts. Anyone know if smooth-shading is allowed, or why not?

@gkv311
Copy link
Contributor

gkv311 commented May 6, 2019

Smoothing normals is a non-trivial ambiguous operation, while computing flat normals (triangle normals) is relatively straight-forward. Usually there is no need computing exact triangle normals - desired visual effect can be achieved on modern hardware using dFdx in a fragment shader.

@gstanlo
Copy link
Author

gstanlo commented May 6, 2019

Using partial derivatives does not seem to be the implication in the spec text. Would you expect the tangent space to be derived in the same way in the case that a primitive has neither normals or tangents specified?

@jjcasmar
Copy link

jjcasmar commented May 9, 2019

I agree with @emackey. In systems without geometry shaders, flat normals requires a pre computation step to split the mesh into separate triangles to assign the normals. This ruins the whole point of sending the data directly to the gpu...

@gstanlo
Copy link
Author

gstanlo commented May 9, 2019

Switching the text to calculate face weighted normals for indexed primitives seems appropriate. For non-indexed primitives, flat normals seems appropriate so that the runtime doesn't need to compute adjacency.

@vpenades
Copy link
Contributor

maybe there's an even easier solution... which is to require the mesh to have normals in the first place.

@jjcasmar
Copy link

@vpenades I guess the same as generating the tangents. Being able to generate normals at runtime saves some memory for the files so you can exchange them easier on networks.

@zellski
Copy link
Contributor

zellski commented Aug 6, 2019

(Yes indeed, any bandwidth-sensitive application would be very unhappy about having to send any significant data over the wire that's redundant, given what can be computed on the client.)

@donmccurdy
Copy link
Contributor

donmccurdy commented Aug 7, 2019

In systems without geometry shaders, flat normals requires a pre computation step to split the mesh into separate triangles to assign the normals.

Without normals, and without splitting the mesh, you can still compute flat shading in the fragment shader as @gkv311 says. See:

https://github.com/mrdoob/three.js/blob/8d7c7ae794b077378362342b1475fa1953537a46/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js#L2-L10

The spec is explicit and a change here would not be backward-compatible, so we can't simply change the specification's text. It would be possible to create a new extension, which specifies that a mesh without normals must have smooth normals computed by some method, rather than flat normals. But we have other mechanisms for reducing geometry size, e.g. Draco compression, and I'm not sure that a standalone extension introducing another way clients must calculate normals is a high-priority addition. Thoughts?

@gstanlo
Copy link
Author

gstanlo commented Oct 1, 2019

I think adding a note that a rendering implementation might use partial derivatives in the fragment shader, and not necessarily split vertices, would help resolve ambiguity. But otherwise this explanation is understandable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants