Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
fktz008
three.js
提交
93cb120e
T
three.js
项目概览
fktz008
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
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,发现更多精彩内容 >>
提交
93cb120e
编写于
4月 12, 2012
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'alteredq/dev' into dev
上级
bc9aac97
b0c25b7b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
254 addition
and
123 deletion
+254
-123
examples/js/ShaderGodRays.js
examples/js/ShaderGodRays.js
+83
-19
examples/webgl_postprocessing_godrays.html
examples/webgl_postprocessing_godrays.html
+171
-104
未找到文件。
examples/js/ShaderGodRays.js
浏览文件 @
93cb120e
...
...
@@ -6,7 +6,7 @@
* Similar implementation to the one used by Crytek for CryEngine 2 [Sousa2008].
* Blurs a mask generated from the depth map along radial lines emanating from the light
* source. The blur repeatedly applies a blur filter of increasing support but constant
* sample count
,
to produce a blur filter with large support.
* sample count to produce a blur filter with large support.
*
* My implementation performs 3 passes, similar to the implementation from Sousa. I found
* just 6 samples per pass produced acceptible results. The blur is applied three times,
...
...
@@ -42,31 +42,42 @@ THREE.ShaderGodRays = {
'
godrays_generate
'
:
{
uniforms
:
{
tInput
:
{
type
:
"
t
"
,
value
:
0
,
texture
:
null
},
fStepSize
:
{
type
:
"
f
"
,
value
:
1.0
},
vSunPositionScreenSpace
:
{
type
:
"
v2
"
,
value
:
new
THREE
.
Vector2
(
0.5
,
0.5
)
}
},
vertexShader
:
[
"
varying vec2 vUv;
"
,
"
void main() {
"
,
"
vUv = vec2( uv.x, 1.0 - uv.y );
"
,
"
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
"
#define TAPS_PER_PASS 6.0
"
,
"
varying vec2 vUv;
"
,
"
uniform sampler2D tInput;
"
,
...
...
@@ -74,15 +85,19 @@ THREE.ShaderGodRays = {
"
uniform vec2 vSunPositionScreenSpace;
"
,
"
uniform float fStepSize;
"
,
// filter step size
"
#define TAPS_PER_PASS 6.0
"
,
"
void main() {
"
,
// delta from current pixel to "sun" position
"
vec2 delta = (vSunPositionScreenSpace - vUv);
"
,
"
float dist = length(delta);
"
,
"
vec2 delta = vSunPositionScreenSpace - vUv;
"
,
"
float dist = length( delta );
"
,
// Step vector (uv space)
"
vec2 stepv = fStepSize*delta/dist;
"
,
"
vec2 stepv = fStepSize * delta / dist;
"
,
// Number of iterations between pixel and sun
"
float iters = dist/fStepSize;
"
,
"
vec2 uv = vUv.xy;
"
,
...
...
@@ -90,16 +105,20 @@ THREE.ShaderGodRays = {
// Unrolling didnt do much on my hardware (ATI Mobility Radeon 3450),
// so i've just left the loop
"
for (float i = 0.0; i < TAPS_PER_PASS; i+=1.0 ) {
"
,
"
for ( float i = 0.0; i < TAPS_PER_PASS; i += 1.0 ) {
"
,
// Accumulate samples, making sure we dont walk past the light source.
// The check for uv.y
<
1 would not be necessary with "border" UV wrap
// The check for uv.y
<
1 would not be necessary with "border" UV wrap
// mode, with a black border colour. I don't think this is currently
// exposed by three.js. As a result there might be artifacts when the
// sun is to the left, right or bottom of screen as these cases are
// not specifically handled.
"
col += (i <= iters && uv.y<1. ? texture2D( tInput, uv ).r : .0) ;
"
,
"
col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );
"
,
"
uv += stepv;
"
,
"
}
"
,
// Should technically be dividing by 'iters', but 'TAPS_PER_PASS' smooths out
...
...
@@ -108,8 +127,10 @@ THREE.ShaderGodRays = {
// TAPS_PER_PASS is greater than the number of samples actually accumulated.
// When the result is inverted (in the shader 'godrays_combine', this produces
// a slight bright spot at the position of the sun, even when it is occluded.
"
gl_FragColor = vec4( col/TAPS_PER_PASS );
"
,
"
gl_FragColor.a = 1.;
"
,
"
gl_FragColor.a = 1.0;
"
,
"
}
"
].
join
(
"
\n
"
)
...
...
@@ -120,35 +141,46 @@ THREE.ShaderGodRays = {
* Additively applies god rays from texture tGodRays to a background (tColors).
* fGodRayIntensity attenuates the god rays.
*/
'
godrays_combine
'
:
{
uniforms
:
{
tColors
:
{
type
:
"
t
"
,
value
:
0
,
texture
:
null
},
tGodRays
:
{
type
:
"
t
"
,
value
:
1
,
texture
:
null
},
fGodRayIntensity
:
{
type
:
"
f
"
,
value
:
0.69
},
vSunPositionScreenSpace
:
{
type
:
"
v2
"
,
value
:
new
THREE
.
Vector2
(
0.5
,
0.5
)
},
}
},
vertexShader
:
[
"
varying vec2 vUv;
"
,
"
void main() {
"
,
"
vUv = vec2( uv.x, 1.0 - uv.y );
"
,
"
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
...
...
@@ -162,41 +194,63 @@ THREE.ShaderGodRays = {
"
uniform float fGodRayIntensity;
"
,
"
void main() {
"
,
// Since THREE.MeshDepthMaterial renders foreground objects white and background
// objects black, the god-rays will be white streaks. Therefore value is inverted
// before being combined with tColors
"
gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity*vec4( 1.-texture2D( tGodRays, vUv ).r );
"
,
"
gl_FragColor.a = 1.;
"
,
"
gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );
"
,
"
gl_FragColor.a = 1.0;
"
,
"
}
"
].
join
(
"
\n
"
)
},
/**
* A dodgy sun/sky shader. Makes a bright spot at the sun location. Would be
* cheaper/faster/simpler to implement this as a simple sun sprite.
*/
'
godrays_fake_sun
'
:
{
uniforms
:
{
vSunPositionScreenSpace
:
{
type
:
"
v2
"
,
value
:
new
THREE
.
Vector2
(
0.5
,
0.5
)
},
fAspect
:
{
type
:
"
f
"
,
value
:
1.0
},
sunColor
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0xffee00
)
},
bgColor
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x000000
)
}
},
vertexShader
:
[
"
varying vec2 vUv;
"
,
"
void main() {
"
,
"
vUv = vec2( uv.x, 1.0 - uv.y );
"
,
"
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
"
,
"
}
"
].
join
(
"
\n
"
),
fragmentShader
:
[
...
...
@@ -206,13 +260,23 @@ THREE.ShaderGodRays = {
"
uniform vec2 vSunPositionScreenSpace;
"
,
"
uniform float fAspect;
"
,
"
uniform vec3 sunColor;
"
,
"
uniform vec3 bgColor;
"
,
"
void main() {
"
,
"
vec2 diff = vUv-vSunPositionScreenSpace;
"
,
"
vec2 diff = vUv - vSunPositionScreenSpace;
"
,
// Correct for aspect ratio
"
diff.x *= fAspect;
"
,
"
float prop = clamp(length(diff)/.5,0.,1.);
"
,
"
prop = .35*pow( 1.0 - prop, 3. ) ;
"
,
"
gl_FragColor = vec4(prop,prop,0.2,1.);
"
,
"
float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );
"
,
"
prop = 0.35 * pow( 1.0 - prop, 3.0 );
"
,
"
gl_FragColor.xyz = mix( sunColor, bgColor, 1.0 - prop );
"
,
"
gl_FragColor.w = 1.0;
"
,
"
}
"
].
join
(
"
\n
"
)
...
...
examples/webgl_postprocessing_godrays.html
浏览文件 @
93cb120e
...
...
@@ -32,9 +32,9 @@
<body>
<script
src=
"../build/Three.js"
></script>
<script
src=
"js/ShaderGodRays.js"
></script>
<script
src=
"js/Detector.js"
></script>
<script
src=
"js/ShaderGodRays.js"
></script>
<script
src=
"js/Stats.js"
></script>
<div
id=
"info"
>
...
...
@@ -47,21 +47,29 @@
if
(
!
Detector
.
webgl
)
Detector
.
addGetWebGLMessage
();
var
container
,
stats
;
var
camera
,
scene
,
renderer
,
parameters
,
material_d
epth
;
var
tree
_mesh
,
sphere_m
esh
;
var
camera
,
scene
,
renderer
,
materialD
epth
;
var
tree
Mesh
,
sphereM
esh
;
var
proj
=
new
THREE
.
Projector
();
var
sunPos
=
new
THREE
.
Vector3
(
0
,
1000
,
-
1000
);
var
projector
=
new
THREE
.
Projector
();
var
sunPosition
=
new
THREE
.
Vector3
(
0
,
1000
,
-
1000
);
var
screenSpacePosition
=
new
THREE
.
Vector3
();
var
mouseX
=
0
,
mouseY
=
0
;
var
windowHalfX
=
window
.
innerWidth
/
2
;
var
windowHalfY
=
window
.
innerHeight
/
2
;
var
height
=
window
.
innerHeight
-
100
;
var
margin
=
100
;
var
height
=
window
.
innerHeight
-
2
*
margin
;
var
postprocessing
=
{
enabled
:
true
};
var
orbitRadius
=
200
;
var
postprocessing
=
{
enabled
:
true
};
var
bgColor
=
0x000511
;
var
sunColor
=
0xffee00
;
init
();
animate
();
...
...
@@ -71,164 +79,194 @@
container
=
document
.
createElement
(
'
div
'
);
document
.
body
.
appendChild
(
container
);
//
scene
=
new
THREE
.
Scene
();
camera
=
new
THREE
.
PerspectiveCamera
(
70
,
window
.
innerWidth
/
height
,
1
,
3000
);
camera
.
position
.
z
=
200
;
scene
.
add
(
camera
);
renderer
=
new
THREE
.
WebGLRenderer
(
{
antialias
:
false
}
);
renderer
.
setSize
(
window
.
innerWidth
,
height
);
container
.
appendChild
(
renderer
.
domElement
);
renderer
.
sortObjects
=
false
;
//
// todo - try with fog
//scene.fog = new THREE.Fog( 0xffaa55, 1000, FAR );
//THREE.ColorUtils.adjustHSV( scene.fog.color, 0.02, -0.15, -0.65 );
material_depth
=
new
THREE
.
MeshDepthMaterial
();
materialDepth
=
new
THREE
.
MeshDepthMaterial
();
var
materialScene
=
new
THREE
.
MeshBasicMaterial
(
{
color
:
0x000000
,
shading
:
THREE
.
FlatShading
}
);
// tree
parameters
=
{
color
:
0x000000
,
shading
:
THREE
.
FlatShading
};
var
zmat
=
new
THREE
.
MeshBasicMaterial
(
parameters
);
var
loader
=
new
THREE
.
JSONLoader
();
// tree mesh
var
jsonLoader
=
new
THREE
.
JSONLoader
();
jsonLoader
.
load
(
"
obj/tree/tree.js
"
,
function
(
geometry
)
{
loader
.
load
(
"
obj/tree/tree.js
"
,
function
(
geometry
)
{
var
m
=
new
THREE
.
Mesh
(
geometry
,
zmat
);
m
.
position
.
set
(
0
,
-
150
,
-
150
);
treeMesh
=
new
THREE
.
Mesh
(
geometry
,
materialScene
);
treeMesh
.
position
.
set
(
0
,
-
150
,
-
150
);
var
sc
=
400
;
m
.
scale
.
set
(
sc
,
sc
,
sc
);
m
.
matrixAutoUpdate
=
false
;
m
.
updateMatrix
();
scene
.
add
(
m
);
tree_mesh
=
m
;
treeMesh
.
scale
.
set
(
sc
,
sc
,
sc
);
treeMesh
.
matrixAutoUpdate
=
false
;
treeMesh
.
updateMatrix
();
scene
.
add
(
treeMesh
);
}
);
// sphere
var
geo
=
new
THREE
.
SphereGeometry
(
1
,
20
,
10
);
mesh
=
new
THREE
.
Mesh
(
geo
,
zmat
);
sphereMesh
=
new
THREE
.
Mesh
(
geo
,
materialScene
);
var
sc
=
20
;
m
esh
.
scale
.
set
(
sc
,
sc
,
sc
);
sphereM
esh
.
scale
.
set
(
sc
,
sc
,
sc
);
mesh
.
matrixAutoUpdate
=
false
;
mesh
.
updateMatrix
();
scene
.
add
(
sphereMesh
);
scene
.
add
(
mesh
);
sphere_mesh
=
mesh
;
scene
.
matrixAutoUpdate
=
false
;
//
initPostprocessing
();
renderer
=
new
THREE
.
WebGLRenderer
(
{
antialias
:
false
}
);
renderer
.
setSize
(
window
.
innerWidth
,
height
);
container
.
appendChild
(
renderer
.
domElement
);
renderer
.
sortObjects
=
false
;
renderer
.
autoClear
=
false
;
renderer
.
setClearColorHex
(
0x000033
,
1
);
renderer
.
setClearColorHex
(
bgColor
,
1
);
renderer
.
domElement
.
style
.
position
=
'
absolute
'
;
renderer
.
domElement
.
style
.
top
=
"
50
px
"
;
renderer
.
domElement
.
style
.
top
=
margin
+
"
px
"
;
renderer
.
domElement
.
style
.
left
=
"
0px
"
;
//
stats
=
new
Stats
();
stats
.
domElement
.
style
.
position
=
'
absolute
'
;
stats
.
domElement
.
style
.
top
=
'
0px
'
;
container
.
appendChild
(
stats
.
domElement
);
stats
.
domElement
.
children
[
0
].
children
[
0
].
style
.
color
=
"
#888
"
;
stats
.
domElement
.
children
[
0
].
style
.
background
=
"
transparent
"
;
stats
.
domElement
.
children
[
0
].
children
[
1
].
style
.
display
=
"
none
"
;
//
document
.
addEventListener
(
'
mousemove
'
,
onDocumentMouseMove
,
false
);
document
.
addEventListener
(
'
touchstart
'
,
onDocumentTouchStart
,
false
);
document
.
addEventListener
(
'
touchmove
'
,
onDocumentTouchMove
,
false
);
//
initPostprocessing
();
}
//
function
onDocumentMouseMove
(
event
)
{
mouseX
=
event
.
clientX
-
windowHalfX
;
mouseY
=
event
.
clientY
-
windowHalfY
;
}
function
onDocumentTouchStart
(
event
)
{
if
(
event
.
touches
.
length
==
1
)
{
if
(
event
.
touches
.
length
==
=
1
)
{
event
.
preventDefault
();
mouseX
=
event
.
touches
[
0
].
pageX
-
windowHalfX
;
mouseY
=
event
.
touches
[
0
].
pageY
-
windowHalfY
;
}
}
function
onDocumentTouchMove
(
event
)
{
if
(
event
.
touches
.
length
==
1
)
{
if
(
event
.
touches
.
length
==
=
1
)
{
event
.
preventDefault
();
mouseX
=
event
.
touches
[
0
].
pageX
-
windowHalfX
;
mouseY
=
event
.
touches
[
0
].
pageY
-
windowHalfY
;
}
}
//
function
initPostprocessing
()
{
postprocessing
.
scene
=
new
THREE
.
Scene
();
postprocessing
.
camera
=
new
THREE
.
OrthographicCamera
(
window
.
innerWidth
/
-
2
,
window
.
innerWidth
/
2
,
window
.
innerHeight
/
2
,
window
.
innerH
eight
/
-
2
,
-
10000
,
10000
);
postprocessing
.
camera
=
new
THREE
.
OrthographicCamera
(
window
.
innerWidth
/
-
2
,
window
.
innerWidth
/
2
,
height
/
2
,
h
eight
/
-
2
,
-
10000
,
10000
);
postprocessing
.
camera
.
position
.
z
=
100
;
postprocessing
.
scene
.
add
(
postprocessing
.
camera
);
var
pars
=
{
minFilter
:
THREE
.
LinearFilter
,
magFilter
:
THREE
.
LinearFilter
,
format
:
THREE
.
RGBFormat
};
postprocessing
.
rtTextureColors
=
new
THREE
.
WebGLRenderTarget
(
window
.
innerWidth
,
height
,
pars
);
// Switching the depth formats to luminance from rgb doesn't seem to work. I didn't
// investigate further for now.
// pars.format = THREE.LuminanceFormat;
// I would have this quarter size and use it as one of the ping-pong render
// targets but the aliasing causes some temporal flickering
postprocessing
.
rtTextureDepth
=
new
THREE
.
WebGLRenderTarget
(
window
.
innerWidth
,
height
,
pars
);
// Aggressive downsize god-ray ping-pong render targets to minimize cost
// Aggressive downsize god-ray ping-pong render targets to minimize cost
var
w
=
window
.
innerWidth
/
4.0
;
var
h
=
height
/
4.0
;
postprocessing
.
rtTextureGodRays1
=
new
THREE
.
WebGLRenderTarget
(
w
,
h
,
pars
);
postprocessing
.
rtTextureGodRays2
=
new
THREE
.
WebGLRenderTarget
(
w
,
h
,
pars
);
// god-ray shaders
var
godray
_gen_s
hader
=
THREE
.
ShaderGodRays
[
"
godrays_generate
"
];
postprocessing
.
godray
_gen_uniforms
=
THREE
.
UniformsUtils
.
clone
(
godray_gen_s
hader
.
uniforms
);
var
godray
sGenS
hader
=
THREE
.
ShaderGodRays
[
"
godrays_generate
"
];
postprocessing
.
godray
GenUniforms
=
THREE
.
UniformsUtils
.
clone
(
godraysGenS
hader
.
uniforms
);
postprocessing
.
materialGodraysGenerate
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
postprocessing
.
godray
_gen_u
niforms
,
vertexShader
:
godray
_gen_s
hader
.
vertexShader
,
fragmentShader
:
godray
_gen_s
hader
.
fragmentShader
uniforms
:
postprocessing
.
godray
GenU
niforms
,
vertexShader
:
godray
sGenS
hader
.
vertexShader
,
fragmentShader
:
godray
sGenS
hader
.
fragmentShader
}
);
var
godrays
_combine_s
hader
=
THREE
.
ShaderGodRays
[
"
godrays_combine
"
];
postprocessing
.
godray
_combine_uniforms
=
THREE
.
UniformsUtils
.
clone
(
godrays_combine_s
hader
.
uniforms
);
var
godrays
CombineS
hader
=
THREE
.
ShaderGodRays
[
"
godrays_combine
"
];
postprocessing
.
godray
CombineUniforms
=
THREE
.
UniformsUtils
.
clone
(
godraysCombineS
hader
.
uniforms
);
postprocessing
.
materialGodraysCombine
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
postprocessing
.
godray
_combine_u
niforms
,
vertexShader
:
godrays
_combine_s
hader
.
vertexShader
,
fragmentShader
:
godrays
_combine_s
hader
.
fragmentShader
uniforms
:
postprocessing
.
godray
CombineU
niforms
,
vertexShader
:
godrays
CombineS
hader
.
vertexShader
,
fragmentShader
:
godrays
CombineS
hader
.
fragmentShader
}
);
var
godrays
_fake_sun_s
hader
=
THREE
.
ShaderGodRays
[
"
godrays_fake_sun
"
];
postprocessing
.
godrays
_fake_sun_uniforms
=
THREE
.
UniformsUtils
.
clone
(
godrays_fake_sun_s
hader
.
uniforms
);
var
godrays
FakeSunS
hader
=
THREE
.
ShaderGodRays
[
"
godrays_fake_sun
"
];
postprocessing
.
godrays
FakeSunUniforms
=
THREE
.
UniformsUtils
.
clone
(
godraysFakeSunS
hader
.
uniforms
);
postprocessing
.
materialGodraysFakeSun
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
postprocessing
.
godrays
_fake_sun_u
niforms
,
vertexShader
:
godrays
_fake_sun_s
hader
.
vertexShader
,
fragmentShader
:
godrays
_fake_sun_s
hader
.
fragmentShader
uniforms
:
postprocessing
.
godrays
FakeSunU
niforms
,
vertexShader
:
godrays
FakeSunS
hader
.
vertexShader
,
fragmentShader
:
godrays
FakeSunS
hader
.
fragmentShader
}
);
postprocessing
.
quad
=
new
THREE
.
Mesh
(
new
THREE
.
PlaneGeometry
(
window
.
innerWidth
,
window
.
innerHeight
),
postprocessing
.
materialGodraysGenerate
);
postprocessing
.
godraysFakeSunUniforms
.
bgColor
.
value
.
setHex
(
bgColor
);
postprocessing
.
godraysFakeSunUniforms
.
sunColor
.
value
.
setHex
(
sunColor
);
postprocessing
.
godrayCombineUniforms
.
fGodRayIntensity
.
value
=
0.75
;
postprocessing
.
quad
=
new
THREE
.
Mesh
(
new
THREE
.
PlaneGeometry
(
window
.
innerWidth
,
height
),
postprocessing
.
materialGodraysGenerate
);
postprocessing
.
quad
.
position
.
z
=
-
9900
;
postprocessing
.
quad
.
rotation
.
x
=
Math
.
PI
/
2
;
postprocessing
.
scene
.
add
(
postprocessing
.
quad
);
...
...
@@ -238,7 +276,7 @@
function
animate
()
{
requestAnimationFrame
(
animate
,
renderer
.
domElement
);
render
();
stats
.
update
();
...
...
@@ -246,66 +284,81 @@
function
render
()
{
if
(
sphere_mesh
)
{
var
time
=
Date
.
now
()
/
4000
;
var
radius
=
100
;
sphere_mesh
.
position
.
x
=
200
*
Math
.
cos
(
Date
.
now
()
/
4000
);
sphere_mesh
.
position
.
z
=
200
*
Math
.
sin
(
Date
.
now
()
/
4000
)
-
100
;
sphere_mesh
.
updateMatrix
();
sphereMesh
.
position
.
x
=
orbitRadius
*
Math
.
cos
(
time
);
sphereMesh
.
position
.
z
=
orbitRadius
*
Math
.
sin
(
time
)
-
100
;
}
camera
.
position
.
x
+=
(
mouseX
-
camera
.
position
.
x
)
*
0.036
;
camera
.
position
.
y
+=
(
-
(
mouseY
)
-
camera
.
position
.
y
)
*
0.036
;
camera
.
position
.
y
+=
(
-
(
mouseY
)
-
camera
.
position
.
y
)
*
0.036
;
camera
.
lookAt
(
scene
.
position
);
if
(
postprocessing
.
enabled
)
{
// Find the screenspace position of the sun
var
sspos
=
new
THREE
.
Vector3
(
sunPos
.
x
,
sunPos
.
y
,
sunPos
.
z
);
proj
.
projectVector
(
sspos
,
camera
);
sspos
.
x
=
(
sspos
.
x
+
1
)
/
2
;
sspos
.
y
=
(
sspos
.
y
+
1
)
/
2
;
screenSpacePosition
.
copy
(
sunPosition
);
projector
.
projectVector
(
screenSpacePosition
,
camera
);
screenSpacePosition
.
x
=
(
screenSpacePosition
.
x
+
1
)
/
2
;
screenSpacePosition
.
y
=
(
screenSpacePosition
.
y
+
1
)
/
2
;
// Give it to the god-ray and sun shaders
postprocessing
.
godray_gen_uniforms
[
"
vSunPositionScreenSpace
"
].
value
=
new
THREE
.
Vector2
(
sspos
.
x
,
sspos
.
y
);
postprocessing
.
godrays_fake_sun_uniforms
[
"
vSunPositionScreenSpace
"
].
value
=
new
THREE
.
Vector2
(
sspos
.
x
,
sspos
.
y
);
postprocessing
.
godrayGenUniforms
[
"
vSunPositionScreenSpace
"
].
value
.
x
=
screenSpacePosition
.
x
;
postprocessing
.
godrayGenUniforms
[
"
vSunPositionScreenSpace
"
].
value
.
y
=
screenSpacePosition
.
y
;
postprocessing
.
godraysFakeSunUniforms
[
"
vSunPositionScreenSpace
"
].
value
.
x
=
screenSpacePosition
.
x
;
postprocessing
.
godraysFakeSunUniforms
[
"
vSunPositionScreenSpace
"
].
value
.
y
=
screenSpacePosition
.
y
;
// -- Draw sky and sun --
// Clear colors and depths, will clear to sky color
renderer
.
clearTarget
(
postprocessing
.
rtTextureColors
,
true
,
true
,
false
);
renderer
.
clearTarget
(
postprocessing
.
rtTextureColors
,
true
,
true
,
false
);
// Sun render. Runs a shader that gives a brightness based on the screen
// space distance to the sun. Not very efficient, so i make a scissor
// rect around the suns position to avoid rendering surrounding pixels.
var
sunsqH
=
0.74
*
height
;
// .74 depends on extent of sun from shader
var
sunsqW
=
0.74
*
height
;
// both dep on height because sun is aspect-corrected
sspos
.
x
*=
window
.
innerWidth
;
sspos
.
y
*=
height
;
renderer
.
setScissor
(
sspos
.
x
-
sunsqW
/
2
,
sspos
.
y
-
sunsqH
/
2
,
sunsqW
,
sunsqH
);
// rectangle around the suns position to avoid rendering surrounding pixels.
var
sunsqH
=
0.74
*
height
;
// 0.74 depends on extent of sun from shader
var
sunsqW
=
0.74
*
height
;
// both depend on height because sun is aspect-corrected
screenSpacePosition
.
x
*=
window
.
innerWidth
;
screenSpacePosition
.
y
*=
height
;
renderer
.
setScissor
(
screenSpacePosition
.
x
-
sunsqW
/
2
,
screenSpacePosition
.
y
-
sunsqH
/
2
,
sunsqW
,
sunsqH
);
renderer
.
enableScissorTest
(
true
);
postprocessing
.
godrays_fake_sun_uniforms
[
"
fAspect
"
].
value
=
window
.
innerWidth
/
height
;
postprocessing
.
godraysFakeSunUniforms
[
"
fAspect
"
].
value
=
window
.
innerWidth
/
height
;
postprocessing
.
scene
.
overrideMaterial
=
postprocessing
.
materialGodraysFakeSun
;
renderer
.
render
(
postprocessing
.
scene
,
postprocessing
.
camera
,
postprocessing
.
rtTextureColors
);
renderer
.
enableScissorTest
(
false
);
// -- Draw scene objects --
// Colors
scene
.
overrideMaterial
=
null
;
renderer
.
render
(
scene
,
camera
,
postprocessing
.
rtTextureColors
);
// Depth
scene
.
overrideMaterial
=
material_depth
;
scene
.
overrideMaterial
=
materialDepth
;
renderer
.
render
(
scene
,
camera
,
postprocessing
.
rtTextureDepth
,
true
);
// -- Render god-rays --
// Maximum length of god-rays (in texture space [0,1]X[0,1])
var
filterLen
=
1.0
;
// Samples taken by filter
var
TAPS_PER_PASS
=
6.0
;
// Pass order could equivalently be 3,2,1 (instead of 1,2,3), which
...
...
@@ -314,31 +367,44 @@
// appear as a glimmer along the length of the beams
// pass 1 - render into first ping-pong target
var
pass
=
1.0
;
var
stepLen
=
filterLen
*
Math
.
pow
(
TAPS_PER_PASS
,
-
pass
);
postprocessing
.
godray_gen_uniforms
[
"
fStepSize
"
].
value
=
stepLen
;
postprocessing
.
godray_gen_uniforms
[
"
tInput
"
].
texture
=
postprocessing
.
rtTextureDepth
;
var
stepLen
=
filterLen
*
Math
.
pow
(
TAPS_PER_PASS
,
-
pass
);
postprocessing
.
godrayGenUniforms
[
"
fStepSize
"
].
value
=
stepLen
;
postprocessing
.
godrayGenUniforms
[
"
tInput
"
].
texture
=
postprocessing
.
rtTextureDepth
;
postprocessing
.
scene
.
overrideMaterial
=
postprocessing
.
materialGodraysGenerate
;
renderer
.
render
(
postprocessing
.
scene
,
postprocessing
.
camera
,
postprocessing
.
rtTextureGodRays2
);
// pass 2 - render into second ping-pong target
pass
=
2.0
;
stepLen
=
filterLen
*
Math
.
pow
(
TAPS_PER_PASS
,
-
pass
);
postprocessing
.
godray_gen_uniforms
[
"
fStepSize
"
].
value
=
stepLen
;
postprocessing
.
godray_gen_uniforms
[
"
tInput
"
].
texture
=
postprocessing
.
rtTextureGodRays2
;
renderer
.
render
(
postprocessing
.
scene
,
postprocessing
.
camera
,
postprocessing
.
rtTextureGodRays1
);
stepLen
=
filterLen
*
Math
.
pow
(
TAPS_PER_PASS
,
-
pass
);
postprocessing
.
godrayGenUniforms
[
"
fStepSize
"
].
value
=
stepLen
;
postprocessing
.
godrayGenUniforms
[
"
tInput
"
].
texture
=
postprocessing
.
rtTextureGodRays2
;
renderer
.
render
(
postprocessing
.
scene
,
postprocessing
.
camera
,
postprocessing
.
rtTextureGodRays1
);
// pass 3 - 1st RT
pass
=
3.0
;
stepLen
=
filterLen
*
Math
.
pow
(
TAPS_PER_PASS
,
-
pass
);
postprocessing
.
godray_gen_uniforms
[
"
fStepSize
"
].
value
=
stepLen
;
postprocessing
.
godray_gen_uniforms
[
"
tInput
"
].
texture
=
postprocessing
.
rtTextureGodRays1
;
stepLen
=
filterLen
*
Math
.
pow
(
TAPS_PER_PASS
,
-
pass
);
postprocessing
.
godrayGenUniforms
[
"
fStepSize
"
].
value
=
stepLen
;
postprocessing
.
godrayGenUniforms
[
"
tInput
"
].
texture
=
postprocessing
.
rtTextureGodRays1
;
renderer
.
render
(
postprocessing
.
scene
,
postprocessing
.
camera
,
postprocessing
.
rtTextureGodRays2
);
// final pass - composite god-rays onto colors
postprocessing
.
godray_combine_uniforms
[
"
tColors
"
].
texture
=
postprocessing
.
rtTextureColors
;
postprocessing
.
godray_combine_uniforms
[
"
tGodRays
"
].
texture
=
postprocessing
.
rtTextureGodRays2
;
postprocessing
.
godrayCombineUniforms
[
"
tColors
"
].
texture
=
postprocessing
.
rtTextureColors
;
postprocessing
.
godrayCombineUniforms
[
"
tGodRays
"
].
texture
=
postprocessing
.
rtTextureGodRays2
;
postprocessing
.
scene
.
overrideMaterial
=
postprocessing
.
materialGodraysCombine
;
renderer
.
render
(
postprocessing
.
scene
,
postprocessing
.
camera
);
postprocessing
.
scene
.
overrideMaterial
=
null
;
...
...
@@ -350,6 +416,7 @@
}
}
</script>
</body>
</html>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录