ModelHandle/sandbox/three_shadow.html
2022-12-20 13:54:23 +01:00

194 lines
5.7 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<title>Online 3D Viewer</title>
<style>
canvas
{
border: 1px solid #cccccc;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/three@0.147.0/build/three.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/shaders/HorizontalBlurShader.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/shaders/VerticalBlurShader.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/three@0.147.0/examples/js/controls/OrbitControls.js"></script>
<script type='text/javascript'>
function Sandbox3D ()
{
let canvas = document.getElementById ('canvas');
let parameters = {
canvas : canvas,
antialias : true
};
let width = 800;
let height = 600;
let renderer = new THREE.WebGLRenderer (parameters);
renderer.setClearColor ('#ffffff', 1);
renderer.setSize (width, height);
renderer.localClippingEnabled = true;
let scene = new THREE.Scene ();
let ambientLight = new THREE.AmbientLight (0x888888);
scene.add (ambientLight);
let light = new THREE.DirectionalLight (0x888888);
light.position.set (3.0, -1.5, 2.0);
scene.add (light);
let camera = new THREE.PerspectiveCamera (45.0, width / height, 0.1, 1000.0);
camera.position.set (3.0, -1.5, 2.0);
camera.up.set (0.0, 0.0, 1.0);
camera.lookAt (new THREE.Vector3 (0.0, 0.0, 0.0));
scene.add (camera);
let box = new THREE.BoxGeometry (0.5, 1.6, 0.75);
let boxMaterial = new THREE.MeshPhongMaterial ({
color : 0xcc0000,
side : THREE.DoubleSide
});
let boxMesh = new THREE.Mesh (box, boxMaterial);
scene.add (boxMesh);
let planeSizeX = 3.0;
let planeSizeY = 3.0;
let planeZ = -1.0;
let shadowGroup = new THREE.Object3D ();
scene.add (shadowGroup);
let shadowRenderTarget = new THREE.WebGLRenderTarget (512, 512);
shadowRenderTarget.texture.generateMipmaps = false;
let shadowPlaneGeometry = new THREE.PlaneGeometry (planeSizeX, planeSizeY)
shadowPlaneMaterial = new THREE.MeshBasicMaterial ({
//color : 0x0000cc,
map : shadowRenderTarget.texture,
opacity : 1.0,
transparent: true,
depthWrite : false
});
let shadowPlaneMesh = new THREE.Mesh (shadowPlaneGeometry, shadowPlaneMaterial);
shadowPlaneMesh.position.z = planeZ;
shadowPlaneMesh.scale.y = -1.0;
shadowGroup.add (shadowPlaneMesh);
let shadowCamera = new THREE.OrthographicCamera (
-planeSizeX / 2.0,
planeSizeX / 2.0,
planeSizeY / 2.0,
-planeSizeY / 2.0,
0.0,
2.0,
);
shadowCamera.rotation.x = Math.PI;
shadowCamera.position.z = planeZ;
shadowGroup.add (shadowCamera);
let shadowMaterial = new THREE.MeshDepthMaterial ();
shadowMaterial.depthTest = false;
shadowMaterial.depthWrite = false;
shadowMaterial.userData.darkness = { value: 0.7 };
shadowMaterial.onBeforeCompile = (shader) => {
shader.uniforms.darkness = shadowMaterial.userData.darkness;
shader.fragmentShader = /* glsl */`
uniform float darkness;
${shader.fragmentShader.replace (
'gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );',
'gl_FragColor = vec4( vec3( 0.0 ), ( 1.0 - fragCoordZ ) * darkness );'
)}
`;
};
// let cameraHelper = new THREE.CameraHelper (shadowCamera);
// shadowGroup.add (cameraHelper);
let blurPlaneGeometry = new THREE.PlaneGeometry (planeSizeX, planeSizeY)
let blurRenderTarget = new THREE.WebGLRenderTarget (512, 512);
blurRenderTarget.texture.generateMipmaps = false;
let blurPlaneMesh = new THREE.Mesh (blurPlaneGeometry);
blurPlaneMesh.visible = false;
shadowGroup.add (blurPlaneMesh);
let blurCamera = new THREE.OrthographicCamera (
-planeSizeX / 2.0,
planeSizeX / 2.0,
planeSizeY / 2.0,
-planeSizeY / 2.0,
0.0,
1.0,
);
shadowGroup.add (blurCamera);
horizontalBlurMaterial = new THREE.ShaderMaterial (THREE.HorizontalBlurShader);
horizontalBlurMaterial.depthTest = false;
verticalBlurMaterial = new THREE.ShaderMaterial (THREE.VerticalBlurShader);
verticalBlurMaterial.depthTest = false;
new THREE.OrbitControls (camera, renderer.domElement);
scene.background = new THREE.Color (0.8, 0.8, 0.8);
renderer.setAnimationLoop ((time) => {
boxMesh.rotation.x = time / 3000;
boxMesh.rotation.y = time / 3000;
boxMesh.rotation.z = time / 3000;
scene.overrideMaterial = shadowMaterial;
renderer.setRenderTarget (shadowRenderTarget);
renderer.render (scene, shadowCamera);
scene.overrideMaterial = null;
blurPlaneMesh.visible = true;
let amount = 5.0;
for (let i = 0; i < 2; i++) {
if (i == 2) {
amount *= 1;
}
blurPlaneMesh.material = horizontalBlurMaterial;
blurPlaneMesh.material.uniforms.tDiffuse.value = shadowRenderTarget.texture;
horizontalBlurMaterial.uniforms.h.value = amount * 1 / 256;
renderer.setRenderTarget (blurRenderTarget);
renderer.render (blurPlaneMesh, blurCamera);
blurPlaneMesh.material = verticalBlurMaterial;
blurPlaneMesh.material.uniforms.tDiffuse.value = blurRenderTarget.texture;
verticalBlurMaterial.uniforms.v.value = amount * 1 / 256;
renderer.setRenderTarget (shadowRenderTarget);
renderer.render (blurPlaneMesh, blurCamera);
}
blurPlaneMesh.visible = false;
renderer.setRenderTarget (null);
renderer.render (scene, camera);
});
}
window.onload = function () {
Sandbox3D ();
};
</script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>