Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
2f84f189
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,体验更适合开发者的 AI 搜索 >>
提交
2f84f189
编写于
9月 30, 2017
作者:
M
Mugen87
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added refractor example
上级
3bdf3cde
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
582 addition
and
0 deletion
+582
-0
examples/files.js
examples/files.js
+1
-0
examples/js/objects/Refractor.js
examples/js/objects/Refractor.js
+324
-0
examples/js/shaders/WaterRefractionShader.js
examples/js/shaders/WaterRefractionShader.js
+101
-0
examples/textures/waterdudv.jpg
examples/textures/waterdudv.jpg
+0
-0
examples/webgl_refraction.html
examples/webgl_refraction.html
+156
-0
未找到文件。
examples/files.js
浏览文件 @
2f84f189
...
...
@@ -231,6 +231,7 @@ var files = {
"
webgl_postprocessing_unreal_bloom
"
,
"
webgl_raycast_texture
"
,
"
webgl_read_float_buffer
"
,
"
webgl_refraction
"
,
"
webgl_rtt
"
,
"
webgl_sandbox
"
,
"
webgl_shader
"
,
...
...
examples/js/objects/Refractor.js
0 → 100644
浏览文件 @
2f84f189
/**
* @author Mugen87 / https://github.com/Mugen87
*
*/
THREE
.
Refractor
=
function
(
width
,
height
,
options
)
{
THREE
.
Mesh
.
call
(
this
,
new
THREE
.
PlaneBufferGeometry
(
width
,
height
)
);
this
.
type
=
'
Refractor
'
;
var
scope
=
this
;
var
color
=
options
.
color
||
new
THREE
.
Color
(
0x7f7f7f
);
var
textureWidth
=
options
.
textureWidth
||
512
;
var
textureHeight
=
options
.
textureHeight
||
512
;
var
clipBias
=
options
.
clipBias
||
0
;
var
shader
=
options
.
shader
||
THREE
.
DefaultRefractionShader
;
//
var
virtualCamera
=
new
THREE
.
PerspectiveCamera
();
virtualCamera
.
matrixAutoUpdate
=
false
;
virtualCamera
.
userData
.
refractor
=
true
;
//
var
refractorPlane
=
new
THREE
.
Plane
();
var
textureMatrix
=
new
THREE
.
Matrix4
();
// render target
var
parameters
=
{
minFilter
:
THREE
.
LinearFilter
,
magFilter
:
THREE
.
LinearFilter
,
format
:
THREE
.
RGBFormat
,
stencilBuffer
:
false
};
var
renderTarget
=
new
THREE
.
WebGLRenderTarget
(
textureWidth
,
textureHeight
,
parameters
);
if
(
!
THREE
.
Math
.
isPowerOfTwo
(
textureWidth
)
||
!
THREE
.
Math
.
isPowerOfTwo
(
textureHeight
)
)
{
renderTarget
.
texture
.
generateMipmaps
=
false
;
}
// material
this
.
material
=
new
THREE
.
ShaderMaterial
(
{
uniforms
:
THREE
.
UniformsUtils
.
clone
(
shader
.
uniforms
),
vertexShader
:
shader
.
vertexShader
,
fragmentShader
:
shader
.
fragmentShader
,
transparent
:
true
// ensures, refractors are drawn from farthest to closest
}
);
this
.
material
.
uniforms
.
color
.
value
=
color
;
this
.
material
.
uniforms
.
tDiffuse
.
value
=
renderTarget
.
texture
;
this
.
material
.
uniforms
.
textureMatrix
.
value
=
textureMatrix
;
// functions
var
visible
=
(
function
()
{
var
refractorWorldPosition
=
new
THREE
.
Vector3
();
var
cameraWorldPosition
=
new
THREE
.
Vector3
();
var
rotationMatrix
=
new
THREE
.
Matrix4
();
var
view
=
new
THREE
.
Vector3
();
var
normal
=
new
THREE
.
Vector3
();
return
function
updateRefractorPlane
(
camera
)
{
refractorWorldPosition
.
setFromMatrixPosition
(
scope
.
matrixWorld
);
cameraWorldPosition
.
setFromMatrixPosition
(
camera
.
matrixWorld
);
view
.
subVectors
(
refractorWorldPosition
,
cameraWorldPosition
);
rotationMatrix
.
extractRotation
(
scope
.
matrixWorld
);
normal
.
set
(
0
,
0
,
1
);
normal
.
applyMatrix4
(
rotationMatrix
);
return
view
.
dot
(
normal
)
<
0
;
};
}
)();
var
updateRefractorPlane
=
(
function
()
{
var
normal
=
new
THREE
.
Vector3
();
var
position
=
new
THREE
.
Vector3
();
var
quaternion
=
new
THREE
.
Quaternion
();
var
scale
=
new
THREE
.
Vector3
();
return
function
updateRefractorPlane
()
{
scope
.
matrixWorld
.
decompose
(
position
,
quaternion
,
scale
);
normal
.
set
(
0
,
0
,
1
).
applyQuaternion
(
quaternion
).
normalize
();
// flip the normal because we want to cull everything above the plane
normal
.
negate
();
refractorPlane
.
setFromNormalAndCoplanarPoint
(
normal
,
position
);
};
}
)();
var
updateVirtualCamera
=
(
function
()
{
var
clipPlane
=
new
THREE
.
Plane
();
var
clipVector
=
new
THREE
.
Vector4
();
var
q
=
new
THREE
.
Vector4
();
return
function
updateVirtualCamera
(
camera
)
{
virtualCamera
.
matrixWorld
.
copy
(
camera
.
matrixWorld
);
virtualCamera
.
matrixWorldInverse
.
getInverse
(
virtualCamera
.
matrixWorld
);
virtualCamera
.
projectionMatrix
.
copy
(
camera
.
projectionMatrix
);
virtualCamera
.
far
=
camera
.
far
;
// used in WebGLBackground
// The following code creates an oblique view frustum for clipping.
// see: Lengyel, Eric. “Oblique View Frustum Depth Projection and Clipping”.
// Journal of Game Development, Vol. 1, No. 2 (2005), Charles River Media, pp. 5–16
clipPlane
.
copy
(
refractorPlane
);
clipPlane
.
applyMatrix4
(
virtualCamera
.
matrixWorldInverse
);
clipVector
.
set
(
clipPlane
.
normal
.
x
,
clipPlane
.
normal
.
y
,
clipPlane
.
normal
.
z
,
clipPlane
.
constant
);
// calculate the clip-space corner point opposite the clipping plane and
// transform it into camera space by multiplying it by the inverse of the projection matrix
var
projectionMatrix
=
virtualCamera
.
projectionMatrix
;
q
.
x
=
(
Math
.
sign
(
clipVector
.
x
)
+
projectionMatrix
.
elements
[
8
]
)
/
projectionMatrix
.
elements
[
0
];
q
.
y
=
(
Math
.
sign
(
clipVector
.
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
clipVector
.
multiplyScalar
(
2.0
/
clipVector
.
dot
(
q
)
);
// replacing the third row of the projection matrix
projectionMatrix
.
elements
[
2
]
=
clipVector
.
x
;
projectionMatrix
.
elements
[
6
]
=
clipVector
.
y
;
projectionMatrix
.
elements
[
10
]
=
clipVector
.
z
+
1.0
-
clipBias
;
projectionMatrix
.
elements
[
14
]
=
clipVector
.
w
;
};
}
)();
// This will update the texture matrix that is used for projective texture mapping in the shader.
// see: http://developer.download.nvidia.com/assets/gamedev/docs/projective_texture_mapping.pdf
function
updateTextureMatrix
(
camera
)
{
// this matrix does range mapping to [ 0, 1 ]
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
);
// we use "Object Linear Texgen", so we need to multiply the texture matrix T
// (matrix above) with the projection and view matrix of the virtual camera
// and the model matrix of the refractor
textureMatrix
.
multiply
(
camera
.
projectionMatrix
);
textureMatrix
.
multiply
(
camera
.
matrixWorldInverse
);
textureMatrix
.
multiply
(
scope
.
matrixWorld
);
}
//
var
render
=
(
function
()
{
var
viewport
=
new
THREE
.
Vector4
();
return
function
render
(
renderer
,
scene
,
camera
)
{
scope
.
visible
=
false
;
var
currentRenderTarget
=
renderer
.
getRenderTarget
();
var
currentVrEnabled
=
renderer
.
vr
.
enabled
;
var
currentShadowAutoUpdate
=
renderer
.
shadowMap
.
autoUpdate
;
renderer
.
vr
.
enabled
=
false
;
// avoid camera modification
renderer
.
shadowMap
.
autoUpdate
=
false
;
// avoid re-computing shadows
renderer
.
render
(
scene
,
virtualCamera
,
renderTarget
,
true
);
renderer
.
vr
.
enabled
=
currentVrEnabled
;
renderer
.
shadowMap
.
autoUpdate
=
currentShadowAutoUpdate
;
renderer
.
setRenderTarget
(
currentRenderTarget
);
// restore viewport
var
bounds
=
camera
.
bounds
;
if
(
bounds
!==
undefined
)
{
var
size
=
renderer
.
getSize
();
var
pixelRatio
=
renderer
.
getPixelRatio
();
viewport
.
x
=
bounds
.
x
*
size
.
width
*
pixelRatio
;
viewport
.
y
=
bounds
.
y
*
size
.
height
*
pixelRatio
;
viewport
.
z
=
bounds
.
z
*
size
.
width
*
pixelRatio
;
viewport
.
w
=
bounds
.
w
*
size
.
height
*
pixelRatio
;
renderer
.
state
.
viewport
(
viewport
);
}
scope
.
visible
=
true
;
};
}
)();
//
this
.
onBeforeRender
=
function
(
renderer
,
scene
,
camera
)
{
// ensure refractors are rendered only once per frame
if
(
camera
.
userData
.
refractor
===
true
)
return
;
// avoid rendering when the refractor is viewed from behind
if
(
!
visible
(
camera
)
===
true
)
return
;
// update
updateRefractorPlane
(
camera
);
updateTextureMatrix
(
camera
);
updateVirtualCamera
(
camera
);
render
(
renderer
,
scene
,
camera
);
};
};
THREE
.
Refractor
.
prototype
=
Object
.
create
(
THREE
.
Mesh
.
prototype
);
THREE
.
Refractor
.
prototype
.
constructor
=
THREE
.
Refractor
;
THREE
.
DefaultRefractionShader
=
{
uniforms
:
{
'
color
'
:
{
type
:
'
c
'
,
value
:
null
},
'
tDiffuse
'
:
{
type
:
'
t
'
,
value
:
null
},
'
textureMatrix
'
:
{
type
:
'
m4
'
,
value
:
null
}
},
vertexShader
:
[
'
uniform mat4 textureMatrix;
'
,
'
varying vec4 vUv;
'
,
'
void main() {
'
,
'
vUv = textureMatrix * vec4( position, 1.0 );
'
,
'
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
'
,
'
}
'
].
join
(
'
\n
'
),
fragmentShader
:
[
'
uniform vec3 color;
'
,
'
uniform sampler2D tDiffuse;
'
,
'
varying vec4 vUv;
'
,
'
float blendOverlay( float base, float blend ) {
'
,
'
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
'
,
'
}
'
,
'
vec3 blendOverlay( vec3 base, vec3 blend ) {
'
,
'
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ),blendOverlay( base.b, blend.b ) );
'
,
'
}
'
,
'
void main() {
'
,
'
vec4 base = texture2DProj( tDiffuse, vUv );
'
,
'
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
'
,
'
}
'
].
join
(
'
\n
'
)
};
examples/js/shaders/WaterRefractionShader.js
0 → 100644
浏览文件 @
2f84f189
/**
* @author Mugen87 / https://github.com/Mugen87
*
*/
THREE
.
WaterRefractionShader
=
{
uniforms
:
{
'
color
'
:
{
type
:
'
c
'
,
value
:
null
},
'
time
'
:
{
type
:
'
f
'
,
value
:
0
},
'
tDiffuse
'
:
{
type
:
'
t
'
,
value
:
null
},
'
tDudv
'
:
{
type
:
'
t
'
,
value
:
null
},
'
textureMatrix
'
:
{
type
:
'
m4
'
,
value
:
null
}
},
vertexShader
:
[
'
uniform mat4 textureMatrix;
'
,
'
varying vec2 vUv;
'
,
'
varying vec4 vUvRefraction;
'
,
'
void main() {
'
,
'
vUv = uv;
'
,
'
vUvRefraction = textureMatrix * vec4( position, 1.0 );
'
,
'
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
'
,
'
}
'
].
join
(
'
\n
'
),
fragmentShader
:
[
'
uniform vec3 color;
'
,
'
uniform float time;
'
,
'
uniform sampler2D tDiffuse;
'
,
'
uniform sampler2D tDudv;
'
,
'
varying vec2 vUv;
'
,
'
varying vec4 vUvRefraction;
'
,
'
float blendOverlay( float base, float blend ) {
'
,
'
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
'
,
'
}
'
,
'
vec3 blendOverlay( vec3 base, vec3 blend ) {
'
,
'
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ),blendOverlay( base.b, blend.b ) );
'
,
'
}
'
,
'
void main() {
'
,
'
float waveStrength = 0.1;
'
,
'
float waveSpeed = 0.03;
'
,
// simple distortion (ripple) via dudv map (see https://www.youtube.com/watch?v=6B7IF6GOu7s)
'
vec2 distortedUv = texture2D( tDudv, vec2( vUv.x + time * waveSpeed, vUv.y ) ).rg * waveStrength;
'
,
'
distortedUv = vUv.xy + vec2( distortedUv.x, distortedUv.y + time * waveSpeed );
'
,
'
vec2 distortion = ( texture2D( tDudv, distortedUv ).rg * 2.0 - 1.0 ) * waveStrength;
'
,
// new uv coords
'
vec4 uv = vec4( vUvRefraction );
'
,
'
uv.xy += distortion;
'
,
'
vec4 base = texture2DProj( tDiffuse, uv );
'
,
'
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
'
,
'
}
'
].
join
(
'
\n
'
)
};
examples/textures/waterdudv.jpg
0 → 100644
浏览文件 @
2f84f189
173.8 KB
examples/webgl_refraction.html
0 → 100644
浏览文件 @
2f84f189
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
three.js refraction
</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
:
#777
;
padding
:
0
;
margin
:
0
;
font-weight
:
bold
;
overflow
:
hidden
;
}
#info
{
position
:
absolute
;
top
:
0px
;
width
:
100%
;
color
:
#ffffff
;
padding
:
5px
;
font-family
:
Monospace
;
font-size
:
13px
;
text-align
:
center
;
}
a
{
color
:
#ffffff
;
}
</style>
<script
src=
"../build/three.js"
></script>
<script
src=
"js/controls/OrbitControls.js"
></script>
<script
src=
"js/shaders/WaterRefractionShader.js"
></script>
<script
src=
"js/objects/Refractor.js"
></script>
<script
src=
"js/Detector.js"
></script>
</head>
<body>
<div
id=
"container"
></div>
<div
id=
"info"
>
<a
href=
"https://threejs.org"
target=
"_blank"
rel=
"noopener noreferrer"
>
three.js
</a>
refraction
</div>
<script>
if
(
!
Detector
.
webgl
)
Detector
.
addGetWebGLMessage
();
var
scene
,
camera
,
clock
,
renderer
,
refractor
;
init
();
function
init
()
{
// scene
scene
=
new
THREE
.
Scene
();
// camera
camera
=
new
THREE
.
PerspectiveCamera
(
45
,
window
.
innerWidth
/
window
.
innerHeight
,
1
,
1000
);
camera
.
position
.
set
(
-
10
,
0
,
15
);
camera
.
lookAt
(
scene
.
position
);
// clock
clock
=
new
THREE
.
Clock
();
// mesh
var
geometry
=
new
THREE
.
TorusKnotBufferGeometry
(
3
,
1
,
256
,
32
);
var
material
=
new
THREE
.
MeshStandardMaterial
(
{
color
:
0x6083c2
}
);
var
mesh
=
new
THREE
.
Mesh
(
geometry
,
material
);
scene
.
add
(
mesh
);
// refractor
refractor
=
new
THREE
.
Refractor
(
10
,
10
,
{
color
:
new
THREE
.
Color
(
0x999999
),
textureWidth
:
1024
,
textureHeight
:
1024
,
shader
:
THREE
.
WaterRefractionShader
}
);
refractor
.
position
.
set
(
0
,
0
,
5
);
scene
.
add
(
refractor
);
// load dudv map for distortion effect
var
dudvMap
=
new
THREE
.
TextureLoader
().
load
(
'
textures/waterdudv.jpg
'
,
function
()
{
animate
();
}
);
dudvMap
.
wrapS
=
dudvMap
.
wrapT
=
THREE
.
RepeatWrapping
;
refractor
.
material
.
uniforms
.
tDudv
.
value
=
dudvMap
;
// light
var
ambientLight
=
new
THREE
.
AmbientLight
(
0xcccccc
,
0.4
);
scene
.
add
(
ambientLight
);
var
pointLight
=
new
THREE
.
PointLight
(
0xffffff
,
0.8
);
camera
.
add
(
pointLight
);
scene
.
add
(
camera
);
// renderer
renderer
=
new
THREE
.
WebGLRenderer
(
{
antialias
:
true
}
);
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
renderer
.
setClearColor
(
0x20252f
);
renderer
.
setPixelRatio
(
window
.
devicePixelRatio
);
document
.
body
.
appendChild
(
renderer
.
domElement
);
//
controls
=
new
THREE
.
OrbitControls
(
camera
,
renderer
.
domElement
);
//
window
.
addEventListener
(
'
resize
'
,
onResize
,
false
);
}
function
onResize
()
{
camera
.
aspect
=
window
.
innerWidth
/
window
.
innerHeight
;
camera
.
updateProjectionMatrix
();
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
}
function
animate
()
{
requestAnimationFrame
(
animate
);
render
();
}
function
render
()
{
refractor
.
material
.
uniforms
.
time
.
value
+=
clock
.
getDelta
();
renderer
.
render
(
scene
,
camera
);
}
</script>
</body>
</html>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录