Shapes multiple point lights realized. I suppose multiple lighting model is wrong, check it out.

This commit is contained in:
Zemledelec 2014-08-28 18:54:55 +04:00
parent 002575230e
commit bf42bffe5c
11 changed files with 313 additions and 109 deletions

View File

@ -0,0 +1,94 @@
goog.provide('og.light.PointLight');
goog.require('og.math.Vector3');
og.light.PointLight = function (name, position, ambient, diffuse, specular, shininess) {
this._name = name || ("p" + og.light.PointLight._counter++);
this._renderNode = null;
this._position = position || new og.math.Vector3()
this._ambient = ambient || new og.math.Vector3();
this._diffuse = diffuse || new og.math.Vector3(0.8, 0.8, 0.8);
this._specular = specular || new og.math.Vector3(0.18, 0.18, 0.18);
this._shininess = shininess || 3.3;
};
og.light.PointLight._counter = 0;
og.light.PointLight.prototype.setPosition = function (position) {
this._position = position;
return this;
};
og.light.PointLight.prototype.setAmbient = function (rgb) {
this._ambient = rgb;
var rn = this._renderNode;
var index = 9 * rn._pointLightsNames.indexOf(this._name);
rn._pointLightsParamsv[index] = rgb.x;
rn._pointLightsParamsv[index + 1] = rgb.y;
rn._pointLightsParamsv[index + 2] = rgb.z;
return this;
};
og.light.PointLight.prototype.setDiffuse = function (rgb) {
this._diffuse = rgb;
var rn = this._renderNode;
var index = 9 * rn._pointLightsNames.indexOf(this._name);
rn._pointLightsParamsv[index + 3] = rgb.x;
rn._pointLightsParamsv[index + 4] = rgb.y;
rn._pointLightsParamsv[index + 5] = rgb.z;
return this;
};
og.light.PointLight.prototype.setSpecular = function (rgb) {
this._specular = rgb;
var rn = this._renderNode;
var index = 9 * rn._pointLightsNames.indexOf(this._name);
rn._pointLightsParamsv[index + 6] = rgb.x;
rn._pointLightsParamsv[index + 7] = rgb.y;
rn._pointLightsParamsv[index + 8] = rgb.z;
return this;
};
og.light.PointLight.prototype.setShininess = function (shininess) {
this._shininess = shininess;
var rn = this._renderNode;
rn._pointLightsParamsf[rn._pointLightsNames.indexOf(this._name)] = shininess;
return this;
};
og.light.PointLight.prototype.setBlack = function () {
this._ambient.clear();
this._diffuse.clear();
this._specular.clear();
this._shininess = 0;
var rn = this._renderNode;
var index = 9 * rn._pointLightsNames.indexOf(this._name);
rn._pointLightsParamsv[index] = rn._pointLightsParamsv[index + 1] = rn._pointLightsParamsv[index + 2] =
rn._pointLightsParamsv[index + 3] = rn._pointLightsParamsv[index + 4] = rn._pointLightsParamsv[index + 5] =
rn._pointLightsParamsv[index + 6] = rn._pointLightsParamsv[index + 7] = rn._pointLightsParamsv[index + 8] = 0;
return this;
};
og.light.PointLight.prototype.addTo = function (renderNode) {
this._renderNode = renderNode;
renderNode._pointLights.push(this);
renderNode._pointLightsNames.push(this._name);
renderNode._pointLightsParamsf.push(this._shininess);
renderNode._pointLightsParamsv.push.apply(renderNode._pointLightsParamsv, this._ambient.toVec());
renderNode._pointLightsParamsv.push.apply(renderNode._pointLightsParamsv, this._diffuse.toVec());
renderNode._pointLightsParamsv.push.apply(renderNode._pointLightsParamsv, this._specular.toVec());
return this;
};
og.light.PointLight.prototype.remove = function () {
var rn = this.renderNode;
var li = rn.getLightById(this._name);
rn._pointLights.splice(li, 1);
rn._pointLightsNames.splice(li, 1);
rn._pointLightsParamsf.splice(li, 1);
rn._pointLightsParamsv.splice(li, 9);//3*3
this._renderNode = null;
};

View File

