<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Babylon.js - Interactive Cylinders Scene (v7.1 - Resized)</title>
<script src="https://preview.babylonjs.com/babylonjs-viewer.js"></script>
<script src="https://preview.babylonjs.com/babylon.js"></script>
<style>
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Babylon.js - Metallic Cylinders Scene</title>
<script src="https://preview.babylonjs.com/babylon.js"></script>
<style>
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script>
window.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('renderCanvas');
const engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
const createScene = async function() {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.9, 0.9, 0.95);
// --- カメラ ---
const camera = new BABYLON.ArcRotateCamera("arcCamera",
BABYLON.Tools.ToRadians(45), BABYLON.Tools.ToRadians(60),
25, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
// --- 光源 ---
const env = BABYLON.CubeTexture.CreateFromPrefilteredData(
"https://assets.babylonjs.com/environments/environmentSpecular.env",
scene
);
scene.environmentTexture = env;
scene.createDefaultSkybox(env, true, 1000, 0.25);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.8;
// --- パネル(同じ機能) ---
const panelWidth = 2.5, panelHeight = 1.2;
const infoPanel = BABYLON.MeshBuilder.CreatePlane("infoPanel", { width: panelWidth, height: panelHeight }, scene);
infoPanel.material = new BABYLON.StandardMaterial("panelMat", scene);
infoPanel.material.backFaceCulling = false;
infoPanel.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL;
infoPanel.isVisible = false;
const textureResolution = 512;
const panelTexture = new BABYLON.DynamicTexture(
"panelTexture",
{ width: textureResolution, height: Math.round(textureResolution * (panelHeight / panelWidth)) },
scene,
true
);
infoPanel.material.diffuseTexture = panelTexture;
infoPanel.material.emissiveColor = new BABYLON.Color3(0.2, 0.2, 0.2);
function updatePanelText(text) {
const ctx = panelTexture.getContext();
const size = panelTexture.getSize();
const fontSize = 28;
const font = `bold ${fontSize}px sans-serif`;
const lines = text.split('\n');
ctx.fillStyle = "#333333";
ctx.fillRect(0, 0, size.width, size.height);
ctx.font = font;
ctx.fillStyle = "white";
lines.forEach((line, index) => {
const y = 50 + index * (fontSize + 15);
ctx.fillText(line, 25, y);
});
panelTexture.update();
}
// --- ギラギラ金属マテリアル生成関数 ---
function createMetalMaterial(type, scene) {
const mat = new BABYLON.PBRMetallicRoughnessMaterial("metalMat", scene);
mat.environmentTexture = scene.environmentTexture;
mat.roughness = 0.05; // 小さいほどツルツル・鏡面
mat.metallic = 1.0;
switch (type) {
case "gold":
mat.baseColor = new BABYLON.Color3(1.0, 0.85, 0.3);
break;
case "silver":
mat.baseColor = new BABYLON.Color3(0.9, 0.9, 0.95);
break;
case "redsilver":
mat.baseColor = new BABYLON.Color3(1.0, 0.4, 0.4);
mat.metallic = 0.95;
break;
}
return mat;
}
// --- シリンダーを配置 ---
const num = 30;
const spread = 20;
const types = ["gold", "silver", "redsilver"];
for (let i = 0; i < num; i++) {
const radius = Math.random() * 0.4 + 0.2;
const height = Math.random() * 1.5 + 0.5;
const type = types[Math.floor(Math.random() * types.length)];
const cylinder = BABYLON.MeshBuilder.CreateCylinder(`cylinder${i}`, {
diameter: radius * 2,
height: height,
tessellation: 32
}, scene);
cylinder.position.x = (Math.random() - 0.5) * spread;
cylinder.position.y = height / 2;
cylinder.position.z = (Math.random() - 0.5) * spread;
cylinder.material = createMetalMaterial(type, scene);
cylinder.metadata = {
info: `シリンダー ${i + 1}\nタイプ: ${type}\n半径: ${radius.toFixed(2)}\n高さ: ${height.toFixed(2)}`
};
}
// --- クリックで情報表示 ---
scene.onPointerDown = function(evt, pickResult) {
if (pickResult.hit && pickResult.pickedMesh && pickResult.pickedMesh.metadata) {
const clicked = pickResult.pickedMesh;
const targetPos = clicked.getAbsolutePosition();
const camPos = scene.activeCamera.position;
const r = clicked.getBoundingInfo().boundingSphere.radius;
const offset = camPos.subtract(targetPos).normalize().scale(r + 0.8);
infoPanel.position.copyFrom(targetPos.add(offset));
updatePanelText(clicked.metadata.info);
infoPanel.isVisible = true;
} else {
infoPanel.isVisible = false;
}
};
return scene;
};
createScene().then(scene => {
engine.runRenderLoop(() => scene.render());
window.addEventListener('resize', () => engine.resize());
});
});
</script>
</body>
</html>
</body>
</html>
使用変数
| ) { const scene = new BABYLON.Scene -------( Function ) | |
| ) { const canvas = document.getElementById -------( Function ) | |
| backFaceCulling | |
| baseColor | |
| billboardMode | |
| camera | |
| camPos | |
| canvas | |
| charset | |
| clearColor | |
| clicked | |
| createMetalMaterial -------( Function ) | |
| createScene | |
| ctx | |
| cylinder | |
| diffuseTexture | |
| emissiveColor | |
| engine | |
| env | |
| environmentTexture | |
| fillStyle | |
| font | |
| fontSize | |
| height | |
| i | |
| id | |
| infoPanel | |
| intensity | |
| isVisible | |
| light | |
| lines | |
| mat | |
| material | |
| metadata | |
| metallic | |
| num | |
| offset | |
| onPointerDown | |
| panelHeight | |
| panelTexture | |
| panelWidth | |
| r | |
| radius | |
| roughness | |
| scene | |
| size | |
| spread | |
| src | |
| targetPos | |
| textureResolution | |
| type | |
| types | |
| updatePanelText -------( Function ) | |
| x | |
| y | |
| z |