Clipping the model and then using viewer.filler.create to 'fill' the clipped objects results in a rather ugly visualization (see image). Is there something I'm doing wrong?
IfcJsViewer.viewer.clipper.createPlane();
let testMaterial2 = new THREE.MeshBasicMaterial({
color: 0x2596be,
side: THREE.BackSide,
clippingPlanes: IfcJsViewer.viewer.context.getClippingPlanes(),
polygonOffset: true,
polygonOffsetFactor: -1,
polygonOffsetUnits: 1})
IfcJsViewer.viewer.filler.create("vukas", 0 ,IfcJsViewer.allIDs,testMaterial2);
Related
I have some text rendering over a background quad. Let's call this a 'label'. Both are positioned at the same point which causes z-fighting.
I'd like to promote the text to avoid z-fighting using polygon offset.
This is how I add the polygon offset to the text material:
const material = new THREE.RawShaderMaterial(
CreateMSDFShader({
map: this.glyphs,
opacity: opt.opacity ?? 1,
alphaTest: (opt.opacity ?? 1) < 1 ? 0.001 : 1,
color: opt.colour ?? '#ffffff',
transparent: opt.transparent ?? true,
glslVersion: opt.renderMode === 'webgl' ? THREE.GLSL1 : THREE.GLSL3,
side: opt.side ?? THREE.DoubleSide,
depthFunc: opt.depthFunc ?? THREE.LessEqualDepth,
depthTest: true,
depthWrite: false,
polygonOffset: true,
polygonOffsetUnits: -1.0,
polygonOffsetFactor: -4.0,
})
);
const mesh = new THREE.Mesh(geom, material);
and this is the background material:
if (tableOptions.background) {
const geometry = new THREE.PlaneGeometry(1, 1, 1, 1);
const backgroundMaterial = new ActivatableMaterial(
{
color: new THREE.Color(tableOptions.backgroundColour),
toneMapped: false,
opacity: 1,
alphaTest: 0.001,
transparent: true,
},
{
activationColour: new THREE.Color(tableOptions.activationColour),
}
);
this.background = buildUIObject(
Actions.ExpandLabel as Action,
geometry,
backgroundMaterial
);
setName(this.background, 'Background');
this.tableGroup.add(this.background);
}
The polygon offset just isn't working (using Chrome). The text disappears behind the background quad as I orbit the camera around, and reappears at random. The labels are always facing the camera (using lookAt).
What could stop the polygon offset from working?
The labels are rendering to a renderpass with a render taget set up as follows:
const pars = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBAFormat,
stencilBuffer: false,
depthBuffer: false,
};
this.renderTargetBuffer = new THREE.WebGLRenderTarget(
resolution.x,
resolution.y,
pars
);
this.renderTargetBuffer.texture.name = 'RenderTargetBuffer';
this.renderTargetBuffer.texture.generateMipmaps = false;
I'm assuming that because the polygonOffset is a state thing it doesn't matter that this is a RawShaderMaterial. Is that a safe assumption?
Edit: I have added the opposite polygonOffset to the background mesh separately and again it doesn't work.
Polygon offset wasn't the best solution in this case. I switched to maintaining a custom order for the labels based on distance to the camera. That way I could force the text render order to be greater than the background.
I was using CanvasRenderer in my scenes to render a brain with neurons.
The problem is that when I draw the neurons (every neuron consists of many many lines) the scene is really slow because I render a lot of neurons. So I switched into WebGLRenderer and it is much faster and smoother, but the scene looked completely different! No opacity is applied any more which made the neurons hidden inside the brain
Here is a comparison between the two scenes:
CanvasRenderer:
The brain has some transparency, and there is a green sphere represents a region of interest (ROI) also has transparency.
WebGLRenderer:
The transparency has completely gone!
I am using the following materials for the brain model and the ROI model:
var brain_material = new THREE.MeshPhongMaterial({
wireframe: false,
color: 0xaaaaaa,
specular: 0xcccccc,
opacity: 0.4
});
var roi_material = new THREE.MeshBasicMaterial({
color: selected_roi_color,
opacity: 0.2,
visible: true
})
and here is my renderer:
renderer = new THREE.WebGLRenderer({alpha:true});
renderer.setClearColor(renderer_clear_color);
renderer.setPixelRatio(viewport_width / viewport_height);
renderer.setSize(viewport_width, viewport_height);
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
How can I get a similar result to the CanvasRenderer using the WebGLRenderer?
Thank you very much
If you use opacity, then you have to use it with transparent:
var brain_material = new THREE.MeshPhongMaterial({
wireframe: false,
color: 0xaaaaaa,
specular: 0xcccccc,
transparent: true, // here
opacity: 0.4
});
var roi_material = new THREE.MeshBasicMaterial({
color: selected_roi_color,
transparent: true, // here
opacity: 0.2,
visible: true
})
When we add text-spites on scene, we saw that our transparent planes hide sprites, but didn't hide any 3d Objects.
Why is this and how to make sprites visible under transparent planes?
To look PNG example click here
My plane is:
// transparent plane
geometry = new THREE.PlaneGeometry(200, 200, 200);
material = new THREE.MeshBasicMaterial({
color: 0xa6cfe2,
side: THREE.DoubleSide,
transparent: true,
opacity: 0.5,
depthFunc: THREE.LessDepth,
});
But it seems no work good.
So, for that examle i wrote some code on fiddle, to figure out the problem:
look fidddle example
three.js renders opaque objects first, then transparent objects.
You can use this pattern to prevent your transparent objects from writing to the depth buffer:
// transparent plane
geometry = new THREE.PlaneBufferGeometry( 200, 200, 1, 1 );
material = new THREE.MeshBasicMaterial( {
color: 0xa6cfe2,
side: THREE.DoubleSide,
transparent: true,
opacity: 0.5,
depthWrite: false
} );
three.js r.112
So I have a simple particle system using THREE.Points and THREE.ParticleBasicMaterial as the material.
All the points are rendered as billboards using this .png image.
When rendered I expect each particle to be a glowing sphere (not exactly glowing, but definitely having that effect due to the radial gradient fading out into transparency). How to get the transparency to work? The result looks like this:
My material looks like this (note that I tried using different types of blending modes, but they just make things worse).
this.material = new THREE.ParticleBasicMaterial({
color: 'transparent',
size: 0.8,
map: this.spriteImage,
transparent: true,
sizeAttenuation: true
});
Add "depthWrite: false" to your material, like this:
this.material = new THREE.ParticleBasicMaterial({
color: 'transparent',
size: 0.8,
map: this.spriteImage,
transparent: true,
opacity: 0.5, // should be less than 1.0
sizeAttenuation: true,
depthWrite: false
});
I use threejs to add a pointCloud to the screen , and set texture map, But I find that the top point can cover the one behind it.
after I add AdditiveBlending , It's much better, but still have some problem.
Because I have another objects so I can't add depthTest:false , how can I solve this problem?
below is the code and the texture
var geometryBig = new THREE.Geometry();
var meshBig = new THREE.PointCloud(geometryBig, new THREE.PointCloudMaterial({
size: 4,
color: 0xFFFFFF,
transparent: true,
blending: THREE.AdditiveBlending,
// depthTest: false,
transparent: true,
sizeAttenuation: true,
map: THREE.ImageUtils.loadTexture(
"img/particle.png"
),
}));
Add to your PointCloudMaterial:
depthWrite: false