1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="user-scalable=no"/>
<script id="vertex" type="x-shader/x-vertex">
attribute vec3 position;
#ifdef WIDTH
attribute float width;
#endif
#ifdef NORMAL
attribute vec3 normal;
#endif
attribute float materialIndex;
#ifdef COLOR
attribute vec4 color;
#endif
uniform mat3 normMat;
uniform mat4 viewMat;
uniform mat4 projViewMat;
#ifdef NORMAL
#ifndef ORTHOGRAPHIC
varying vec3 ViewPosition;
#endif
varying vec3 Normal;
#endif
varying vec4 diffuse;
varying vec3 specular;
varying float roughness,metallic,fresnel0;
varying vec4 emissive;
struct Material {
vec4 diffuse,emissive,specular;
float shininess,metallic,fresnel0;
};
uniform Material Materials[nMaterials];
void main(void)
{
vec4 v=vec4(position,1.0);
gl_Position=projViewMat*v;
#ifdef NORMAL
#ifndef ORTHOGRAPHIC
ViewPosition=(viewMat*v).xyz;
#endif
Normal=normal*normMat;
Material m;
#ifdef TRANSPARENT
m=Materials[int(abs(materialIndex))-1];
if(materialIndex >= 0.0) {
diffuse=m.diffuse;
emissive=m.emissive;
} else {
diffuse=color;
emissive=vec4(0.0);
}
#else
m=Materials[int(materialIndex)];
#ifdef COLOR
diffuse=color;
emissive=vec4(0.0);
#else
diffuse=m.diffuse;
emissive=m.emissive;
#endif
#endif
specular=m.specular.rgb;
roughness=1.0-m.shininess;
metallic=m.metallic;
fresnel0=m.fresnel0;
#else
emissive=Materials[int(materialIndex)].emissive;
#endif
#ifdef WIDTH
gl_PointSize=width;
#endif
}
</script>
<script id="fragment" type="x-shader/x-fragment">
#ifdef NORMAL
#ifndef ORTHOGRAPHIC
varying vec3 ViewPosition;
#endif
varying vec3 Normal;
varying vec4 diffuse;
varying vec3 specular;
varying float roughness,metallic,fresnel0;
float Roughness2;
vec3 normal;
struct Light {
vec3 direction;
vec3 color;
};
uniform Light Lights[nLights];
float NDF_TRG(vec3 h)
{
float ndoth=max(dot(normal,h),0.0);
float alpha2=Roughness2*Roughness2;
float denom=ndoth*ndoth*(alpha2-1.0)+1.0;
return denom != 0.0 ? alpha2/(denom*denom) : 0.0;
}
float GGX_Geom(vec3 v)
{
float ndotv=max(dot(v,normal),0.0);
float ap=1.0+Roughness2;
float k=0.125*ap*ap;
return ndotv/((ndotv*(1.0-k))+k);
}
float Geom(vec3 v, vec3 l)
{
return GGX_Geom(v)*GGX_Geom(l);
}
float Fresnel(vec3 h, vec3 v, float fresnel0)
{
float a=1.0-max(dot(h,v),0.0);
float b=a*a;
return fresnel0+(1.0-fresnel0)*b*b*a;
}
// physical based shading using UE4 model.
vec3 BRDF(vec3 viewDirection, vec3 lightDirection)
{
vec3 lambertian=diffuse.rgb;
vec3 h=normalize(lightDirection+viewDirection);
float omegain=max(dot(viewDirection,normal),0.0);
float omegali=max(dot(lightDirection,normal),0.0);
float D=NDF_TRG(h);
float G=Geom(viewDirection,lightDirection);
float F=Fresnel(h,viewDirection,fresnel0);
float denom=4.0*omegain*omegali;
float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;
vec3 dielectric=mix(lambertian,rawReflectance*specular,F);
vec3 metal=rawReflectance*diffuse.rgb;
return mix(dielectric,metal,metallic);
}
#endif
varying vec4 emissive;
void main(void)
{
#ifdef NORMAL
normal=normalize(Normal);
normal=gl_FrontFacing ? normal : -normal;
#ifdef ORTHOGRAPHIC
vec3 viewDir=vec3(0.0,0.0,1.0);
#else
vec3 viewDir=-normalize(ViewPosition);
#endif
Roughness2=roughness*roughness;
vec3 color=emissive.rgb;
for (int i=0; i < nLights; ++i) {
Light Li=Lights[i];
vec3 L=Li.direction;
float cosTheta=max(dot(normal,L),0.0);
vec3 radiance=cosTheta*Li.color;
color += BRDF(viewDir,L)*radiance;
}
gl_FragColor=vec4(color,diffuse.a);
#else
gl_FragColor=emissive;
#endif
}
</script>
|