@ -20,20 +20,42 @@ og.node.RenderNode = function (name) {
this.translationMatrix = new og.math.Matrix4().setIdentity();
this.transformationMatrix = new og.math.Matrix4().setIdentity();
this.itransformationMatrix = new og.math.Matrix4().setIdentity();
this._pointLights = [];
this._pointLightsParamsv = [];
this._pointLightsParamsf = [];
this._pointLightsNames = [];
};
og.inheritance.extend(og.node.RenderNode, og.node.Node);
og.node.RenderNode.prototype.addLight = function (light) {
light.addTo(this);
return light;
};
og.node.RenderNode.prototype.getLightByName = function(name){
var li = this._pointLightsNames.indexOf(name);
return this._pointLights[li];
};
og.node.RenderNode.prototype.removeLight = function (light) {
light.remove();
};
og.node.RenderNode.prototype.setScale = function (xyz) {
this.scaleMatrix.scale(xyz);
return this;
};
og.node.RenderNode.prototype.setOrigin = function (origin) {
this.translationMatrix.translate(origin);
return this;
};
og.node.RenderNode.prototype.setAngles = function (ax, ay, az) {
this.rotationMatrix.eulerToMatrix(ax, ay, az);
return this;
};
og.node.RenderNode.prototype.updateMatrices = function () {

View File

@ -1,23 +1,22 @@
goog.provide('og.shaderProgram.shape');
goog.provide('og.shaderProgram.shape_wl');
goog.provide('og.shaderProgram.shape_nl');
goog.require('og.shaderProgram');
goog.require('og.shaderProgram.ShaderProgram');
goog.require('og.shaderProgram.types');
goog.require('og.utils');
og.shaderProgram.shape = function () {
return new og.shaderProgram.ShaderProgram("shape", {
og.shaderProgram.shape_wl = function () {
return new og.shaderProgram.ShaderProgram("shape_wl", {
uniforms: {
uMVMatrix: { type: og.shaderProgram.types.MAT4 },
uPMatrix: { type: og.shaderProgram.types.MAT4 },
uTRSMatrix: { type: og.shaderProgram.types.MAT4 },
uNMatrix: { type: og.shaderProgram.types.MAT4 },
uAmbientColor: { type: og.shaderProgram.types.VEC3 },
uPointLightingLocation: { type: og.shaderProgram.types.VEC3 },
uPointLightingSpecularColor: { type: og.shaderProgram.types.VEC3 },
uPointLightingDiffuseColor: { type: og.shaderProgram.types.VEC3 },
uMaterialShininess: { type: og.shaderProgram.types.FLOAT },
pointLightsPositions:{ type: og.shaderProgram.types.VEC3 },
pointLightsParamsv: { type: og.shaderProgram.types.VEC3 },
pointLightsParamsf: { type: og.shaderProgram.types.FLOAT },
uColor: { type: og.shaderProgram.types.VEC4 }
},
@ -25,7 +24,22 @@ og.shaderProgram.shape = function () {
aVertexNormal: { type: og.shaderProgram.types.VEC3, enableArray: true },
aVertexPosition: { type: og.shaderProgram.types.VEC3, enableArray: true }
},
vertexShader: og.utils.readTextFile(og.shaderProgram.SHADERS_URL + "shape_vs.txt"),
fragmentShader: og.utils.readTextFile(og.shaderProgram.SHADERS_URL + "shape_fs.txt")
vertexShader: og.utils.readTextFile(og.shaderProgram.SHADERS_URL + "shape_wl_vs.txt"),
fragmentShader: og.utils.readTextFile(og.shaderProgram.SHADERS_URL + "shape_wl_fs.txt")
});
};
og.shaderProgram.shape_nl = function () {
return new og.shaderProgram.ShaderProgram("shape_nl", {
uniforms: {
uPMVMatrix: { type: og.shaderProgram.types.MAT4 },
uTRSMatrix: { type: og.shaderProgram.types.MAT4 },
uColor: { type: og.shaderProgram.types.VEC4 }
},
attributes: {
aVertexPosition: { type: og.shaderProgram.types.VEC3, enableArray: true }
},
vertexShader: og.utils.readTextFile(og.shaderProgram.SHADERS_URL + "shape_nl_vs.txt"),
fragmentShader: og.utils.readTextFile(og.shaderProgram.SHADERS_URL + "shape_nl_fs.txt")
});
};

View File

@ -1,44 +0,0 @@
precision mediump float;
//varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
varying mat4 umv;
uniform float uMaterialShininess;
uniform vec4 uColor;
uniform vec3 uAmbientColor;
varying vec3 vTransformedLightLocation;
uniform vec3 uPointLightingSpecularColor;
uniform vec3 uPointLightingDiffuseColor;
void main(void) {
vec3 lightWeighting;
vec3 lightDirection = normalize(vTransformedLightLocation - vPosition.xyz);
vec3 normal = normalize(vTransformedNormal);
float specularLightWeighting = 0.0;
vec3 eyeDirection = normalize(-vPosition.xyz);
vec3 reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), uMaterialShininess);
float diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting = uAmbientColor
+ uPointLightingSpecularColor * specularLightWeighting
+ uPointLightingDiffuseColor * diffuseLightWeighting;
vec4 fragmentColor;
fragmentColor = uColor;
gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a);
}

View File

@ -0,0 +1,6 @@
precision mediump float;
uniform vec4 uColor;
void main(void) {
gl_FragColor = uColor;
}

View File

@ -0,0 +1,8 @@
attribute vec3 aVertexPosition;
uniform mat4 uPMVMatrix;
uniform mat4 uTRSMatrix;
void main(void) {
gl_Position = uPMVMatrix * (uTRSMatrix * vec4(aVertexPosition, 1.0));
}

View File

@ -1,25 +0,0 @@
attribute vec3 aVertexNormal;
attribute vec3 aVertexPosition;
//attribute vec2 aTextureCoord;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
uniform mat4 uTRSMatrix;
uniform mat3 uNMatrix;
uniform vec3 uPointLightingLocation;
varying vec3 vTransformedLightLocation;
//varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
void main(void) {
vPosition = uMVMatrix * uTRSMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * vPosition;
vTransformedLightLocation = (uMVMatrix * vec4(uPointLightingLocation, 1.0)).xyz;
vTransformedNormal = uNMatrix * aVertexNormal;
//vTextureCoord = aTextureCoord;
}

View File

@ -0,0 +1,80 @@
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
uniform vec4 uColor;
#define MAX_POINT_LIGHTS 5
uniform int pointLightsQuantity;
uniform vec3 pointLightsPositions[MAX_POINT_LIGHTS];
uniform vec3 pointLightsParamsv[MAX_POINT_LIGHTS * 3];
uniform float pointLightsParamsf[MAX_POINT_LIGHTS];
void main(void) {
vec3 lightWeighting;
vec3 lightDirection;
vec3 normal;
vec3 eyeDirection;
vec3 reflectionDirection;
float specularLightWeighting;
float diffuseLightWeighting;
//i=0
lightDirection = normalize(pointLightsPositions[0] - vPosition.xyz);
//float distance = length(dir);
//float attenuation = 1.0/(1.0+0.1*distance+0.01*distance*distance);
normal = normalize(vTransformedNormal);
eyeDirection = normalize(-vPosition.xyz);
reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), pointLightsParamsf[0]);
diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting += pointLightsParamsv[0] + pointLightsParamsv[1] * diffuseLightWeighting + pointLightsParamsv[2] * specularLightWeighting;
//i=1
lightDirection = normalize(pointLightsPositions[1] - vPosition.xyz);
normal = normalize(vTransformedNormal);
eyeDirection = normalize(-vPosition.xyz);
reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), pointLightsParamsf[1]);
diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting += pointLightsParamsv[3] + pointLightsParamsv[4] * diffuseLightWeighting + pointLightsParamsv[5] * specularLightWeighting ;
//i=2
lightDirection = normalize(pointLightsPositions[2] - vPosition.xyz);
normal = normalize(vTransformedNormal);
eyeDirection = normalize(-vPosition.xyz);
reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), pointLightsParamsf[2]);
diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting += pointLightsParamsv[6] + pointLightsParamsv[7] * diffuseLightWeighting + pointLightsParamsv[8] * specularLightWeighting ;
//i=3
lightDirection = normalize(pointLightsPositions[3] - vPosition.xyz);
normal = normalize(vTransformedNormal);
eyeDirection = normalize(-vPosition.xyz);
reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), pointLightsParamsf[3]);
diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting += pointLightsParamsv[9] + pointLightsParamsv[10] * diffuseLightWeighting + pointLightsParamsv[11] * specularLightWeighting ;
//i=4
lightDirection = normalize(pointLightsPositions[4] - vPosition.xyz);
normal = normalize(vTransformedNormal);
eyeDirection = normalize(-vPosition.xyz);
reflectionDirection = reflect(-lightDirection, normal);
specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), pointLightsParamsf[4]);
diffuseLightWeighting = max(dot(normal, lightDirection), 0.0);
lightWeighting += pointLightsParamsv[12] + pointLightsParamsv[13] * diffuseLightWeighting + pointLightsParamsv[14] * specularLightWeighting ;
vec4 fragmentColor;
fragmentColor = uColor;
gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a);
}

