ts-game-engine
Version:
Simple WebGL game/render engine written in TypeScript
139 lines (120 loc) • 7.29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Material_1 = require("./Material");
const gl_matrix_1 = require("gl-matrix");
const Constants_1 = require("../Constants");
const Texture2D_1 = require("../Textures/Texture2D");
class BlinnPhongMaterial extends Material_1.Material {
constructor(scene) {
super(scene, vsSource, fsSource);
this.Shader.DefineUniform(Constants_1.MODEL_MATRIX_UNIFORM, 10 /* Matrix4 */);
this.Shader.DefineUniform(Constants_1.VIEW_MATRIX_UNIFORM, 10 /* Matrix4 */);
this.Shader.DefineUniform(Constants_1.PROJECTION_MATRIX_UNIFORM, 10 /* Matrix4 */);
this.Shader.DefineUniform(Constants_1.NORMAL_MATRIX_UNIFORM, 9 /* Matrix3 */);
this.Shader.DefineUniform(Constants_1.VIEW_POSITION_UNIFORM, 5 /* Float3 */);
this.Shader.DefineUniform(Constants_1.AMBIENT_LIGHT_UNIFORM, 5 /* Float3 */);
this.Shader.DefineUniform(Constants_1.POINT_LIGHTS_DATA_UNIFORM, 8 /* Float4Vector */);
this.Shader.DefineUniform(Constants_1.POINT_LIGHTS_COUNT_UNIFORM, 0 /* Int1 */);
this.Shader.DefineUniform("uColor", 5 /* Float3 */);
this.Shader.DefineUniform("uMainTexture", 11 /* Sampler2D */);
this.Shader.DefineUniform("uSpecularPower", 3 /* Float2 */);
this.Shader.DefineUniform("uGlossTexture", 11 /* Sampler2D */);
this.color = gl_matrix_1.vec3.fromValues(1, 1, 1);
this.specularPower = gl_matrix_1.vec2.fromValues(1, 32);
this.mainTexture = Texture2D_1.Texture2D.GetBlank(scene);
this.glossTexture = Texture2D_1.Texture2D.GetBlank(scene);
}
get Color() { return this.color; }
set Color(color) { this.color = color; }
get Specular() { return this.specularPower[0]; }
set Specular(specular) { this.specularPower[0] = specular; }
get SpecularPower() { return this.specularPower[1]; }
set SpecularPower(power) { this.specularPower[1] = power; }
get MainTexture() { return this.mainTexture; }
set MainTexture(texture2D) { this.mainTexture = texture2D; }
get GlossTexture() { return this.glossTexture; }
set GlossTexture(texture2D) { this.glossTexture = texture2D; }
SetUniforms(globalUniforms) {
this.Shader.SetMatrix4Uniform(Constants_1.MODEL_MATRIX_UNIFORM, globalUniforms.modelMatrix);
this.Shader.SetMatrix4Uniform(Constants_1.VIEW_MATRIX_UNIFORM, globalUniforms.viewMatrix);
this.Shader.SetMatrix4Uniform(Constants_1.PROJECTION_MATRIX_UNIFORM, globalUniforms.projectionMatrix);
this.Shader.SetMatrix3Uniform(Constants_1.NORMAL_MATRIX_UNIFORM, globalUniforms.normalMatrix);
this.Shader.SetFloat3Uniform(Constants_1.VIEW_POSITION_UNIFORM, globalUniforms.viewPosition);
this.Shader.SetFloat3Uniform(Constants_1.AMBIENT_LIGHT_UNIFORM, globalUniforms.ambientLight);
this.Shader.SetFloat4VectorUniform(Constants_1.POINT_LIGHTS_DATA_UNIFORM, globalUniforms.pointLightsData);
this.Shader.SetInt1Uniform(Constants_1.POINT_LIGHTS_COUNT_UNIFORM, globalUniforms.pointLightsCount);
this.Shader.SetFloat3Uniform("uColor", this.color);
this.Shader.SetFloat2Uniform("uSpecularPower", this.specularPower);
this.Shader.SetSamplerUniform("uMainTexture", 0, this.mainTexture, 3553 /* Texture2D */);
this.Shader.SetSamplerUniform("uGlossTexture", 1, this.glossTexture, 3553 /* Texture2D */);
}
}
exports.BlinnPhongMaterial = BlinnPhongMaterial;
const vsSource = `#version 300 es
layout(location = ${Constants_1.POSITION_ATTRIBUTE_LOCATION}) in vec3 ${Constants_1.POSITION_ATTRIBUTE};
layout(location = ${Constants_1.COLOR_ATTRIBUTE_LOCATION}) in vec4 ${Constants_1.COLOR_ATTRIBUTE};
layout(location = ${Constants_1.NORMAL_ATTRIBUTE_LOCATION}) in vec3 ${Constants_1.NORMAL_ATTRIBUTE};
layout(location = ${Constants_1.UV0_ATTRIBUTE_LOCATION}) in vec2 ${Constants_1.UV0_ATTRIBUTE};
uniform mat4 ${Constants_1.MODEL_MATRIX_UNIFORM};
uniform mat4 ${Constants_1.VIEW_MATRIX_UNIFORM};
uniform mat4 ${Constants_1.PROJECTION_MATRIX_UNIFORM};
uniform mat3 ${Constants_1.NORMAL_MATRIX_UNIFORM};
out vec4 vWorldPosition;
out vec3 vWorldNormal;
out vec4 vColor;
out vec2 vUV0;
void main() {
vec4 worldPosition = ${Constants_1.MODEL_MATRIX_UNIFORM} * vec4(${Constants_1.POSITION_ATTRIBUTE}, 1);
gl_Position = ${Constants_1.PROJECTION_MATRIX_UNIFORM} * ${Constants_1.VIEW_MATRIX_UNIFORM} * worldPosition;
vWorldPosition = worldPosition;
vWorldNormal = ${Constants_1.NORMAL_MATRIX_UNIFORM} * ${Constants_1.NORMAL_ATTRIBUTE};
vColor = ${Constants_1.COLOR_ATTRIBUTE};
vUV0 = ${Constants_1.UV0_ATTRIBUTE};
}`;
const fsSource = `#version 300 es
precision mediump float;
in vec4 vWorldPosition;
in vec3 vWorldNormal;
in vec4 vColor;
in vec2 vUV0;
uniform vec3 ${Constants_1.VIEW_POSITION_UNIFORM};
uniform vec3 ${Constants_1.AMBIENT_LIGHT_UNIFORM};
uniform vec4 ${Constants_1.POINT_LIGHTS_DATA_UNIFORM}[${Constants_1.MAX_LIGHTS} * ${Constants_1.LIGHT_DATA_SIZE}];
uniform int ${Constants_1.POINT_LIGHTS_COUNT_UNIFORM};
uniform vec3 uColor;
uniform sampler2D uMainTexture;
uniform vec2 uSpecularPower;
uniform sampler2D uGlossTexture;
out vec4 fragColor;
#define POINT_LIGHT_CONSTANT 1.0
#define POINT_LIGHT_LINEAR 0.22
#define POINT_LIGHT_QUADRATIC 0.20
vec3 CalcPointLight(vec3 lightPosition, float lightIntensity, vec3 lightColor, vec3 diffuse, float specularStrength, float specularPower, vec3 worldNormal, vec3 viewDir)
{
float distance = length(lightPosition - vWorldPosition.xyz);
vec3 lightDir = normalize(lightPosition - vWorldPosition.xyz);
vec3 halfwayDir = normalize(lightDir + viewDir);
float attenuation = 1.0 / (POINT_LIGHT_CONSTANT + POINT_LIGHT_LINEAR * distance + POINT_LIGHT_QUADRATIC * (distance * distance));
vec3 light = diffuse * max(dot(worldNormal, lightDir), 0.0);
light *= attenuation * lightIntensity;
float specular = pow(max(dot(worldNormal, halfwayDir), 0.0), specularPower);
specular *= specularStrength * attenuation * lightIntensity;
return (light + vec3(specular, specular, specular)) * lightColor;
}
void main() {
vec3 normalizedWorldNormal = normalize(vWorldNormal);
vec3 viewDir = normalize(${Constants_1.VIEW_POSITION_UNIFORM} - vWorldPosition.xyz);
vec3 diffuseColor = (texture(uMainTexture, vUV0).rgb * vColor.rgb * uColor).rgb;
float specularTex = texture(uGlossTexture, vUV0).x;
float specularStrength = mix(0.25, uSpecularPower.x, specularTex);
float specularPower = mix(1.0, uSpecularPower.y, specularTex);
vec3 lights = vec3(0, 0, 0);
for(int i = 0; i < ${Constants_1.MAX_LIGHTS}; i++)
{
if(i >= ${Constants_1.POINT_LIGHTS_COUNT_UNIFORM}) break;
vec4 lightPositionIntensity = ${Constants_1.POINT_LIGHTS_DATA_UNIFORM}[i * ${Constants_1.LIGHT_DATA_SIZE}];
vec4 lightColor = ${Constants_1.POINT_LIGHTS_DATA_UNIFORM}[i * ${Constants_1.LIGHT_DATA_SIZE} + 1];
lights += CalcPointLight(lightPositionIntensity.xyz, lightPositionIntensity.w, lightColor.rgb, diffuseColor, specularStrength, specularPower, normalizedWorldNormal, viewDir);
}
fragColor = vec4(lights + ${Constants_1.AMBIENT_LIGHT_UNIFORM} * diffuseColor, 1);
}`;