summaryrefslogtreecommitdiff
path: root/graphics/asymptote/base/webgl/WebGLheader.html
blob: ac2f08390107f0271b50867107a6e73f61f969ae (plain)
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
181
182
183
184
185
186
187
188
<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;
#if nlights > 0
    emissive=vec4(0.0);
#else
    emissive=color;
#endif
  }
#else
  m=Materials[int(materialIndex)];
#ifdef COLOR
  diffuse=color;
#if nlights > 0
  emissive=vec4(0.0);
#else
  emissive=color;
#endif
#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)
{
#if defined(NORMAL) && nlights > 0
  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>