Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
b1653ec7
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,发现更多精彩内容 >>
提交
b1653ec7
编写于
1月 01, 2014
作者:
J
Joshua Koo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Importing @jbouny Ocean/Water example which is based on the Mirror Shader (see #3856)
上级
a1d6af33
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
464 addition
and
0 deletion
+464
-0
examples/index.html
examples/index.html
+1
-0
examples/js/WaterShader.js
examples/js/WaterShader.js
+272
-0
examples/textures/waternormals.jpg
examples/textures/waternormals.jpg
+0
-0
examples/webgl_shaders_ocean.html
examples/webgl_shaders_ocean.html
+191
-0
未找到文件。
examples/index.html
浏览文件 @
b1653ec7
...
...
@@ -243,6 +243,7 @@
"
webgl_sandbox
"
,
"
webgl_shader
"
,
"
webgl_shader2
"
,
"
webgl_shaders_ocean
"
,
"
webgl_shader_lava
"
,
"
webgl_shading_physical
"
,
"
webgl_shadowmap
"
,
...
...
examples/js/WaterShader.js
0 → 100644
浏览文件 @
b1653ec7
/**
* @author jbouny / https://github.com/jbouny
*
* Work based on :
* @author Slayvin / http://slayvin.net : Flat mirror for three.js
* @author Stemkoski / http://www.adelphi.edu/~stemkoski : An implementation of water shader based on the flat mirror
* @author Jonas Wagner / http://29a.ch/ && http://29a.ch/slides/2012/webglwater/ : Water shader explanations in WebGL
*/
THREE
.
ShaderLib
[
'
water
'
]
=
{
uniforms
:
{
"
normalSampler
"
:
{
type
:
"
t
"
,
value
:
null
},
"
mirrorSampler
"
:
{
type
:
"
t
"
,
value
:
null
},
"
alpha
"
:
{
type
:
"
f
"
,
value
:
1.0
},
"
time
"
:
{
type
:
"
f
"
,
value
:
0.0
},
"
distortionScale
"
:
{
type
:
"
f
"
,
value
:
20.0
},
"
textureMatrix
"
:
{
type
:
"
m4
"
,
value
:
new
THREE
.
Matrix4
()
},
"
sunColor
"
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x7F7F7F
)
},
"
sunDirection
"
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0.70707
,
0.70707
,
0
)
},
"
eye
"
:
{
type
:
"
v3
"
,
value
:
new
THREE
.
Vector3
(
0
,
0
,
0
)
},
"
waterColor
"
:
{
type
:
"
c
"
,
value
:
new
THREE
.
Color
(
0x555555
)
}
},
vertexShader
:
[
'
uniform mat4 textureMatrix;
'
,
'
uniform float time;
'
,
'
varying vec4 mirrorCoord;
'
,
'
varying vec3 worldPosition;
'
,
'
void main()
'
,
'
{
'
,
'
mirrorCoord = modelMatrix * vec4( position, 1.0 );
'
,
'
worldPosition = mirrorCoord.xyz;
'
,
'
mirrorCoord = textureMatrix * mirrorCoord;
'
,
'
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
'
,
'
}
'
].
join
(
'
\n
'
),
fragmentShader
:
[
'
precision highp float;
'
,
'
uniform sampler2D mirrorSampler;
'
,
'
uniform float alpha;
'
,
'
uniform float time;
'
,
'
uniform float distortionScale;
'
,
'
uniform sampler2D normalSampler;
'
,
'
uniform vec3 sunColor;
'
,
'
uniform vec3 sunDirection;
'
,
'
uniform vec3 eye;
'
,
'
uniform vec3 waterColor;
'
,
'
varying vec4 mirrorCoord;
'
,
'
varying vec3 worldPosition;
'
,
'
vec4 getNoise( vec2 uv )
'
,
'
{
'
,
'
vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);
'
,
'
vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );
'
,
'
vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );
'
,
'
vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );
'
,
'
vec4 noise = ( texture2D( normalSampler, uv0 ) ) +
'
,
'
( texture2D( normalSampler, uv1 ) ) +
'
,
'
( texture2D( normalSampler, uv2 ) ) +
'
,
'
( texture2D( normalSampler, uv3 ) );
'
,
'
return noise * 0.5 - 1.0;
'
,
'
}
'
,
'
void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor )
'
,
'
{
'
,
'
vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );
'
,
'
float direction = max( 0.0, dot( eyeDirection, reflection ) );
'
,
'
specularColor += pow( direction, shiny ) * sunColor * spec;
'
,
'
diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;
'
,
'
}
'
,
'
void main()
'
,
'
{
'
,
'
vec4 noise = getNoise( worldPosition.xz );
'
,
'
vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );
'
,
'
vec3 diffuseLight = vec3(0.0);
'
,
'
vec3 specularLight = vec3(0.0);
'
,
'
vec3 worldToEye = eye-worldPosition;
'
,
'
vec3 eyeDirection = normalize( worldToEye );
'
,
'
sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );
'
,
'
float distance = length(worldToEye);
'
,
'
vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;
'
,
'
vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.z + distortion ) );
'
,
'
float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );
'
,
'
float rf0 = 0.3;
'
,
'
float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );
'
,
'
vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;
'
,
'
vec3 albedo = mix( sunColor * diffuseLight * 0.3 + scatter, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );
'
,
'
gl_FragColor = vec4( albedo, alpha );
'
,
'
}
'
].
join
(
'
\n
'
)
};
THREE
.
Water
=
function
(
renderer
,
camera
,
scene
,
options
)
{
THREE
.
Object3D
.
call
(
this
);
this
.
name
=
'
water_
'
+
this
.
id
;
function
isPowerOfTwo
(
value
)
{
return
(
value
&
(
value
-
1
)
)
===
0
;
};
function
optionalParameter
(
value
,
defaultValue
)
{
return
value
!==
undefined
?
value
:
defaultValue
;
};
options
=
options
||
{};
this
.
matrixNeedsUpdate
=
true
;
var
width
=
optionalParameter
(
options
.
textureWidth
,
512
);
var
height
=
optionalParameter
(
options
.
textureHeight
,
512
);
this
.
clipBias
=
optionalParameter
(
options
.
clipBias
,
0.0
);
this
.
alpha
=
optionalParameter
(
options
.
alpha
,
1.0
);
this
.
time
=
optionalParameter
(
options
.
time
,
0.0
);
this
.
normalSampler
=
optionalParameter
(
options
.
waterNormals
,
null
);
this
.
sunDirection
=
optionalParameter
(
options
.
sunDirection
,
new
THREE
.
Vector3
(
0.70707
,
0.70707
,
0.0
)
);
this
.
sunColor
=
new
THREE
.
Color
(
optionalParameter
(
options
.
sunColor
,
0xffffff
)
);
this
.
waterColor
=
new
THREE
.
Color
(
optionalParameter
(
options
.
waterColor
,
0x7F7F7F
)
);
this
.
eye
=
optionalParameter
(
options
.
eye
,
new
THREE
.
Vector3
(
0
,
0
,
0
)
);
this
.
distortionScale
=
optionalParameter
(
options
.
distortionScale
,
20.0
);
this
.
renderer
=
renderer
;
this
.
scene
=
scene
;
this
.
mirrorPlane
=
new
THREE
.
Plane
();
this
.
normal
=
new
THREE
.
Vector3
(
0
,
0
,
1
);
this
.
mirrorWorldPosition
=
new
THREE
.
Vector3
();
this
.
cameraWorldPosition
=
new
THREE
.
Vector3
();
this
.
rotationMatrix
=
new
THREE
.
Matrix4
();
this
.
lookAtPosition
=
new
THREE
.
Vector3
(
0
,
0
,
-
1
);
this
.
clipPlane
=
new
THREE
.
Vector4
();
if
(
camera
instanceof
THREE
.
PerspectiveCamera
)
this
.
camera
=
camera
;
else
{
this
.
camera
=
new
THREE
.
PerspectiveCamera
();
console
.
log
(
this
.
name
+
'
: camera is not a Perspective Camera!
'
)
}
this
.
textureMatrix
=
new
THREE
.
Matrix4
();
this
.
mirrorCamera
=
this
.
camera
.
clone
();
this
.
texture
=
new
THREE
.
WebGLRenderTarget
(
width
,
height
);
this
.
tempTexture
=
new
THREE
.
WebGLRenderTarget
(
width
,
height
);
var
mirrorShader
=
THREE
.
ShaderLib
[
"
water
"
];
var
mirrorUniforms
=
THREE
.
UniformsUtils
.
clone
(
mirrorShader
.
uniforms
);
this
.
material
=
new
THREE
.
ShaderMaterial
(
{
fragmentShader
:
mirrorShader
.
fragmentShader
,
vertexShader
:
mirrorShader
.
vertexShader
,
uniforms
:
mirrorUniforms
,
transparent
:
true
}
);
this
.
material
.
uniforms
.
mirrorSampler
.
value
=
this
.
texture
;
this
.
material
.
uniforms
.
textureMatrix
.
value
=
this
.
textureMatrix
;
this
.
material
.
uniforms
.
alpha
.
value
=
this
.
alpha
;
this
.
material
.
uniforms
.
time
.
value
=
this
.
time
;
this
.
material
.
uniforms
.
normalSampler
.
value
=
this
.
normalSampler
;
this
.
material
.
uniforms
.
sunColor
.
value
=
this
.
sunColor
;
this
.
material
.
uniforms
.
waterColor
.
value
=
this
.
waterColor
;
this
.
material
.
uniforms
.
sunDirection
.
value
=
this
.
sunDirection
;
this
.
material
.
uniforms
.
distortionScale
.
value
=
this
.
distortionScale
;
this
.
material
.
uniforms
.
eye
.
value
=
this
.
eye
;
if
(
!
isPowerOfTwo
(
width
)
||
!
isPowerOfTwo
(
height
)
)
{
this
.
texture
.
generateMipmaps
=
false
;
this
.
tempTexture
.
generateMipmaps
=
false
;
}
this
.
updateTextureMatrix
();
this
.
render
();
};
THREE
.
Water
.
prototype
=
Object
.
create
(
THREE
.
Mirror
.
prototype
);
THREE
.
Water
.
prototype
.
updateTextureMatrix
=
function
()
{
function
sign
(
x
)
{
return
x
?
x
<
0
?
-
1
:
1
:
0
;
}
this
.
updateMatrixWorld
();
this
.
camera
.
updateMatrixWorld
();
this
.
mirrorWorldPosition
.
setFromMatrixPosition
(
this
.
matrixWorld
);
this
.
cameraWorldPosition
.
setFromMatrixPosition
(
this
.
camera
.
matrixWorld
);
this
.
rotationMatrix
.
extractRotation
(
this
.
matrixWorld
);
this
.
normal
.
set
(
0
,
0
,
1
);
this
.
normal
.
applyMatrix4
(
this
.
rotationMatrix
);
var
view
=
this
.
mirrorWorldPosition
.
clone
().
sub
(
this
.
cameraWorldPosition
);
var
reflectView
=
view
.
reflect
(
this
.
normal
);
reflectView
.
add
(
this
.
mirrorWorldPosition
);
this
.
rotationMatrix
.
extractRotation
(
this
.
camera
.
matrixWorld
);
this
.
lookAtPosition
.
set
(
0
,
0
,
-
1
);
this
.
lookAtPosition
.
applyMatrix4
(
this
.
rotationMatrix
);
this
.
lookAtPosition
.
add
(
this
.
cameraWorldPosition
);
var
target
=
this
.
mirrorWorldPosition
.
clone
().
sub
(
this
.
lookAtPosition
);
var
reflectTarget
=
target
.
reflect
(
this
.
normal
);
reflectTarget
.
add
(
this
.
mirrorWorldPosition
);
this
.
up
.
set
(
0
,
-
1
,
0
);
this
.
up
.
applyMatrix4
(
this
.
rotationMatrix
);
var
reflectUp
=
this
.
up
.
reflect
(
this
.
normal
);
this
.
mirrorCamera
.
position
.
copy
(
reflectView
);
this
.
mirrorCamera
.
up
=
reflectUp
;
this
.
mirrorCamera
.
lookAt
(
reflectTarget
);
this
.
mirrorCamera
.
aspect
=
this
.
camera
.
aspect
;
this
.
mirrorCamera
.
updateProjectionMatrix
();
this
.
mirrorCamera
.
updateMatrixWorld
();
this
.
mirrorCamera
.
matrixWorldInverse
.
getInverse
(
this
.
mirrorCamera
.
matrixWorld
);
// Update the texture matrix
this
.
textureMatrix
.
set
(
0.5
,
0.0
,
0.0
,
0.5
,
0.0
,
0.5
,
0.0
,
0.5
,
0.0
,
0.0
,
0.5
,
0.5
,
0.0
,
0.0
,
0.0
,
1.0
);
this
.
textureMatrix
.
multiply
(
this
.
mirrorCamera
.
projectionMatrix
);
this
.
textureMatrix
.
multiply
(
this
.
mirrorCamera
.
matrixWorldInverse
);
// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
// Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
this
.
mirrorPlane
.
setFromNormalAndCoplanarPoint
(
this
.
normal
,
this
.
mirrorWorldPosition
);
this
.
mirrorPlane
.
applyMatrix4
(
this
.
mirrorCamera
.
matrixWorldInverse
);
this
.
clipPlane
.
set
(
this
.
mirrorPlane
.
normal
.
x
,
this
.
mirrorPlane
.
normal
.
y
,
this
.
mirrorPlane
.
normal
.
z
,
this
.
mirrorPlane
.
constant
);
var
q
=
new
THREE
.
Vector4
();
var
projectionMatrix
=
this
.
mirrorCamera
.
projectionMatrix
;
q
.
x
=
(
sign
(
this
.
clipPlane
.
x
)
+
projectionMatrix
.
elements
[
8
])
/
projectionMatrix
.
elements
[
0
];
q
.
y
=
(
sign
(
this
.
clipPlane
.
y
)
+
projectionMatrix
.
elements
[
9
])
/
projectionMatrix
.
elements
[
5
];
q
.
z
=
-
1.0
;
q
.
w
=
(
1.0
+
projectionMatrix
.
elements
[
10
])
/
projectionMatrix
.
elements
[
14
];
// Calculate the scaled plane vector
var
c
=
new
THREE
.
Vector4
();
c
=
this
.
clipPlane
.
multiplyScalar
(
2.0
/
this
.
clipPlane
.
dot
(
q
)
);
// Replacing the third row of the projection matrix
projectionMatrix
.
elements
[
2
]
=
c
.
x
;
projectionMatrix
.
elements
[
6
]
=
c
.
y
;
projectionMatrix
.
elements
[
10
]
=
c
.
z
+
1.0
-
this
.
clipBias
;
projectionMatrix
.
elements
[
14
]
=
c
.
w
;
var
worldCoordinates
=
new
THREE
.
Vector3
();
worldCoordinates
.
setFromMatrixPosition
(
this
.
camera
.
matrixWorld
);
this
.
eye
=
worldCoordinates
;
this
.
material
.
uniforms
.
eye
.
value
=
this
.
eye
;
};
examples/textures/waternormals.jpg
0 → 100644
浏览文件 @
b1653ec7
243.0 KB
examples/webgl_shaders_ocean.html
0 → 100644
浏览文件 @
b1653ec7
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
three.js webgl - geometry - terrain
</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
{
color
:
#000
;
font-family
:
Monospace
;
font-size
:
13px
;
text-align
:
center
;
margin
:
0px
;
overflow
:
hidden
;
}
#info
{
position
:
absolute
;
top
:
0px
;
width
:
100%
;
padding
:
5px
;
}
a
{
color
:
#a06851
;
}
</style>
</head>
<body>
<div
id=
"info"
><a
href=
"http://threejs.org"
target=
"_blank"
>
three.js
</a>
- webgl ocean demo
</div>
<script
src=
"../build/three.min.js"
></script>
<script
src=
"js/controls/OrbitControls.js"
></script>
<script
src=
"js/Mirror.js"
></script>
<script
src=
"js/WaterShader.js"
></script>
<script
src=
"js/Detector.js"
></script>
<script
src=
"js/libs/stats.min.js"
></script>
<script>
if
(
!
Detector
.
webgl
)
{
Detector
.
addGetWebGLMessage
();
document
.
getElementById
(
'
container
'
).
innerHTML
=
""
;
}
var
container
,
stats
;
var
camera
,
scene
,
renderer
;
var
parameters
=
{
width
:
2000
,
height
:
2000
,
widthSegments
:
250
,
heightSegments
:
250
,
depth
:
1500
,
param
:
4
,
filterparam
:
1
}
var
waterNormals
;
init
();
animate
();
function
init
()
{
container
=
document
.
createElement
(
'
div
'
);
document
.
body
.
appendChild
(
container
);
renderer
=
new
THREE
.
WebGLRenderer
();
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
container
.
appendChild
(
renderer
.
domElement
);
scene
=
new
THREE
.
Scene
();
camera
=
new
THREE
.
PerspectiveCamera
(
55
,
window
.
innerWidth
/
window
.
innerHeight
,
0.5
,
3000000
);
// resize(innerWidth, innerHeight);
camera
.
position
.
set
(
0
,
Math
.
max
(
parameters
.
width
*
1.5
,
parameters
.
height
)
/
8
,
-
parameters
.
height
);
camera
.
lookAt
(
new
THREE
.
Vector3
(
0
,
0
,
0
)
);
controls
=
new
THREE
.
OrbitControls
(
camera
,
renderer
.
domElement
);
controls
.
userPan
=
false
;
controls
.
userPanSpeed
=
0.0
;
controls
.
maxDistance
=
5000.0
;
controls
.
maxPolarAngle
=
Math
.
PI
*
0.495
;
directionalLight
=
new
THREE
.
DirectionalLight
(
0xffff55
,
1
);
directionalLight
.
position
.
set
(
-
600
,
300
,
600
);
scene
.
add
(
directionalLight
);
waterNormals
=
new
THREE
.
ImageUtils
.
loadTexture
(
'
textures/waternormals.jpg
'
);
waterNormals
.
wrapS
=
waterNormals
.
wrapT
=
THREE
.
RepeatWrapping
;
water
=
new
THREE
.
Water
(
renderer
,
camera
,
scene
,
{
textureWidth
:
512
,
textureHeight
:
512
,
waterNormals
:
waterNormals
,
alpha
:
1.0
,
sunDirection
:
directionalLight
.
position
.
normalize
(),
sunColor
:
0xffffff
,
waterColor
:
0x001e0f
,
distortionScale
:
50.0
,
}
);
mirrorMesh
=
new
THREE
.
Mesh
(
new
THREE
.
PlaneGeometry
(
parameters
.
width
*
500
,
parameters
.
height
*
500
,
50
,
50
),
water
.
material
);
mirrorMesh
.
add
(
water
);
mirrorMesh
.
rotation
.
x
=
-
Math
.
PI
*
0.5
;
scene
.
add
(
mirrorMesh
);
// load skybox
var
path
=
"
textures/cube/skybox/
"
;
var
cubeMap
=
THREE
.
ImageUtils
.
loadTextureCube
(
[
path
+
'
px.jpg
'
,
path
+
'
nx.jpg
'
,
path
+
'
py.jpg
'
,
path
+
'
ny.jpg
'
,
path
+
'
pz.jpg
'
,
path
+
'
nz.jpg
'
]
);
cubeMap
.
format
=
THREE
.
RGBFormat
;
var
cubeShader
=
THREE
.
ShaderLib
[
'
cube
'
];
cubeShader
.
uniforms
[
'
tCube
'
].
value
=
cubeMap
;
var
skyBoxMaterial
=
new
THREE
.
ShaderMaterial
(
{
fragmentShader
:
cubeShader
.
fragmentShader
,
vertexShader
:
cubeShader
.
vertexShader
,
uniforms
:
cubeShader
.
uniforms
,
depthWrite
:
false
,
side
:
THREE
.
BackSide
});
var
skyBox
=
new
THREE
.
Mesh
(
new
THREE
.
CubeGeometry
(
1000000
,
1000000
,
1000000
),
skyBoxMaterial
);
scene
.
add
(
skyBox
);
}
//
function
animate
()
{
requestAnimationFrame
(
animate
);
render
();
}
function
render
()
{
water
.
material
.
uniforms
.
time
.
value
+=
1.0
/
60.0
;
controls
.
update
();
water
.
render
();
renderer
.
render
(
scene
,
camera
);
}
function
resize
(
width
,
height
)
{
camera
.
aspect
=
width
/
height
;
camera
.
updateProjectionMatrix
();
renderer
.
setSize
(
width
,
height
);
}
</script>
</body>
</html>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录