Dear community!
I have some BufferGeometry which holds indexed triangles.
I want it to have a face normals. But it seems I can add only per-vertex normals.
When I compute normals in per-triangle basis, and then add normals of length of (indices.length), via
geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array(normals), 3 ) );
I get glDrawElements: attempt to access out of range vertices in attribute 1
The geometry I work with contains tetrahedrons, so I need those face normals.
And I do not want to split it to non-indexed geometry, because my original tetrohedron mesh already tooo big.
So my question is. Where can I digg into ThreeJS source and implement face normals to BufferGeometry?
Unfortunately this is a limitation of WebGL itself.
But Geometry class has face normals?...
22.02.2015 14:17 пользователь "Mr.doob" [email protected] написал:
Unfortunately this is a limitation of WebGL itself.
—
Reply to this email directly or view it on GitHub
https://github.com/mrdoob/three.js/issues/6117#issuecomment-75426757.
Yes. And at render time it creates non-indexed buffers.
Well, you still have this:
vec3 fdx = vec3(dFdx(vPos.x),dFdx(vPos.y),dFdx(vPos.z));
vec3 fdy = vec3(dFdy(vPos.x),dFdy(vPos.y),dFdy(vPos.z));
vec3 N = normalize(cross(fdx,fdy));
Oh! Interesting...
I bet people will still want custom face normals though, but this could be what THREE.FlatShaded does...
I hoped that THREE.FlatShading is brilliand idea and will work. Hovewer shading property does not work at all in r70 and in dev... ;-(
Seems "shading" property of materials is broken somehow.
Maybe I misunderstand and there is a difference betweeen THREE.FlatShaded and THREE.FlatShading ?
Please look at example, scroll down in navigation to "Spheres->Trimesh", I set shading to "flat-shading" and there is still smooth shading visually:
http://threejs.org/editor/#app=http://svn.lact.ru:4567/files/visual/2015-02-24/2015-02-24-at-21-21-05.jpg.json
Another example, with part of tetrahedron mesh: http://threejs.org/editor/#app=http://svn.lact.ru:4567/files/visual/2015-02-24/2015-02-24-at-22-03-25.jpg.json
@pavelvasev what @mrdoob is saying is that he could make THREE.FlatShaded work with BufferGeometry in the future, but right now you need to write your own shader, via ShaderMaterial.
Ehh!.. Makc, thanks for clarification!
Should be easy to patch, really. I have no idea how this shader building business works, so can't do meaningful PR on this, but look:

(before)

(after - 4 lines added)
What I can do is maybe example PR. But we sure would like to see this in core lib.
That's look like what I need ;-) Is that behavior can be enabled for BufferGeometry by THREE.FlatShaded, theoretically?
why not, see this extension support stats:

in fact, I see it already used in three.js here, for example.
Working on it ^^
Implemented!
MeshLambertMaterial is a problem though... (because the shading is computed in the vertex shader)
Also, many thanks @makc!
@mrdoob Unfortunately, with this screen-space derivatives approach, lighting is not correct with double-sided materials. You can test with two lights of different colors on opposite sides to see that the normals are not correct. I do not have a solution as of yet.
var geometry = new THREE.PlaneBufferGeometry( 10, 10, 4, 4 );
var material = new THREE.MeshPhongMaterial( {
shading: THREE.FlatShading,
side: THREE.DoubleSide
} );
The shader code is very fragile, unfortunately. You have to be careful with your ifdefs.
There may be further issues if skinning or morphs are active.
I bet you can use gl_FrontFacing to fix double-sided issues. Go on, I trust in you :stuck_out_tongue:
I have this shader here that says
if(!gl_FrontFacing) {
normalVec = -normalVec;
}
if that helps.
ps @WestLangley did you notice how your github avatar looks like the war plane shooting missiles?
hehe. I do now.
Hi guys! Many thanks to you for your efforts. I checked and now all works good!
But as WestLangley noted, some lights stop working on back-sides. However, it seems not a problem for me now.. ;-)
Hmmm, there is some code to address that but doesn't seem to be working...
https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl#L15-L19
maybe #ifdef DOUBLE_SIDED && !FLAT_SHADED then?
Based experimentation...
#ifndef FLAT_SHADED
#ifdef DOUBLE_SIDED
...
#endif
#ifdef FLIP_SIDED
...
#endif
#endif
@arose thanks!
Most helpful comment
ps @WestLangley did you notice how your github avatar looks like the war plane shooting missiles?