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

Compute ParametricGeometry normals from tangent vectors #11056

Merged
merged 3 commits into from Mar 26, 2017
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/geometries/ParametricGeometry.js
Expand Up @@ -36,6 +36,7 @@ ParametricGeometry.prototype.constructor = ParametricGeometry;

import { BufferGeometry } from '../core/BufferGeometry';
import { Float32BufferAttribute } from '../core/BufferAttribute';
import { Vector3 } from '../math/Vector3';

function ParametricBufferGeometry( func, slices, stacks ) {

Expand All @@ -53,11 +54,15 @@ function ParametricBufferGeometry( func, slices, stacks ) {

var indices = [];
var vertices = [];
var normals = [];
var uvs = [];

var EPS = 0.00001;
var pu = new Vector3(), pv = new Vector3(), normal = new Vector3();

var i, j;

// generate vertices and uvs
// generate vertices, normals and uvs

var sliceCount = slices + 1;

Expand All @@ -72,6 +77,16 @@ function ParametricBufferGeometry( func, slices, stacks ) {
var p = func( u, v );
vertices.push( p.x, p.y, p.z );

// approximate tangent plane vectors via central difference

pu.subVectors( func( u + EPS, v ), func( u - EPS, v ) );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is func( u, v ) guaranteed to be well-defined for values of u, v outside [ 0, 1 ] ?

Copy link
Collaborator

@Mugen87 Mugen87 Mar 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point! According to the implementation of func(), values outside [ 0, 1 ] can be problematic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, use non-centered differences with a special case for the edge. By reusing p, only two additional calls are needed.

pv.subVectors( func( u, v + EPS ), func( u, v - EPS ) );
Copy link
Contributor Author

@jaxry jaxry Mar 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the Vector3s returned by func be .cloneed here in case the Vector3s actually reference the same object? Or is there a better way to do this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func normally returns a new instance of Vector3, see https://github.com/mrdoob/three.js/blob/dev/examples/js/ParametricGeometries.js

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mugen87 Actually, there should be no reason to instantiate 4 * slices * stacks Vector3's when using central differences. We could add an optionalTarget to func() and reuse just two instances.

var result = optionalTarget || new THREE.Vector3();
...
return result.set( x, y, z );

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable. We can also adjust some entities in THREE.ParametricGeometries so they use the optionalTarget. But let's do this in a separate PR, okay?

@jaxry Are you interested in doing this 😉 ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Separate PR.


// cross product of tangent plane vectors returns surface normal

normal.crossVectors( pu, pv );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normal.crossVectors( pu, pv ).normalize();

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

normals.push( normal.x, normal.y, normal.z );

uvs.push( u, v );

}
Expand Down Expand Up @@ -102,11 +117,10 @@ function ParametricBufferGeometry( func, slices, stacks ) {

this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );

// generate normals

this.computeVertexNormals();
this.normalizeNormals();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed


}

Expand Down