I have a THREE.PlaneBufferGeometry() with a map that is part wise transparent. When this object cast shadow, the shadow is a rectangle. I want the shadow to be the same as displayed mesh. Can someone help me with this?
Thanks in advance!
I use a shader I found years ago that fixes this. I will find it and post a bit later today…
<script type='x-shader/x-fragment' id='fragmentShaderDepth'>
uniform sampler2D texture;
varying vec2 vUV;
vec4 pack_depth( const in float depth ) {
const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );
const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );
vec4 res = fract( depth * bit_shift );
res -= res.xxyz * bit_mask;
return res;
}
void main() {
vec4 pixel = texture2D( texture, vUV );
if ( pixel.a < 0.5 ) discard;
gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );
}
</script>
<script type='x-shader/x-vertex' id='vertexShaderDepth'>
varying vec2 vUV;
void main() {
vUV = 0.99 * uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
</script>
To use this add those to your html then call it like this
Texture = new THREE.TextureLoader().load(“picture.png”);
Geometry = new THREE.PlaneGeometry(10,6 );//or whatever size
Material= new THREE.MeshBasicMaterial( {side:THREE.DoubleSide, transparent : true, opacity: 1, map: Texture } );
MyMesh = new THREE.Mesh(Geometry, Material);
var uniforms = { texture: { type: “t”, value: Texture } };
var vertexShader = document.getElementById( ‘vertexShaderDepth’ ).textContent;
var fragmentShader = document.getElementById( ‘fragmentShaderDepth’ ).textContent;
MyMesh.customDepthMaterial = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader } );
This is what it will look like
Thank you!
You bet, glad I was able to help. Others have been so kind here answering all my stupid questions, it feels good to be on the other end
Another option is to use MeshDepthMaterial
. Something like this:
let texture = _your_texture_ ;
let mesh = new THREE.Mesh(
_your_geometry_,
new THREE.MeshBasicMaterial({
map: texture,
alphaTest: 0.5,
side: THREE.DoubleSide
})
);
mesh.customDepthMaterial = new THREE.MeshDepthMaterial({
depthPacking: THREE.RGBADepthPacking,
map: texture,
alphaTest: 0.5
});
Sweet, I may change mine to that if I get the same results