Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
c75213d5
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,发现更多精彩内容 >>
提交
c75213d5
编写于
9月 26, 2016
作者:
T
Takahiro
提交者:
Mr.doob
9月 26, 2016
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Recover and clean up WebGLDeferredRenderer (#9772)
上级
b9ef4dce
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
1869 addition
and
0 deletion
+1869
-0
examples/files.js
examples/files.js
+1
-0
examples/js/renderers/WebGLDeferredRenderer.js
examples/js/renderers/WebGLDeferredRenderer.js
+1574
-0
examples/webgl_deferred_animation.html
examples/webgl_deferred_animation.html
+294
-0
未找到文件。
examples/files.js
浏览文件 @
c75213d5
...
...
@@ -10,6 +10,7 @@ var files = {
"
webgl_clipping
"
,
"
webgl_clipping_advanced
"
,
"
webgl_decals
"
,
"
webgl_deferred_animation
"
,
"
webgl_depth_texture
"
,
"
webgl_effects_anaglyph
"
,
"
webgl_effects_parallaxbarrier
"
,
...
...
examples/js/renderers/WebGLDeferredRenderer.js
0 → 100644
浏览文件 @
c75213d5
/**
* @author alteredq / http://alteredqualia.com/
* @author MPanknin / http://www.redplant.de/
* @author takahiro / https://github.com/takahirox
*
* Dependencies
* - THREE.CopyShader
* - THREE.RenderPass
* - THREE.ShaderPass
* - THREE.EffectComposer
* - THREE.FXAAShader
*
* TODO
* - reuse existing glsl
* - shared material
* - shadow
* - optimization
* - MRT (when it's available on Three.js)
* - AmbientLight
* - HemisphereLight
* - PointLight (distance < 0)
* - morphNormals
* - BumpMap
* - ToneMap
* - envMap
* - wrapAround
* - addEffect
*/
THREE
.
WebGLDeferredRenderer
=
function
(
parameters
)
{
parameters
=
parameters
||
{};
// private properties
var
_this
=
this
;
var
_gl
;
var
_width
,
_height
;
var
_compColor
,
_compNormalDepth
,
_compLight
,
_compFinal
;
var
_passColor
,
_passNormalDepth
,
_passLight
,
_passLightFullscreen
,
_passFinal
,
_passForward
,
_passCopy
,
_passFXAA
;
var
_lightScene
,
_lightFullscreenScene
;
var
_antialias
=
false
,
_hasTransparentObject
=
false
;
var
_invisibleMaterial
=
new
THREE
.
ShaderMaterial
(
{
visible
:
false
}
);
var
_tmpVector3
=
new
THREE
.
Vector3
();
// external properties
this
.
renderer
;
this
.
domElement
;
this
.
forwardRendering
=
false
;
// for debug
// private methods
var
init
=
function
(
parameters
)
{
_this
.
renderer
=
parameters
.
renderer
!==
undefined
?
parameters
.
renderer
:
new
THREE
.
WebGLRenderer
(
{
antialias
:
false
}
);
_this
.
domElement
=
_this
.
renderer
.
domElement
;
_gl
=
_this
.
renderer
.
context
;
_width
=
parameters
.
width
!==
undefined
?
parameters
.
width
:
_this
.
renderer
.
getSize
().
width
;
_height
=
parameters
.
height
!==
undefined
?
parameters
.
height
:
_this
.
renderer
.
getSize
().
height
;
var
antialias
=
parameters
.
antialias
!==
undefined
?
parameters
.
antialias
:
false
;
initPassFXAA
();
initPassNormalDepth
();
initPassColor
();
initPassLight
();
initPassFinal
();
_this
.
setSize
(
_width
,
_height
);
_this
.
setAntialias
(
antialias
);
};
var
initPassFXAA
=
function
()
{
_passFXAA
=
new
THREE
.
ShaderPass
(
THREE
.
FXAAShader
);
};
var
initPassNormalDepth
=
function
()
{
_passNormalDepth
=
new
THREE
.
RenderPass
();
_passNormalDepth
.
clear
=
true
;
var
rt
=
new
THREE
.
WebGLRenderTarget
(
_width
,
_height
,
{
minFilter
:
THREE
.
NearestFilter
,
magFilter
:
THREE
.
NearestFilter
,
format
:
THREE
.
RGBAFormat
,
type
:
THREE
.
FloatType
,
stencilBuffer
:
true
,
depthTexture
:
new
THREE
.
DepthTexture
(
_width
,
_height
,
THREE
.
UnsignedInt248Type
,
undefined
,
undefined
,
undefined
,
undefined
,
undefined
,
undefined
,
THREE
.
DepthStencilFormat
)
}
);
rt
.
texture
.
generateMipamps
=
false
;
_compNormalDepth
=
new
THREE
.
EffectComposer
(
_this
.
renderer
,
rt
);
_compNormalDepth
.
addPass
(
_passNormalDepth
);
};
var
initPassColor
=
function
()
{
_passColor
=
new
THREE
.
RenderPass
();
_passColor
.
clear
=
true
;
var
rt
=
new
THREE
.
WebGLRenderTarget
(
_width
,
_height
,
{
minFilter
:
THREE
.
NearestFilter
,
magFilter
:
THREE
.
NearestFilter
,
format
:
THREE
.
RGBAFormat
,
type
:
THREE
.
FloatType
,
depthTexture
:
_compNormalDepth
.
renderTarget2
.
depthTexture
}
);
rt
.
texture
.
generateMipamps
=
false
;
_compColor
=
new
THREE
.
EffectComposer
(
_this
.
renderer
,
rt
);
_compColor
.
addPass
(
_passColor
);
};
var
initPassLight
=
function
()
{
_passLightFullscreen
=
new
THREE
.
RenderPass
();
_passLightFullscreen
.
clear
=
true
;
_passLightFullscreen
.
camera
=
new
THREE
.
OrthographicCamera
(
-
1
,
1
,
1
,
-
1
,
0
,
1
);
_passLight
=
new
THREE
.
RenderPass
();
_passLight
.
clear
=
false
;
var
rt
=
new
THREE
.
WebGLRenderTarget
(
_width
,
_height
,
{
minFilter
:
THREE
.
NearestFilter
,
magFilter
:
THREE
.
NearestFilter
,
format
:
THREE
.
RGBAFormat
,
type
:
THREE
.
FloatType
,
depthTexture
:
_compNormalDepth
.
renderTarget2
.
depthTexture
}
);
rt
.
texture
.
generateMipamps
=
false
;
_compLight
=
new
THREE
.
EffectComposer
(
_this
.
renderer
,
rt
);
_compLight
.
addPass
(
_passLightFullscreen
);
_compLight
.
addPass
(
_passLight
);
};
var
initPassFinal
=
function
()
{
_passFinal
=
new
THREE
.
ShaderPass
(
THREE
.
ShaderDeferred
[
'
composite
'
]
);
_passFinal
.
clear
=
true
;
_passFinal
.
uniforms
.
samplerLight
.
value
=
_compLight
.
renderTarget2
.
texture
;
_passFinal
.
material
.
blending
=
THREE
.
NoBlending
;
_passFinal
.
material
.
depthWrite
=
false
;
_passFinal
.
material
.
depthTest
=
false
;
_passForward
=
new
THREE
.
RenderPass
();
_passForward
.
clear
=
false
;
_passCopy
=
new
THREE
.
ShaderPass
(
THREE
.
CopyShader
);
var
rt
=
new
THREE
.
WebGLRenderTarget
(
_width
,
_height
,
{
minFilter
:
THREE
.
NearestFilter
,
magFilter
:
THREE
.
LinearFilter
,
format
:
THREE
.
RGBFormat
,
type
:
THREE
.
UnsignedByteType
,
depthTexture
:
_compNormalDepth
.
renderTarget2
.
depthTexture
}
);
rt
.
texture
.
generateMipamps
=
false
;
_compFinal
=
new
THREE
.
EffectComposer
(
_this
.
renderer
,
rt
);
_compFinal
.
addPass
(
_passFinal
);
_compFinal
.
addPass
(
_passForward
);
_compFinal
.
addPass
(
_passCopy
);
_compFinal
.
addPass
(
_passFXAA
);
};
var
initLightScene
=
function
(
scene
)
{
if
(
scene
.
userData
.
lightScene
===
undefined
)
{
var
lightScene
=
new
THREE
.
Scene
();
lightScene
.
userData
.
lights
=
{};
scene
.
userData
.
lightScene
=
lightScene
;
}
if
(
scene
.
userData
.
lightFullscreenScene
===
undefined
)
{
var
lightScene
=
new
THREE
.
Scene
();
lightScene
.
userData
.
lights
=
{};
lightScene
.
userData
.
emissiveLight
=
createDeferredEmissiveLight
();
lightScene
.
add
(
lightScene
.
userData
.
emissiveLight
);
scene
.
userData
.
lightFullscreenScene
=
lightScene
;
}
_lightScene
=
scene
.
userData
.
lightScene
;
_lightFullscreenScene
=
scene
.
userData
.
lightFullscreenScene
;
};
var
initDeferredProperties
=
function
(
object
)
{
if
(
object
.
userData
.
deferredInitialized
===
true
)
return
;
if
(
object
.
material
)
initDeferredMaterials
(
object
);
if
(
object
instanceof
THREE
.
Light
)
initDeferredLight
(
object
);
object
.
userData
.
deferredInitialized
=
true
;
};
var
initDeferredMaterials
=
function
(
object
)
{
if
(
object
.
material
instanceof
THREE
.
MultiMaterial
)
{
var
normalDepthMaterials
=
[];
var
colorMaterials
=
[];
var
forwardMaterials
=
[];
var
materials
=
object
.
material
.
materials
;
for
(
var
i
=
0
,
il
=
materials
.
length
;
i
<
il
;
i
++
)
{
normalDepthMaterials
.
push
(
createDeferredNormalDepthMaterial
(
materials
[
i
]
)
);
colorMaterials
.
push
(
createDeferredColorMaterial
(
materials
[
i
]
)
);
forwardMaterials
.
push
(
_invisibleMaterial
);
}
object
.
userData
.
normalDepthMaterial
=
new
THREE
.
MultiMaterial
(
normalDepthMaterials
);
object
.
userData
.
colorMaterial
=
new
THREE
.
MultiMaterial
(
colorMaterials
);
object
.
userData
.
forwardMaterial
=
new
THREE
.
MultiMaterial
(
forwardMaterials
);
}
else
{
object
.
userData
.
normalDepthMaterial
=
createDeferredNormalDepthMaterial
(
object
.
material
);
object
.
userData
.
colorMaterial
=
createDeferredColorMaterial
(
object
.
material
);
}
};
var
createDeferredNormalDepthMaterial
=
function
(
originalMaterial
)
{
var
shader
=
THREE
.
ShaderDeferred
[
'
normalDepth
'
];
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
fragmentShader
:
shader
.
fragmentShader
,
vertexShader
:
shader
.
vertexShader
,
blending
:
THREE
.
NoBlending
}
);
return
material
;
};
var
updateDeferredNormalDepthMaterial
=
function
(
material
,
originalMaterial
)
{
if
(
originalMaterial
.
skinning
!==
undefined
)
material
.
skinning
=
originalMaterial
.
skinning
;
if
(
originalMaterial
.
morphTargets
!==
undefined
)
material
.
morphTargets
=
originalMaterial
.
morphTargets
;
if
(
originalMaterial
.
visible
===
true
)
{
material
.
visible
=
!
originalMaterial
.
transparent
;
}
else
{
material
.
visible
=
false
;
}
};
var
createDeferredColorMaterial
=
function
(
originalMaterial
)
{
var
shader
=
THREE
.
ShaderDeferred
[
'
color
'
];
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
fragmentShader
:
shader
.
fragmentShader
,
vertexShader
:
shader
.
vertexShader
,
blending
:
THREE
.
NoBlending
}
);
if
(
originalMaterial
.
map
!==
undefined
)
material
.
map
=
originalMaterial
.
map
;
return
material
;
};
var
updateDeferredColorMaterial
=
function
(
material
,
originalMaterial
)
{
var
diffuse
,
emissive
;
if
(
originalMaterial
instanceof
THREE
.
MeshBasicMaterial
)
{
emissive
=
originalMaterial
.
color
;
}
else
{
diffuse
=
originalMaterial
.
color
;
emissive
=
originalMaterial
.
emissive
;
}
var
specular
=
originalMaterial
.
specular
;
var
shininess
=
originalMaterial
.
shininess
;
var
map
=
originalMaterial
.
map
;
if
(
(
originalMaterial
instanceof
THREE
.
ShaderMaterial
)
&&
originalMaterial
.
uniforms
!==
undefined
)
{
if
(
diffuse
===
undefined
&&
originalMaterial
.
uniforms
.
diffuse
!==
undefined
)
diffuse
=
originalMaterial
.
uniforms
.
diffuse
.
value
;
if
(
emissive
===
undefined
&&
originalMaterial
.
uniforms
.
emissive
!==
undefined
)
emissive
=
originalMaterial
.
uniforms
.
emissive
.
value
;
if
(
specular
===
undefined
&&
originalMaterial
.
uniforms
.
specular
!==
undefined
)
specular
=
originalMaterial
.
uniforms
.
specular
.
value
;
if
(
shininess
===
undefined
&&
originalMaterial
.
uniforms
.
shininess
!==
undefined
)
shininess
=
originalMaterial
.
uniforms
.
shininess
.
value
;
}
if
(
diffuse
!==
undefined
)
material
.
uniforms
.
diffuse
.
value
.
copy
(
diffuse
);
if
(
emissive
!==
undefined
)
material
.
uniforms
.
emissive
.
value
.
copy
(
emissive
);
if
(
specular
!==
undefined
)
material
.
uniforms
.
specular
.
value
.
copy
(
specular
);
if
(
shininess
!==
undefined
)
material
.
uniforms
.
shininess
.
value
=
shininess
;
if
(
map
!==
undefined
)
{
material
.
map
=
map
;
material
.
uniforms
.
map
.
value
=
map
;
}
if
(
originalMaterial
.
skinning
!==
undefined
)
material
.
skinning
=
originalMaterial
.
skinning
;
if
(
originalMaterial
.
morphTargets
!==
undefined
)
material
.
morphTargets
=
originalMaterial
.
morphTargets
;
if
(
originalMaterial
.
visible
===
true
)
{
material
.
visible
=
!
originalMaterial
.
transparent
;
}
else
{
material
.
visible
=
false
;
}
};
var
getForwardRenderingMaterial
=
function
(
originalMaterial
)
{
if
(
originalMaterial
.
transparent
===
true
&&
originalMaterial
.
visible
===
true
)
{
return
originalMaterial
}
else
{
return
_invisibleMaterial
;
}
};
var
initDeferredLight
=
function
(
light
)
{
var
deferredLight
;
if
(
light
instanceof
THREE
.
PointLight
)
{
deferredLight
=
createDeferredPointLight
(
light
);
}
else
if
(
light
instanceof
THREE
.
SpotLight
)
{
deferredLight
=
createDeferredSpotLight
(
light
);
}
else
if
(
light
instanceof
THREE
.
DirectionalLight
)
{
deferredLight
=
createDeferredDirectionalLight
(
light
);
}
light
.
userData
.
deferredLight
=
deferredLight
;
};
var
updateDeferredLight
=
function
(
light
,
camera
)
{
var
originalLight
=
light
.
userData
.
originalLight
;
if
(
originalLight
instanceof
THREE
.
PointLight
)
{
updateDeferredPointLight
(
light
,
camera
);
}
else
if
(
originalLight
instanceof
THREE
.
SpotLight
)
{
updateDeferredSpotLight
(
light
,
camera
);
}
else
if
(
originalLight
instanceof
THREE
.
DirectionalLight
)
{
updateDeferredDirectionalLight
(
light
,
camera
);
}
};
var
createDeferredEmissiveLight
=
function
()
{
var
shader
=
THREE
.
ShaderDeferred
[
'
emissiveLight
'
];
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
vertexShader
:
shader
.
vertexShader
,
fragmentShader
:
shader
.
fragmentShader
,
blending
:
THREE
.
NoBlending
,
depthWrite
:
false
}
);
material
.
uniforms
.
samplerColor
.
value
=
_compColor
.
renderTarget2
.
texture
;
var
geometry
=
new
THREE
.
PlaneBufferGeometry
(
2
,
2
);
var
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
return
mesh
;
};
var
updateDeferredEmissiveLight
=
function
(
light
,
camera
)
{
var
uniforms
=
light
.
material
.
uniforms
;
uniforms
.
viewWidth
.
value
=
_width
;
uniforms
.
viewHeight
.
value
=
_height
;
};
var
createDeferredPointLight
=
function
(
light
)
{
var
shader
=
THREE
.
ShaderDeferred
[
'
pointLight
'
];
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
vertexShader
:
shader
.
vertexShader
,
fragmentShader
:
shader
.
fragmentShader
,
transparent
:
true
,
side
:
THREE
.
BackSide
,
blending
:
THREE
.
AdditiveBlending
,
depthWrite
:
false
,
depthFunc
:
THREE
.
GreaterEqualDepth
}
);
material
.
uniforms
.
samplerNormalDepth
.
value
=
_compNormalDepth
.
renderTarget2
.
texture
;
material
.
uniforms
.
samplerColor
.
value
=
_compColor
.
renderTarget2
.
texture
;
var
geometry
=
new
THREE
.
SphereGeometry
(
1
,
16
,
8
);
var
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
userData
.
originalLight
=
light
;
return
mesh
;
};
var
updateDeferredPointLight
=
function
(
light
,
camera
)
{
var
originalLight
=
light
.
userData
.
originalLight
;
var
distance
=
originalLight
.
distance
;
var
uniforms
=
light
.
material
.
uniforms
;
uniforms
.
matProjInverse
.
value
.
getInverse
(
camera
.
projectionMatrix
);
uniforms
.
viewWidth
.
value
=
_width
;
uniforms
.
viewHeight
.
value
=
_height
;
uniforms
.
lightColor
.
value
.
copy
(
originalLight
.
color
);
if
(
distance
>
0
)
{
light
.
scale
.
set
(
1
,
1
,
1
).
multiplyScalar
(
distance
);
uniforms
.
lightRadius
.
value
=
distance
;
uniforms
.
lightIntensity
.
value
=
originalLight
.
intensity
;
uniforms
.
lightPositionVS
.
value
.
setFromMatrixPosition
(
originalLight
.
matrixWorld
).
applyMatrix4
(
camera
.
matrixWorldInverse
);
light
.
position
.
setFromMatrixPosition
(
originalLight
.
matrixWorld
);
}
else
{
uniforms
.
lightRadius
.
value
=
Infinity
;
}
};
var
createDeferredSpotLight
=
function
(
light
)
{
var
shader
=
THREE
.
ShaderDeferred
[
'
spotLight
'
];
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
vertexShader
:
shader
.
vertexShader
,
fragmentShader
:
shader
.
fragmentShader
,
transparent
:
true
,
blending
:
THREE
.
AdditiveBlending
,
depthWrite
:
false
,
depthTest
:
false
}
);
material
.
uniforms
.
samplerNormalDepth
.
value
=
_compNormalDepth
.
renderTarget2
.
texture
;
material
.
uniforms
.
samplerColor
.
value
=
_compColor
.
renderTarget2
.
texture
;
var
geometry
=
new
THREE
.
PlaneBufferGeometry
(
2
,
2
);
var
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
userData
.
originalLight
=
light
;
return
mesh
;
};
var
updateDeferredSpotLight
=
function
(
light
,
camera
)
{
var
originalLight
=
light
.
userData
.
originalLight
;
var
uniforms
=
light
.
material
.
uniforms
;
uniforms
.
matProjInverse
.
value
.
getInverse
(
camera
.
projectionMatrix
);
uniforms
.
viewWidth
.
value
=
_width
;
uniforms
.
viewHeight
.
value
=
_height
;
uniforms
.
lightAngle
.
value
=
originalLight
.
angle
;
uniforms
.
lightColor
.
value
.
copy
(
originalLight
.
color
);
uniforms
.
lightIntensity
.
value
=
originalLight
.
intensity
;
uniforms
.
lightPositionVS
.
value
.
setFromMatrixPosition
(
originalLight
.
matrixWorld
).
applyMatrix4
(
camera
.
matrixWorldInverse
);
var
vec
=
uniforms
.
lightDirectionVS
.
value
;
var
vec2
=
_tmpVector3
;
vec
.
setFromMatrixPosition
(
originalLight
.
matrixWorld
);
vec2
.
setFromMatrixPosition
(
originalLight
.
target
.
matrixWorld
);
vec
.
sub
(
vec2
).
normalize
().
transformDirection
(
camera
.
matrixWorldInverse
);
};
var
createDeferredDirectionalLight
=
function
(
light
)
{
var
shader
=
THREE
.
ShaderDeferred
[
'
directionalLight
'
];
var
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
vertexShader
:
shader
.
vertexShader
,
fragmentShader
:
shader
.
fragmentShader
,
transparent
:
true
,
blending
:
THREE
.
AdditiveBlending
,
depthWrite
:
false
,
depthTest
:
false
}
);
material
.
uniforms
.
samplerNormalDepth
.
value
=
_compNormalDepth
.
renderTarget2
.
texture
;
material
.
uniforms
.
samplerColor
.
value
=
_compColor
.
renderTarget2
.
texture
;
var
geometry
=
new
THREE
.
PlaneBufferGeometry
(
2
,
2
);
var
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
userData
.
originalLight
=
light
;
return
mesh
;
};
var
updateDeferredDirectionalLight
=
function
(
light
,
camera
)
{
var
originalLight
=
light
.
userData
.
originalLight
;
var
uniforms
=
light
.
material
.
uniforms
;
uniforms
.
matProjInverse
.
value
.
getInverse
(
camera
.
projectionMatrix
);
uniforms
.
viewWidth
.
value
=
_width
;
uniforms
.
viewHeight
.
value
=
_height
;
uniforms
.
lightColor
.
value
.
copy
(
originalLight
.
color
);
uniforms
.
lightIntensity
.
value
=
originalLight
.
intensity
;
var
vec
=
uniforms
.
lightDirectionVS
.
value
;
var
vec2
=
_tmpVector3
;
vec
.
setFromMatrixPosition
(
originalLight
.
matrixWorld
);
vec2
.
setFromMatrixPosition
(
originalLight
.
target
.
matrixWorld
);
vec
.
sub
(
vec2
).
normalize
().
transformDirection
(
camera
.
matrixWorldInverse
);
};
var
setMaterialNormalDepth
=
function
(
object
)
{
if
(
object
.
material
===
undefined
)
return
;
if
(
object
.
userData
.
normalDepthMaterial
!==
undefined
)
{
object
.
material
=
object
.
userData
.
normalDepthMaterial
;
if
(
object
.
userData
.
originalMaterial
instanceof
THREE
.
MultiMaterial
)
{
for
(
var
i
=
0
,
il
=
object
.
userData
.
originalMaterial
.
materials
.
length
;
i
<
il
;
i
++
)
{
updateDeferredNormalDepthMaterial
(
object
.
material
.
materials
[
i
],
object
.
userData
.
originalMaterial
.
materials
[
i
]
);
}
}
else
{
updateDeferredNormalDepthMaterial
(
object
.
material
,
object
.
userData
.
originalMaterial
);
}
}
};
var
setMaterialColor
=
function
(
object
)
{
if
(
object
.
material
===
undefined
)
return
;
if
(
object
.
userData
.
colorMaterial
!==
undefined
)
{
object
.
material
=
object
.
userData
.
colorMaterial
;
if
(
object
.
userData
.
originalMaterial
instanceof
THREE
.
MultiMaterial
)
{
for
(
var
i
=
0
,
il
=
object
.
userData
.
originalMaterial
.
materials
.
length
;
i
<
il
;
i
++
)
{
updateDeferredColorMaterial
(
object
.
material
.
materials
[
i
],
object
.
userData
.
originalMaterial
.
materials
[
i
]
);
}
}
else
{
updateDeferredColorMaterial
(
object
.
material
,
object
.
userData
.
originalMaterial
);
}
}
};
var
setMaterialForwardRendering
=
function
(
object
)
{
if
(
object
.
material
===
undefined
)
return
;
if
(
object
.
userData
.
originalMaterial
instanceof
THREE
.
MultiMaterial
)
{
object
.
material
=
object
.
userData
.
forwardMaterial
;
for
(
var
i
=
0
,
il
=
object
.
userData
.
originalMaterial
.
materials
.
length
;
i
<
il
;
i
++
)
{
object
.
material
.
materials
[
i
]
=
getForwardRenderingMaterial
(
object
.
userData
.
originalMaterial
.
materials
[
i
]
);
}
}
else
{
object
.
material
=
getForwardRenderingMaterial
(
object
.
userData
.
originalMaterial
);
}
};
var
saveOriginalMaterialAndCheckTransparency
=
function
(
object
)
{
if
(
object
.
material
!==
undefined
)
{
object
.
userData
.
originalMaterial
=
object
.
material
;
if
(
object
.
material
instanceof
THREE
.
MultiMaterial
)
{
for
(
var
i
=
0
,
il
=
object
.
material
.
materials
.
length
;
i
<
il
;
i
++
)
{
if
(
object
.
material
.
materials
[
i
].
transparent
===
true
)
_hasTransparentObject
=
true
;
}
}
else
{
if
(
object
.
material
.
transparent
===
true
)
_hasTransparentObject
=
true
;
}
}
};
var
restoreOriginalMaterial
=
function
(
object
)
{
if
(
object
.
userData
.
originalMaterial
!==
undefined
)
object
.
material
=
object
.
userData
.
originalMaterial
;
};
var
enableCompositePasses
=
function
()
{
if
(
_hasTransparentObject
)
{
if
(
_antialias
)
{
_passFinal
.
renderToScreen
=
false
;
_passForward
.
renderToScreen
=
false
;
_passForward
.
enabled
=
true
;
_passCopy
.
renderToScreen
=
false
;
_passCopy
.
enabled
=
false
;
_passFXAA
.
renderToScreen
=
true
;
_passFXAA
.
enabled
=
true
;
}
else
{
_passFinal
.
renderToScreen
=
false
;
_passForward
.
renderToScreen
=
false
;
_passForward
.
enabled
=
true
;
_passCopy
.
renderToScreen
=
true
;
_passCopy
.
enabled
=
true
;
_passFXAA
.
renderToScreen
=
false
;
_passFXAA
.
enabled
=
false
;
}
}
else
{
if
(
_antialias
)
{
_passFinal
.
renderToScreen
=
false
;
_passForward
.
renderToScreen
=
false
;
_passForward
.
enabled
=
false
;
_passCopy
.
renderToScreen
=
false
;
_passCopy
.
enabled
=
false
;
_passFXAA
.
renderToScreen
=
true
;
_passFXAA
.
enabled
=
true
;
}
else
{
_passFinal
.
renderToScreen
=
true
;
_passForward
.
renderToScreen
=
false
;
_passForward
.
enabled
=
false
;
_passCopy
.
renderToScreen
=
false
;
_passCopy
.
enabled
=
false
;
_passFXAA
.
renderToScreen
=
false
;
_passFXAA
.
enabled
=
false
;
}
}
};
var
addDeferredLightsToLightScene
=
function
(
object
)
{
var
light
=
object
.
userData
.
deferredLight
;
if
(
light
!==
undefined
)
{
var
originalLight
=
light
.
userData
.
originalLight
;
var
scene
;
if
(
originalLight
instanceof
THREE
.
PointLight
)
{
scene
=
_lightScene
;
}
else
{
scene
=
_lightFullscreenScene
;
}
var
lights
=
scene
.
userData
.
lights
;
if
(
lights
[
light
.
uuid
]
===
undefined
)
{
scene
.
add
(
light
);
lights
[
light
.
uuid
]
=
{
light
:
light
,
found
:
true
};
}
lights
[
light
.
uuid
].
found
=
true
;
}
};
var
updateDeferredLightsInLightScene
=
function
(
scene
,
camera
)
{
var
lights
=
scene
.
userData
.
lights
;
var
keys
=
Object
.
keys
(
lights
);
for
(
var
i
=
0
,
il
=
keys
.
length
;
i
<
il
;
i
++
)
{
var
key
=
keys
[
i
];
if
(
lights
[
key
].
found
===
false
)
{
scene
.
remove
(
lights
[
key
].
light
);
delete
lights
[
key
];
}
else
{
updateDeferredLight
(
lights
[
key
].
light
,
camera
);
lights
[
key
].
found
=
false
;
}
}
};
/*
* 1) g-buffer normal + depth pass
*
* RGB: normal
* A: depth
*/
var
renderNormalDepth
=
function
(
scene
,
camera
)
{
scene
.
traverse
(
setMaterialNormalDepth
);
_passNormalDepth
.
scene
=
scene
;
_passNormalDepth
.
camera
=
camera
;
_this
.
renderer
.
autoClearDepth
=
true
;
_this
.
renderer
.
autoClearStencil
=
true
;
_gl
.
enable
(
_gl
.
STENCIL_TEST
);
_gl
.
stencilFunc
(
_gl
.
ALWAYS
,
1
,
0xffffffff
);
_gl
.
stencilOp
(
_gl
.
REPLACE
,
_gl
.
REPLACE
,
_gl
.
REPLACE
);
_compNormalDepth
.
render
();
};
/*
* 2) g-buffer color pass
*
* R: diffuse
* G: emissive
* B: specular
* A: shininess
*/
var
renderColor
=
function
(
scene
,
camera
)
{
scene
.
traverse
(
setMaterialColor
);
_passColor
.
scene
=
scene
;
_passColor
.
camera
=
camera
;
_this
.
renderer
.
autoClearDepth
=
false
;
_this
.
renderer
.
autoClearStencil
=
false
;
_gl
.
stencilFunc
(
_gl
.
EQUAL
,
1
,
0xffffffff
);
_gl
.
stencilOp
(
_gl
.
KEEP
,
_gl
.
KEEP
,
_gl
.
KEEP
);
_compColor
.
render
();
};
/*
* 3) light pass
*
* optimization:
* Here renders PointLight only back face with stencil test.
*/
var
renderLight
=
function
(
scene
,
camera
)
{
updateDeferredEmissiveLight
(
_lightFullscreenScene
.
userData
.
emissiveLight
,
camera
);
scene
.
traverse
(
addDeferredLightsToLightScene
);
updateDeferredLightsInLightScene
(
_lightScene
,
camera
);
updateDeferredLightsInLightScene
(
_lightFullscreenScene
,
camera
);
_passLight
.
scene
=
_lightScene
;
_passLight
.
camera
=
camera
;
_passLightFullscreen
.
scene
=
_lightFullscreenScene
;
_this
.
renderer
.
autoClearDepth
=
false
;
_this
.
renderer
.
autoClearStencil
=
false
;
_compLight
.
render
();
_gl
.
disable
(
_gl
.
STENCIL_TEST
);
};
/*
* 4) composite pass
*
* transparency handling:
* If there's any transparent objects, here renders them on the deferred rendering result
* with forward rendering. This may be the easist way but heavy.
* We should consider any better ways someday.
*
* antialias handling:
* Here uses postprocessing FXAA for antialias.
*/
var
renderComposite
=
function
(
scene
,
camera
)
{
if
(
_hasTransparentObject
)
{
scene
.
traverse
(
setMaterialForwardRendering
);
_passForward
.
scene
=
scene
;
_passForward
.
camera
=
camera
;
}
enableCompositePasses
();
_this
.
renderer
.
autoClearDepth
=
false
;
_this
.
renderer
.
autoClearStencil
=
false
;
_compFinal
.
render
();
};
// external APIs
this
.
setSize
=
function
(
width
,
height
)
{
_width
=
width
;
_height
=
height
;
this
.
renderer
.
setSize
(
_width
,
_height
);
_compNormalDepth
.
setSize
(
_width
,
_height
);
_compColor
.
setSize
(
_width
,
_height
);
_compLight
.
setSize
(
_width
,
_height
);
_compFinal
.
setSize
(
_width
,
_height
);
_compNormalDepth
.
renderTarget2
.
depthTexture
.
image
.
width
=
_width
;
_compNormalDepth
.
renderTarget2
.
depthTexture
.
image
.
height
=
_height
;
_compNormalDepth
.
renderTarget2
.
depthTexture
.
needsUpdate
=
true
;
_passFXAA
.
uniforms
.
resolution
.
value
.
set
(
1
/
_width
,
1
/
_height
);
};
this
.
setAntialias
=
function
(
enabled
)
{
_antialias
=
enabled
;
};
this
.
render
=
function
(
scene
,
camera
)
{
// for debug to compare with normal forward rendering
if
(
this
.
forwardRendering
)
{
this
.
renderer
.
render
(
scene
,
camera
);
return
;
}
var
tmpSceneAutoUpdate
=
scene
.
autoUpdate
;
var
tmpAutoClearColor
=
this
.
renderer
.
autoClearColor
;
var
tmpAutoClearDepth
=
this
.
renderer
.
autoClearDepth
;
var
tmpAutoClearStencil
=
this
.
renderer
.
autoClearStencil
;
initLightScene
(
scene
);
scene
.
autoUpdate
=
false
;
scene
.
updateMatrixWorld
();
_hasTransparentObject
=
false
;
scene
.
traverse
(
initDeferredProperties
);
scene
.
traverse
(
saveOriginalMaterialAndCheckTransparency
);
renderNormalDepth
(
scene
,
camera
);
renderColor
(
scene
,
camera
);
renderLight
(
scene
,
camera
);
renderComposite
(
scene
,
camera
);
scene
.
traverse
(
restoreOriginalMaterial
);
scene
.
autoUpdate
=
tmpSceneAutoUpdate
;
this
.
renderer
.
autoClearColor
=
tmpAutoClearColor
;
this
.
renderer
.
autoClearDepth
=
tmpAutoClearDepth
;
this
.
renderer
.
autoClearStencil
=
tmpAutoClearStencil
;
};
// initialize
init
(
parameters
);
};
THREE
.
DeferredShaderChunk
=
{
packVector3
:
[
"
float vec3_to_float( vec3 data ) {
"
,
"
const float unit = 255.0/256.0;
"
,
"
highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;
"
,
"
return compressed;
"
,
"
}
"
].
join
(
"
\n
"
),
unpackFloat
:
[
"
vec3 float_to_vec3( float data ) {
"
,
"
const float unit = 255.0;
"
,
"
vec3 uncompressed;
"
,
"
uncompressed.x = fract( data );
"
,
"
float zInt = floor( data / unit );
"
,
"
uncompressed.z = fract( zInt / unit );
"
,
"
uncompressed.y = fract( floor( data - ( zInt * unit ) ) / unit );
"
,
"
return uncompressed;
"
,
"
}
"
].
join
(
"
\n
"
),
computeTextureCoord
:
[
"
vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );
"
].
join
(
"
\n
"
),
packNormalDepth
:
[
"
vec4 packedNormalDepth;
"
,
"
packedNormalDepth.xyz = normal * 0.5 + 0.5;
"
,
"
packedNormalDepth.w = position.z / position.w;
"
,
].
join
(
"
\n
"
),
unpackNormalDepth
:
[
"
vec4 normalDepthMap = texture2D( samplerNormalDepth, texCoord );
"
,
"
float depth = normalDepthMap.w;
"
,
"
if ( depth == 0.0 ) discard;
"
,
"
vec3 normal = normalDepthMap.xyz * 2.0 - 1.0;
"
].
join
(
"
\n
"
),
packColor
:
[
"
vec4 packedColor;
"
,
"
packedColor.x = vec3_to_float( diffuseColor );
"
,
"
packedColor.y = vec3_to_float( emissiveColor );
"
,
"
packedColor.z = vec3_to_float( specularColor );
"
,
"
packedColor.w = shininess;
"
].
join
(
"
\n
"
),
unpackColor
:
[
"
vec4 colorMap = texture2D( samplerColor, texCoord );
"
,
"
vec3 diffuseColor = float_to_vec3( colorMap.x );
"
,
"
vec3 emissiveColor = float_to_vec3( colorMap.y );
"
,
"
vec3 specularColor = float_to_vec3( colorMap.z );
"
,
"
float shininess = colorMap.w;
"
,
].
join
(
"
\n
"
),
computeVertexPositionVS
:
[
"
vec2 xy = texCoord * 2.0 - 1.0;
"
,
"
vec4 vertexPositionProjected = vec4( xy, depth, 1.0 );
"
,
"
vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;
"
,
"
vertexPositionVS.xyz /= vertexPositionVS.w;
"
,
"
vertexPositionVS.w = 1.0;
"
].
join
(
"
\n
"
),
computeSpecular
:
[
"
vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );
"
,
"
float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );
"
,
"
float specularNormalization = ( shininess + 2.0001 ) / 8.0;
"
,
"
vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, halfVector ), 5.0 );
"
,
"
vec3 specular = schlick * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuseColor * max( dot( normal, lightVector ), 0.0 ) * specularNormalization;
"
].
join
(
"
\n
"
),
combine
:
[
"
gl_FragColor = vec4( lightIntensity * lightColor * ( diffuseColor * max( dot( normal, lightVector ), 0.0 ) + specular ), attenuation );
"
].
join
(
"
\n
"
)
};
THREE
.
ShaderDeferred
=
{
normalDepth
:
{
uniforms
:
{},
vertexShader
:
[
"
varying vec3 vNormal;
"
,
"
varying vec4 vPosition;
"
,
THREE
.
ShaderChunk
[
"
morphtarget_pars_vertex
"
],
THREE
.
ShaderChunk
[
"
skinning_pars_vertex
"
],
"
void main() {
"
,
THREE
.
ShaderChunk
[
"
begin_vertex
"
],
THREE
.
ShaderChunk
[
"
beginnormal_vertex
"
],
THREE
.
ShaderChunk
[
"
skinbase_vertex
"
],
THREE
.
ShaderChunk
[
"
skinnormal_vertex
"
],
THREE
.
ShaderChunk
[
"
defaultnormal_vertex
"
],
THREE
.
ShaderChunk
[
"
morphtarget_vertex
"
],
THREE
.
ShaderChunk
[
"
skinning_vertex
"
],
THREE
.
ShaderChunk
[
"
project_vertex
"
],
"
vNormal = normalize( normalMatrix * objectNormal );
"
,
"
vPosition = gl_Position;
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
varying vec3 vNormal;
"
,
"
varying vec4 vPosition;
"
,
"
void main() {
"
,
"
vec3 normal = vNormal;
"
,
"
vec4 position = vPosition;
"
,
THREE
.
DeferredShaderChunk
[
"
packNormalDepth
"
],
"
gl_FragColor = packedNormalDepth;
"
,
"
}
"
].
join
(
"
\n
"
)
},
color
:
{
uniforms
:
{
map
:
{
type
:
"
t
"
,
value
:
null
},
offsetRepeat
:
{
type
:
"
v4
"
,
value
:
new
THREE
.
Vector4
(
0
,
0
,
1
,
1
)
},
diffuse
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
},
emissive
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
},
specular
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
},
shininess
:
{
type
:
"
f
"
,
value
:
30.0
}
},
vertexShader
:
[
THREE
.
ShaderChunk
[
"
uv_pars_vertex
"
],
THREE
.
ShaderChunk
[
"
morphtarget_pars_vertex
"
],
THREE
.
ShaderChunk
[
"
skinning_pars_vertex
"
],
"
void main() {
"
,
THREE
.
ShaderChunk
[
"
uv_vertex
"
],
THREE
.
ShaderChunk
[
"
begin_vertex
"
],
THREE
.
ShaderChunk
[
"
beginnormal_vertex
"
],
THREE
.
ShaderChunk
[
"
skinbase_vertex
"
],
THREE
.
ShaderChunk
[
"
skinnormal_vertex
"
],
THREE
.
ShaderChunk
[
"
defaultnormal_vertex
"
],
THREE
.
ShaderChunk
[
"
morphtarget_vertex
"
],
THREE
.
ShaderChunk
[
"
skinning_vertex
"
],
THREE
.
ShaderChunk
[
"
project_vertex
"
],
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
uniform vec3 diffuse;
"
,
"
uniform vec3 emissive;
"
,
"
uniform vec3 specular;
"
,
"
uniform float shininess;
"
,
THREE
.
ShaderChunk
[
"
uv_pars_fragment
"
],
THREE
.
ShaderChunk
[
"
map_pars_fragment
"
],
THREE
.
DeferredShaderChunk
[
"
packVector3
"
],
"
void main() {
"
,
"
vec3 diffuseColor = diffuse;
"
,
"
vec3 emissiveColor = emissive;
"
,
"
vec3 specularColor = specular;
"
,
THREE
.
ShaderChunk
[
"
map_fragment
"
],
THREE
.
DeferredShaderChunk
[
"
packColor
"
],
"
gl_FragColor = packedColor;
"
,
"
}
"
].
join
(
"
\n
"
)
},
emissiveLight
:
{
uniforms
:
{
samplerColor
:
{
type
:
"
t
"
,
value
:
null
},
viewWidth
:
{
type
:
"
f
"
,
value
:
800
},
viewHeight
:
{
type
:
"
f
"
,
value
:
600
}
},
vertexShader
:
[
"
void main() {
"
,
"
gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );
"
,
"
}
"
].
join
(
'
\n
'
),
fragmentShader
:
[
"
uniform sampler2D samplerColor;
"
,
"
uniform float viewHeight;
"
,
"
uniform float viewWidth;
"
,
THREE
.
DeferredShaderChunk
[
"
unpackFloat
"
],
"
void main() {
"
,
THREE
.
DeferredShaderChunk
[
"
computeTextureCoord
"
],
THREE
.
DeferredShaderChunk
[
"
unpackColor
"
],
"
gl_FragColor = vec4( emissiveColor, 1.0 );
"
,
"
}
"
].
join
(
'
\n
'
)
},
pointLight
:
{
uniforms
:
{
samplerNormalDepth
:
{
type
:
"
t
"
,
value
:
null
},
samplerColor
:
{
type
:
"
t
"
,
value
:
null
},
matProjInverse
:
{
type
:
"
m4
"
,
value
:
new
THREE
.
Matrix4
()
},
viewWidth
:
{
type
:
"
f
"
,
value
:
800
},
viewHeight
:
{
type
:
"
f
"
,
value
:
600
},
lightColor
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
},
lightPositionVS
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0
,
1
,
0
)
},
lightIntensity
:
{
type
:
"
f
"
,
value
:
1.0
},
lightRadius
:
{
type
:
"
f
"
,
value
:
1.0
}
},
vertexShader
:
[
"
void main() {
"
,
"
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
uniform sampler2D samplerNormalDepth;
"
,
"
uniform sampler2D samplerColor;
"
,
"
uniform float viewHeight;
"
,
"
uniform float viewWidth;
"
,
"
uniform vec3 lightColor;
"
,
"
uniform vec3 lightPositionVS;
"
,
"
uniform float lightIntensity;
"
,
"
uniform float lightRadius;
"
,
"
uniform mat4 matProjInverse;
"
,
THREE
.
DeferredShaderChunk
[
"
unpackFloat
"
],
"
void main() {
"
,
THREE
.
DeferredShaderChunk
[
"
computeTextureCoord
"
],
THREE
.
DeferredShaderChunk
[
"
unpackNormalDepth
"
],
THREE
.
DeferredShaderChunk
[
"
computeVertexPositionVS
"
],
"
vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;
"
,
"
float distance = length( lightVector );
"
,
"
if ( distance > lightRadius ) discard;
"
,
"
lightVector = normalize( lightVector );
"
,
THREE
.
DeferredShaderChunk
[
"
unpackColor
"
],
THREE
.
DeferredShaderChunk
[
"
computeSpecular
"
],
"
//float cutoff = 0.3;
"
,
"
//float denom = distance / lightRadius + 1.0;
"
,
"
//float attenuation = 1.0 / ( denom * denom );
"
,
"
//attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );
"
,
"
//attenuation = max( attenuation, 0.0 );
"
,
"
//attenuation *= attenuation;
"
,
"
//diffuseColor *= saturate( -distance / lightRadius + 1.0 );
"
,
"
//float attenuation = 1.0;
"
,
"
float attenuation = saturate( -distance / lightRadius + 1.0 );
"
,
THREE
.
DeferredShaderChunk
[
"
combine
"
],
"
}
"
].
join
(
"
\n
"
)
},
spotLight
:
{
uniforms
:
{
samplerNormalDepth
:
{
type
:
"
t
"
,
value
:
null
},
samplerColor
:
{
type
:
"
t
"
,
value
:
null
},
matProjInverse
:
{
type
:
"
m4
"
,
value
:
new
THREE
.
Matrix4
()
},
viewWidth
:
{
type
:
"
f
"
,
value
:
800
},
viewHeight
:
{
type
:
"
f
"
,
value
:
600
},
lightColor
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
},
lightDirectionVS
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0
,
1
,
0
)
},
lightPositionVS
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0
,
1
,
0
)
},
lightAngle
:
{
type
:
"
f
"
,
value
:
1.0
},
lightIntensity
:
{
type
:
"
f
"
,
value
:
1.0
}
},
vertexShader
:
[
"
void main() {
"
,
"
gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
uniform sampler2D samplerNormalDepth;
"
,
"
uniform sampler2D samplerColor;
"
,
"
uniform float viewHeight;
"
,
"
uniform float viewWidth;
"
,
"
uniform vec3 lightColor;
"
,
"
uniform vec3 lightPositionVS;
"
,
"
uniform vec3 lightDirectionVS;
"
,
"
uniform float lightAngle;
"
,
"
uniform float lightIntensity;
"
,
"
uniform mat4 matProjInverse;
"
,
THREE
.
DeferredShaderChunk
[
"
unpackFloat
"
],
"
void main() {
"
,
THREE
.
DeferredShaderChunk
[
"
computeTextureCoord
"
],
THREE
.
DeferredShaderChunk
[
"
unpackNormalDepth
"
],
THREE
.
DeferredShaderChunk
[
"
computeVertexPositionVS
"
],
THREE
.
DeferredShaderChunk
[
"
unpackColor
"
],
"
vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );
"
,
"
float rho = dot( lightDirectionVS, lightVector );
"
,
"
float rhoMax = cos( lightAngle * 0.5 );
"
,
"
if ( rho <= rhoMax ) discard;
"
,
"
float theta = rhoMax + 0.0001;
"
,
"
float phi = rhoMax + 0.05;
"
,
"
float falloff = 4.0;
"
,
"
float spot = 0.0;
"
,
"
if ( rho >= phi ) {
"
,
"
spot = 1.0;
"
,
"
} else if ( rho <= theta ) {
"
,
"
spot = 0.0;
"
,
"
} else {
"
,
"
spot = pow( ( rho - theta ) / ( phi - theta ), falloff );
"
,
"
}
"
,
"
diffuseColor *= spot;
"
,
THREE
.
DeferredShaderChunk
[
"
computeSpecular
"
],
"
const float attenuation = 1.0;
"
,
THREE
.
DeferredShaderChunk
[
"
combine
"
],
"
}
"
].
join
(
"
\n
"
)
},
directionalLight
:
{
uniforms
:
{
samplerNormalDepth
:
{
type
:
"
t
"
,
value
:
null
},
samplerColor
:
{
type
:
"
t
"
,
value
:
null
},
matProjInverse
:
{
type
:
"
m4
"
,
value
:
new
THREE
.
Matrix4
()
},
viewWidth
:
{
type
:
"
f
"
,
value
:
800
},
viewHeight
:
{
type
:
"
f
"
,
value
:
600
},
lightColor
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
},
lightDirectionVS
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0
,
1
,
0
)
},
lightIntensity
:
{
type
:
"
f
"
,
value
:
1.0
}
},
vertexShader
:
[
"
void main() {
"
,
"
gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );
"
,
"
}
"
].
join
(
'
\n
'
),
fragmentShader
:
[
"
uniform sampler2D samplerNormalDepth;
"
,
"
uniform sampler2D samplerColor;
"
,
"
uniform float viewHeight;
"
,
"
uniform float viewWidth;
"
,
"
uniform vec3 lightColor;
"
,
"
uniform vec3 lightDirectionVS;
"
,
"
uniform float lightIntensity;
"
,
"
uniform mat4 matProjInverse;
"
,
THREE
.
DeferredShaderChunk
[
"
unpackFloat
"
],
"
void main() {
"
,
THREE
.
DeferredShaderChunk
[
"
computeTextureCoord
"
],
THREE
.
DeferredShaderChunk
[
"
unpackNormalDepth
"
],
THREE
.
DeferredShaderChunk
[
"
computeVertexPositionVS
"
],
THREE
.
DeferredShaderChunk
[
"
unpackColor
"
],
"
vec3 lightVector = normalize( lightDirectionVS );
"
,
THREE
.
DeferredShaderChunk
[
"
computeSpecular
"
],
"
const float attenuation = 1.0;
"
,
THREE
.
DeferredShaderChunk
[
"
combine
"
],
"
}
"
].
join
(
'
\n
'
),
},
composite
:
{
uniforms
:
{
samplerLight
:
{
type
:
"
t
"
,
value
:
null
}
},
vertexShader
:
[
"
varying vec2 texCoord;
"
,
"
void main() {
"
,
"
vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );
"
,
"
texCoord = pos.xy * vec2( 0.5 ) + 0.5;
"
,
"
gl_Position = pos;
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
varying vec2 texCoord;
"
,
"
uniform sampler2D samplerLight;
"
,
"
void main() {
"
,
"
gl_FragColor = texture2D( samplerLight, texCoord );
"
,
"
}
"
].
join
(
"
\n
"
)
}
};
\ No newline at end of file
examples/webgl_deferred_animation.html
0 → 100644
浏览文件 @
c75213d5
<!DOCTYPE HTML>
<html
lang=
"en"
>
<head>
<title>
three.js webgl - deferred rendering [morphing + skinning]
</title>
<meta
charset=
"utf-8"
/>
<meta
name=
"viewport"
content=
"width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
>
<style>
body
{
background-color
:
#000
;
margin
:
0px
;
overflow
:
hidden
;
}
#info
{
position
:
absolute
;
top
:
20px
;
width
:
100%
;
color
:
#ffffff
;
padding
:
5px
;
font-family
:
Monospace
;
font-size
:
13px
;
text-align
:
center
;
}
a
{
color
:
#ff0080
;
text-decoration
:
none
;
}
a
:hover
{
color
:
#0080ff
;
}
#stats
{
position
:
absolute
;
top
:
10px
;
left
:
5px
}
#stats
#fps
{
background
:
transparent
!important
}
#stats
#fps
#fpsText
{
color
:
#aaa
!important
}
#stats
#fps
#fpsGraph
{
display
:
none
}
</style>
</head>
<body>
<div
id=
"container"
></div>
<script
src=
"js/libs/stats.min.js"
></script>
<script
src=
"../build/three.js"
></script>
<script
src=
"js/Detector.js"
></script>
<script
src=
"js/shaders/CopyShader.js"
></script>
<script
src=
"js/shaders/FXAAShader.js"
></script>
<script
src=
"js/postprocessing/EffectComposer.js"
></script>
<script
src=
"js/postprocessing/RenderPass.js"
></script>
<script
src=
"js/postprocessing/ShaderPass.js"
></script>
<script
src=
"js/renderers/WebGLDeferredRenderer.js"
></script>
<script>
var
WIDTH
=
window
.
innerWidth
;
var
HEIGHT
=
window
.
innerHeight
;
var
windowHalfX
=
WIDTH
/
2
;
var
windowHalfY
=
HEIGHT
/
2
;
var
mouseX
=
0
,
mouseY
=
0
;
var
NEAR
=
1.0
,
FAR
=
350.0
;
var
VIEW_ANGLE
=
45
;
var
renderer
,
camera
,
scene
,
stats
,
clock
,
mixer
;
var
numLights
=
40
;
var
lights
=
[];
var
ready
=
false
;
init
();
animate
();
function
init
()
{
renderer
=
new
THREE
.
WebGLDeferredRenderer
();
renderer
.
setSize
(
WIDTH
,
HEIGHT
);
camera
=
new
THREE
.
PerspectiveCamera
(
VIEW_ANGLE
,
WIDTH
/
HEIGHT
,
NEAR
,
FAR
);
camera
.
position
.
z
=
150
;
scene
=
new
THREE
.
Scene
();
stats
=
new
Stats
();
stats
.
domElement
.
style
.
position
=
'
absolute
'
;
stats
.
domElement
.
style
.
top
=
'
8px
'
;
stats
.
domElement
.
style
.
zIndex
=
100
;
var
container
=
document
.
getElementById
(
'
container
'
);
container
.
appendChild
(
renderer
.
domElement
);
container
.
appendChild
(
stats
.
domElement
);
initKnight
();
initRoom
();
initLights
();
document
.
addEventListener
(
'
mousemove
'
,
onDocumentMouseMove
,
false
);
window
.
addEventListener
(
'
resize
'
,
onWindowResize
,
false
);
clock
=
new
THREE
.
Clock
();
}
function
initKnight
()
{
var
loader
=
new
THREE
.
JSONLoader
();
loader
.
load
(
"
models/skinned/knight.js
"
,
function
(
geometry
,
materials
)
{
var
material
=
materials
[
0
];
material
.
emissive
.
set
(
0x101010
);
material
.
skinning
=
true
;
material
.
morphTargets
=
true
;
var
mesh
=
new
THREE
.
SkinnedMesh
(
geometry
,
material
);
mesh
.
position
.
y
=
-
30
;
mesh
.
scale
.
multiplyScalar
(
5
);
mixer
=
new
THREE
.
AnimationMixer
(
mesh
);
for
(
var
i
=
0
;
i
<
mesh
.
geometry
.
animations
.
length
;
i
++
)
{
var
action
=
mixer
.
clipAction
(
mesh
.
geometry
.
animations
[
i
]
);
if
(
i
===
1
)
action
.
timeScale
=
0.25
;
action
.
play
();
}
scene
.
add
(
mesh
);
ready
=
true
;
}
);
}
function
initLights
()
{
var
distance
=
20
;
var
c
=
new
THREE
.
Vector3
();
var
geometry
=
new
THREE
.
SphereGeometry
(
1
,
1
,
1
);
for
(
var
i
=
0
;
i
<
numLights
;
i
++
)
{
var
light
=
new
THREE
.
PointLight
(
0xffffff
,
2.0
,
distance
);
c
.
set
(
Math
.
random
(),
Math
.
random
(),
Math
.
random
()
).
normalize
();
light
.
color
.
setRGB
(
c
.
x
,
c
.
y
,
c
.
z
);
scene
.
add
(
light
);
lights
.
push
(
light
);
var
material
=
new
THREE
.
MeshBasicMaterial
(
{
color
:
light
.
color
}
);
var
emitter
=
new
THREE
.
Mesh
(
geometry
,
material
);
light
.
add
(
emitter
);
}
var
directionalLight
=
new
THREE
.
DirectionalLight
(
0x101010
);
directionalLight
.
position
.
set
(
-
1
,
1
,
1
).
normalize
();
scene
.
add
(
directionalLight
);
var
spotLight
=
new
THREE
.
SpotLight
(
0x404040
);
spotLight
.
position
.
set
(
0
,
50
,
0
);
scene
.
add
(
spotLight
);
}
function
initRoom
()
{
var
size
=
100
;
var
geometry
=
new
THREE
.
PlaneBufferGeometry
(
size
,
size
);
var
material
=
new
THREE
.
MeshPhongMaterial
(
{
color
:
0x222222
,
specular
:
0x222222
,
shininess
:
75
}
);
var
transparentMaterial
=
new
THREE
.
MeshPhongMaterial
(
{
color
:
0x222222
,
emissive
:
0x88888888
,
specular
:
0x222222
,
shininess
:
75
,
opacity
:
0.3
,
transparent
:
true
}
);
var
room
=
new
THREE
.
Object3D
();
room
.
position
.
y
=
size
/
2
-
30
;
// top
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
rotation
.
x
=
Math
.
PI
/
2
;
mesh
.
position
.
y
=
size
/
2
;
room
.
add
(
mesh
);
// bottom
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
rotation
.
x
=
-
Math
.
PI
/
2
;
mesh
.
position
.
y
=
-
size
/
2
;
room
.
add
(
mesh
);
// left
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
position
.
x
=
-
size
/
2
;
mesh
.
rotation
.
y
=
Math
.
PI
/
2
;
room
.
add
(
mesh
);
// right
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
position
.
x
=
size
/
2
;
mesh
.
rotation
.
y
=
-
Math
.
PI
/
2
;
room
.
add
(
mesh
);
// back
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
mesh
.
position
.
z
=
-
size
/
2
;
room
.
add
(
mesh
);
// front, to check if transparency works
mesh
=
new
THREE
.
Mesh
(
geometry
,
transparentMaterial
);
mesh
.
position
.
z
=
size
/
2
;
mesh
.
scale
.
multiplyScalar
(
0.33
);
//room.add( mesh );
// back2, to check if transparency works
mesh
=
new
THREE
.
Mesh
(
geometry
,
transparentMaterial
);
mesh
.
position
.
z
=
-
size
/
4
;
mesh
.
scale
.
multiplyScalar
(
0.75
);
//room.add( mesh );
scene
.
add
(
room
);
}
function
onDocumentMouseMove
(
event
)
{
mouseX
=
(
event
.
clientX
-
windowHalfX
)
/
10.0
;
mouseY
=
(
event
.
clientY
-
windowHalfY
)
/
10.0
;
}
function
onWindowResize
(
event
)
{
WIDTH
=
window
.
innerWidth
;
HEIGHT
=
window
.
innerHeight
;
windowHalfX
=
WIDTH
/
2
;
windowHalfY
=
HEIGHT
/
2
;
renderer
.
setSize
(
WIDTH
,
HEIGHT
);
camera
.
aspect
=
WIDTH
/
HEIGHT
;
camera
.
updateProjectionMatrix
();
}
function
animate
()
{
requestAnimationFrame
(
animate
);
if
(
ready
)
{
update
();
render
();
}
stats
.
update
();
}
function
update
()
{
var
delta
=
clock
.
getDelta
();
var
time
=
Date
.
now
()
*
0.0005
;
mixer
.
update
(
delta
/
2.0
);
for
(
var
i
=
0
,
il
=
lights
.
length
;
i
<
il
;
i
++
)
{
var
light
=
lights
[
i
];
var
x
=
Math
.
sin
(
time
+
i
*
7.0
)
*
45
;
var
y
=
Math
.
cos
(
time
+
i
*
5.0
)
*
45
+
20
;
var
z
=
Math
.
cos
(
time
+
i
*
3.0
)
*
45
;
light
.
position
.
set
(
x
,
y
,
z
);
}
}
function
render
()
{
camera
.
position
.
x
+=
(
-
mouseX
-
camera
.
position
.
x
)
*
.
05
;
camera
.
position
.
y
+=
(
-
mouseY
-
camera
.
position
.
y
)
*
.
05
;
camera
.
lookAt
(
scene
.
position
);
renderer
.
render
(
scene
,
camera
);
}
</script>
</body>
</html>
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录