View File

@ -0,0 +1,19 @@
attribute vec3 aVertexNormal;
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
uniform mat4 uTRSMatrix;
uniform mat3 uNMatrix;
varying vec2 vTextureCoord;
varying vec3 vTransformedNormal;
varying vec4 vPosition;
void main(void) {
vPosition = uMVMatrix * uTRSMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * vPosition;
vTransformedNormal = uNMatrix * aVertexNormal;
vTextureCoord = aTextureCoord;
}

View File

@ -4,9 +4,9 @@ goog.require('og.math.Vector3');
goog.require('og.math.Quaternion');
goog.require('og.math.Matrix4');
og.shapes.BaseShape = function (renderer) {
og.shapes.BaseShape = function (renderNode) {
this.renderer = renderer;
this.renderNode = renderNode;
this.position = new og.math.Vector3();
this.orientation = new og.math.Quaternion(0.0, 0.0, 0.0, 1.0);
@ -26,9 +26,10 @@ og.shapes.BaseShape = function (renderer) {
this._mxTranslation = new og.math.Matrix4().setIdentity();
this._mxTRS = new og.math.Matrix4().setIdentity();
this.drawMode = renderer.handler.gl.TRIANGLES;
this.drawMode = renderNode.renderer.handler.gl.TRIANGLES;
this.texture = null;
this.lightEnabled = false;
};
og.shapes.BaseShape.prototype.clear = function () {
@ -49,9 +50,10 @@ og.shapes.BaseShape.prototype.clear = function () {
};
og.shapes.BaseShape.prototype.deleteBuffers = function () {
this.renderer.handler.gl.deleteBuffer(this._positionBuffer);
this.renderer.handler.gl.deleteBuffer(this._normalBuffer);
this.renderer.handler.gl.deleteBuffer(this._indexBuffer);
var r = this.renderNode.renderer;
r.handler.gl.deleteBuffer(this._positionBuffer);
r.handler.gl.deleteBuffer(this._normalBuffer);
r.handler.gl.deleteBuffer(this._indexBuffer);
this._positionBuffer = null;
this._normalBuffer = null;
this._indexBuffer = null;
@ -73,9 +75,10 @@ og.shapes.BaseShape.prototype.setScale = function (scale) {
};
og.shapes.BaseShape.prototype.createBuffers = function () {
this._positionBuffer = this.renderer.handler.createArrayBuffer(new Float32Array(this._positionData), 3, this._positionData.length / 3);
this._normalBuffer = this.renderer.handler.createArrayBuffer(new Float32Array(this._normalData), 3, this._normalData.length / 3);
this._indexBuffer = this.renderer.handler.createElementArrayBuffer(new Uint16Array(this._indexData), 1, this._indexData.length);
var r = this.renderNode.renderer;
this._positionBuffer = r.handler.createArrayBuffer(new Float32Array(this._positionData), 3, this._positionData.length / 3);
this._normalBuffer = r.handler.createArrayBuffer(new Float32Array(this._normalData), 3, this._normalData.length / 3);
this._indexBuffer = r.handler.createElementArrayBuffer(new Uint16Array(this._indexData), 1, this._indexData.length);
}
og.shapes.BaseShape.prototype.setPositionData = function (positionData) {
@ -96,34 +99,58 @@ og.shapes.BaseShape.prototype.refresh = function () {
og.shapes.BaseShape.prototype.draw = function () {
var sh = this.renderer.handler.shaderPrograms.shape;
var p = sh._program;
var gl = this.renderer.handler.gl,
sha = p.attributes,
shu = p.uniforms;
var rn = this.renderNode;
var r = rn.renderer;
sh.activate();
var sh, p, gl;
if (this.lightEnabled) {
sh = r.handler.shaderPrograms.shape_wl;
p = sh._program;
gl = r.handler.gl,
sha = p.attributes,
shu = p.uniforms;
gl.uniform4fv(shu.uColor._pName, this.color);
sh.activate();
gl.uniform3f(shu.uPointLightingLocation._pName, 0.0, 0.0, -5000.0);
gl.uniform3f(shu.uAmbientColor._pName, 0, 0, 0);
gl.uniform4fv(shu.uColor._pName, this.color);
gl.uniform1f(shu.uMaterialShininess._pName, 32.0);
gl.uniform3f(shu.uPointLightingSpecularColor._pName, 1.0, 0.0, 0.0);
gl.uniform3f(shu.uPointLightingDiffuseColor._pName, 0.8, 0.8, 0.8);
var transformedPointLightsPositions = [];
for (var i = 0; i < rn._pointLights.length; i++) {
var tp = r.activeCamera.mvMatrix.mulVec3(rn._pointLights[i]._position);
transformedPointLightsPositions[i * 3] = tp.x;
transformedPointLightsPositions[i * 3 + 1] = tp.y;
transformedPointLightsPositions[i * 3 + 2] = tp.z;
}
gl.uniform3fv(shu.pointLightsPositions._pName, transformedPointLightsPositions);
gl.uniform3fv(shu.pointLightsParamsv._pName, rn._pointLightsParamsv);
gl.uniform1fv(shu.pointLightsParamsf._pName, rn._pointLightsParamsf);
gl.uniformMatrix4fv(shu.uPMatrix._pName, false, this.renderer.activeCamera.pMatrix._m);
gl.uniformMatrix4fv(shu.uMVMatrix._pName, false, this.renderer.activeCamera.mvMatrix._m);
gl.uniformMatrix4fv(shu.uPMatrix._pName, false, r.activeCamera.pMatrix._m);
gl.uniformMatrix4fv(shu.uMVMatrix._pName, false, r.activeCamera.mvMatrix._m);
var mmm = this.renderer.activeCamera.mvMatrix.toInverseMatrix3().transpose();
gl.uniformMatrix3fv(shu.uNMatrix._pName, false, mmm._m);
var mmm = r.activeCamera.mvMatrix.toInverseMatrix3().transpose();
gl.uniformMatrix3fv(shu.uNMatrix._pName, false, mmm._m);
gl.uniformMatrix4fv(shu.uTRSMatrix._pName, false, this._mxTRS._m);
gl.uniformMatrix4fv(shu.uTRSMatrix._pName, false, this._mxTRS._m);
gl.bindBuffer(gl.ARRAY_BUFFER, this._normalBuffer);
gl.vertexAttribPointer(sha.aVertexNormal._pName, this._normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._normalBuffer);
gl.vertexAttribPointer(sha.aVertexNormal._pName, this._normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
} else {
sh = r.handler.shaderPrograms.shape_nl;
p = sh._program;
gl = r.handler.gl,
sha = p.attributes,
shu = p.uniforms;
sh.activate();
gl.uniform4fv(shu.uColor._pName, this.color);
gl.uniformMatrix4fv(shu.uPMVMatrix._pName, false, r.activeCamera.pmvMatrix._m);
gl.uniformMatrix4fv(shu.uTRSMatrix._pName, false, this._mxTRS._m);
}
gl.bindBuffer(gl.ARRAY_BUFFER, this._positionBuffer);
gl.vertexAttribPointer(sha.aVertexPosition._pName, this._positionBuffer.itemSize, gl.FLOAT, false, 0, 0);
@ -135,4 +162,5 @@ og.shapes.BaseShape.prototype.draw = function () {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer);
gl.drawElements(this.drawMode, this._indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
};

View File

@ -4,18 +4,20 @@ goog.require('og.shapes.BaseShape');
og.shapes.Sphere = function (renderer, radius, latBands, lonBands) {
goog.base(this, renderer);
this._radius = radius;
this._latBands = latBands;
this._lonBands = lonBands;
this._createData();
this.createData();
this.createBuffers();
};
goog.inherits(og.shapes.Sphere, og.shapes.BaseShape);
og.shapes.Sphere.prototype._createData = function () {
og.shapes.Sphere.prototype.createData = function () {
for (var latNumber = 0; latNumber <= this._latBands; latNumber++) {
var theta = latNumber * Math.PI / this._latBands;