3

Because I needed transparency for every face on its own I switched from MeshBasicMaterial to ShaderMaterial.

I draw my geometry twice: First my filled trianges and then a wireframe to get a border for every triangle.
Is there a better way to archive this?

With MeshBasicMaterial it looks fine: Render with MeshBasicMaterial

But if I switch to ShaderMaterial: (Opacity is reduced to .3 so that you can see the wireframe) Render with ShaderMaterial

Is there a way to tell webgl which shader "comes first"?

My MeshBasicMaterial:

var material = new THREE.MeshBasicMaterial({
   color: new THREE.Color(0xa5a5a5),
   side: THREE.DoubleSide,
   transparent: true,
   opacity: .99
});

and

var materialLines = new THREE.MeshBasicMaterial({
   color: new THREE.Color(0x0),
   side: THREE.DoubleSide,
   wireframe: true
});

My ShaderMaterial:

var attributes = {
   customColor: {    type: 'c', value: [] },
   customOpacity: { type: 'f', value: []}
};
var shaderMaterial = new THREE.ShaderMaterial({
   attributes: attributes,
   vertexShader: document.getElementById('vertexshader').textContent,
   fragmentShader: document.getElementById('fragmentshader').textContent,
   blending: THREE.NormalBlending,
   depthTest: false,
   transparent: true,
   side: THREE.DoubleSide
});
shaderMaterial.linewidth = 5;

and

var uniforms = {
   color: { type: "c", value: new THREE.Color(0x0) }
};
var ShaderMaterialLines = new THREE.ShaderMaterial({
   uniforms: uniforms,
   vertexShader: document.getElementById('vertexshaderline').textContent,
   fragmentShader: document.getElementById('fragmentshaderline').textContent,
   depthTest: false,
   side: THREE.DoubleSide,
   wireframe: true
});

with my shaders:

<script type="x-shader/x-vertex" id="vertexshader">
    attribute vec3 customColor;
    attribute float customOpacity;

    varying vec3 vColor;
    varying float vOpacity;

    void main() {
        vColor = customColor;
        vOpacity = customOpacity;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
    varying vec3 vColor;
    varying float vOpacity;

    void main() {
        gl_FragColor = vec4( vColor, vOpacity);
    }
</script>
<script type="x-shader/x-vertex" id="vertexshaderline">
    uniform vec3 color;

    varying vec3 vColor;

    void main() {
        vColor = color;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
</script>
<script type="x-shader/x-fragment" id="fragmentshaderline">
    varying vec3 vColor;

    void main() {
        gl_FragColor =  vec4( vColor, 1.0);
    }
</script>

Edit 1:

What exactly are you trying to achieve?
I want to draw a 3D object that consist of triangles.
I want to have the possibility to control transparency and color for every triangle.

What are the requirements?
The user should see every triangle edge / a border around every triangle.
Each triangle surfaces can have a different color (based on the color of the three corners) and alpha / transpareny value.
The user can set every triangle to invisible (opacity = 0.0), visible (opacity = 1.0) or something between.(Only the triangle surface not the border)

What is your question?
What is the best way to draw triangles with a border in black or whatever color.
What is the best way to get transparency for every triangle( but keep the border).

endofsource
  • 354
  • 5
  • 18
  • What exactly are you trying to achieve? What are the requirements? What is your question? – WestLangley Jan 19 '14 at 19:07
  • @WestLangley I just updated my post to answer your questions (: – endofsource Jan 19 '14 at 19:37
  • OK. Very well-stated. It seems that you know how to handle the individual triangle color/opacity with with a custom `ShaderMaterial`. You just need to know how to combine that with a border around each triangle. Is that correct? – WestLangley Jan 19 '14 at 20:13
  • You are correct. Color and opacity works fine with my `shaderMaterial`. I'm just not sure how to add the border in a nice and simple way (: – endofsource Jan 19 '14 at 20:19

1 Answers1

8

EDIT - answer updated. WireframeHelper has been deprecated.


You want your mesh to have both a transparent material and a wireframe.

To render a border around each triangle, use WireframeGeometry, and make sure your mesh material has transparent = true.

Transparent objects are rendered last, so the entire wireframe will show.

var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

// wireframe
var geometry2 = new THREE.WireframeGeometry( geometry ); // or EdgesGeometry
var material2 = new THREE.LineBasicMaterial( { color: 0x000000, transparent: true } );
var wireframe = new THREE.LineSegments( geometry2, material2 );
mesh.add( wireframe );

three.js r.84

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • really great answer, you saved my day, and how can we do this with the traverse on object onclick a html element? let me know if there any possibility – Jothi Kannan Jun 24 '14 at 11:03
  • Sorry to bother you but is it possible to remove the diagonals from the wireframe?(The [docs](http://threejs.org/docs/#Reference/Extras.Helpers/WireframeHelper) for `WireframeHelper` are still pending :-() – Ashwini Chaudhary Jul 09 '14 at 14:44
  • @undefinedisnotafunction try `EdgesHelper`. See http://stackoverflow.com/questions/20153705/three-js-wireframe-material-all-polygons-vs-just-edges/20154589#20154589 – WestLangley Jul 09 '14 at 15:32
  • @WestLangley Thanks for the quick reply, but I am trying to do that on a `PlaneGeometry`, so the options available in the linked answer won't work with it. `GridHelper`'s output is exactly what I am looking for, but the problem with it is that it creates a grid of square shape only. And I want something that can work for rectangles too. – Ashwini Chaudhary Jul 09 '14 at 15:44
  • But what if I want to add polygon specific wireframe? I am using MeshFaceMaterial and other specific materials. – sahil shekhawat Dec 26 '14 at 16:21
  • @sahilshekhawat You need to make a new post, and provide sufficient information so your issue can be replicated. – WestLangley Dec 26 '14 at 16:29
  • Thanks for your quick reply, there you go: http://stackoverflow.com/questions/27659592/three-js-wireframe-with-surface-while-using-multiple-materials-passed-in-meshf – sahil shekhawat Dec 26 '14 at 16:41