UNPKG

ts-game-engine

Version:

Simple WebGL game/render engine written in TypeScript

139 lines (120 loc) 7.29 kB
"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); }`;