<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Realistic 3D House</title>
<style>
*{
box-sizing:border-box;
user-select:none;
}
html,body{
margin:0;
width:100%;
height:100%;
overflow:hidden;
background:#111;
font-family:Arial,sans-serif;
}
#game{
position:fixed;
inset:0;
}
#hud{
position:fixed;
top:15px;
left:15px;
z-index:20;
color:white;
background:rgba(5,8,12,.68);
padding:13px 16px;
border-radius:12px;
backdrop-filter:blur(8px);
box-shadow:0 5px 25px rgba(0,0,0,.35);
line-height:1.8;
}
#crosshair{
position:fixed;
left:50%;
top:50%;
transform:translate(-50%,-50%);
z-index:20;
color:white;
font-size:22px;
text-shadow:0 0 8px #000;
}
#message{
position:fixed;
left:50%;
bottom:18px;
transform:translateX(-50%);
z-index:20;
color:white;
background:rgba(0,0,0,.65);
padding:10px 18px;
border-radius:20px;
}
#quality{
position:fixed;
right:15px;
top:15px;
z-index:20;
color:white;
background:rgba(5,8,12,.65);
padding:9px 13px;
border-radius:10px;
}
</style>
</head>
<body>
<div id="game"></div>
<div id="hud">
<b>REALISTIC HOUSE</b><br>
WASD = حرکت<br>
Shift = دویدن<br>
Space = پرش<br>
V = اول شخص / سوم شخص<br>
F = لگد<br>
کلیک = تعامل / ضربه
</div>
<div id="quality">
QUALITY: HIGH
</div>
<div id="crosshair">+</div>
<div id="message">
برای شروع کلیک کن
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
<script>
////////////////////////////////////////////////////////////
// SCENE
////////////////////////////////////////////////////////////
const scene =
new THREE.Scene();
scene.background =
new THREE.Color(0x9bbfd4);
scene.fog =
new THREE.FogExp2(
0x9bbfd4,
0.012
);
////////////////////////////////////////////////////////////
// CAMERA
////////////////////////////////////////////////////////////
const camera =
new THREE.PerspectiveCamera(
68,
innerWidth/innerHeight,
.05,
250
);
////////////////////////////////////////////////////////////
// RENDERER
////////////////////////////////////////////////////////////
const renderer =
new THREE.WebGLRenderer({
antialias:true,
powerPreference:"high-performance"
});
renderer.setSize(
innerWidth,
innerHeight
);
renderer.setPixelRatio(
Math.min(
window.devicePixelRatio,
1.5
)
);
renderer.shadowMap.enabled=true;
renderer.shadowMap.type =
THREE.PCFSoftShadowMap;
renderer.outputColorSpace =
THREE.SRGBColorSpace;
renderer.toneMapping =
THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure=1.15;
renderer.physicallyCorrectLights=true;
document
.getElementById("game")
.appendChild(renderer.domElement);
////////////////////////////////////////////////////////////
// MATERIALS
////////////////////////////////////////////////////////////
function material(
color,
roughness=.6,
metalness=0
){
return new THREE.MeshStandardMaterial({
color,
roughness,
metalness
});
}
const MAT={
wall:material(0xd4cec2,.9),
wall2:material(0xb8b0a2,.9),
floor:material(0x74553b,.9),
wood:material(0x58351f,.7),
wood2:material(0x8a5b35,.65),
dark:material(0x15191d,.35,.55),
metal:material(0x747b81,.3,.85),
black:material(0x090b0e,.25,.65),
white:material(0xe5e2dc,.8),
blue:material(0x263f69,.6),
green:material(0x315d39,.75),
red:material(0x771e1e,.5),
road:material(0x252729,.95),
grass:material(0x435a39,1),
concrete:material(0x8b8982,.95),
screen:material(0x07151c,.18,.15)
};
////////////////////////////////////////////////////////////
// BASIC OBJECTS
////////////////////////////////////////////////////////////
function box(
x,y,z,
sx,sy,sz,
m,
parent=scene
){
const mesh=
new THREE.Mesh(
new THREE.BoxGeometry(
sx,sy,sz
),
m
);
mesh.position.set(
x,y,z
);
mesh.castShadow=true;
mesh.receiveShadow=true;
parent.add(mesh);
return mesh;
}
function sphere(
x,y,z,
r,
m,
parent=scene
){
const mesh=
new THREE.Mesh(
new THREE.SphereGeometry(
r,
32,
20
),
m
);
mesh.position.set(
x,y,z
);
mesh.castShadow=true;
mesh.receiveShadow=true;
parent.add(mesh);
return mesh;
}
function cylinder(
x,y,z,
r,
h,
m,
parent=scene
){
const mesh=
new THREE.Mesh(
new THREE.CylinderGeometry(
r,
r,
h,
32
),
m
);
mesh.position.set(
x,y,z
);
mesh.castShadow=true;
mesh.receiveShadow=true;
parent.add(mesh);
return mesh;
}
////////////////////////////////////////////////////////////
// LIGHTING
////////////////////////////////////////////////////////////
const skyLight=
new THREE.HemisphereLight(
0xcfe8ff,
0x493d32,
2.2
);
scene.add(skyLight);
const sun=
new THREE.DirectionalLight(
0xffe4b5,
4
);
sun.position.set(
-25,
35,
-20
);
sun.castShadow=true;
sun.shadow.mapSize.width=1536;
sun.shadow.mapSize.height=1536;
sun.shadow.camera.left=-60;
sun.shadow.camera.right=60;
sun.shadow.camera.top=60;
sun.shadow.camera.bottom=-60;
sun.shadow.bias=-.0003;
scene.add(sun);
////////////////////////////////////////////////////////////
// GROUND
////////////////////////////////////////////////////////////
box(
0,-.4,0,
100,.5,100,
MAT.grass
);
////////////////////////////////////////////////////////////
// HOUSE
////////////////////////////////////////////////////////////
box(
0,0,0,
24,.25,20,
MAT.floor
);
// outer walls
box(
0,3,-10,
24,6,.35,
MAT.wall
);
box(
-12,3,0,
.35,6,20,
MAT.wall
);
box(
12,3,0,
.35,6,20,
MAT.wall
);
box(
0,3,10,
24,6,.35,
MAT.wall
);
// ceiling
box(
0,6.3,0,
24,.3,20,
MAT.wall2
);
////////////////////////////////////////////////////////////
// INTERNAL WALLS
////////////////////////////////////////////////////////////
box(
-4,3,1,
.3,6,18,
MAT.wall2
);
box(
4,3,-4,
8,6,.3,
MAT.wall2
);
box(
7.8,3,3,
.3,6,6,
MAT.wall2
);
////////////////////////////////////////////////////////////
// FLOOR RUGS
////////////////////////////////////////////////////////////
box(
7,.04,5,
8,.05,6,
material(0x5c3941,.98)
);
box(
-7,.04,-5,
7,.05,6,
material(0x3b4554,.98)
);
////////////////////////////////////////////////////////////
// WINDOWS
////////////////////////////////////////////////////////////
function makeWindow(
x,y,z,
width,height,
rotation=0
){
const g=
new THREE.Group();
g.position.set(
x,y,z
);
g.rotation.y=
rotation;
const glass=
new THREE.MeshStandardMaterial({
color:0x6e9db5,
roughness:.12,
metalness:.15,
transparent:true,
opacity:.42
});
box(
0,0,0,
width,
height,
.08,
glass,
g
);
box(
0,height/2,
0,
width+.18,
.13,
.12,
MAT.wood2,
g
);
box(
0,-height/2,
0,
width+.18,
.13,
.12,
MAT.wood2,
g
);
box(
-width/2,
0,
0,
.13,
height,
.12,
MAT.wood2,
g
);
box(
width/2,
0,
0,
.13,
height,
.12,
MAT.wood2,
g
);
box(
0,0,.04,
.09,
height,
.1,
MAT.wood2,
g
);
scene.add(g);
}
makeWindow(
-7,
3.1,
-9.82,
4.2,
2.5
);
makeWindow(
7,
3.1,
-9.82,
4.2,
2.5
);
makeWindow(
-11.82,
3,
-3,
3,
2.5,
Math.PI/2
);
////////////////////////////////////////////////////////////
// DOORS
////////////////////////////////////////////////////////////
function door(
x,z,rotation=0
){
const g=
new THREE.Group();
g.position.set(
x,1.5,z
);
g.rotation.y=
rotation;
box(
0,0,0,
1.5,3,.12,
MAT.wood2,
g
);
box(
.45,0,.08,
.06,.06,.06,
MAT.metal,
g
);
scene.add(g);
}
door(
-4,-3.5,
Math.PI/2
);
door(
4,-1
);
door(
7.8,2,
Math.PI/2
);
////////////////////////////////////////////////////////////
// REAL GLB MODEL SYSTEM
////////////////////////////////////////////////////////////
const loader=
new THREE.GLTFLoader();
function loadModel(
url,
position,
scale,
rotationY=0
){
loader.load(
url,
function(gltf){
const model=
gltf.scene;
model.position.copy(
position
);
model.scale.set(
scale,
scale,
scale
);
model.rotation.y=
rotationY;
model.traverse(
function(obj){
if(obj.isMesh){
obj.castShadow=true;
obj.receiveShadow=true;
if(
obj.material
){
obj.material.needsUpdate=true;
}
}
}
);
scene.add(model);
},
undefined,
function(error){
console.warn(
"Model failed:",
url,
error
);
}
);
}
////////////////////////////////////////////////////////////
// REAL 3D MODELS
////////////////////////////////////////////////////////////
// Human character
loadModel(
"https://threejs.org/examples/models/gltf/RobotExpressive/RobotExpressive.glb",
new THREE.Vector3(-6,0,3),
.75
);
// Real detailed chair
loadModel(
"https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/2.0/SheenChair/glTF-Binary/SheenChair.glb",
new THREE.Vector3(-7.5,0,-4),
1.6,
Math.PI
);
// Detailed helmet model as a physical PC decoration
loadModel(
"https://threejs.org/examples/models/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb",
new THREE.Vector3(-7.7,2.6,-5.8),
.55
);
////////////////////////////////////////////////////////////
// COMPUTER DESK
////////////////////////////////////////////////////////////
const computer=
new THREE.Group();
computer.position.set(
-8,
0,
-5.5
);
scene.add(computer);
// tabletop
box(
0,2.35,0,
5.7,.28,2.1,
MAT.wood2,
computer
);
// legs
for(
const x of [-2.4,2.4]
){
for(
const z of [-.75,.75]
){
box(
x,1.1,z,
.3,2.2,.3,
MAT.metal,
computer
);
}
}
// drawer unit
box(
-1.8,1.25,.15,
1.2,1.6,1.25,
MAT.wood,
computer
);
////////////////////////////////////////////////////////////
// PC CASE
////////////////////////////////////////////////////////////
const pc=
new THREE.Group();
pc.position.set(
-1.7,3.85,0
);
computer.add(pc);
box(
0,0,0,
1.65,3,2,
MAT.black,
pc
);
// glass panel
const pcGlass=
new THREE.MeshStandardMaterial({
color:0x23404c,
roughness:.1,
metalness:.15,
transparent:true,
opacity:.32
});
box(
.84,0,0,
.04,2.6,1.7,
pcGlass,
pc
);
// motherboard
box(
.7,.1,-.25,
.05,1.9,1.35,
MAT.green,
pc
);
// CPU
box(
.78,.55,-.3,
.16,.45,.5,
MAT.metal,
pc
);
// RAM
for(
let i=0;
i<4;
i++
){
box(
.82,
.1+i*.35,
.25,
.07,
.25,
.1,
MAT.blue,
pc
);
}
// GPU
box(
.82,-.55,-.15,
.12,.42,1.35,
MAT.red,
pc
);
// GPU fans
for(
let i=0;
i<2;
i++
){
const fan=
cylinder(
.89,
-.55,
-.5+i*.7,
.22,
.07,
MAT.black,
pc
);
fan.rotation.z=
Math.PI/2;
}
// front fans
for(
let i=0;
i<3;
i++
){
const fan=
cylinder(
0,
-.8+i*.8,
-1.03,
.3,
.07,
MAT.black,
pc
);
fan.rotation.x=
Math.PI/2;
}
// RGB strips
box(
.85,1.2,0,
.03,.08,1.5,
material(0x26a9ff,.25,.1),
pc
);
////////////////////////////////////////////////////////////
// MONITOR
////////////////////////////////////////////////////////////
const monitor=
new THREE.Group();
monitor.position.set(
.1,
3.45,
-.25
);
computer.add(monitor);
box(
0,1.3,0,
4,.2+2.1,.16,
MAT.black,
monitor
);
box(
0,1.3,.1,
3.55,1.75,.04,
MAT.screen,
monitor
);
// screen glow
box(
0,1.3,.13,
2.8,.06,.015,
material(0x1887b5,.2,.1),
monitor
);
box(
0,.05,0,
.18,2.3,.18,
MAT.black,
monitor
);
box(
0,-1.08,0,
1.8,.14,.85,
MAT.black,
monitor
);
////////////////////////////////////////////////////////////
// KEYBOARD
////////////////////////////////////////////////////////////
const keyboard=
new THREE.Group();
keyboard.position.set(
.1,2.6,.65
);
keyboard.rotation.x=
-.08;
computer.add(keyboard);
box(
0,0,0,
3.8,.15,1.25,
MAT.black,
keyboard
);
for(
let row=0;
row<4;
row++
){
for(
let col=0;
col<12;
col++
){
box(
-1.5+col*.27,
.11,
-.4+row*.25,
.2,.06,.18,
MAT.white,
keyboard
);
}
}
box(
0,.11,.56,
1.5,.06,.2,
MAT.white,
keyboard
);
////////////////////////////////////////////////////////////
// MOUSE
////////////////////////////////////////////////////////////
sphere(
2,
2.75,
.75,
.28,
MAT.black,
computer
);
////////////////////////////////////////////////////////////
// CABLES
////////////////////////////////////////////////////////////
function makeCable(
points
){
const curve=
new THREE.CatmullRomCurve3(
points
);
const geo=
new THREE.TubeGeometry(
curve,
30,
.035,
8,
false
);
const cable=
new THREE.Mesh(
geo,
MAT.black
);
cable.castShadow=true;
computer.add(cable);
}
makeCable([
new THREE.Vector3(
1.9,2.65,.7
),
new THREE.Vector3(
2.6,2.1,.8
),
new THREE.Vector3(
2.2,1.2,.9
)
]);
makeCable([
new THREE.Vector3(
.1,2.5,.3
),
new THREE.Vector3(
.1,2,.3
),
new THREE.Vector3(
-.8,1.15,.1
)
]);
////////////////////////////////////////////////////////////
// LIVING ROOM
////////////////////////////////////////////////////////////
const living=
new THREE.Group();
living.position.set(
7,0,6
);
scene.add(living);
// sofa base
box(
0,1,0,
5.5,.9,1.6,
MAT.blue,
living
);
// sofa back
box(
0,1.95,-.55,
5.5,1.7,.4,
MAT.blue,
living
);
// sofa cushions
for(
const x of [-1.8,0,1.8]
){
box(
x,
1.35,
.05,
1.45,
.5,
1,
material(0x38547c,.9),
living
);
}
// table
box(
0,.8,2.5,
3.2,.15,1.7,
MAT.wood2,
living
);
for(
const x of [-1.2,1.2]
){
for(
const z of [2,3]
){
box(
x,.4,z,
.15,.8,.15,
MAT.metal,
living
);
}
}
// TV cabinet
box(
0,1,-2.5,
5,.5,1,
MAT.wood,
living
);
// TV
box(
0,2.7,-2.5,
4.4,2.5,.18,
MAT.black,
living
);
box(
0,2.7,-2.38,
4,2.05,.04,
MAT.screen,
living
);
////////////////////////////////////////////////////////////
// KITCHEN
////////////////////////////////////////////////////////////
const kitchen=
new THREE.Group();
kitchen.position.set(
7,0,-5
);
scene.add(kitchen);
box(
0,1.1,0,
8,1.5,1.2,
MAT.wood,
kitchen
);
box(
0,1.9,0,
8,.18,1.25,
MAT.concrete,
kitchen
);
// cabinets
for(
let i=0;
i<5;
i++
){
box(
-3.2+i*1.6,
3.5,
-.3,
1.35,
2.1,
.6,
MAT.wood2,
kitchen
);
}
// fridge
box(
3.5,2.3,1.8,
1.5,4.5,1.4,
MAT.white,
kitchen
);
box(
3.5,2.3,1.08,
.06,3.8,.06,
MAT.metal,
kitchen
);
////////////////////////////////////////////////////////////
// BEDROOM
////////////////////////////////////////////////////////////
const bedroom=
new THREE.Group();
bedroom.position.set(
0,0,6
);
scene.add(bedroom);
// bed
box(
0,.65,0,
6,1,3.5,
MAT.wood,
bedroom
);
box(
0,1.3,0,
5.7,.55,3.2,
MAT.white,
bedroom
);
// blanket
box(
.8,1.58,.25,
3.3,.12,3,
MAT.blue,
bedroom
);
// pillows
box(
-1.7,1.62,-1.05,
1.35,.28,.75,
MAT.white,
bedroom
);
box(
-.1,1.62,-1.05,
1.35,.28,.75,
MAT.white,
bedroom
);
// wardrobe
box(
-4,2.2,-2.5,
1.7,4.4,2,
MAT.wood,
bedroom
);
////////////////////////////////////////////////////////////
// BATHROOM
////////////////////////////////////////////////////////////
const bathroom=
new THREE.Group();
bathroom.position.set(
9,0,4
);
scene.add(bathroom);
// floor
box(
0,.16,0,
5,.12,5,
MAT.white,
bathroom
);
// toilet
cylinder(
-1.2,.7,-.8,
.55,1,
MAT.white,
bathroom
);
box(
-1.2,1.25,-.8,
.8,.2,.7,
MAT.white,
bathroom
);
// sink
box(
1.2,1.1,-1,
1.5,.2,.8,
MAT.white,
bathroom
);
cylinder(
1.2,1.55,-1,
.06,.7,
MAT.metal,
bathroom
);
// mirror
const mirror=
new THREE.MeshStandardMaterial({
color:0x7994a1,
roughness:.05,
metalness:.8
});
box(
1.2,2.7,-1.4,
1.8,1.6,.06,
mirror,
bathroom
);
// bathtub
box(
0,.7,1.25,
3.6,1.1,1.5,
MAT.white,
bathroom
);
////////////////////////////////////////////////////////////
// OUTSIDE ROAD
////////////////////////////////////////////////////////////
box(
0,.03,-17,
55,.08,5,
MAT.road
);
for(
let x=-25;
x<26;
x+=5
){
box(
x,.09,-17,
2.6,.025,.13,
MAT.white
);
}
////////////////////////////////////////////////////////////
// TREES
////////////////////////////////////////////////////////////
function tree(
x,z
){
cylinder(
x,2,z,
.32,4,
MAT.wood
);
sphere(
x,4.7,z,
1.8,
MAT.green
);
sphere(
x-1,4.4,z+.3,
1.2,
MAT.green
);
sphere(
x+1,4.4,z-.2,
1.2,
MAT.green
);
}
tree(-18,-14);
tree(18,-14);
tree(-18,14);
tree(18,15);
////////////////////////////////////////////////////////////
// PLAYER
////////////////////////////////////////////////////////////
const player=
new THREE.Group();
player.⚠️Content was pasted as plain text and auto-formatted as a code block. Use the Code Block button in the editor for proper formatting.