Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
车家大少爷
three.js
提交
1558bf0e
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,发现更多精彩内容 >>
提交
1558bf0e
编写于
4月 25, 2017
作者:
M
Mr.doob
提交者:
GitHub
4月 25, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #11232 from WestLangley/dev-rect_area
RectAreaLight: cleanup and refactoring
上级
edc89403
6d59904e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
134 addition
and
371 deletion
+134
-371
src/renderers/shaders/ShaderChunk/bsdfs.glsl
src/renderers/shaders/ShaderChunk/bsdfs.glsl
+74
-341
src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl
...erers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl
+30
-16
src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl
...rs/shaders/ShaderChunk/lights_physical_pars_fragment.glsl
+30
-14
未找到文件。
src/renderers/shaders/ShaderChunk/bsdfs.glsl
浏览文件 @
1558bf0e
float
punctualLightIntensityToIrradianceFactor
(
const
in
float
lightDistance
,
const
in
float
cutoffDistance
,
const
in
float
decayExponent
)
{
if
(
decayExponent
>
0
.
0
)
{
if
(
decayExponent
>
0
.
0
)
{
#if defined ( PHYSICALLY_CORRECT_LIGHTS )
// based upon Frostbite 3 Moving to Physically-based Rendering
// page 32, equation 26: E[window1]
// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
// this is intended to be used on spot and point lights who are represented as luminous intensity
// but who must be converted to luminous irradiance for surface lighting calculation
float
distanceFalloff
=
1
.
0
/
max
(
pow
(
lightDistance
,
decayExponent
),
0
.
01
);
float
maxDistanceCutoffFactor
=
pow2
(
saturate
(
1
.
0
-
pow4
(
lightDistance
/
cutoffDistance
)
)
);
return
distanceFalloff
*
maxDistanceCutoffFactor
;
// based upon Frostbite 3 Moving to Physically-based Rendering
// page 32, equation 26: E[window1]
// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
// this is intended to be used on spot and point lights who are represented as luminous intensity
// but who must be converted to luminous irradiance for surface lighting calculation
float
distanceFalloff
=
1
.
0
/
max
(
pow
(
lightDistance
,
decayExponent
),
0
.
01
);
float
maxDistanceCutoffFactor
=
pow2
(
saturate
(
1
.
0
-
pow4
(
lightDistance
/
cutoffDistance
)
)
);
return
distanceFalloff
*
maxDistanceCutoffFactor
;
#else
return
pow
(
saturate
(
-
lightDistance
/
cutoffDistance
+
1
.
0
),
decayExponent
);
return
pow
(
saturate
(
-
lightDistance
/
cutoffDistance
+
1
.
0
),
decayExponent
);
#endif
}
}
return
1
.
0
;
return
1
.
0
;
}
vec3
BRDF_Diffuse_Lambert
(
const
in
vec3
diffuseColor
)
{
...
...
@@ -30,11 +31,10 @@ vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {
}
// validated
vec3
F_Schlick
(
const
in
vec3
specularColor
,
const
in
float
dotLH
)
{
// Original approximation by Christophe Schlick '94
//
;
float fresnel = pow( 1.0 - dotLH, 5.0 );
//
float fresnel = pow( 1.0 - dotLH, 5.0 );
// Optimized variant (presented by Epic at SIGGRAPH '13)
float
fresnel
=
exp2
(
(
-
5
.
55473
*
dotLH
-
6
.
98316
)
*
dotLH
);
...
...
@@ -43,7 +43,6 @@ vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
}
// validated
// Microfacet Models for Refraction through Rough Surfaces - equation (34)
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
// alpha is "roughness squared" in Disney’s reparameterization
...
...
@@ -60,7 +59,8 @@ float G_GGX_Smith( const in float alpha, const in float dotNL, const in float do
}
// validated
// from page 12, listing 2 of http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
// Moving Frostbite to Physically Based Rendering 2.0 - page 12, listing 2
// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
float
G_GGX_SmithCorrelated
(
const
in
float
alpha
,
const
in
float
dotNL
,
const
in
float
dotNV
)
{
float
a2
=
pow2
(
alpha
);
...
...
@@ -72,8 +72,6 @@ float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const i
return
0
.
5
/
max
(
gv
+
gl
,
EPSILON
);
}
// Microfacet Models for Refraction through Rough Surfaces - equation (33)
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
// alpha is "roughness squared" in Disney’s reparameterization
...
...
@@ -87,7 +85,6 @@ float D_GGX( const in float alpha, const in float dotNH ) {
}
// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility
vec3
BRDF_Specular_GGX
(
const
in
IncidentLight
incidentLight
,
const
in
GeometricContext
geometry
,
const
in
vec3
specularColor
,
const
in
float
roughness
)
{
...
...
@@ -110,29 +107,21 @@ vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in Geometric
}
// validated
//
// Rect Area Light BRDF Approximations
//
// Rect Area Light
// Area light computation code adapted from:
// http://blog.selfshadow.com/sandbox/ltc.html
//
// Based on paper:
// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
// By: Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt
// https://drive.google.com/file/d/0BzvWIdpUpRx_d09ndGVjNVJzZjA/view
// https://eheitzresearch.wordpress.com/415-2/
// http://blog.selfshadow.com/sandbox/ltc.html
vec2
ltcTextureCoords
(
const
in
GeometricContext
geometry
,
const
in
float
roughness
)
{
vec2
LTC_Uv
(
const
in
vec3
N
,
const
in
vec3
V
,
const
in
float
roughness
)
{
const
float
LUT_SIZE
=
64
.
0
;
const
float
LUT_SCALE
=
(
LUT_SIZE
-
1
.
0
)
/
LUT_SIZE
;
const
float
LUT_BIAS
=
0
.
5
/
LUT_SIZE
;
vec3
N
=
geometry
.
normal
;
vec3
V
=
geometry
.
viewDir
;
vec3
P
=
geometry
.
position
;
const
float
LUT_SCALE
=
(
LUT_SIZE
-
1
.
0
)
/
LUT_SIZE
;
const
float
LUT_BIAS
=
0
.
5
/
LUT_SIZE
;
// view angle on surface determines which LTC BRDF values we use
float
theta
=
acos
(
dot
(
N
,
V
)
);
// Parameterization of texture:
...
...
@@ -151,340 +140,84 @@ vec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughn
}
void
clipQuadToHorizon
(
inout
vec3
L
[
5
],
out
int
n
)
{
// detect clipping config
int
config
=
0
;
if
(
L
[
0
].
z
>
0
.
0
)
config
+=
1
;
if
(
L
[
1
].
z
>
0
.
0
)
config
+=
2
;
if
(
L
[
2
].
z
>
0
.
0
)
config
+=
4
;
if
(
L
[
3
].
z
>
0
.
0
)
config
+=
8
;
// clip
n
=
0
;
if
(
config
==
0
)
{
// clip all
}
else
if
(
config
==
1
)
{
// V1 clip V2 V3 V4
n
=
3
;
L
[
1
]
=
-
L
[
1
].
z
*
L
[
0
]
+
L
[
0
].
z
*
L
[
1
];
L
[
2
]
=
-
L
[
3
].
z
*
L
[
0
]
+
L
[
0
].
z
*
L
[
3
];
}
else
if
(
config
==
2
)
{
// V2 clip V1 V3 V4
n
=
3
;
L
[
0
]
=
-
L
[
0
].
z
*
L
[
1
]
+
L
[
1
].
z
*
L
[
0
];
L
[
2
]
=
-
L
[
2
].
z
*
L
[
1
]
+
L
[
1
].
z
*
L
[
2
];
}
else
if
(
config
==
3
)
{
// V1 V2 clip V3 V4
n
=
4
;
L
[
2
]
=
-
L
[
2
].
z
*
L
[
1
]
+
L
[
1
].
z
*
L
[
2
];
L
[
3
]
=
-
L
[
3
].
z
*
L
[
0
]
+
L
[
0
].
z
*
L
[
3
];
}
else
if
(
config
==
4
)
{
// V3 clip V1 V2 V4
n
=
3
;
L
[
0
]
=
-
L
[
3
].
z
*
L
[
2
]
+
L
[
2
].
z
*
L
[
3
];
L
[
1
]
=
-
L
[
1
].
z
*
L
[
2
]
+
L
[
2
].
z
*
L
[
1
];
}
else
if
(
config
==
5
)
{
// V1 V3 clip V2 V4) impossible
n
=
0
;
}
else
if
(
config
==
6
)
{
// V2 V3 clip V1 V4
n
=
4
;
L
[
0
]
=
-
L
[
0
].
z
*
L
[
1
]
+
L
[
1
].
z
*
L
[
0
];
L
[
3
]
=
-
L
[
3
].
z
*
L
[
2
]
+
L
[
2
].
z
*
L
[
3
];
}
else
if
(
config
==
7
)
{
// V1 V2 V3 clip V4
n
=
5
;
L
[
4
]
=
-
L
[
3
].
z
*
L
[
0
]
+
L
[
0
].
z
*
L
[
3
];
L
[
3
]
=
-
L
[
3
].
z
*
L
[
2
]
+
L
[
2
].
z
*
L
[
3
];
}
else
if
(
config
==
8
)
{
// V4 clip V1 V2 V3
n
=
3
;
L
[
0
]
=
-
L
[
0
].
z
*
L
[
3
]
+
L
[
3
].
z
*
L
[
0
];
L
[
1
]
=
-
L
[
2
].
z
*
L
[
3
]
+
L
[
3
].
z
*
L
[
2
];
L
[
2
]
=
L
[
3
];
}
else
if
(
config
==
9
)
{
// V1 V4 clip V2 V3
n
=
4
;
L
[
1
]
=
-
L
[
1
].
z
*
L
[
0
]
+
L
[
0
].
z
*
L
[
1
];
L
[
2
]
=
-
L
[
2
].
z
*
L
[
3
]
+
L
[
3
].
z
*
L
[
2
];
}
else
if
(
config
==
10
)
{
// V2 V4 clip V1 V3) impossible
n
=
0
;
}
else
if
(
config
==
11
)
{
// V1 V2 V4 clip V3
n
=
5
;
L
[
4
]
=
L
[
3
];
L
[
3
]
=
-
L
[
2
].
z
*
L
[
3
]
+
L
[
3
].
z
*
L
[
2
];
L
[
2
]
=
-
L
[
2
].
z
*
L
[
1
]
+
L
[
1
].
z
*
L
[
2
];
}
else
if
(
config
==
12
)
{
// V3 V4 clip V1 V2
n
=
4
;
L
[
1
]
=
-
L
[
1
].
z
*
L
[
2
]
+
L
[
2
].
z
*
L
[
1
];
L
[
0
]
=
-
L
[
0
].
z
*
L
[
3
]
+
L
[
3
].
z
*
L
[
0
];
}
else
if
(
config
==
13
)
{
// V1 V3 V4 clip V2
n
=
5
;
L
[
4
]
=
L
[
3
];
L
[
3
]
=
L
[
2
];
L
[
2
]
=
-
L
[
1
].
z
*
L
[
2
]
+
L
[
2
].
z
*
L
[
1
];
L
[
1
]
=
-
L
[
1
].
z
*
L
[
0
]
+
L
[
0
].
z
*
L
[
1
];
}
else
if
(
config
==
14
)
{
// V2 V3 V4 clip V1
n
=
5
;
L
[
4
]
=
-
L
[
0
].
z
*
L
[
3
]
+
L
[
3
].
z
*
L
[
0
];
L
[
0
]
=
-
L
[
0
].
z
*
L
[
1
]
+
L
[
1
].
z
*
L
[
0
];
}
else
if
(
config
==
15
)
{
// V1 V2 V3 V4
n
=
4
;
}
if
(
n
==
3
)
L
[
3
]
=
L
[
0
];
if
(
n
==
4
)
L
[
4
]
=
L
[
0
];
}
// Equation (11) of "Real-Time Polygonal-Light Shading with Linearly Transformed Cosines"
float
integrateLtcBrdfOverRectEdge
(
vec3
v1
,
vec3
v2
)
{
// Real-Time Area Lighting: a Journey from Research to Production
// By: Stephen Hill & Eric Heitz
// http://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf
// An approximation for the form factor of a clipped rectangle.
float
LTC_ClippedSphereFormFactor
(
const
in
vec3
f
)
{
float
cosTheta
=
dot
(
v1
,
v2
);
float
theta
=
acos
(
cosTheta
);
float
res
=
cross
(
v1
,
v2
).
z
*
(
(
theta
>
0
.
001
)
?
theta
/
sin
(
theta
)
:
1
.
0
);
float
l
=
length
(
f
);
return
res
;
return
max
(
(
l
*
l
+
f
.
z
)
/
(
l
+
1
.
0
),
0
.
0
)
;
}
void
initRectPoints
(
const
in
vec3
pos
,
const
in
vec3
halfWidth
,
const
in
vec3
halfHeight
,
out
vec3
rectPoints
[
4
]
)
{
// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
// also Real-Time Area Lighting: a Journey from Research to Production
// http://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf
// Normalization by 2*PI is incorporated in this function itself.
// theta/sin(theta) is approximated by rational polynomial
vec3
LTC_EdgeVectorFormFactor
(
const
in
vec3
v1
,
const
in
vec3
v2
)
{
rectPoints
[
0
]
=
pos
-
halfWidth
-
halfHeight
;
rectPoints
[
1
]
=
pos
+
halfWidth
-
halfHeight
;
rectPoints
[
2
]
=
pos
+
halfWidth
+
halfHeight
;
rectPoints
[
3
]
=
pos
-
halfWidth
+
halfHeight
;
float
x
=
dot
(
v1
,
v2
);
}
float
y
=
abs
(
x
);
float
a
=
0
.
86267
+
(
0
.
49788
+
0
.
01436
*
y
)
*
y
;
float
b
=
3
.
45068
+
(
4
.
18814
+
y
)
*
y
;
float
v
=
a
/
b
;
vec3
integrateLtcBrdfOverRect
(
const
in
GeometricContext
geometry
,
const
in
mat3
brdfMat
,
const
in
vec3
rectPoints
[
4
]
)
{
float
theta_sintheta
=
(
x
>
0
.
0
)
?
v
:
0
.
5
*
inversesqrt
(
1
.
0
-
x
*
x
)
-
v
;
vec3
N
=
geometry
.
normal
;
vec3
V
=
geometry
.
viewDir
;
vec3
P
=
geometry
.
position
;
// construct orthonormal basis around N
vec3
T1
,
T2
;
T1
=
normalize
(
V
-
N
*
dot
(
V
,
N
));
// TODO (abelnation): I had to negate this cross product to get proper light. Curious why sample code worked without negation
T2
=
-
cross
(
N
,
T1
);
// rotate area light in (T1, T2, N) basis
mat3
brdfWrtSurface
=
brdfMat
*
transpose
(
mat3
(
T1
,
T2
,
N
)
);
// transformed rect relative to surface point
vec3
clippedRect
[
5
];
clippedRect
[
0
]
=
brdfWrtSurface
*
(
rectPoints
[
0
]
-
P
);
clippedRect
[
1
]
=
brdfWrtSurface
*
(
rectPoints
[
1
]
-
P
);
clippedRect
[
2
]
=
brdfWrtSurface
*
(
rectPoints
[
2
]
-
P
);
clippedRect
[
3
]
=
brdfWrtSurface
*
(
rectPoints
[
3
]
-
P
);
// clip light rect to horizon, resulting in at most 5 points
// we do this because we are integrating the BRDF over the hemisphere centered on the surface points normal
int
n
;
clipQuadToHorizon
(
clippedRect
,
n
);
// light is completely below horizon
if
(
n
==
0
)
return
vec3
(
0
,
0
,
0
);
// project clipped rect onto sphere
clippedRect
[
0
]
=
normalize
(
clippedRect
[
0
]
);
clippedRect
[
1
]
=
normalize
(
clippedRect
[
1
]
);
clippedRect
[
2
]
=
normalize
(
clippedRect
[
2
]
);
clippedRect
[
3
]
=
normalize
(
clippedRect
[
3
]
);
clippedRect
[
4
]
=
normalize
(
clippedRect
[
4
]
);
// integrate
// simplified integration only needs to be evaluated for each edge in the polygon
float
sum
=
0
.
0
;
sum
+=
integrateLtcBrdfOverRectEdge
(
clippedRect
[
0
],
clippedRect
[
1
]
);
sum
+=
integrateLtcBrdfOverRectEdge
(
clippedRect
[
1
],
clippedRect
[
2
]
);
sum
+=
integrateLtcBrdfOverRectEdge
(
clippedRect
[
2
],
clippedRect
[
3
]
);
if
(
n
>=
4
)
sum
+=
integrateLtcBrdfOverRectEdge
(
clippedRect
[
3
],
clippedRect
[
4
]
);
if
(
n
==
5
)
sum
+=
integrateLtcBrdfOverRectEdge
(
clippedRect
[
4
],
clippedRect
[
0
]
);
// TODO (abelnation): two-sided area light
// sum = twoSided ? abs(sum) : max(0.0, sum);
sum
=
max
(
0
.
0
,
sum
);
// sum = abs( sum );
vec3
Lo_i
=
vec3
(
sum
,
sum
,
sum
);
return
Lo_i
/
(
2
.
0
*
PI
);
return
cross
(
v1
,
v2
)
*
theta_sintheta
;
}
/* From http://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf
Basically its an approximation for the form factor of a clipped rectangle.
*/
vec3
LTC_Evaluate
(
const
in
vec3
N
,
const
in
vec3
V
,
const
in
vec3
P
,
const
in
mat3
mInv
,
const
in
vec3
rectCoords
[
4
]
)
{
float
ClippedSphereFormFactor
(
const
in
vec3
f
)
{
float
l
=
length
(
f
);
return
max
((
l
*
l
+
f
.
z
)
/
(
l
+
1
.
0
),
0
.
0
);
}
// bail if point is on back side of plane of light
// assumes ccw winding order of light vertices
vec3
v1
=
rectCoords
[
1
]
-
rectCoords
[
0
];
vec3
v2
=
rectCoords
[
3
]
-
rectCoords
[
0
];
vec3
lightNormal
=
cross
(
v1
,
v2
);
/* From http://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf
Normalization by 2*PI is incorporated in this function itself.
This Normalization can be seen in Eq 11 of
https://drive.google.com/file/d/0BzvWIdpUpRx_d09ndGVjNVJzZjA/view
theta/sin(theta) is approximated by rational polynomial
*/
vec3
EdgeVectorFormFactor
(
const
in
vec3
v1
,
const
in
vec3
v2
)
{
float
x
=
dot
(
v1
,
v2
);
float
y
=
abs
(
x
);
float
a
=
0
.
86267
+
(
0
.
49788
+
0
.
01436
*
y
)
*
y
;
float
b
=
3
.
45068
+
(
4
.
18814
+
y
)
*
y
;
float
v
=
a
/
b
;
float
theta_sintheta
=
(
x
>
0
.
0
)
?
v
:
0
.
5
*
inversesqrt
(
1
.
0
-
x
*
x
)
-
v
;
return
cross
(
v1
,
v2
)
*
theta_sintheta
;
}
vec3
integrateLtcBrdfOverRectOptimized
(
const
in
GeometricContext
geometry
,
const
in
mat3
brdfMat
,
const
in
vec3
rectPoints
[
4
]
)
{
vec3
N
=
geometry
.
normal
;
vec3
V
=
geometry
.
viewDir
;
vec3
P
=
geometry
.
position
;
if
(
dot
(
lightNormal
,
P
-
rectCoords
[
0
]
)
<
0
.
0
)
return
vec3
(
0
.
0
);
// construct orthonormal basis around N
vec3
T1
,
T2
;
T1
=
normalize
(
V
-
N
*
dot
(
V
,
N
));
// TODO (abelnation): I had to negate this cross product to get proper light. Curious why sample code worked without negation
T2
=
-
cross
(
N
,
T1
);
// rotate area light in (T1, T2, N) basis
mat3
brdfWrtSurface
=
brdfMat
*
transpose
(
mat3
(
T1
,
T2
,
N
)
);
// transformed rect relative to surface point
vec3
clippedRect
[
4
];
clippedRect
[
0
]
=
brdfWrtSurface
*
(
rectPoints
[
0
]
-
P
);
clippedRect
[
1
]
=
brdfWrtSurface
*
(
rectPoints
[
1
]
-
P
);
clippedRect
[
2
]
=
brdfWrtSurface
*
(
rectPoints
[
2
]
-
P
);
clippedRect
[
3
]
=
brdfWrtSurface
*
(
rectPoints
[
3
]
-
P
);
// Find light normal
vec3
v1
=
clippedRect
[
1
]
-
clippedRect
[
0
];
vec3
v2
=
clippedRect
[
3
]
-
clippedRect
[
0
];
vec3
lightNormal
=
cross
(
v1
,
v2
);
bool
bSameSide
=
dot
(
lightNormal
,
clippedRect
[
0
])
>
0
.
0
;
if
(
!
bSameSide
)
return
vec3
(
0
.
0
);
// project clipped rect onto sphere
clippedRect
[
0
]
=
normalize
(
clippedRect
[
0
]
);
clippedRect
[
1
]
=
normalize
(
clippedRect
[
1
]
);
clippedRect
[
2
]
=
normalize
(
clippedRect
[
2
]
);
clippedRect
[
3
]
=
normalize
(
clippedRect
[
3
]
);
// Accumulate vector form factor
vec3
edgeVectorFormFactor
=
vec3
(
0
.
0
);
edgeVectorFormFactor
+=
EdgeVectorFormFactor
(
clippedRect
[
0
],
clippedRect
[
1
]
);
edgeVectorFormFactor
+=
EdgeVectorFormFactor
(
clippedRect
[
1
],
clippedRect
[
2
]
);
edgeVectorFormFactor
+=
EdgeVectorFormFactor
(
clippedRect
[
2
],
clippedRect
[
3
]
);
edgeVectorFormFactor
+=
EdgeVectorFormFactor
(
clippedRect
[
3
],
clippedRect
[
0
]
);
vec3
Lo_i
=
vec3
(
ClippedSphereFormFactor
(
edgeVectorFormFactor
)
);
return
Lo_i
;
}
vec3
Rect_Area_Light_Specular_Reflectance
(
const
in
GeometricContext
geometry
,
const
in
vec3
lightPos
,
const
in
vec3
lightHalfWidth
,
const
in
vec3
lightHalfHeight
,
const
in
float
roughness
,
const
in
sampler2D
ltcMat
,
const
in
sampler2D
ltcMag
)
{
vec3
rectPoints
[
4
];
initRectPoints
(
lightPos
,
lightHalfWidth
,
lightHalfHeight
,
rectPoints
);
T1
=
normalize
(
V
-
N
*
dot
(
V
,
N
)
);
T2
=
-
cross
(
N
,
T1
);
// negated from paper; possibly due to a different assumed handedness of world coordinate system
vec2
uv
=
ltcTextureCoords
(
geometry
,
roughness
);
// compute transform
mat3
mat
=
mInv
*
transpose
(
mat3
(
T1
,
T2
,
N
)
);
vec4
brdfLtcApproxParams
,
t
;
// transform rect
vec3
coords
[
4
];
coords
[
0
]
=
mat
*
(
rectCoords
[
0
]
-
P
);
coords
[
1
]
=
mat
*
(
rectCoords
[
1
]
-
P
);
coords
[
2
]
=
mat
*
(
rectCoords
[
2
]
-
P
);
coords
[
3
]
=
mat
*
(
rectCoords
[
3
]
-
P
);
brdfLtcApproxParams
=
texture2D
(
ltcMat
,
uv
);
t
=
texture2D
(
ltcMat
,
uv
);
// project rect onto sphere
coords
[
0
]
=
normalize
(
coords
[
0
]
);
coords
[
1
]
=
normalize
(
coords
[
1
]
);
coords
[
2
]
=
normalize
(
coords
[
2
]
);
coords
[
3
]
=
normalize
(
coords
[
3
]
);
float
brdfLtcScalar
=
texture2D
(
ltcMag
,
uv
).
a
;
// calculate vector form factor
vec3
vectorFormFactor
=
vec3
(
0
.
0
);
vectorFormFactor
+=
LTC_EdgeVectorFormFactor
(
coords
[
0
],
coords
[
1
]
);
vectorFormFactor
+=
LTC_EdgeVectorFormFactor
(
coords
[
1
],
coords
[
2
]
);
vectorFormFactor
+=
LTC_EdgeVectorFormFactor
(
coords
[
2
],
coords
[
3
]
);
vectorFormFactor
+=
LTC_EdgeVectorFormFactor
(
coords
[
3
],
coords
[
0
]
);
// inv(M) matrix referenced by equation (6) in paper
mat3
brdfLtcApproxMat
=
mat3
(
vec3
(
1
,
0
,
t
.
y
),
vec3
(
0
,
t
.
z
,
0
),
vec3
(
t
.
w
,
0
,
t
.
x
)
);
// adjust for horizon clipping
vec3
result
=
vec3
(
LTC_ClippedSphereFormFactor
(
vectorFormFactor
)
);
vec3
specularReflectance
=
integrateLtcBrdfOverRectOptimized
(
geometry
,
brdfLtcApproxMat
,
rectPoints
);
specularReflectance
*=
brdfLtcScalar
;
return
specularReflectance
;
return
result
;
}
vec3
Rect_Area_Light_Diffuse_Reflectance
(
const
in
GeometricContext
geometry
,
const
in
vec3
lightPos
,
const
in
vec3
lightHalfWidth
,
const
in
vec3
lightHalfHeight
)
{
vec3
rectPoints
[
4
];
initRectPoints
(
lightPos
,
lightHalfWidth
,
lightHalfHeight
,
rectPoints
);
mat3
diffuseBrdfMat
=
mat3
(
1
);
vec3
diffuseReflectance
=
integrateLtcBrdfOverRectOptimized
(
geometry
,
diffuseBrdfMat
,
rectPoints
);
return
diffuseReflectance
;
}
// End RectArea BRDF
// End Rect Area Light
// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
vec3
BRDF_Specular_GGX_Environment
(
const
in
GeometricContext
geometry
,
const
in
vec3
specularColor
,
const
in
float
roughness
)
{
...
...
src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl
浏览文件 @
1558bf0e
...
...
@@ -17,29 +17,42 @@ struct BlinnPhongMaterial {
};
#if NUM_RECT_AREA_LIGHTS > 0
void
RE_Direct_RectArea_BlinnPhong
(
const
in
RectAreaLight
rectAreaLight
,
const
in
GeometricContext
geometry
,
const
in
BlinnPhongMaterial
material
,
inout
ReflectedLight
reflectedLight
)
{
vec3
matDiffColor
=
material
.
diffuseColor
;
vec3
matSpecColor
=
material
.
specularColor
;
vec3
lightColor
=
rectAreaLight
.
color
;
void
RE_Direct_RectArea_BlinnPhong
(
const
in
RectAreaLight
rectAreaLight
,
const
in
GeometricContext
geometry
,
const
in
BlinnPhongMaterial
material
,
inout
ReflectedLight
reflectedLight
)
{
vec3
normal
=
geometry
.
normal
;
vec3
viewDir
=
geometry
.
viewDir
;
vec3
position
=
geometry
.
position
;
vec3
lightPos
=
rectAreaLight
.
position
;
vec3
halfWidth
=
rectAreaLight
.
halfWidth
;
vec3
halfHeight
=
rectAreaLight
.
halfHeight
;
vec3
lightColor
=
rectAreaLight
.
color
;
float
roughness
=
BlinnExponentToGGXRoughness
(
material
.
specularShininess
);
// Evaluate Lighting Equation
vec3
spec
=
Rect_Area_Light_Specular_Reflectance
(
geometry
,
rectAreaLight
.
position
,
rectAreaLight
.
halfWidth
,
rectAreaLight
.
halfHeight
,
roughness
,
ltcMat
,
ltcMag
);
vec3
diff
=
Rect_Area_Light_Diffuse_Reflectance
(
geometry
,
rectAreaLight
.
position
,
rectAreaLight
.
halfWidth
,
rectAreaLight
.
halfHeight
);
vec3
rectCoords
[
4
];
rectCoords
[
0
]
=
lightPos
-
halfWidth
-
halfHeight
;
// counterclockwise
rectCoords
[
1
]
=
lightPos
+
halfWidth
-
halfHeight
;
rectCoords
[
2
]
=
lightPos
+
halfWidth
+
halfHeight
;
rectCoords
[
3
]
=
lightPos
-
halfWidth
+
halfHeight
;
vec2
uv
=
LTC_Uv
(
normal
,
viewDir
,
roughness
);
float
norm
=
texture2D
(
ltcMag
,
uv
).
a
;
vec4
t
=
texture2D
(
ltcMat
,
uv
);
// division by 2 * PI is moved inside the above calls. This is essential as Eq (11) is having this normalization.
reflectedLight
.
directSpecular
+=
lightColor
*
matSpecColor
*
spec
;
reflectedLight
.
directDiffuse
+=
lightColor
*
matDiffColor
*
diff
;
mat3
mInv
=
mat3
(
vec3
(
1
,
0
,
t
.
y
),
vec3
(
0
,
t
.
z
,
0
),
vec3
(
t
.
w
,
0
,
t
.
x
)
);
reflectedLight
.
directSpecular
+=
lightColor
*
material
.
specularColor
*
norm
*
LTC_Evaluate
(
normal
,
viewDir
,
position
,
mInv
,
rectCoords
);
// no fresnel
reflectedLight
.
directDiffuse
+=
lightColor
*
material
.
diffuseColor
*
LTC_Evaluate
(
normal
,
viewDir
,
position
,
mat3
(
1
),
rectCoords
);
}
#endif
void
RE_Direct_BlinnPhong
(
const
in
IncidentLight
directLight
,
const
in
GeometricContext
geometry
,
const
in
BlinnPhongMaterial
material
,
inout
ReflectedLight
reflectedLight
)
{
...
...
@@ -62,6 +75,7 @@ void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in Geometri
#endif
reflectedLight
.
directDiffuse
+=
irradiance
*
BRDF_Diffuse_Lambert
(
material
.
diffuseColor
);
reflectedLight
.
directSpecular
+=
irradiance
*
BRDF_Specular_BlinnPhong
(
directLight
,
geometry
,
material
.
specularColor
,
material
.
specularShininess
)
*
material
.
specularStrength
;
}
...
...
src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl
浏览文件 @
1558bf0e
...
...
@@ -22,27 +22,42 @@ float clearCoatDHRApprox( const in float roughness, const in float dotNL ) {
}
#if NUM_RECT_AREA_LIGHTS > 0
void
RE_Direct_RectArea_Physical
(
const
in
RectAreaLight
rectAreaLight
,
const
in
GeometricContext
geometry
,
const
in
PhysicalMaterial
material
,
inout
ReflectedLight
reflectedLight
)
{
vec3
matDiffColor
=
material
.
diffuseColor
;
vec3
matSpecColor
=
material
.
specularColor
;
vec3
lightColor
=
rectAreaLight
.
color
;
vec3
normal
=
geometry
.
normal
;
vec3
viewDir
=
geometry
.
viewDir
;
vec3
position
=
geometry
.
position
;
vec3
lightPos
=
rectAreaLight
.
position
;
vec3
halfWidth
=
rectAreaLight
.
halfWidth
;
vec3
halfHeight
=
rectAreaLight
.
halfHeight
;
vec3
lightColor
=
rectAreaLight
.
color
;
float
roughness
=
material
.
specularRoughness
;
vec3
spec
=
Rect_Area_Light_Specular_Reflectance
(
geometry
,
rectAreaLight
.
position
,
rectAreaLight
.
halfWidth
,
rectAreaLight
.
halfHeight
,
roughness
,
ltcMat
,
ltcMag
);
vec3
diff
=
Rect_Area_Light_Diffuse_Reflectance
(
geometry
,
rectAreaLight
.
position
,
rectAreaLight
.
halfWidth
,
rectAreaLight
.
halfHeight
);
vec3
rectCoords
[
4
];
rectCoords
[
0
]
=
lightPos
-
halfWidth
-
halfHeight
;
// counterclockwise
rectCoords
[
1
]
=
lightPos
+
halfWidth
-
halfHeight
;
rectCoords
[
2
]
=
lightPos
+
halfWidth
+
halfHeight
;
rectCoords
[
3
]
=
lightPos
-
halfWidth
+
halfHeight
;
vec2
uv
=
LTC_Uv
(
normal
,
viewDir
,
roughness
);
float
norm
=
texture2D
(
ltcMag
,
uv
).
a
;
vec4
t
=
texture2D
(
ltcMat
,
uv
);
// division by 2 * PI is inside the above calls. This is essential as Eq (11) is having this normalization.
reflectedLight
.
directSpecular
+=
lightColor
*
matSpecColor
*
spec
;
reflectedLight
.
directDiffuse
+=
lightColor
*
matDiffColor
*
diff
;
mat3
mInv
=
mat3
(
vec3
(
1
,
0
,
t
.
y
),
vec3
(
0
,
t
.
z
,
0
),
vec3
(
t
.
w
,
0
,
t
.
x
)
);
reflectedLight
.
directSpecular
+=
lightColor
*
material
.
specularColor
*
norm
*
LTC_Evaluate
(
normal
,
viewDir
,
position
,
mInv
,
rectCoords
);
// no fresnel
reflectedLight
.
directDiffuse
+=
lightColor
*
material
.
diffuseColor
*
LTC_Evaluate
(
normal
,
viewDir
,
position
,
mat3
(
1
),
rectCoords
);
}
#endif
void
RE_Direct_Physical
(
const
in
IncidentLight
directLight
,
const
in
GeometricContext
geometry
,
const
in
PhysicalMaterial
material
,
inout
ReflectedLight
reflectedLight
)
{
...
...
@@ -64,6 +79,7 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricC
#endif
reflectedLight
.
directSpecular
+=
(
1
.
0
-
clearCoatDHR
)
*
irradiance
*
BRDF_Specular_GGX
(
directLight
,
geometry
,
material
.
specularColor
,
material
.
specularRoughness
);
reflectedLight
.
directDiffuse
+=
(
1
.
0
-
clearCoatDHR
)
*
irradiance
*
BRDF_Diffuse_Lambert
(
material
.
diffuseColor
);
#ifndef STANDARD
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录