I’m using the MeshTransmissionMaterial from react drei in a project for a client with nextjs, fiber and drei. The problem is that with that material the GPU goes up to 100, my Mac Air M2 heats up and on other computers it lags and performances are poor. If I disable the material everything goes back to normal and working. I don’t know how to optimize it while maintaining the transmission effect. Any suggestions??
Well… maybe change material…?
or
As a result of these complex shading features, MeshPhysicalMaterial has a higher performance cost, per pixel, than other three.js materials. Most effects are disabled by default, and add cost as they are enabled. For best results, always specify an environment map when using this material.
Although it should be faster than MPM keep in mind that it can still be expensive as it causes an additional render pass of the scene. Low samples and low resolution will make it faster. If you use roughness consider using a tiny resolution, for instance 32x32 pixels, it will still look good but perform much faster.
Thanks for your feedback! @Lukasz_D_Mastalerz
Yeah I can try to change material but… there is another way to reproduce a glass effect or similar one?
I don’t know without using physicalmaterial…
lower DPR to 1 ? // sacrifice quality for 4x performance
also:
minimize the number of unique materials you have using Transmission… each material type will cause a re-render of the scene… since it needs to re-render what’s behind the refracting object. If you have multiple meshes using transmissive material, consider merging them into a single mesh…
Thanks @manthrax!
I’ll try now with DPR to 1 and I’ll update you.
About the number of unique materials I have this object:
<group
dispose={null}
scale={viewport.width / 8}
rotation={[0, -1.04, 0]}
position={[viewport.width / 1.5, 0, 4]}
ref={model}
>
<group ref={inner}>
<group ref={seatSX} position={[8, 0, 0]} visible={false}>
<mesh
castShadow
receiveShadow
geometry={nodes.sedute_SX.geometry}
material={materials["Default material.002"]}
position={[0.01, -0.34, 1.509]}
rotation={[-Math.PI / 2, 0, 1.573]}
scale={0.005}
/>
</group>
<group ref={seatDX} position={[-8, 0, 0]} visible={false}>
<mesh
castShadow
receiveShadow
geometry={nodes.sedute_DX.geometry}
material={materials["Default material.002"]}
position={[0.01, -0.34, 1.509]}
rotation={[-Math.PI / 2, 0, 1.573]}
scale={0.005}
/>
</group>
<mesh
geometry={nodes.Iveco_Daily_Tourus_L4H3_2022.geometry}
// material={materials["Default material.002"]}
material={material}
position={[0.01, -0.34, 1.509]}
rotation={[-Math.PI / 2, 0, 1.573]}
scale={0.005}
ref={ref}
>
<MeshTransmissionMaterial buffer={buffer.texture} />
</mesh>
<group ref={clima} position={[0, 8, 0]} visible={false}>
<mesh
castShadow
receiveShadow
geometry={nodes.clima_interno_plafoniere.geometry}
material={materials["Default material.002"]}
position={[0.01, -0.34, 1.509]}
rotation={[-Math.PI / 2, 0, 1.573]}
scale={0.005}
/>
</group>
<group ref={tetto} position={[0, 8, 0]} visible={false}>
<mesh
castShadow
receiveShadow
geometry={nodes.clima_e_tetto.geometry}
material={materials["Default material.002"]}
position={[0.01, -0.34, 1.509]}
rotation={[-Math.PI / 2, 0, 1.573]}
scale={0.005}
/>
</group>
</group>
</group>
So I use the transmission material only in one mesh.
Do you think I have to make other optimizations?
I don’t know the semantics in r3f, but that looks right? I dunno…
I’d try removing everything But the transmissive object, and see how that runs… then start adding things in to see if there is some breaking point in complexity.
In addition to the above:
- Do you have a specific reason for rendering the transmission texture yourself?
- You can use the PerformanceMonitor component to monitor performance and adjust your settings as necessary, so you can change your DPR as needed.
@Arthur drei docs says:
If each material rendering the scene on its own is too expensive you can share a buffer texture. Either by enabling
transmissionSampler
which would use the threejs-internal buffer that MeshPhysicalMaterials use. This might be faster, the downside is that no transmissive material can “see” other transparent or transmissive objects.
…
Or, by passing a texture to buffer manually, for instance using useFBO.
So I thought it could be better for performace. Do you think I could use just the material without setting the buffer?
Or do you have any other suggestions to further improve performance, in addition to DPR?
Anyway, now I’m using the PerfomanceMonitor and with DPR to 1 I noticed a huge performances improvement, so thanks a lot @manthrax! I appreciate it!
Ahh i didn’t notice that you were passing in your own buffer… That might be an issue if that buffer is excessively large… does not setting it help?
@manthrax @Arthur without the buffer looks better, I’ll remove it definitely!
This is my monitor for performance. Any comments on it?
where does state.scene come from? (check out drei/rendertexture)
what’s the buffer for?
mtm is on the expensive side due to chrome, ansio and noise blur. but it has some properties that can lessen the impact, for instance samples and resolution. transmissionSampler means that it will use three’s internal buffer, if you have multiple objects with mtm that can also help.
@drcmda I can’use trasmissionSamper because I need to see the trasmission from other elements behind the mtm eelement.
Have you got any suggestion about properties to set up to improve it?
Now with DPR setted to 1 it’s pretty good
your buffer usage looks suspect, my suspicion is that you double or tripple render the scene for nothing. this is what drei/rendertexture would help you with. if you don’t use a buffer you can set resolution. if you do use a buffer you can control resolution on your own via useFBO or whatever you use for keeping the buffer texture, just make it small.
@drcmda @manthrax @Lukasz_D_Mastalerz @Arthur
Best result by removing the buffer and setting DPR to 1. This could be the final solution!
I wonder if there is some other setting to lighten the use of the GPU, in some devices its use is 100%.
dpr 1 could be too low for mobile, it affects sharpness. i would first make sure that this isn’t an accidental problem, like rendering stuff for nothing. and then look at vertex count etc. i often use 1.5, it’s good enough for both mobile and laptops.
the only way to adapt to device performance is a performance monitor, drei has one GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber