|
@@ -42,6 +42,21 @@ THREE.ShaderLib[ 'line' ] = {
|
|
|
|
|
|
varying vec2 vUv;
|
|
|
|
|
|
+ void trimSegment( const in vec4 start, inout vec4 end ) {
|
|
|
+
|
|
|
+ // trim end segment so it terminates between the camera plane and the near plane
|
|
|
+
|
|
|
+ // conservative estimate of the near plane
|
|
|
+ float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column
|
|
|
+ float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column
|
|
|
+ float nearEstimate = - 0.5 * b / a;
|
|
|
+
|
|
|
+ float alpha = ( nearEstimate - start.z ) / ( end.z - start.z );
|
|
|
+
|
|
|
+ end.xyz = mix( start.xyz, end.xyz, alpha );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
void main() {
|
|
|
|
|
|
#ifdef USE_COLOR
|
|
@@ -56,6 +71,27 @@ THREE.ShaderLib[ 'line' ] = {
|
|
|
vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
|
|
|
vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
|
|
|
|
|
|
+ // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
|
|
|
+ // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
|
|
|
+ // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
|
|
|
+ // perhaps there is a more elegant solution -- WestLangley
|
|
|
+
|
|
|
+ bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column
|
|
|
+
|
|
|
+ if ( perspective ) {
|
|
|
+
|
|
|
+ if ( start.z < 0.0 && end.z >= 0.0 ) {
|
|
|
+
|
|
|
+ trimSegment( start, end );
|
|
|
+
|
|
|
+ } else if ( end.z < 0.0 && start.z >= 0.0 ) {
|
|
|
+
|
|
|
+ trimSegment( end, start );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// clip space
|
|
|
vec4 clipStart = projectionMatrix * start;
|
|
|
vec4 clipEnd = projectionMatrix * end;
|
|
@@ -95,7 +131,7 @@ THREE.ShaderLib[ 'line' ] = {
|
|
|
// adjust for linewidth
|
|
|
offset *= linewidth;
|
|
|
|
|
|
- // adjust for clip-space to screen-space conversion // maybe it should be based on viewport ...
|
|
|
+ // adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
|
|
|
offset /= resolution.y;
|
|
|
|
|
|
// select end
|
|
@@ -166,8 +202,6 @@ THREE.LineMaterial = function ( parameters ) {
|
|
|
|
|
|
type: 'LineMaterial',
|
|
|
|
|
|
- side: THREE.DoubleSide, // for now. there is an issue with segments that terminate behind the camera
|
|
|
-
|
|
|
uniforms: THREE.UniformsUtils.clone( THREE.ShaderLib[ 'line' ].uniforms ),
|
|
|
|
|
|
vertexShader: THREE.ShaderLib[ 'line' ].vertexShader,
|