Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
skyuning
ThreeJS 范例演示
提交
45b0241f
T
ThreeJS 范例演示
项目概览
skyuning
/
ThreeJS 范例演示
与 Fork 源项目一致
Fork自
inscode / VueJS
通知
1
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
ThreeJS 范例演示
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
“0feae533ddebe02cda6ccce5cac7349b446776a8”上不存在“include/linux/amd-iommu.h”
提交
45b0241f
编写于
10月 20, 2023
作者:
S
skyun
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Auto Commit
上级
e8ea12b9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
210 addition
and
63 deletion
+210
-63
src/threejs-utils/threejs-manager.js
src/threejs-utils/threejs-manager.js
+46
-33
src/threejs-utils/threejs-tools.js
src/threejs-utils/threejs-tools.js
+10
-13
src/views/light-option.vue
src/views/light-option.vue
+142
-15
src/views/lights.vue
src/views/lights.vue
+12
-2
未找到文件。
src/threejs-utils/threejs-manager.js
浏览文件 @
45b0241f
import
{
onMounted
}
from
'
vue
'
import
{
ref
,
reactive
,
toRef
,
watch
,
onMounted
}
from
'
vue
'
import
*
as
THREE
from
'
three
'
import
{
OrbitControls
}
from
'
three/addons/controls/OrbitControls.js
'
import
*
as
TT
from
'
./threejs-tools
'
export
default
class
ThreejsManager
{
constructor
(
container
)
{
// init scene camera
constructor
()
{
this
.
animateFuncs
=
{}
this
.
lights
=
reactive
([])
}
addScene
()
{
this
.
scene
=
new
THREE
.
Scene
()
// init renderer
}
addRenderer
()
{
this
.
renderer
=
new
THREE
.
WebGLRenderer
()
this
.
animateFuncs
=
{}
const
animate
=
()
=>
{
requestAnimationFrame
(
animate
)
Object
.
values
(
this
.
animateFuncs
).
forEach
(
animFunc
=>
animFunc
())
this
.
renderer
.
render
(
this
.
scene
,
this
.
camera
)
}
startRender
(
container
)
{
this
.
renderer
.
rendering
=
true
container
.
value
.
appendChild
(
this
.
renderer
.
domElement
)
this
.
renderer
.
setSize
(
container
.
value
.
clientWidth
,
container
.
value
.
clientHeight
)
this
.
camera
=
new
THREE
.
PerspectiveCamera
(
60
,
container
.
value
.
clientWidth
/
container
.
value
.
clientHeight
,
0.1
,
1000
)
this
.
camera
.
position
.
set
(
0
,
10
,
10
)
this
.
controls
=
new
OrbitControls
(
this
.
camera
,
this
.
renderer
.
domElement
);
this
.
animate
()
}
animate
()
{
if
(
!
this
.
renderer
.
rendering
)
{
return
}
onMounted
(()
=>
{
container
.
value
.
appendChild
(
this
.
renderer
.
domElement
)
this
.
renderer
.
setSize
(
container
.
value
.
clientWidth
,
container
.
value
.
clientHeight
)
this
.
camera
=
new
THREE
.
PerspectiveCamera
(
60
,
container
.
value
.
clientWidth
/
container
.
value
.
clientHeight
,
0.1
,
1000
)
this
.
camera
.
position
.
set
(
0
,
10
,
10
)
this
.
controls
=
new
OrbitControls
(
this
.
camera
,
this
.
renderer
.
domElement
);
animate
()
})
this
.
initDefaultScene
()
requestAnimationFrame
(
this
.
animate
.
bind
(
this
))
Object
.
values
(
this
.
animateFuncs
).
forEach
(
animFunc
=>
animFunc
())
this
.
renderer
.
render
(
this
.
scene
,
this
.
camera
)
}
initDefaultScene
()
{
this
.
scene
.
add
(
new
THREE
.
GridHelper
(
100
,
100
,
0x660000
,
0x004400
))
this
.
addPlane
()
this
.
addCube
()
this
.
lightHelpers
=
[]
this
.
lightHelpers
.
push
(
this
.
addAmbientLight
())
this
.
lightHelpers
.
push
(
this
.
addDirectLight
())
this
.
lightHelpers
.
push
(
this
.
addPointLight
())
this
.
lightHelpers
.
push
(
this
.
addSpotLight
())
this
.
addAmbientLight
()
}
onAnimate
(
name
,
animFunc
)
{
this
.
animateFuncs
[
name
]
=
animFunc
...
...
@@ -61,15 +58,31 @@ export default class ThreejsManager {
return
cube
}
addAmbientLight
()
{
return
TT
.
addLight
(
this
.
scene
,
THREE
.
AmbientLight
,
[
0xffffff
,
.
1
])
const
light
=
TT
.
createLight
(
THREE
.
AmbientLight
,
[
0xffffff
,
.
1
])
this
.
scene
.
add
(
light
)
this
.
lights
.
push
(
light
)
light
.
name
=
light
.
type
+
`-`
+
this
.
lights
.
length
return
light
}
addDirectLight
()
{
return
TT
.
addLight
(
this
.
scene
,
THREE
.
DirectionalLight
,
[
0xff0000
,
1
],
[
-
4
,
5
,
-
3
])
const
light
=
TT
.
createLight
(
THREE
.
DirectionalLight
,
[
0xff0000
,
1
],
[
-
4
,
5
,
-
3
])
this
.
scene
.
add
(
light
)
this
.
lights
.
push
(
light
)
light
.
name
=
light
.
type
+
`-`
+
this
.
lights
.
length
return
light
}
addPointLight
()
{
return
TT
.
addLight
(
this
.
scene
,
THREE
.
PointLight
,
[
0x00ff00
,
50
],
[
3
,
3
,
-
2
],
.
5
)
const
light
=
TT
.
createLight
(
THREE
.
PointLight
,
[
0x00ff00
,
50
,
10
],
[
3
,
3
,
-
2
])
this
.
scene
.
add
(
light
)
this
.
lights
.
push
(
light
)
light
.
name
=
light
.
type
+
`-`
+
this
.
lights
.
length
return
light
}
addSpotLight
()
{
return
TT
.
addLight
(
this
.
scene
,
THREE
.
SpotLight
,
[
0x0000ff
,
1000
,
7
,
.
2
,
.
5
],
[
-
1
,
6
,
1
])
const
light
=
TT
.
createLight
(
THREE
.
SpotLight
,
[
0x0000ff
,
1000
,
7
,
.
2
,
.
5
],
[
-
1
,
6
,
1
])
this
.
scene
.
add
(
light
)
this
.
lights
.
push
(
light
)
light
.
name
=
light
.
type
+
`-`
+
this
.
lights
.
length
return
light
}
}
src/threejs-utils/threejs-tools.js
浏览文件 @
45b0241f
...
...
@@ -20,25 +20,22 @@ export function createCube() {
return
cube
}
export
function
createLight
(
lightConstuctor
,
lightArgs
=
[
0xffffff
,
1
],
lightPos
=
[
0
,
0
,
1
]
,
...
helperArgs
)
{
export
function
createLight
(
lightConstuctor
,
lightArgs
=
[
0xffffff
,
1
],
lightPos
=
[
0
,
0
,
1
])
{
const
light
=
new
lightConstuctor
(...
lightArgs
)
light
.
position
.
set
(...
lightPos
)
return
light
}
export
function
createLightHelper
(
light
,
...
helperArgs
)
{
let
helperType
if
(
light
Constuctor
===
THREE
.
AmbientLight
)
{
}
else
if
(
light
Constuctor
===
THREE
.
DirectionalLight
)
{
if
(
light
.
type
===
'
AmbientLight
'
)
{
}
else
if
(
light
.
type
===
'
DirectionalLight
'
)
{
helperType
=
THREE
.
DirectionalLightHelper
}
else
if
(
light
Constuctor
===
THREE
.
PointLight
)
{
}
else
if
(
light
.
type
===
'
PointLight
'
)
{
helperType
=
THREE
.
PointLightHelper
}
else
if
(
light
Constuctor
===
THREE
.
SpotLight
)
{
}
else
if
(
light
.
type
===
'
SpotLight
'
)
{
helperType
=
THREE
.
SpotLightHelper
}
const
helper
=
helperType
&&
new
helperType
(
light
,
...
helperArgs
)
||
{
light
,
isMockHelper
:
true
}
const
helper
=
!!
helperType
&&
new
helperType
(
light
,
...
helperArgs
)
||
null
return
helper
}
export
function
addLight
(
scene
,
...
createArgs
)
{
const
helper
=
createLight
(...
createArgs
)
scene
.
add
(
helper
.
light
)
helper
.
isMockHelper
||
scene
.
add
(
helper
)
return
helper
}
\ No newline at end of file
src/views/light-option.vue
浏览文件 @
45b0241f
<
template
>
<div
class=
"options"
>
<h1>
Light Options
{{
test
}}
</h1>
<div
v-for=
"l in lights"
class=
"light-option flex-col flex-align-start"
>
<Checkbox
:label=
"l.name"
v-model=
"l.visible"
>
{{
l
.
type
}}
</Checkbox>
<h2>
灯光选项
</h2>
<div
v-for=
"l in props.lights"
class=
"light-option flex-col flex-align-start"
>
<Checkbox
class=
"check-box"
:label=
"l.name"
size=
"small"
@
on-change=
"refresh"
v-model=
"l.visible"
>
{{
l
.
name
}}
</Checkbox>
<div
class=
"match-width flex-row"
>
<label
class=
"mr10px"
>
强度
</label>
<Slider
class=
"flex-1"
v-model=
"l.intensity"
:step=
l._intensity*.01
:max=
l._intensity*10
></Slider>
<span
class=
"lable"
>
位置
</span>
<Input
size=
"small"
@
on-keydown=
"onPositionKeyPress($event, l)"
style=
"width: 50px;"
/>
</div>
<div
class=
"match-width flex-row"
>
<span
class=
"lable"
>
光照强度:
{{
l
.
intensity
}}
</span>
<Slider
class=
"flex-1"
@
on-change=
"saveOptions"
:step=
l._intensity*.01
:max=
l._intensity*10
v-model=
"l.intensity"
/>
</div>
<template
v-if=
"['PointLight', 'SpotLight'].includes(l.type)"
>
<div
class=
"match-width flex-row"
>
<span
class=
"lable"
>
照射距离:
{{
l
.
distance
}}
</span>
<Slider
class=
"flex-1"
@
on-input=
"refresh"
@
on-change=
"saveOptions"
:step=
l._distance*.01
:max=
l._distance*3
v-model=
"l.distance"
/>
</div>
<div
class=
"match-width flex-row"
>
<span
class=
"lable"
>
距离衰减:
{{
l
.
decay
}}
</span>
<Slider
class=
"flex-1"
@
on-input=
"refresh"
@
on-change=
"saveOptions"
:step=
0.1
:max=
10
v-model=
"l.decay"
/>
</div>
</
template
>
<
template
v-if=
"['SpotLight'].includes(l.type)"
>
<div
class=
"match-width flex-row"
>
<span
class=
"lable"
>
散射角度:
{{
(
l
.
angle
*
180
/
Math
.
PI
).
toFixed
(
0
)
}}
</span>
<Slider
class=
"flex-1"
@
on-input=
"refresh"
@
on-change=
"saveOptions"
:step=
0.01
:max=
Math.PI/2
v-model=
"l.angle"
/>
</div>
<div
class=
"match-width flex-row"
>
<span
class=
"lable"
>
散射衰减:
{{
l
.
penumbra
}}
</span>
<Slider
class=
"flex-1"
@
on-input=
"refresh"
@
on-change=
"saveOptions"
:step=
0.01
:max=
1
v-model=
"l.penumbra"
/>
</div>
</
template
>
</div>
</div>
</template>
<
script
setup
>
import
{
ref
,
reactive
,
toRef
,
watch
,
onMounted
,
defineProps
}
from
'
vue
'
import
{
ref
,
shallowRef
,
reactive
,
toRef
,
toRefs
,
watch
,
onMounted
,
defineProps
}
from
'
vue
'
import
*
as
TT
from
'
../threejs-utils/threejs-tools
'
function
onPositionKeyPress
(
ev
,
light
)
{
console
.
log
(
ev
.
type
,
ev
.
key
,
ev
.
altKey
)
const
step
=
.
5
if
(
ev
.
altKey
&&
ev
.
key
===
`ArrowUp`
)
{
light
.
position
.
z
-=
step
}
else
if
(
ev
.
altKey
&&
ev
.
key
===
`ArrowDown`
)
{
light
.
position
.
z
+=
step
}
else
if
(
ev
.
key
===
`ArrowLeft`
)
{
light
.
position
.
x
-=
step
}
else
if
(
ev
.
key
===
`ArrowRight`
)
{
light
.
position
.
x
+=
step
}
else
if
(
ev
.
key
===
`ArrowUp`
)
{
light
.
position
.
y
-=
step
}
else
if
(
ev
.
key
===
`ArrowDown`
)
{
light
.
position
.
y
+=
step
}
else
if
(
ev
.
key
===
`ArrowRight`
)
{
}
}
const
props
=
defineProps
({
lights
:{
type
:
Array
,
},
})
props
.
lights
.
forEach
(
l
=>
{
l
.
_intensity
=
l
.
intensity
scene
:
{
type
:
Object
},
lights
:
{
type
:
Array
},
})
const
lights
=
reactive
(
props
.
lights
)
// helper逻辑
let
helpers
=
[]
watch
(
toRef
(
props
.
lights
,
`length`
),
(
newVal
,
oldVal
)
=>
{
props
.
lights
.
forEach
(
l
=>
{
l
.
_intensity
=
l
.
intensity
l
.
_distance
=
l
.
distance
})
helpers
.
forEach
(
h
=>
{
h
.
dispose
()
props
.
scene
.
remove
(
h
)
})
helpers
=
props
.
lights
.
filter
(
light
=>
light
.
type
!==
`AmbientLight`
)
.
map
(
light
=>
TT
.
createLightHelper
(
light
))
helpers
.
forEach
(
helper
=>
{
props
.
scene
.
add
(
helper
)
})
},
{
immediate
:
true
,
deep
:
false
})
function
refresh
()
{
helpers
.
forEach
(
helper
=>
{
helper
.
visible
=
helper
.
light
.
visible
helper
.
update
()
})
}
// load/save options
function
loadOptions
()
{
const
options
=
JSON
.
parse
(
localStorage
.
getItem
(
`light-options`
))
options
.
forEach
((
opt
,
i
)
=>
{
Object
.
keys
(
opt
).
forEach
(
key
=>
{
props
.
lights
[
i
][
key
]
=
opt
[
key
]
})
})
}
function
saveOptions
()
{
const
options
=
props
.
lights
.
map
(
l
=>
{
return
[
`visible`
,
`intensity`
,
`distance`
,
`decay`
,
`angle`
,
`penumbra`
].
reduce
((
res
,
attr
)
=>
{
res
[
attr
]
=
l
[
attr
]
return
res
},
{})
})
localStorage
.
setItem
(
`light-options`
,
JSON
.
stringify
(
options
))
}
</
script
>
<
style
scoped
>
.options
{
width
:
100%
;
height
:
100%
;
padding
:
40px
2
0px
;
padding
:
1
0px
;
align-items
:
flex-start
;
overflow-y
:
scroll
;
}
.light-option
{
width
:
100%
;
margin-top
:
20px
;
display
:
flex
;
}
.check-box
{
width
:
100%
;
margin
:
8px
0
;
padding
:
2px
5px
;
background
:
#223
;
}
.lable
{
width
:
120px
;
margin-left
:
10px
;
}
</
style
>
\ No newline at end of file
src/views/lights.vue
浏览文件 @
45b0241f
<
template
>
<div
id=
"root"
class=
"flex-row"
>
<LightOption
class=
"options"
:
lights=
"tm.lightHelpers.map(helper => helper.light)
"
/>
<LightOption
class=
"options"
:
scene=
"tm.scene"
:lights=
"tm.lights
"
/>
<div
id=
"container"
ref=
"container"
></div>
{{
tm
.
lightHelpers
[
1
].
light
.
intensity
}}
</div>
</
template
>
...
...
@@ -14,6 +13,17 @@ import LightOption from './light-option.vue'
const
container
=
ref
(
null
)
const
tm
=
new
ThreeManager
(
container
)
tm
.
addScene
()
tm
.
addRenderer
()
onMounted
(()
=>
{
tm
.
startRender
(
container
)
})
tm
.
initDefaultScene
()
tm
.
addDirectLight
()
tm
.
addPointLight
()
tm
.
addSpotLight
()
</
script
>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录