shaders = {
const vs = `#version 300 es
in vec3 position; // Attribute
in vec3 normal; // Attribute
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform float aspect;
out vec3 fragPosition;
out vec3 fragNormal;
uniform vec3 offsets[3];
void main(){
vec4 newPos = modelMatrix*vec4(position,1);
fragPosition = newPos.xyz;
gl_Position = projMatrix*viewMatrix*newPos;
mat4 normalMatrix = transpose(inverse(modelMatrix));
fragNormal = (normalMatrix * vec4(normal, 0.0) ).xyz;
}`;
const fs = `#version 300 es
precision mediump float;
out vec4 outColor;
in vec3 fragPosition;
in vec3 fragNormal;
uniform vec4 lightPosOrDir;
uniform vec3 eyePosition;
uniform float ambientIntensity;
uniform float K_s;
uniform vec3 materialColor;
uniform vec3 material;
uniform float roughness;
uniform float anisotropy;
uniform bool enableAnisotropy;
float PI = 3.14f;
float square(float x)
{
return pow(x, 2.0);
}
vec3 fresnelTerm(vec3 N, vec3 L)
{
vec3 F0 = material;
float NdotL = dot(N,L);
NdotL = clamp(NdotL, 0.0, 1.0);
vec3 F = F0 + (1.0 - F0) * pow(1.0 - NdotL , 5.0);
return F;
}
float distributionTerm(vec3 N, vec3 H)
{
float r = pow(roughness, 2.0);
float NdotH = clamp(dot(N,H), 0.0, 1.0);
float D = r/( PI * square( square(NdotH)*(r-1.0) + 1.0 ) );
return D;
}
float geometryTerm(vec3 N, vec3 V, vec3 L)
{
float r = square(roughness);
float NdotV = dot(N,V);
float NdotL = dot(N,L);
NdotV = clamp(NdotV, 0.0, 1.0);
NdotL = clamp(NdotL, 0.0, 1.0);
float Gv = NdotV / (NdotV*(1.0-r*0.5) + r);
float Gl = NdotL / (NdotL*(1.0-r*0.5) + r);
float G = Gv * Gl;
return G;
}
float anisotropicDistribution(vec3 N, vec3 H)
{
vec3 A = normalize(cross(N, N-vec3(1,0,0)));
vec3 B = normalize(cross(N, A));
vec3 T = normalize(cross(B, N));
float at = max(roughness * (1.0 + anisotropy), 0.001);
float ab = max(roughness * (1.0 - anisotropy), 0.001);
float a2 = at*ab;
float NdotH = dot(N,H);
float TdotH = dot(T,H);
float BdotH = dot(B,H);
float Dani = (square(at*ab))/ ( PI * (square(at*TdotH) + square(ab*BdotH) + square(a2*square(NdotH)) ));
return Dani;
}
void main(){
vec3 N = normalize(fragNormal);
vec3 L;
if (lightPosOrDir.w==0.0){
L = normalize(lightPosOrDir.xyz);
}
else{
L = normalize(lightPosOrDir.xyz-fragPosition);
}
vec3 V = normalize(eyePosition-fragPosition);
vec3 H = normalize(L+V);
vec3 ambient = ambientIntensity*materialColor;
vec3 diffuse = materialColor * clamp(dot(L,N), 0.0, 1.0);
// compute F : fresnel term
vec3 F = fresnelTerm(N, L);
// compute G: Geometry term
float G = geometryTerm(N, V, L);
// compute D: Distribution term
float D;
if (enableAnisotropy==true)
D = anisotropicDistribution(N, H);
else
D = distributionTerm(N, H);
vec3 microfacet = F*G*D;
vec3 color = ambient + (1.0-K_s)*diffuse + K_s*microfacet;
outColor = vec4(color, 1.0);
}`;
return [vs, fs];
}