Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
ffaa6bf0
T
three.js
项目概览
车家大少爷
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
three.js
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ffaa6bf0
编写于
9月 25, 2015
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #7153 from mkkellogg/dev
Added shadow functionality for point lights.
上级
c95ac998
a7eed9d6
变更
14
显示空白变更内容
内联
并排
Showing
14 changed file
with
1042 addition
and
173 deletion
+1042
-173
examples/index.html
examples/index.html
+1
-0
examples/webgl_shadowmap_omnidirectional.html
examples/webgl_shadowmap_omnidirectional.html
+281
-0
examples/webgl_shadowmap_viewer.html
examples/webgl_shadowmap_viewer.html
+2
-2
src/lights/PointLight.js
src/lights/PointLight.js
+40
-0
src/renderers/WebGLRenderer.js
src/renderers/WebGLRenderer.js
+49
-10
src/renderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl
...nderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl
+6
-0
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl
+208
-89
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl
...enderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl
+121
-1
src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl
src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl
+2
-1
src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl
src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl
+33
-1
src/renderers/shaders/ShaderLib.js
src/renderers/shaders/ShaderLib.js
+68
-0
src/renderers/webgl/WebGLProgram.js
src/renderers/webgl/WebGLProgram.js
+2
-0
src/renderers/webgl/WebGLPrograms.js
src/renderers/webgl/WebGLPrograms.js
+14
-7
src/renderers/webgl/WebGLShadowMap.js
src/renderers/webgl/WebGLShadowMap.js
+215
-62
未找到文件。
examples/index.html
浏览文件 @
ffaa6bf0
...
...
@@ -362,6 +362,7 @@
"
webgl_shadowmap
"
,
"
webgl_shadowmap_performance
"
,
"
webgl_shadowmap_viewer
"
,
"
webgl_shadowmap_omnidirectional
"
,
"
webgl_shadowmesh
"
,
"
webgl_skinning_simple
"
,
"
webgl_sprites
"
,
...
...
examples/webgl_shadowmap_omnidirectional.html
0 → 100644
浏览文件 @
ffaa6bf0
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
three.js webgl - Omni-directional Shadow map viewer example
</title>
<meta
charset=
"utf-8"
>
<style>
body
{
font-family
:
Monospace
;
background-color
:
#000
;
color
:
#fff
;
margin
:
0px
;
overflow
:
hidden
;
}
#info
{
position
:
absolute
;
top
:
10px
;
width
:
100%
;
text-align
:
center
;
z-index
:
100
;
display
:
block
;
}
#info
a
{
color
:
#f00
;
font-weight
:
bold
;
text-decoration
:
underline
;
cursor
:
pointer
}
</style>
</head>
<body>
<div
id=
"info"
>
<a
href=
"http://threejs.org"
target=
"_blank"
>
three.js
</a>
- Omni-directional Shadow map viewer example by
<a
href=
"https://github.com/mkkellogg"
>
mkkellogg
</a>
</div>
<script
src=
"../build/three.min.js"
></script>
<script
src=
"js/controls/OrbitControls.js"
></script>
<script
src=
"js/Detector.js"
></script>
<script
src=
"js/libs/stats.min.js"
></script>
<script>
if
(
!
Detector
.
webgl
)
Detector
.
addGetWebGLMessage
();
var
camera
,
scene
,
renderer
,
clock
,
stats
;
var
dirLight
,
pointLight
;
var
pointLightParent
;
var
torusKnot
,
cube
,
cube2
,
cube3
,
cube4
;
var
cubeMaterial
;
var
wallMaterial
;
var
ground
;
init
();
animate
();
function
init
()
{
initScene
();
initMisc
();
document
.
body
.
appendChild
(
renderer
.
domElement
);
window
.
addEventListener
(
'
resize
'
,
onWindowResize
,
false
);
}
function
initScene
()
{
camera
=
new
THREE
.
PerspectiveCamera
(
45
,
window
.
innerWidth
/
window
.
innerHeight
,
1
,
1000
);
camera
.
position
.
set
(
0
,
15
,
35
);
scene
=
new
THREE
.
Scene
();
// Lights
var
ambient
=
new
THREE
.
AmbientLight
(
0x404040
);
scene
.
add
(
ambient
);
pointLight
=
new
THREE
.
PointLight
(
0xffffff
);
pointLight
.
position
.
set
(
0
,
11
,
4
);
pointLight
.
castShadow
=
true
;
pointLight
.
shadowCameraNear
=
1
;
pointLight
.
shadowCameraFar
=
30
;
pointLight
.
shadowDarkness
=
0.5
;
pointLight
.
shadowCameraVisible
=
true
;
pointLight
.
shadowMapWidth
=
2048
;
pointLight
.
shadowMapHeight
=
1024
;
pointLight
.
shadowBias
=
0.1
;
pointLight
.
name
=
'
Point Light
'
;
scene
.
add
(
pointLight
);
/*dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.position.set( 0, 50, 0 );
dirLight.castShadow = true;
dirLight.shadowCameraNear = 1;
dirLight.shadowCameraFar = 100;
dirLight.shadowCameraRight = 15;
dirLight.shadowCameraLeft = -15;
dirLight.shadowCameraTop = 15;
dirLight.shadowCameraBottom = -15;
dirLight.shadowDarkness = 0.5;
dirLight.shadowCameraVisible = true;
dirLight.shadowMapWidth = 1024;
dirLight.shadowMapHeight = 1024;
dirLight.name = 'Dir. Light';
scene.add( dirLight );*/
cubeMaterial
=
new
THREE
.
MeshPhongMaterial
(
{
color
:
0xff0000
,
shininess
:
150
,
specular
:
0x222222
,
shading
:
THREE
.
SmoothShading
,
}
);
var
cubeGeometry
=
new
THREE
.
BoxGeometry
(
3
,
3
,
3
);
cube
=
new
THREE
.
Mesh
(
cubeGeometry
,
cubeMaterial
);
cube
.
name
=
"
cube 1
"
;
cube
.
position
.
set
(
8
,
3
,
6
);
cube
.
castShadow
=
true
;
cube
.
receiveShadow
=
true
;
scene
.
add
(
cube
);
cube2
=
new
THREE
.
Mesh
(
cubeGeometry
,
cubeMaterial
);
cube2
.
name
=
"
cube 2
"
;
cube2
.
position
.
set
(
-
8
,
3
,
4
);
cube2
.
castShadow
=
true
;
cube2
.
receiveShadow
=
true
;
scene
.
add
(
cube2
);
cube3
=
new
THREE
.
Mesh
(
cubeGeometry
,
cubeMaterial
);
cube3
.
name
=
"
cube 3
"
;
cube3
.
position
.
set
(
-
4
,
15
,
-
6
);
cube3
.
castShadow
=
true
;
cube3
.
receiveShadow
=
true
;
scene
.
add
(
cube3
);
var
torusGeometry
=
new
THREE
.
TorusKnotGeometry
(
25
,
8
,
75
,
20
);
torusKnot
=
new
THREE
.
Mesh
(
torusGeometry
,
cubeMaterial
);
torusKnot
.
scale
.
multiplyScalar
(
1
/
18
);
torusKnot
.
position
.
set
(
-
1
,
3
,
-
4
);
torusKnot
.
castShadow
=
true
;
torusKnot
.
receiveShadow
=
true
;
scene
.
add
(
torusKnot
);
wallMaterial
=
new
THREE
.
MeshPhongMaterial
(
{
color
:
0xa0adaf
,
shininess
:
10
,
specular
:
0x111111
,
shading
:
THREE
.
SmoothShading
}
);
var
wallGeometry
=
new
THREE
.
BoxGeometry
(
10
,
0.15
,
10
);
ground
=
new
THREE
.
Mesh
(
wallGeometry
,
wallMaterial
);
ground
.
name
=
"
ground
"
;
ground
.
scale
.
multiplyScalar
(
3
);
ground
.
castShadow
=
false
;
ground
.
receiveShadow
=
true
;
scene
.
add
(
ground
);
ground
.
position
.
set
(
0
,
-
5
,
0
);
var
ceiling
=
new
THREE
.
Mesh
(
wallGeometry
,
wallMaterial
);
ceiling
.
name
=
"
ceiling
"
;
ceiling
.
scale
.
multiplyScalar
(
3
);
ceiling
.
castShadow
=
false
;
ceiling
.
receiveShadow
=
true
;
scene
.
add
(
ceiling
);
ceiling
.
position
.
set
(
0
,
24
,
0
);
var
wall
=
new
THREE
.
Mesh
(
wallGeometry
,
wallMaterial
);
wall
.
name
=
"
left wall
"
;
wall
.
scale
.
multiplyScalar
(
3
);
wall
.
castShadow
=
false
;
wall
.
receiveShadow
=
true
;
scene
.
add
(
wall
);
wall
.
position
.
set
(
-
14
,
10
,
0
);
wall
.
rotation
.
z
=
Math
.
PI
/
2
;
wall
=
new
THREE
.
Mesh
(
wallGeometry
,
wallMaterial
);
wall
.
name
=
"
right wall
"
;
wall
.
scale
.
multiplyScalar
(
3
);
wall
.
castShadow
=
false
;
wall
.
receiveShadow
=
true
;
scene
.
add
(
wall
);
wall
.
position
.
set
(
14
,
10
,
0
);
wall
.
rotation
.
z
=
Math
.
PI
/
2
;
wall
=
new
THREE
.
Mesh
(
wallGeometry
,
wallMaterial
);
wall
.
name
=
"
back wall
"
;
wall
.
scale
.
multiplyScalar
(
3
);
wall
.
castShadow
=
false
;
wall
.
receiveShadow
=
true
;
scene
.
add
(
wall
);
wall
.
position
.
set
(
0
,
10
,
-
14
);
wall
.
rotation
.
y
=
Math
.
PI
/
2
;
wall
.
rotation
.
z
=
Math
.
PI
/
2
;
/*wall = new THREE.Mesh( wallGeometry, wallMaterial );
wall.name = "front wall";
wall.scale.multiplyScalar( 3 );
wall.castShadow = false;
wall.receiveShadow = true;
scene.add( wall );
wall.position.set( 0, 10, 14 );
wall.rotation.y = Math.PI / 2;
wall.rotation.z = Math.PI / 2;*/
var
sphereGeometry
=
new
THREE
.
SphereGeometry
(
1
,
32
,
32
);
var
material
=
new
THREE
.
MeshBasicMaterial
(
{
color
:
0xffffff
}
);
var
sphere
=
new
THREE
.
Mesh
(
sphereGeometry
,
material
);
sphere
.
castShadow
=
false
;
sphere
.
receiveShadow
=
false
;
sphere
.
position
.
set
(
0
,
11
,
4
);
scene
.
add
(
sphere
);
pointLightParent
=
new
THREE
.
Object3D
();
pointLightParent
.
add
(
pointLight
);
pointLightParent
.
add
(
sphere
);
scene
.
add
(
pointLightParent
);
}
function
initMisc
()
{
renderer
=
new
THREE
.
WebGLRenderer
();
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
renderer
.
setClearColor
(
0x000000
);
renderer
.
shadowMap
.
enabled
=
true
;
renderer
.
shadowMap
.
type
=
THREE
.
BasicShadowMap
;
// Mouse control
controls
=
new
THREE
.
OrbitControls
(
camera
,
renderer
.
domElement
);
controls
.
target
.
set
(
0
,
2
,
0
);
controls
.
update
();
clock
=
new
THREE
.
Clock
();
stats
=
new
Stats
();
stats
.
domElement
.
style
.
position
=
'
absolute
'
;
stats
.
domElement
.
style
.
right
=
'
0px
'
;
stats
.
domElement
.
style
.
top
=
'
0px
'
;
document
.
body
.
appendChild
(
stats
.
domElement
);
}
function
onWindowResize
()
{
camera
.
aspect
=
window
.
innerWidth
/
window
.
innerHeight
;
camera
.
updateProjectionMatrix
();
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
}
function
animate
()
{
requestAnimationFrame
(
animate
);
render
();
stats
.
update
();
}
function
renderScene
()
{
renderer
.
render
(
scene
,
camera
);
}
function
render
()
{
var
delta
=
clock
.
getDelta
();
pointLightParent
.
rotation
.
y
+=
delta
*
2
;
renderScene
();
cube
.
rotation
.
x
+=
0.25
*
delta
;
cube
.
rotation
.
y
+=
2
*
delta
;
cube
.
rotation
.
z
+=
1
*
delta
;
cube2
.
rotation
.
x
+=
0.25
*
delta
;
cube2
.
rotation
.
y
+=
2
*
delta
;
cube2
.
rotation
.
z
+=
1
*
delta
;
cube3
.
rotation
.
x
+=
0.25
*
delta
;
cube3
.
rotation
.
y
+=
2
*
delta
;
cube3
.
rotation
.
z
+=
1
*
delta
;
}
</script>
</body>
</html>
examples/webgl_shadowmap_viewer.html
浏览文件 @
ffaa6bf0
...
...
@@ -65,7 +65,7 @@
function
initScene
()
{
camera
=
new
THREE
.
PerspectiveCamera
(
45
,
window
.
innerWidth
/
window
.
innerHeight
,
0.0
1
,
1000
);
camera
=
new
THREE
.
PerspectiveCamera
(
45
,
window
.
innerWidth
/
window
.
innerHeight
,
1
,
1000
);
camera
.
position
.
set
(
0
,
15
,
35
);
scene
=
new
THREE
.
Scene
();
...
...
@@ -89,7 +89,7 @@
dirLight
=
new
THREE
.
DirectionalLight
(
0xffffff
,
1
);
dirLight
.
position
.
set
(
0
,
10
,
0
);
dirLight
.
castShadow
=
true
;
dirLight
.
shadowCameraNear
=
0.0
1
;
dirLight
.
shadowCameraNear
=
1
;
dirLight
.
shadowCameraFar
=
10
;
dirLight
.
shadowCameraRight
=
15
;
dirLight
.
shadowCameraLeft
=
-
15
;
...
...
src/lights/PointLight.js
浏览文件 @
ffaa6bf0
...
...
@@ -2,6 +2,7 @@
* @author mrdoob / http://mrdoob.com/
*/
THREE
.
PointLight
=
function
(
color
,
intensity
,
distance
,
decay
)
{
THREE
.
Light
.
call
(
this
,
color
);
...
...
@@ -12,6 +13,30 @@ THREE.PointLight = function ( color, intensity, distance, decay ) {
this
.
distance
=
(
distance
!==
undefined
)
?
distance
:
0
;
this
.
decay
=
(
decay
!==
undefined
)
?
decay
:
1
;
// for physically correct lights, should be 2.
this
.
castShadow
=
false
;
this
.
onlyShadow
=
false
;
//
this
.
shadowCameraNear
=
1
;
this
.
shadowCameraFar
=
500
;
this
.
shadowCameraFov
=
90
;
this
.
shadowCameraVisible
=
false
;
this
.
shadowBias
=
0
;
this
.
shadowDarkness
=
0.5
;
this
.
shadowMapWidth
=
512
;
this
.
shadowMapHeight
=
512
;
//
this
.
shadowMap
=
null
;
this
.
shadowMapSize
=
null
;
this
.
shadowCamera
=
null
;
this
.
shadowMatrix
=
null
;
};
THREE
.
PointLight
.
prototype
=
Object
.
create
(
THREE
.
Light
.
prototype
);
...
...
@@ -25,6 +50,21 @@ THREE.PointLight.prototype.copy = function ( source ) {
this
.
distance
=
source
.
distance
;
this
.
decay
=
source
.
decay
;
this
.
castShadow
=
source
.
castShadow
;
this
.
onlyShadow
=
source
.
onlyShadow
;
this
.
shadowCameraNear
=
source
.
shadowCameraNear
;
this
.
shadowCameraFar
=
source
.
shadowCameraFar
;
this
.
shadowCameraFov
=
source
.
shadowCameraFov
;
this
.
shadowCameraVisible
=
source
.
shadowCameraVisible
;
this
.
shadowBias
=
source
.
shadowBias
;
this
.
shadowDarkness
=
source
.
shadowDarkness
;
this
.
shadowMapWidth
=
source
.
shadowMapWidth
;
this
.
shadowMapHeight
=
source
.
shadowMapHeight
;
return
this
;
};
...
...
src/renderers/WebGLRenderer.js
浏览文件 @
ffaa6bf0
...
...
@@ -374,6 +374,16 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this
.
getViewport
=
function
(
dimensions
)
{
dimensions
.
x
=
_viewportX
;
dimensions
.
y
=
_viewportY
;
dimensions
.
z
=
_viewportWidth
;
dimensions
.
w
=
_viewportHeight
;
};
this
.
setScissor
=
function
(
x
,
y
,
width
,
height
)
{
_gl
.
scissor
(
...
...
@@ -1701,7 +1711,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if
(
object
.
receiveShadow
&&
!
material
.
_shadowPass
)
{
refreshUniformsShadow
(
m_uniforms
,
lights
);
refreshUniformsShadow
(
m_uniforms
,
lights
,
camera
);
}
...
...
@@ -1953,7 +1963,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
function
refreshUniformsShadow
(
uniforms
,
lights
)
{
function
refreshUniformsShadow
(
uniforms
,
lights
,
camera
)
{
if
(
uniforms
.
shadowMatrix
)
{
...
...
@@ -1965,14 +1975,22 @@ THREE.WebGLRenderer = function ( parameters ) {
if
(
!
light
.
castShadow
)
continue
;
if
(
light
instanceof
THREE
.
SpotLight
||
(
light
instanceof
THREE
.
DirectionalLight
)
)
{
if
(
light
instanceof
THREE
.
PointLight
||
light
instanceof
THREE
.
SpotLight
||
light
instanceof
THREE
.
DirectionalLight
)
{
uniforms
.
shadowMap
.
value
[
j
]
=
light
.
shadowMap
;
uniforms
.
shadowMapSize
.
value
[
j
]
=
light
.
shadowMapSize
;
if
(
light
instanceof
THREE
.
PointLight
)
{
uniforms
.
shadowMatrix
.
value
[
j
]
=
light
.
shadowMatrix
;
// for point lights we set the sign of the shadowDarkness uniform to be negative
uniforms
.
shadowDarkness
.
value
[
j
]
=
-
light
.
shadowDarkness
;
}
else
{
uniforms
.
shadowDarkness
.
value
[
j
]
=
light
.
shadowDarkness
;
}
uniforms
.
shadowMatrix
.
value
[
j
]
=
light
.
shadowMatrix
;
uniforms
.
shadowMap
.
value
[
j
]
=
light
.
shadowMap
;
uniforms
.
shadowMapSize
.
value
[
j
]
=
light
.
shadowMapSize
;
uniforms
.
shadowBias
.
value
[
j
]
=
light
.
shadowBias
;
j
++
;
...
...
@@ -2308,7 +2326,7 @@ THREE.WebGLRenderer = function ( parameters ) {
case
'
tv
'
:
// array of THREE.Texture (2d)
// array of THREE.Texture (2d
or cube
)
if
(
uniform
.
_array
===
undefined
)
{
...
...
@@ -2331,10 +2349,25 @@ THREE.WebGLRenderer = function ( parameters ) {
if
(
!
texture
)
continue
;
if
(
texture
instanceof
THREE
.
CubeTexture
||
(
texture
.
image
instanceof
Array
&&
texture
.
image
.
length
===
6
)
)
{
// CompressedTexture can have Array in image :/
setCubeTexture
(
texture
,
textureUnit
);
}
else
if
(
texture
instanceof
THREE
.
WebGLRenderTargetCube
)
{
setCubeTextureDynamic
(
texture
,
textureUnit
);
}
else
{
_this
.
setTexture
(
texture
,
textureUnit
);
}
}
break
;
default
:
...
...
@@ -3011,7 +3044,6 @@ THREE.WebGLRenderer = function ( parameters ) {
renderTargetProperties
.
__webglFramebuffer
[
i
]
=
_gl
.
createFramebuffer
();
renderTargetProperties
.
__webglRenderbuffer
[
i
]
=
_gl
.
createRenderbuffer
();
state
.
texImage2D
(
_gl
.
TEXTURE_CUBE_MAP_POSITIVE_X
+
i
,
0
,
glFormat
,
renderTarget
.
width
,
renderTarget
.
height
,
0
,
glFormat
,
glType
,
null
);
setupFrameBuffer
(
renderTargetProperties
.
__webglFramebuffer
[
i
],
renderTarget
,
_gl
.
TEXTURE_CUBE_MAP_POSITIVE_X
+
i
);
...
...
@@ -3124,6 +3156,13 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if
(
isCube
)
{
var
renderTargetProperties
=
properties
.
get
(
renderTarget
);
_gl
.
framebufferTexture2D
(
_gl
.
FRAMEBUFFER
,
_gl
.
COLOR_ATTACHMENT0
,
_gl
.
TEXTURE_CUBE_MAP_POSITIVE_X
+
renderTarget
.
activeCubeFace
,
renderTargetProperties
.
__webglTexture
,
0
);
}
_currentWidth
=
width
;
_currentHeight
=
height
;
...
...
src/renderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl
浏览文件 @
ffaa6bf0
...
...
@@ -3,3 +3,9 @@
varying
vec3
vWorldPosition
;
#endif
#if MAX_POINT_LIGHTS > 0
uniform
vec3
pointLightPosition
[
MAX_POINT_LIGHTS
];
#endif
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl
浏览文件 @
ffaa6bf0
...
...
@@ -14,7 +14,22 @@
for
(
int
i
=
0
;
i
<
MAX_SHADOWS
;
i
++
)
{
// to save on uniform space, we use the sign of @shadowDarkness[ i ] to determine
// whether or not this light is a point light ( shadowDarkness[ i ] < 0 == point light)
bool
isPointLight
=
shadowDarkness
[
i
]
<
0
.
0
;
// get the real shadow darkness
float
realShadowDarkness
=
abs
(
shadowDarkness
[
i
]
);
// for point lights, the uniform @vShadowCoord is re-purposed to hold
// the distance from the light to the world-space position of the fragment.
vec3
lightToPosition
=
vShadowCoord
[
i
].
xyz
;
float
texelSizeX
=
1
.
0
/
shadowMapSize
[
i
].
x
;
float
texelSizeY
=
1
.
0
/
shadowMapSize
[
i
].
y
;
vec3
shadowCoord
=
vShadowCoord
[
i
].
xyz
/
vShadowCoord
[
i
].
w
;
float
shadow
=
0
.
0
;
// if ( something && something ) breaks ATI OpenGL shader compiler
// if ( all( something, something ) ) using this instead
...
...
@@ -26,45 +41,75 @@
bool
frustumTest
=
all
(
frustumTestVec
);
if
(
frustumTest
)
{
shadowCoord
.
z
+=
shadowBias
[
i
];
if
(
frustumTest
||
isPointLight
)
{
#if defined( SHADOWMAP_TYPE_PCF )
#if defined(POINT_LIGHT_SHADOWS)
if
(
isPointLight
)
{
float
cubeTexelSize
=
1
.
0
/
(
shadowMapSize
[
i
].
x
*
0
.
25
);
vec3
baseDirection3D
=
normalize
(
lightToPosition
);
vec2
baseDirection2D
=
cubeToUV
(
baseDirection3D
,
texelSizeX
,
texelSizeY
);
initGridSamplingDisk
();
float
diskRadius
=
1
.
25
;
float
numSamples
=
1
.
0
;
shadow
=
0
.
0
;
vec3
baseDirection
=
normalize
(
lightToPosition
);
float
curDistance
=
length
(
lightToPosition
);
float
dist
=
unpack1K
(
texture2D
(
shadowMap
[
i
],
baseDirection2D
)
)
+
0
.
1
;
if
(
curDistance
>=
dist
)
shadow
+=
1
.
0
;
// evaluate each sampling direction
for
(
int
s
=
0
;
s
<
20
;
s
++
)
{
vec3
offset
=
gridSamplingDisk
[
s
]
*
diskRadius
*
cubeTexelSize
;
vec3
adjustedBaseDirection3D
=
baseDirection3D
+
offset
;
vec2
adjustedBaseDirection2D
=
cubeToUV
(
adjustedBaseDirection3D
,
texelSizeX
,
texelSizeY
);
dist
=
unpack1K
(
texture2D
(
shadowMap
[
i
],
adjustedBaseDirection2D
)
)
+
shadowBias
[
i
];
if
(
curDistance
>=
dist
)
shadow
+=
1
.
0
;
numSamples
+=
1
.
0
;
}
shadow
/=
numSamples
;
}
else
{
#endif
// Percentage-close filtering
// (9 pixel kernel)
// http://fabiensanglard.net/shadowmappingPCF/
float
shadow
=
0
.
0
;
/*
// nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
// must enroll loop manually
for ( float y = -1.25; y <= 1.25; y += 1.25 )
for ( float x = -1.25; x <= 1.25; x += 1.25 ) {
vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );
// doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup
//vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );
float fDepth = unpackDepth( rgbaDepth );
if ( fDepth < shadowCoord.z )
shadow += 1.0;
}
shadow /= 9.0;
*/
shadowCoord
.
z
+=
shadowBias
[
i
];
const
float
shadowDelta
=
1
.
0
/
9
.
0
;
float
xPixelOffset
=
1
.
0
/
shadowMapSize
[
i
].
x
;
float
yPixelOffset
=
1
.
0
/
shadowMapSize
[
i
].
y
;
float
xPixelOffset
=
texelSizeX
;
float
yPixelOffset
=
texelSizeY
;
float
dx0
=
-
1
.
25
*
xPixelOffset
;
float
dy0
=
-
1
.
25
*
yPixelOffset
;
...
...
@@ -98,18 +143,64 @@
fDepth
=
unpackDepth
(
texture2D
(
shadowMap
[
i
],
shadowCoord
.
xy
+
vec2
(
dx1
,
dy1
)
)
);
if
(
fDepth
<
shadowCoord
.
z
)
shadow
+=
shadowDelta
;
shadowColor
=
shadowColor
*
vec3
(
(
1
.
0
-
shadowDarkness
[
i
]
*
shadow
)
);
#if defined(POINT_LIGHT_SHADOWS)
}
#endif
shadowColor
=
shadowColor
*
vec3
(
(
1
.
0
-
realShadowDarkness
*
shadow
)
);
#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
#if defined(POINT_LIGHT_SHADOWS)
if
(
isPointLight
)
{
float
cubeTexelSize
=
1
.
0
/
(
shadowMapSize
[
i
].
x
*
0
.
25
);
vec3
baseDirection3D
=
normalize
(
lightToPosition
);
vec2
baseDirection2D
=
cubeToUV
(
baseDirection3D
,
texelSizeX
,
texelSizeY
);
initGridSamplingDisk
();
float
diskRadius
=
2
.
25
;
float
numSamples
=
1
.
0
;
shadow
=
0
.
0
;
vec3
baseDirection
=
normalize
(
lightToPosition
);
float
curDistance
=
length
(
lightToPosition
);
float
dist
=
unpack1K
(
texture2D
(
shadowMap
[
i
],
baseDirection2D
)
)
+
0
.
1
;
if
(
curDistance
>=
dist
)
shadow
+=
1
.
0
;
// evaluate each sampling direction
for
(
int
s
=
0
;
s
<
20
;
s
++
)
{
vec3
offset
=
gridSamplingDisk
[
s
]
*
diskRadius
*
cubeTexelSize
;
vec3
adjustedBaseDirection3D
=
baseDirection3D
+
offset
;
vec2
adjustedBaseDirection2D
=
cubeToUV
(
adjustedBaseDirection3D
,
texelSizeX
,
texelSizeY
);
dist
=
unpack1K
(
texture2D
(
shadowMap
[
i
],
adjustedBaseDirection2D
)
)
+
shadowBias
[
i
];
if
(
curDistance
>=
dist
)
shadow
+=
1
.
0
;
numSamples
+=
1
.
0
;
}
shadow
/=
numSamples
;
}
else
{
#endif
// Percentage-close filtering
// (9 pixel kernel)
// http://fabiensanglard.net/shadowmappingPCF/
float
shadow
=
0
.
0
;
shadowCoord
.
z
+=
shadowBias
[
i
]
;
float
xPixelOffset
=
1
.
0
/
shadowMapSize
[
i
].
x
;
float
yPixelOffset
=
1
.
0
/
shadowMapSize
[
i
].
y
;
float
xPixelOffset
=
texelSizeX
;
float
yPixelOffset
=
texelSizeY
;
float
dx0
=
-
1
.
0
*
xPixelOffset
;
float
dy0
=
-
1
.
0
*
yPixelOffset
;
...
...
@@ -152,10 +243,32 @@
shadow
=
dot
(
shadowValues
,
vec4
(
1
.
0
)
);
shadowColor
=
shadowColor
*
vec3
(
(
1
.
0
-
shadowDarkness
[
i
]
*
shadow
)
);
#if defined(POINT_LIGHT_SHADOWS)
}
#endif
shadowColor
=
shadowColor
*
vec3
(
(
1
.
0
-
realShadowDarkness
*
shadow
)
);
#else
#if defined(POINT_LIGHT_SHADOWS)
if
(
isPointLight
)
{
vec3
baseDirection3D
=
normalize
(
lightToPosition
);
vec2
baseDirection2D
=
cubeToUV
(
baseDirection3D
,
texelSizeX
,
texelSizeY
);
vec4
data
=
texture2D
(
shadowMap
[
i
],
baseDirection2D
);
float
dist
=
unpack1K
(
data
)
+
shadowBias
[
i
];
if
(
length
(
lightToPosition
)
>=
dist
)
shadowColor
=
shadowColor
*
vec3
(
1
.
0
-
realShadowDarkness
);
}
else
{
#endif
shadowCoord
.
z
+=
shadowBias
[
i
];
vec4
rgbaDepth
=
texture2D
(
shadowMap
[
i
],
shadowCoord
.
xy
);
float
fDepth
=
unpackDepth
(
rgbaDepth
);
...
...
@@ -163,11 +276,17 @@
// spot with multiple shadows is darker
shadowColor
=
shadowColor
*
vec3
(
1
.
0
-
shadowDarkness
[
i
]
);
shadowColor
=
shadowColor
*
vec3
(
1
.
0
-
realShadowDarkness
);
// spot with multiple shadows has the same color as single shadow spot
// shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );
// shadowColor = min( shadowColor, vec3( realShadowDarkness ) );
#if defined(POINT_LIGHT_SHADOWS)
}
#endif
#endif
...
...
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl
浏览文件 @
ffaa6bf0
...
...
@@ -16,4 +16,124 @@
}
#if defined(POINT_LIGHT_SHADOWS)
float
unpack1K
(
vec4
color
)
{
const
vec4
bitSh
=
vec4
(
1
.
0
/
(
256
.
0
*
256
.
0
*
256
.
0
),
1
.
0
/
(
256
.
0
*
256
.
0
),
1
.
0
/
256
.
0
,
1
.
0
);
return
dot
(
color
,
bitSh
)
*
1000
.
0
;
}
/**
* cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D
* vector suitable for 2D texture mapping. This code uses the following layout for the
* 2D texture:
*
* xzXZ
* y Y
*
* Y - Positive y direction
* y - Negative y direction
* X - Positive x direction
* x - Negative x direction
* Z - Positive z direction
* z - Negative z direction
*
* Alternate code for a horizontal cross layout can be found here:
* https://gist.github.com/tschw/da10c43c467ce8afd0c4
*/
vec2
cubeToUV
(
vec3
v
,
float
texelSizeX
,
float
texelSizeY
)
{
// Number of texels to avoid at the edge of each square
vec3
absV
=
abs
(
v
);
// Intersect unit cube
float
scaleToCube
=
1
.
0
/
max
(
absV
.
x
,
max
(
absV
.
y
,
absV
.
z
)
);
absV
*=
scaleToCube
;
// Apply scale to avoid seams
// two texels less per square (one texel will do for NEAREST)
v
*=
scaleToCube
*
(
1
.
0
-
4
.
0
*
texelSizeY
);
// Unwrap
// space: -1 ... 1 range for each square
//
// #X## dim := ( 4 , 2 )
// # # center := ( 1 , 1 )
vec2
planar
=
v
.
xy
;
float
almostATexel
=
1
.
5
*
texelSizeY
;
float
almostOne
=
1
.
0
-
almostATexel
;
if
(
absV
.
z
>=
almostOne
)
{
if
(
v
.
z
>
0
.
0
)
planar
.
x
=
4
.
0
-
v
.
x
;
}
else
if
(
absV
.
x
>=
almostOne
)
{
float
signX
=
sign
(
v
.
x
);
planar
.
x
=
v
.
z
*
signX
+
2
.
0
*
signX
;
}
else
if
(
absV
.
y
>=
almostOne
)
{
float
signY
=
sign
(
v
.
y
);
planar
.
x
=
v
.
x
+
2
.
0
*
signY
+
2
.
0
;
planar
.
y
=
v
.
z
*
signY
-
2
.
0
;
}
// Transform to UV space
// scale := 0.5 / dim
// translate := ( center + 0.5 ) / dim
return
vec2
(
0
.
125
,
0
.
25
)
*
planar
+
vec2
(
0
.
375
,
0
.
75
);
}
vec3
gridSamplingDisk
[
20
];
bool
gridSamplingInitialized
=
false
;
void
initGridSamplingDisk
(){
if
(
gridSamplingInitialized
){
return
;
}
gridSamplingDisk
[
0
]
=
vec3
(
1
,
1
,
1
);
gridSamplingDisk
[
1
]
=
vec3
(
1
,
-
1
,
1
);
gridSamplingDisk
[
2
]
=
vec3
(
-
1
,
-
1
,
1
);
gridSamplingDisk
[
3
]
=
vec3
(
-
1
,
1
,
1
);
gridSamplingDisk
[
4
]
=
vec3
(
1
,
1
,
-
1
);
gridSamplingDisk
[
5
]
=
vec3
(
1
,
-
1
,
-
1
);
gridSamplingDisk
[
6
]
=
vec3
(
-
1
,
-
1
,
-
1
);
gridSamplingDisk
[
7
]
=
vec3
(
-
1
,
1
,
-
1
);
gridSamplingDisk
[
8
]
=
vec3
(
1
,
1
,
0
);
gridSamplingDisk
[
9
]
=
vec3
(
1
,
-
1
,
0
);
gridSamplingDisk
[
10
]
=
vec3
(
-
1
,
-
1
,
0
);
gridSamplingDisk
[
11
]
=
vec3
(
-
1
,
1
,
0
);
gridSamplingDisk
[
12
]
=
vec3
(
1
,
0
,
1
);
gridSamplingDisk
[
13
]
=
vec3
(
-
1
,
0
,
1
);
gridSamplingDisk
[
14
]
=
vec3
(
1
,
0
,
-
1
);
gridSamplingDisk
[
15
]
=
vec3
(
-
1
,
0
,
-
1
);
gridSamplingDisk
[
16
]
=
vec3
(
0
,
1
,
1
);
gridSamplingDisk
[
17
]
=
vec3
(
0
,
-
1
,
1
);
gridSamplingDisk
[
18
]
=
vec3
(
0
,
-
1
,
-
1
);
gridSamplingDisk
[
19
]
=
vec3
(
0
,
1
,
-
1
);
gridSamplingInitialized
=
true
;
}
#endif
#endif
\ No newline at end of file
src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl
浏览文件 @
ffaa6bf0
#ifdef USE_SHADOWMAP
varying
vec4
vShadowCoord
[
MAX_SHADOWS
];
uniform
float
shadowDarkness
[
MAX_SHADOWS
];
uniform
mat4
shadowMatrix
[
MAX_SHADOWS
];
varying
vec4
vShadowCoord
[
MAX_SHADOWS
];
#endif
\ No newline at end of file
src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl
浏览文件 @
ffaa6bf0
...
...
@@ -2,8 +2,40 @@
for
(
int
i
=
0
;
i
<
MAX_SHADOWS
;
i
++
)
{
#if defined(POINT_LIGHT_SHADOWS)
// if shadowDarkness[ i ] < 0.0, that means we have a point light with a cube
// shadow map
if
(
shadowDarkness
[
i
]
<
0
.
0
)
{
// calculate vector from light to vertex in view space
vec3
fromLight
=
mvPosition
.
xyz
-
pointLightPosition
[
i
];
// Transform 'fromLight' into world space by multiplying it on the left
// side of 'viewMatrix'. This is equivalent to multiplying it on the right
// side of the transpose of 'viewMatrix'. Since 'viewMatrix' is orthogonal,
// its transpose is the same as its inverse.
fromLight
=
fromLight
*
mat3
(
viewMatrix
);
// We repurpose vShadowCoord to hold the distance in world space from the
// light to the vertex. This value will be interpolated correctly in the fragment shader.
vShadowCoord
[
i
]
=
vec4
(
fromLight
,
1
.
0
);
}
else
{
vShadowCoord
[
i
]
=
shadowMatrix
[
i
]
*
worldPosition
;
}
#else
vShadowCoord
[
i
]
=
shadowMatrix
[
i
]
*
worldPosition
;
#endif
}
#endif
\ No newline at end of file
src/renderers/shaders/ShaderLib.js
浏览文件 @
ffaa6bf0
...
...
@@ -835,6 +835,74 @@ THREE.ShaderLib = {
].
join
(
"
\n
"
)
},
'
distanceRGBA
'
:
{
uniforms
:
{
"
lightPos
"
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0
,
0
,
0
)
}
},
vertexShader
:
[
"
varying vec4 vWorldPosition;
"
,
THREE
.
ShaderChunk
[
"
common
"
],
THREE
.
ShaderChunk
[
"
morphtarget_pars_vertex
"
],
THREE
.
ShaderChunk
[
"
skinning_pars_vertex
"
],
"
void main() {
"
,
THREE
.
ShaderChunk
[
"
skinbase_vertex
"
],
THREE
.
ShaderChunk
[
"
begin_vertex
"
],
THREE
.
ShaderChunk
[
"
morphtarget_vertex
"
],
THREE
.
ShaderChunk
[
"
skinning_vertex
"
],
THREE
.
ShaderChunk
[
"
project_vertex
"
],
THREE
.
ShaderChunk
[
"
worldpos_vertex
"
],
"
vWorldPosition = worldPosition;
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
uniform vec3 lightPos;
"
,
"
varying vec4 vWorldPosition;
"
,
THREE
.
ShaderChunk
[
"
common
"
],
"
vec4 pack1K ( float depth ) {
"
,
"
depth /= 1000.0;
"
,
"
const vec4 bitSh = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );
"
,
"
const vec4 bitMsk = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );
"
,
"
vec4 res = fract( depth * bitSh );
"
,
"
res -= res.xxyz * bitMsk;
"
,
"
return res;
"
,
"
}
"
,
"
float unpack1K ( vec4 color ) {
"
,
"
const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
"
,
"
return dot( color, bitSh ) * 1000.0;
"
,
"
}
"
,
"
void main () {
"
,
"
gl_FragColor = pack1K( length( vWorldPosition.xyz - lightPos.xyz ) );
"
,
"
}
"
].
join
(
"
\n
"
)
}
};
src/renderers/webgl/WebGLProgram.js
浏览文件 @
ffaa6bf0
...
...
@@ -219,6 +219,7 @@ THREE.WebGLProgram = ( function () {
parameters
.
shadowMapEnabled
?
'
#define USE_SHADOWMAP
'
:
''
,
parameters
.
shadowMapEnabled
?
'
#define
'
+
shadowMapTypeDefine
:
''
,
parameters
.
shadowMapDebug
?
'
#define SHADOWMAP_DEBUG
'
:
''
,
parameters
.
pointLightShadows
>
0
?
'
#define POINT_LIGHT_SHADOWS
'
:
''
,
parameters
.
sizeAttenuation
?
'
#define USE_SIZEATTENUATION
'
:
''
,
...
...
@@ -330,6 +331,7 @@ THREE.WebGLProgram = ( function () {
parameters
.
shadowMapEnabled
?
'
#define USE_SHADOWMAP
'
:
''
,
parameters
.
shadowMapEnabled
?
'
#define
'
+
shadowMapTypeDefine
:
''
,
parameters
.
shadowMapDebug
?
'
#define SHADOWMAP_DEBUG
'
:
''
,
parameters
.
pointLightShadows
>
0
?
'
#define POINT_LIGHT_SHADOWS
'
:
''
,
parameters
.
logarithmicDepthBuffer
?
'
#define USE_LOGDEPTHBUF
'
:
''
,
parameters
.
logarithmicDepthBuffer
&&
renderer
.
extensions
.
get
(
'
EXT_frag_depth
'
)
?
'
#define USE_LOGDEPTHBUF_EXT
'
:
''
,
...
...
src/renderers/webgl/WebGLPrograms.js
浏览文件 @
ffaa6bf0
...
...
@@ -20,7 +20,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
"
flatShading
"
,
"
sizeAttenuation
"
,
"
logarithmicDepthBuffer
"
,
"
skinning
"
,
"
maxBones
"
,
"
useVertexTexture
"
,
"
morphTargets
"
,
"
morphNormals
"
,
"
maxMorphTargets
"
,
"
maxMorphNormals
"
,
"
maxDirLights
"
,
"
maxPointLights
"
,
"
maxSpotLights
"
,
"
maxHemiLights
"
,
"
maxShadows
"
,
"
shadowMapEnabled
"
,
"
maxSpotLights
"
,
"
maxHemiLights
"
,
"
maxShadows
"
,
"
shadowMapEnabled
"
,
"
pointLightShadows
"
,
"
shadowMapType
"
,
"
shadowMapDebug
"
,
"
alphaTest
"
,
"
metal
"
,
"
doubleSided
"
,
"
flipSided
"
];
...
...
@@ -91,6 +91,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
function
allocateShadows
(
lights
)
{
var
maxShadows
=
0
;
var
pointLightShadows
=
0
;
for
(
var
l
=
0
,
ll
=
lights
.
length
;
l
<
ll
;
l
++
)
{
...
...
@@ -98,12 +99,17 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
if
(
!
light
.
castShadow
)
continue
;
if
(
light
instanceof
THREE
.
SpotLight
)
maxShadows
++
;
if
(
light
instanceof
THREE
.
DirectionalLight
)
maxShadows
++
;
if
(
light
instanceof
THREE
.
SpotLight
||
light
instanceof
THREE
.
DirectionalLight
)
maxShadows
++
;
if
(
light
instanceof
THREE
.
PointLight
)
{
maxShadows
++
;
pointLightShadows
++
;
}
}
return
maxShadows
;
return
{
'
maxShadows
'
:
maxShadows
,
'
pointLightShadows
'
:
pointLightShadows
}
;
}
...
...
@@ -114,7 +120,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
// (not to blow over maxLights budget)
var
maxLightCount
=
allocateLights
(
lights
);
var
max
Shadows
=
allocateShadows
(
lights
);
var
allocated
Shadows
=
allocateShadows
(
lights
);
var
maxBones
=
allocateBones
(
object
);
var
precision
=
renderer
.
getPrecision
();
...
...
@@ -176,8 +182,9 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
maxSpotLights
:
maxLightCount
.
spot
,
maxHemiLights
:
maxLightCount
.
hemi
,
maxShadows
:
maxShadows
,
shadowMapEnabled
:
renderer
.
shadowMap
.
enabled
&&
object
.
receiveShadow
&&
maxShadows
>
0
,
maxShadows
:
allocatedShadows
.
maxShadows
,
pointLightShadows
:
allocatedShadows
.
pointLightShadows
,
shadowMapEnabled
:
renderer
.
shadowMap
.
enabled
&&
object
.
receiveShadow
&&
allocatedShadows
.
maxShadows
>
0
,
shadowMapType
:
renderer
.
shadowMap
.
type
,
shadowMapDebug
:
renderer
.
shadowMap
.
debug
,
...
...
src/renderers/webgl/WebGLShadowMap.js
浏览文件 @
ffaa6bf0
...
...
@@ -13,36 +13,51 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
_min
=
new
THREE
.
Vector3
(),
_max
=
new
THREE
.
Vector3
(),
_matrixPosition
=
new
THREE
.
Vector3
(),
_lookTarget
=
new
THREE
.
Vector3
(),
_lightPositionWorld
=
new
THREE
.
Vector3
(),
_renderList
=
[];
var
_depthMaterial
,
_depthMaterialMorph
,
_depthMaterialSkin
,
_depthMaterialMorphSkin
,
_distanceMaterial
,
_distanceMaterialMorph
,
_distanceMaterialSkin
,
_distanceMaterialMorphSkin
;
var
cubeDirections
=
[
new
THREE
.
Vector3
(
1
,
0
,
0
),
new
THREE
.
Vector3
(
-
1
,
0
,
0
),
new
THREE
.
Vector3
(
0
,
0
,
1
),
new
THREE
.
Vector3
(
0
,
0
,
-
1
),
new
THREE
.
Vector3
(
0
,
1
,
0
),
new
THREE
.
Vector3
(
0
,
-
1
,
0
)
];
var
cubeUps
=
[
new
THREE
.
Vector3
(
0
,
1
,
0
),
new
THREE
.
Vector3
(
0
,
1
,
0
),
new
THREE
.
Vector3
(
0
,
1
,
0
),
new
THREE
.
Vector3
(
0
,
1
,
0
),
new
THREE
.
Vector3
(
0
,
0
,
1
),
new
THREE
.
Vector3
(
0
,
0
,
-
1
)
];
var
cube2DViewPorts
=
[
new
THREE
.
Vector4
(),
new
THREE
.
Vector4
(),
new
THREE
.
Vector4
(),
new
THREE
.
Vector4
(),
new
THREE
.
Vector4
(),
new
THREE
.
Vector4
()
];
var
_vector4
=
new
THREE
.
Vector4
();
// init
var
depthShader
=
THREE
.
ShaderLib
[
"
depthRGBA
"
];
var
depthUniforms
=
THREE
.
UniformsUtils
.
clone
(
depthShader
.
uniforms
);
var
_depthMaterial
=
new
THREE
.
ShaderMaterial
(
{
_depthMaterial
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
depthUniforms
,
vertexShader
:
depthShader
.
vertexShader
,
fragmentShader
:
depthShader
.
fragmentShader
}
);
var
_depthMaterialMorph
=
new
THREE
.
ShaderMaterial
(
{
_depthMaterialMorph
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
depthUniforms
,
vertexShader
:
depthShader
.
vertexShader
,
fragmentShader
:
depthShader
.
fragmentShader
,
morphTargets
:
true
}
);
var
_depthMaterialSkin
=
new
THREE
.
ShaderMaterial
(
{
_depthMaterialSkin
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
depthUniforms
,
vertexShader
:
depthShader
.
vertexShader
,
fragmentShader
:
depthShader
.
fragmentShader
,
skinning
:
true
}
);
var
_depthMaterialMorphSkin
=
new
THREE
.
ShaderMaterial
(
{
_depthMaterialMorphSkin
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
depthUniforms
,
vertexShader
:
depthShader
.
vertexShader
,
fragmentShader
:
depthShader
.
fragmentShader
,
...
...
@@ -55,6 +70,43 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
_depthMaterialSkin
.
_shadowPass
=
true
;
_depthMaterialMorphSkin
.
_shadowPass
=
true
;
var
distanceShader
=
THREE
.
ShaderLib
[
"
distanceRGBA
"
];
var
distanceUniforms
=
THREE
.
UniformsUtils
.
clone
(
distanceShader
.
uniforms
);
_distanceMaterial
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
distanceUniforms
,
vertexShader
:
distanceShader
.
vertexShader
,
fragmentShader
:
distanceShader
.
fragmentShader
}
);
_distanceMaterialMorph
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
distanceUniforms
,
vertexShader
:
distanceShader
.
vertexShader
,
fragmentShader
:
distanceShader
.
fragmentShader
,
morphTargets
:
true
}
);
_distanceMaterialSkin
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
distanceUniforms
,
vertexShader
:
distanceShader
.
vertexShader
,
fragmentShader
:
distanceShader
.
fragmentShader
,
skinning
:
true
}
);
_distanceMaterialMorphSkin
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
distanceUniforms
,
vertexShader
:
distanceShader
.
vertexShader
,
fragmentShader
:
distanceShader
.
fragmentShader
,
morphTargets
:
true
,
skinning
:
true
}
);
_distanceMaterial
.
_shadowPass
=
true
;
_distanceMaterialMorph
.
_shadowPass
=
true
;
_distanceMaterialSkin
.
_shadowPass
=
true
;
_distanceMaterialMorphSkin
.
_shadowPass
=
true
;
//
var
scope
=
this
;
...
...
@@ -69,6 +121,8 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
this
.
render
=
function
(
scene
)
{
var
faceCount
,
isPointLight
;
if
(
scope
.
enabled
===
false
)
return
;
if
(
scope
.
autoUpdate
===
false
&&
scope
.
needsUpdate
===
false
)
return
;
...
...
@@ -98,13 +152,58 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
var
light
=
_lights
[
i
];
if
(
light
instanceof
THREE
.
PointLight
)
{
faceCount
=
6
;
isPointLight
=
true
;
var
vpWidth
=
light
.
shadowMapWidth
/
4.0
;
var
vpHeight
=
light
.
shadowMapHeight
/
2.0
;
/*
*
* These viewports map a cube-map onto a 2D texture with the
* following orientation:
*
* xzXZ
* y Y
*
* Y - Positive y direction
* y - Negative y direction
* X - Positive x direction
* x - Negative x direction
* Z - Positive z direction
* z - Negative z direction
*
*/
// positive X
cube2DViewPorts
[
0
].
set
(
vpWidth
*
2
,
vpHeight
,
vpWidth
,
vpHeight
);
// negative X
cube2DViewPorts
[
1
].
set
(
0
,
vpHeight
,
vpWidth
,
vpHeight
);
// positive Z
cube2DViewPorts
[
2
].
set
(
vpWidth
*
3
,
vpHeight
,
vpWidth
,
vpHeight
);
// negative Z
cube2DViewPorts
[
3
].
set
(
vpWidth
,
vpHeight
,
vpWidth
,
vpHeight
);
// positive Y
cube2DViewPorts
[
4
].
set
(
vpWidth
*
3
,
0
,
vpWidth
,
vpHeight
);
// negative Y
cube2DViewPorts
[
5
].
set
(
vpWidth
,
0
,
vpWidth
,
vpHeight
);
}
else
{
faceCount
=
1
;
isPointLight
=
false
;
}
if
(
!
light
.
castShadow
)
continue
;
if
(
!
light
.
shadowMap
)
{
var
shadowFilter
=
THREE
.
LinearFilter
;
if
(
scope
.
type
===
THREE
.
PCFSoftShadowMap
)
{
if
(
scope
.
type
===
THREE
.
PCFSoftShadowMap
)
{
shadowFilter
=
THREE
.
NearestFilter
;
...
...
@@ -131,8 +230,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
}
else
{
console
.
error
(
"
THREE.ShadowMapPlugin: Unsupported light type for shadow
"
,
light
);
continue
;
light
.
shadowCamera
=
new
THREE
.
PerspectiveCamera
(
light
.
shadowCameraFov
,
1.0
,
light
.
shadowCameraNear
,
light
.
shadowCameraFar
);
}
...
...
@@ -153,16 +251,38 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
var
shadowMatrix
=
light
.
shadowMatrix
;
var
shadowCamera
=
light
.
shadowCamera
;
//
_lightPositionWorld
.
setFromMatrixPosition
(
light
.
matrixWorld
);
shadowCamera
.
position
.
copy
(
_lightPositionWorld
);
shadowCamera
.
position
.
setFromMatrixPosition
(
light
.
matrixWorld
);
_matrixPosition
.
setFromMatrixPosition
(
light
.
target
.
matrixWorld
);
shadowCamera
.
lookAt
(
_matrixPosition
);
shadowCamera
.
updateMatrixWorld
();
// save the existing viewport so it can be restored later
_renderer
.
getViewport
(
_vector4
);
shadowCamera
.
matrixWorldInverse
.
getInverse
(
shadowCamera
.
matrixWorld
);
_renderer
.
setRenderTarget
(
shadowMap
);
_renderer
.
clear
();
//
// render shadow map for each cube face (if omni-directional) or
// run a single pass if not
for
(
var
face
=
0
;
face
<
faceCount
;
face
++
)
{
if
(
isPointLight
)
{
_lookTarget
.
copy
(
shadowCamera
.
position
);
_lookTarget
.
add
(
cubeDirections
[
face
]
);
shadowCamera
.
up
.
copy
(
cubeUps
[
face
]
);
shadowCamera
.
lookAt
(
_lookTarget
);
var
vpDimensions
=
cube2DViewPorts
[
face
];
_renderer
.
setViewport
(
vpDimensions
.
x
,
vpDimensions
.
y
,
vpDimensions
.
z
,
vpDimensions
.
w
);
}
else
{
_lookTarget
.
setFromMatrixPosition
(
light
.
target
.
matrixWorld
);
shadowCamera
.
lookAt
(
_lookTarget
);
}
shadowCamera
.
updateMatrixWorld
();
shadowCamera
.
matrixWorldInverse
.
getInverse
(
shadowCamera
.
matrixWorld
);
if
(
light
.
cameraHelper
)
light
.
cameraHelper
.
visible
=
light
.
shadowCameraVisible
;
if
(
light
.
shadowCameraVisible
)
light
.
cameraHelper
.
update
();
...
...
@@ -184,18 +304,13 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
_projScreenMatrix
.
multiplyMatrices
(
shadowCamera
.
projectionMatrix
,
shadowCamera
.
matrixWorldInverse
);
_frustum
.
setFromMatrix
(
_projScreenMatrix
);
// render shadow map
_renderer
.
setRenderTarget
(
shadowMap
);
_renderer
.
clear
();
// set object matrices & frustum culling
_renderList
.
length
=
0
;
projectObject
(
scene
,
shadowCamera
);
// render shadow map
// render regular objects
for
(
var
j
=
0
,
jl
=
_renderList
.
length
;
j
<
jl
;
j
++
)
{
...
...
@@ -216,7 +331,8 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
if
(
groupMaterial
.
visible
===
true
)
{
_renderer
.
renderBufferDirect
(
shadowCamera
,
_lights
,
null
,
geometry
,
getDepthMaterial
(
object
,
groupMaterial
),
object
,
group
);
var
depthMaterial
=
getDepthMaterial
(
object
,
groupMaterial
,
isPointLight
,
_lightPositionWorld
);
_renderer
.
renderBufferDirect
(
shadowCamera
,
_lights
,
null
,
geometry
,
depthMaterial
,
object
,
group
);
}
...
...
@@ -224,7 +340,10 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
}
else
{
_renderer
.
renderBufferDirect
(
shadowCamera
,
_lights
,
null
,
geometry
,
getDepthMaterial
(
object
,
material
),
object
,
null
);
var
depthMaterial
=
getDepthMaterial
(
object
,
material
,
isPointLight
,
_lightPositionWorld
);
_renderer
.
renderBufferDirect
(
shadowCamera
,
_lights
,
null
,
geometry
,
depthMaterial
,
object
,
null
);
}
}
...
...
@@ -246,44 +365,78 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
}
_renderer
.
setViewport
(
_vector4
.
x
,
_vector4
.
y
,
_vector4
.
z
,
_vector4
.
w
);
_renderer
.
resetGLState
();
scope
.
needsUpdate
=
false
;
};
function
getDepthMaterial
(
object
,
material
)
{
function
getDepthMaterial
(
object
,
material
,
isPointLight
,
lightPositionWorld
)
{
var
geometry
=
object
.
geometry
;
var
useMorphing
=
geometry
.
morphTargets
!==
undefined
&&
geometry
.
morphTargets
.
length
>
0
&&
material
.
morphTargets
;
var
useSkinning
=
object
instanceof
THREE
.
SkinnedMesh
&&
material
.
skinning
;
var
depth
Material
;
var
new
Material
;
if
(
object
.
customDepthMaterial
)
{
var
depthMaterial
=
_depthMaterial
;
var
depthMaterialMorph
=
_depthMaterialMorph
;
var
depthMaterialSkin
=
_depthMaterialSkin
;
var
depthMaterialMorphSkin
=
_depthMaterialMorphSkin
;
depthMaterial
=
object
.
customDepthMaterial
;
if
(
isPointLight
)
{
depthMaterial
=
_distanceMaterial
;
depthMaterialMorph
=
_distanceMaterialMorph
;
depthMaterialSkin
=
_distanceMaterialSkin
;
depthMaterialMorphSkin
=
_distanceMaterialMorphSkin
;
}
if
(
object
.
customDepthMaterial
||
object
.
customDistanceMaterial
)
{
if
(
isPointLight
)
{
newMaterial
=
object
.
customDistanceMaterial
;
}
else
{
newMaterial
=
object
.
customDepthMaterial
;
}
}
else
if
(
useSkinning
)
{
depthMaterial
=
useMorphing
?
_depthMaterialMorphSkin
:
_
depthMaterialSkin
;
newMaterial
=
useMorphing
?
depthMaterialMorphSkin
:
depthMaterialSkin
;
}
else
if
(
useMorphing
)
{
depthMaterial
=
_
depthMaterialMorph
;
newMaterial
=
depthMaterialMorph
;
}
else
{
depthMaterial
=
_
depthMaterial
;
newMaterial
=
depthMaterial
;
}
depthMaterial
.
visible
=
material
.
visible
;
depthMaterial
.
wireframe
=
material
.
wireframe
;
depthMaterial
.
wireframeLinewidth
=
material
.
wireframeLinewidth
;
newMaterial
.
visible
=
material
.
visible
;
newMaterial
.
wireframe
=
material
.
wireframe
;
newMaterial
.
wireframeLinewidth
=
material
.
wireframeLinewidth
;
if
(
isPointLight
)
{
if
(
newMaterial
.
uniforms
.
lightPos
)
{
newMaterial
.
uniforms
.
lightPos
.
value
.
copy
(
lightPositionWorld
);
}
}
return
depth
Material
;
return
new
Material
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录