1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-01 19:00:34 +02:00

#12 flash lights

This commit is contained in:
XProger
2016-11-16 03:26:41 +03:00
parent 08dc561617
commit 0921c615e3
8 changed files with 170 additions and 101 deletions

Binary file not shown.

View File

@@ -688,6 +688,7 @@ struct Controller {
Core::active.shader->setParam(uModel, m); Core::active.shader->setParam(uModel, m);
Core::active.shader->setParam(uColor, vec4(0.0f, 0.0f, 0.0f, 0.5f)); Core::active.shader->setParam(uColor, vec4(0.0f, 0.0f, 0.0f, 0.5f));
Core::active.shader->setParam(uAmbient, vec3(0.0f));
mesh->renderShadowSpot(); mesh->renderShadowSpot();
} }

View File

@@ -83,6 +83,8 @@
#endif #endif
#endif #endif
#define MAX_LIGHTS 3
struct Shader; struct Shader;
struct Texture; struct Texture;
@@ -113,8 +115,8 @@ namespace Core {
float deltaTime; float deltaTime;
mat4 mView, mProj, mViewProj, mViewInv, mModel; mat4 mView, mProj, mViewProj, mViewInv, mModel;
vec3 viewPos; vec3 viewPos;
vec3 lightPos; vec3 lightPos[MAX_LIGHTS];
vec4 lightColor; vec4 lightColor[MAX_LIGHTS];
vec3 ambient; vec3 ambient;
vec4 color; vec4 color;
@@ -185,6 +187,9 @@ namespace Core {
support.VAO = (void*)glBindVertexArray != NULL; support.VAO = (void*)glBindVertexArray != NULL;
Sound::init(); Sound::init();
for (int i = 0; i < MAX_LIGHTS; i++)
lightColor[i] = vec4(0, 0, 0, 1);
} }
void free() { void free() {

View File

@@ -26,6 +26,7 @@
#define DESCENT_SPEED 2048.0f #define DESCENT_SPEED 2048.0f
#define MUZZLE_FLASH_TIME 0.1f #define MUZZLE_FLASH_TIME 0.1f
#define FLASH_LIGHT_COLOR vec4(0.8f, 0.7f, 0.3f, 2048 * 2048)
#define TARGET_MAX_DIST (8.0f * 1024.0f) #define TARGET_MAX_DIST (8.0f * 1024.0f)
struct Lara : Controller { struct Lara : Controller {
@@ -490,12 +491,15 @@ struct Lara : Controller {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Arm *arm; Arm *arm;
int armIndex;
if (wpnCurrent == Weapon::SHOTGUN) { if (wpnCurrent == Weapon::SHOTGUN) {
if (!rightHand) continue; if (!rightHand) continue;
arm = &arms[0]; arm = &arms[0];
armIndex = 0;
} else { } else {
if (!(i ? leftHand : rightHand)) continue; if (!(i ? leftHand : rightHand)) continue;
arm = &arms[i]; arm = &arms[i];
armIndex = i;
} }
arm->shotTimer = 0.0f; arm->shotTimer = 0.0f;
@@ -523,6 +527,9 @@ struct Lara : Controller {
nearDist = dist; nearDist = dist;
} }
} }
Core::lightPos[1 + armIndex] = getJoint(armIndex == 0 ? 10 : 13, false).getPos();
Core::lightColor[1 + armIndex] = FLASH_LIGHT_COLOR;
} }
if (hasShot) { if (hasShot) {
@@ -571,6 +578,9 @@ struct Lara : Controller {
for (int i = 0; i < 2; i++){ for (int i = 0; i < 2; i++){
arms[i].animTime += Core::deltaTime * arms[i].animDir; arms[i].animTime += Core::deltaTime * arms[i].animDir;
arms[i].shotTimer += Core::deltaTime; arms[i].shotTimer += Core::deltaTime;
float intensity = clamp((0.1f - arms[i].shotTimer) * 20.0f, 0.0f, 1.0f);
Core::lightColor[1 + i] = FLASH_LIGHT_COLOR * vec4(intensity, intensity, intensity, sqrtf(intensity));
} }
if (isRifle) if (isRifle)

View File

@@ -172,11 +172,11 @@ struct Level {
void initShaders() { void initShaders() {
char def[255], ext[255]; char def[255], ext[255];
sprintf(def, "#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n", mesh->animTexRangesCount, mesh->animTexOffsetsCount); sprintf(def, "#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n", MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount);
shaders[shStatic] = new Shader(SHADER, def); shaders[shStatic] = new Shader(SHADER, def);
sprintf(ext, "%s#define CAUSTICS\n", def); sprintf(ext, "#define MAX_LIGHTS %d\n%s#define CAUSTICS\n", MAX_LIGHTS, def);
shaders[shCaustics] = new Shader(SHADER, ext); shaders[shCaustics] = new Shader(SHADER, ext);
sprintf(ext, "%s#define SPRITE\n", def); sprintf(ext, "#define MAX_LIGHTS %d\n%s#define SPRITE\n", MAX_LIGHTS, def);
shaders[shSprite] = new Shader(SHADER, ext); shaders[shSprite] = new Shader(SHADER, ext);
} }
@@ -238,11 +238,12 @@ struct Level {
sh->bind(); sh->bind();
sh->setParam(uColor, Core::color); sh->setParam(uColor, Core::color);
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
sh->setParam(uAmbient, vec3(0.0f));//Core::ambient);
// room static meshes // room static meshes
{ {
PROFILE_MARKER("R_MESH");
for (int i = 0; i < room.meshesCount; i++) { for (int i = 0; i < room.meshesCount; i++) {
TR::Room::Mesh &rMesh = room.meshes[i]; TR::Room::Mesh &rMesh = room.meshes[i];
if (rMesh.flags.rendered) continue; // skip if already rendered if (rMesh.flags.rendered) continue; // skip if already rendered
@@ -261,11 +262,17 @@ struct Level {
// set light parameters // set light parameters
getLight(offset, roomIndex); getLight(offset, roomIndex);
if (rMesh.intensity >= 0) {
Core::ambient = vec3(intensity(rMesh.intensity) / 255.0f);
Core::ambient = vec3(0.0);
sh->setParam(uAmbient, Core::ambient);
}
// render static mesh // render static mesh
mat4 mTemp = Core::mModel; mat4 mTemp = Core::mModel;
Core::mModel.translate(offset); Core::mModel.translate(offset);
Core::mModel.rotateY(rMesh.rotation); Core::mModel.rotateY(rMesh.rotation);
Core::active.shader->setParam(uModel, Core::mModel); sh->setParam(uModel, Core::mModel);
mesh->renderMesh(mesh->meshMap[sMesh->mesh]); mesh->renderMesh(mesh->meshMap[sMesh->mesh]);
Core::mModel = mTemp; Core::mModel = mTemp;
} }
@@ -275,14 +282,13 @@ struct Level {
if (!room.flags.rendered) { // skip if already rendered if (!room.flags.rendered) { // skip if already rendered
mat4 mTemp = Core::mModel; mat4 mTemp = Core::mModel;
{
PROFILE_MARKER("R_GEOM");
room.flags.rendered = true; room.flags.rendered = true;
Core::lightColor = vec4(0.0f, 0.0f, 0.0f, 1.0f); Core::lightColor[0] = vec4(0, 0, 0, 1);
Core::ambient = vec3(1.0f); Core::ambient = vec3(0.0);
sh->setParam(uLightColor, Core::lightColor);
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
sh->setParam(uAmbient, Core::ambient); sh->setParam(uAmbient, Core::ambient);
Core::mModel.translate(offset); Core::mModel.translate(offset);
@@ -290,15 +296,16 @@ struct Level {
// render room geometry // render room geometry
sh->setParam(uModel, Core::mModel); sh->setParam(uModel, Core::mModel);
mesh->renderRoomGeometry(roomIndex); mesh->renderRoomGeometry(roomIndex);
}
// render room sprites // render room sprites
if (mesh->hasRoomSprites(roomIndex)) { if (mesh->hasRoomSprites(roomIndex)) {
PROFILE_MARKER("R_SPR");
sh = shaders[shSprite]; sh = shaders[shSprite];
sh->bind(); sh->bind();
sh->setParam(uModel, Core::mModel); sh->setParam(uModel, Core::mModel);
sh->setParam(uColor, Core::color); sh->setParam(uColor, Core::color);
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
sh->setParam(uAmbient, vec3(0.0f));//Core::ambient);
mesh->renderRoomSprites(roomIndex); mesh->renderRoomSprites(roomIndex);
} }
@@ -353,17 +360,17 @@ struct Level {
if (idx > -1) { if (idx > -1) {
TR::Room::Light &light = level.rooms[room].lights[idx]; TR::Room::Light &light = level.rooms[room].lights[idx];
float c = level.rooms[room].lights[idx].intensity / 8191.0f; float c = level.rooms[room].lights[idx].intensity / 8191.0f;
Core::lightPos = vec3(light.x, light.y, light.z); Core::lightPos[0] = vec3(light.x, light.y, light.z);
Core::lightColor = vec4(c, c, c, (float)light.attenuation * (float)light.attenuation); Core::lightColor[0] = vec4(c, c, c, (float)light.attenuation * (float)light.attenuation);
} else { } else {
Core::lightPos = vec3(0); Core::lightPos[0] = vec3(0);
Core::lightColor = vec4(0, 0, 0, 1); Core::lightColor[0] = vec4(0, 0, 0, 1);
} }
Core::ambient = vec3(1.0f - level.rooms[roomIndex].ambient / 8191.0f); Core::ambient = vec3(1.0f - level.rooms[roomIndex].ambient / 8191.0f);
Core::active.shader->setParam(uAmbient, Core::ambient); Core::active.shader->setParam(uAmbient, Core::ambient);
Core::active.shader->setParam(uLightPos, Core::lightPos); Core::active.shader->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
Core::active.shader->setParam(uLightColor, Core::lightColor); Core::active.shader->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
} }
void renderEntity(const TR::Entity &entity) { void renderEntity(const TR::Entity &entity) {

View File

@@ -106,6 +106,20 @@ struct Mesh {
n.z = (int)o.z;\ n.z = (int)o.z;\
}\ }\
#define CHECK_ROOM_NORMAL(n) \
vec3 o(d.vertices[f.vertices[0]].vertex);\
vec3 a = o - d.vertices[f.vertices[1]].vertex;\
vec3 b = o - d.vertices[f.vertices[2]].vertex;\
o = b.cross(a).normal() * 16300.0f;\
n.x = (int)o.x;\
n.y = (int)o.y;\
n.z = (int)o.z;
uint8 intensity(int lighting) {
float a = 1.0f - (lighting >> 5) / 255.0f;
return int(255 * a * a);
}
struct MeshBuilder { struct MeshBuilder {
// rooms // rooms
@@ -252,13 +266,14 @@ struct MeshBuilder {
addQuad(indices, iCount, vCount, vStart, vertices, &t); addQuad(indices, iCount, vCount, vStart, vertices, &t);
TR::Vertex n;
CHECK_ROOM_NORMAL(n);
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
TR::Room::Data::Vertex &v = d.vertices[f.vertices[k]]; TR::Room::Data::Vertex &v = d.vertices[f.vertices[k]];
uint8 a = 255 - (v.lighting >> 5);
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 }; vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
vertices[vCount].color = { a, a, a, 255 }; vertices[vCount].color = { 255, 255, 255, intensity(v.lighting) };
vertices[vCount].normal = { 0, 0, 0, 1 }; vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vCount++; vCount++;
} }
} }
@@ -269,13 +284,14 @@ struct MeshBuilder {
addTriangle(indices, iCount, vCount, vStart, vertices, &t); addTriangle(indices, iCount, vCount, vStart, vertices, &t);
TR::Vertex n;
CHECK_ROOM_NORMAL(n);
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
auto &v = d.vertices[f.vertices[k]]; auto &v = d.vertices[f.vertices[k]];
uint8 a = 255 - (v.lighting >> 5);
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 }; vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
vertices[vCount].color = { a, a, a, 255 }; vertices[vCount].color = { 255, 255, 255, intensity(v.lighting) };
vertices[vCount].normal = { 0, 0, 0, 1 }; vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vCount++; vCount++;
} }
} }
@@ -288,8 +304,7 @@ struct MeshBuilder {
TR::Room::Data::Vertex &v = d.vertices[f.vertex]; TR::Room::Data::Vertex &v = d.vertices[f.vertex];
TR::SpriteTexture &sprite = level.spriteTextures[f.texture]; TR::SpriteTexture &sprite = level.spriteTextures[f.texture];
uint8 intensity = 255 - (v.lighting >> 5); addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting));
addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity);
} }
} }
@@ -335,21 +350,26 @@ struct MeshBuilder {
addQuad(indices, iCount, vCount, vStart, vertices, &t); addQuad(indices, iCount, vCount, vStart, vertices, &t);
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
uint16 idx = f.vertices[k]; TR::Vertex &v = mVertices[f.vertices[k]];
TR::Vertex &v = mVertices[idx];
vertices[vCount].coord = { v.x, v.y, v.z, 0 }; vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (normals) { if (normals) {
TR::Vertex &n = normals[idx]; TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n); CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 }; vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { 255, 255, 255, 255 }; vertices[vCount].color = { 255, 255, 255, 0 };
} else { } else {
uint8 a = 255 - (lights[idx] >> 5); vertices[vCount].normal = normal;
vertices[vCount].normal = { 0, 0, 0, 1 }; vertices[vCount].color = { 255, 255, 255, intensity(lights[f.vertices[k]]) };
vertices[vCount].color = { a, a, a, 255 };
} }
vCount++; vCount++;
} }
@@ -363,19 +383,25 @@ struct MeshBuilder {
addTriangle(indices, iCount, vCount, vStart, vertices, &t); addTriangle(indices, iCount, vCount, vStart, vertices, &t);
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
auto &v = mVertices[f.vertices[k]]; auto &v = mVertices[f.vertices[k]];
vertices[vCount].coord = { v.x, v.y, v.z, 0 }; vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (nCount > 0) { if (normals) {
TR::Vertex &n = normals[f.vertices[k]]; TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n); CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 }; vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { 255, 255, 255, 255 }; vertices[vCount].color = { 255, 255, 255, 0 };
} else { } else {
uint8 a = 255 - (lights[f.vertices[k]] >> 5); vertices[vCount].normal = normal;
vertices[vCount].normal = { 0, 0, 0, 1 }; vertices[vCount].color = { 255, 255, 255, intensity(lights[f.vertices[k]]) };
vertices[vCount].color = { a, a, a, 255 };
} }
vCount++; vCount++;
} }
@@ -389,20 +415,26 @@ struct MeshBuilder {
addQuad(indices, iCount, vCount, vStart, vertices, &whiteTileQuad); addQuad(indices, iCount, vCount, vStart, vertices, &whiteTileQuad);
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
auto &v = mVertices[f.vertices[k]]; auto &v = mVertices[f.vertices[k]];
vertices[vCount].coord = { v.x, v.y, v.z, 0 }; vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (nCount > 0) { if (normals) {
TR::Vertex &n = normals[f.vertices[k]]; TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n); CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 }; vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { c.r, c.g, c.b, 255 }; vertices[vCount].color = { c.r, c.g, c.b, 0 };
} else { } else {
uint8 a = 255 - (lights[f.vertices[k]] >> 5); vertices[vCount].normal = normal;
vertices[vCount].normal = { 0, 0, 0, 1 }; vertices[vCount].color = { c.r, c.g, c.b, intensity(lights[f.vertices[k]]) };
vertices[vCount].color = { a, a, a, 255 };
} }
vCount++; vCount++;
} }
@@ -421,15 +453,21 @@ struct MeshBuilder {
vertices[vCount].coord = { v.x, v.y, v.z, 0 }; vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (nCount > 0) { short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
if (normals) {
TR::Vertex &n = normals[f.vertices[k]]; TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n); CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 }; vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { c.r, c.g, c.b, 255 }; vertices[vCount].color = { c.r, c.g, c.b, 0 };
} else { } else {
uint8 a = 255 - (lights[f.vertices[k]] >> 5); vertices[vCount].normal = normal;
vertices[vCount].normal = { 0, 0, 0, 1 }; vertices[vCount].color = { c.r, c.g, c.b, intensity(lights[f.vertices[k]]) };
vertices[vCount].color = { a, a, a, 255 };
} }
vCount++; vCount++;
} }
@@ -450,8 +488,8 @@ struct MeshBuilder {
// build shadow spot // build shadow spot
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
Vertex &v = vertices[vCount + i]; Vertex &v = vertices[vCount + i];
v.normal = { 0, 0, 0, 1 }; v.normal = { 0, -1, 0, 0 };
v.color = { 255, 255, 255, 255 }; v.color = { 255, 255, 255, 0 };
v.texCoord = { 32688, 32688, 0, 0 }; v.texCoord = { 32688, 32688, 0, 0 };
float a = i * (PI / 4.0f) + (PI / 8.0f); float a = i * (PI / 4.0f) + (PI / 8.0f);
@@ -618,7 +656,7 @@ struct MeshBuilder {
quad[0].coord = quad[1].coord = quad[2].coord = quad[3].coord = { x, y, z, 0 }; quad[0].coord = quad[1].coord = quad[2].coord = quad[3].coord = { x, y, z, 0 };
quad[0].normal = quad[1].normal = quad[2].normal = quad[3].normal = { 0, 0, 0, 0 }; quad[0].normal = quad[1].normal = quad[2].normal = quad[3].normal = { 0, 0, 0, 0 };
quad[0].color = quad[1].color = quad[2].color = quad[3].color = { intensity, intensity, intensity, 255 }; quad[0].color = quad[1].color = quad[2].color = quad[3].color = { 255, 255, 255, intensity };
int tx = (sprite.tile % 4) * 256; int tx = (sprite.tile % 4) * 256;
int ty = (sprite.tile / 4) * 256; int ty = (sprite.tile / 4) * 256;

View File

@@ -1,9 +1,7 @@
R"====( R"====(
#ifndef SPRITE varying vec4 vNormal;
varying vec4 vNormal; varying vec3 vLightVec[MAX_LIGHTS];
varying vec3 vLightVec; varying vec3 vViewVec;
varying vec3 vViewVec;
#endif
varying vec2 vTexCoord; varying vec2 vTexCoord;
varying vec4 vColor; varying vec4 vColor;
@@ -11,11 +9,10 @@ varying vec4 vColor;
uniform mat4 uViewProj; uniform mat4 uViewProj;
uniform mat4 uModel; uniform mat4 uModel;
uniform mat4 uViewInv; uniform mat4 uViewInv;
uniform vec4 uColor; uniform vec3 uLightPos[MAX_LIGHTS];
uniform vec3 uViewPos;
#ifndef SPRITE #ifndef SPRITE
uniform vec3 uViewPos;
uniform vec3 uLightPos;
uniform vec2 uAnimTexRanges[MAX_RANGES]; uniform vec2 uAnimTexRanges[MAX_RANGES];
uniform vec2 uAnimTexOffsets[MAX_OFFSETS]; uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
#endif #endif
@@ -31,7 +28,7 @@ varying vec4 vColor;
void main() { void main() {
vec4 coord = uModel * vec4(aCoord.xyz, 1.0); vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
vColor = aColor * uColor; vColor = aColor;
#ifdef CAUSTICS #ifdef CAUSTICS
float sum = coord.x + coord.y + coord.z; float sum = coord.x + coord.y + coord.z;
@@ -46,49 +43,59 @@ varying vec4 vColor;
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
vViewVec = uViewPos - coord.xyz;
vLightVec = uLightPos - coord.xyz;
vNormal = uModel * aNormal; vNormal = uModel * aNormal;
#else #else
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE; vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
coord.xyz -= uViewInv[0].xyz * aTexCoord.z + uViewInv[1].xyz * aTexCoord.w; coord.xyz -= uViewInv[0].xyz * aTexCoord.z + uViewInv[1].xyz * aTexCoord.w;
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
#endif #endif
vViewVec = uViewPos - coord.xyz;
for (int i = 0; i < MAX_LIGHTS; i++)
vLightVec[i] = uLightPos[i] - coord.xyz;
gl_Position = uViewProj * coord; gl_Position = uViewProj * coord;
} }
#else #else
uniform sampler2D sDiffuse; uniform sampler2D sDiffuse;
uniform vec4 uColor;
#ifndef SPRITE
uniform vec3 uAmbient; uniform vec3 uAmbient;
uniform vec4 uLightColor; uniform vec4 uLightColor[MAX_LIGHTS];
#endif
void main() { void main() {
vec4 color = texture2D(sDiffuse, vTexCoord); vec4 color = texture2D(sDiffuse, vTexCoord);
if (color.w < 0.6) if (color.w < 0.6)
discard; discard;
color *= vColor; color *= uColor;
#ifndef SPRITE color.xyz *= vColor.xyz;
color.xyz = pow(abs(color.xyz), vec3(2.2));
color.xyz = pow(abs(color.xyz), vec3(2.2)); // to linear space
// calc point lights
vec3 normal = normalize(vNormal.xyz); vec3 normal = normalize(vNormal.xyz);
vec3 lightVec = normalize(vLightVec);
vec3 viewVec = normalize(vViewVec); vec3 viewVec = normalize(vViewVec);
float lum = dot(normal, lightVec); vec3 light = uAmbient;
float att = max(0.0, 1.0 - dot(vLightVec, vLightVec) / uLightColor.w); for (int i = 0; i < MAX_LIGHTS; i++) {
vec3 light = uLightColor.xyz * max(vNormal.w, lum * att) + uAmbient; vec3 lv = vLightVec[i];
// apply backlight vec4 lc = uLightColor[i];
light *= max(vNormal.w, dot(normal, viewVec) * 0.5 + 0.5); float lum = max(0.0, dot(normal, normalize(lv)));
color.xyz *= light; float att = max(0.0, 1.0 - dot(lv, lv) / lc.w);
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); light += lc.xyz * (lum * att);
#endif }
// calc backlight
light *= dot(normal, viewVec) * 0.5 + 0.5;
// fog // apply lighting
color.xyz *= vColor.w + light;
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); // back to gamma space
// apply fog
float fog = clamp(1.0 / exp(gl_FragCoord.z / gl_FragCoord.w * 0.000025), 0.0, 1.0); float fog = clamp(1.0 / exp(gl_FragCoord.z / gl_FragCoord.w * 0.000025), 0.0, 1.0);
color = mix(vec4(0.0, 0.0, 0.0, 1.0), color, fog);
gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), color, fog); gl_FragColor = color;
} }
#endif #endif
)====" )===="

View File

@@ -158,6 +158,7 @@ struct vec4 {
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
vec4(const vec3 &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {} vec4(const vec3 &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {}
vec4 operator * (const vec4 &v) const { return vec4(x*v.x, y*v.y, z*v.z, w*v.w); }
vec4& operator *= (const vec4 &v) { x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this; } vec4& operator *= (const vec4 &v) { x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this; }
}; };