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:
But if I switch to ShaderMaterial
: (Opacity is reduced to .3 so that you can see the wireframe)
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).
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