mirror of
https://github.com/XProger/OpenLara.git
synced 2025-01-17 21:09:00 +01:00
#12 flash lights
This commit is contained in:
parent
08dc561617
commit
0921c615e3
BIN
bin/OpenLara.exe
BIN
bin/OpenLara.exe
Binary file not shown.
@ -688,6 +688,7 @@ struct Controller {
|
||||
|
||||
Core::active.shader->setParam(uModel, m);
|
||||
Core::active.shader->setParam(uColor, vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
Core::active.shader->setParam(uAmbient, vec3(0.0f));
|
||||
mesh->renderShadowSpot();
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX_LIGHTS 3
|
||||
|
||||
struct Shader;
|
||||
struct Texture;
|
||||
|
||||
@ -113,8 +115,8 @@ namespace Core {
|
||||
float deltaTime;
|
||||
mat4 mView, mProj, mViewProj, mViewInv, mModel;
|
||||
vec3 viewPos;
|
||||
vec3 lightPos;
|
||||
vec4 lightColor;
|
||||
vec3 lightPos[MAX_LIGHTS];
|
||||
vec4 lightColor[MAX_LIGHTS];
|
||||
vec3 ambient;
|
||||
vec4 color;
|
||||
|
||||
@ -185,6 +187,9 @@ namespace Core {
|
||||
support.VAO = (void*)glBindVertexArray != NULL;
|
||||
|
||||
Sound::init();
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
lightColor[i] = vec4(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
void free() {
|
||||
|
10
src/lara.h
10
src/lara.h
@ -26,6 +26,7 @@
|
||||
|
||||
#define DESCENT_SPEED 2048.0f
|
||||
#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)
|
||||
|
||||
struct Lara : Controller {
|
||||
@ -490,12 +491,15 @@ struct Lara : Controller {
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Arm *arm;
|
||||
int armIndex;
|
||||
if (wpnCurrent == Weapon::SHOTGUN) {
|
||||
if (!rightHand) continue;
|
||||
arm = &arms[0];
|
||||
armIndex = 0;
|
||||
} else {
|
||||
if (!(i ? leftHand : rightHand)) continue;
|
||||
arm = &arms[i];
|
||||
armIndex = i;
|
||||
}
|
||||
|
||||
arm->shotTimer = 0.0f;
|
||||
@ -523,6 +527,9 @@ struct Lara : Controller {
|
||||
nearDist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
Core::lightPos[1 + armIndex] = getJoint(armIndex == 0 ? 10 : 13, false).getPos();
|
||||
Core::lightColor[1 + armIndex] = FLASH_LIGHT_COLOR;
|
||||
}
|
||||
|
||||
if (hasShot) {
|
||||
@ -571,6 +578,9 @@ struct Lara : Controller {
|
||||
for (int i = 0; i < 2; i++){
|
||||
arms[i].animTime += Core::deltaTime * arms[i].animDir;
|
||||
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)
|
||||
|
57
src/level.h
57
src/level.h
@ -172,11 +172,11 @@ struct Level {
|
||||
|
||||
void initShaders() {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -238,11 +238,12 @@ struct Level {
|
||||
|
||||
sh->bind();
|
||||
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
|
||||
{
|
||||
PROFILE_MARKER("R_MESH");
|
||||
|
||||
for (int i = 0; i < room.meshesCount; i++) {
|
||||
TR::Room::Mesh &rMesh = room.meshes[i];
|
||||
if (rMesh.flags.rendered) continue; // skip if already rendered
|
||||
@ -261,11 +262,17 @@ struct Level {
|
||||
// set light parameters
|
||||
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
|
||||
mat4 mTemp = Core::mModel;
|
||||
Core::mModel.translate(offset);
|
||||
Core::mModel.rotateY(rMesh.rotation);
|
||||
Core::active.shader->setParam(uModel, Core::mModel);
|
||||
sh->setParam(uModel, Core::mModel);
|
||||
mesh->renderMesh(mesh->meshMap[sMesh->mesh]);
|
||||
Core::mModel = mTemp;
|
||||
}
|
||||
@ -275,30 +282,30 @@ struct Level {
|
||||
if (!room.flags.rendered) { // skip if already rendered
|
||||
|
||||
mat4 mTemp = Core::mModel;
|
||||
{
|
||||
PROFILE_MARKER("R_GEOM");
|
||||
room.flags.rendered = true;
|
||||
|
||||
room.flags.rendered = true;
|
||||
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
||||
Core::ambient = vec3(0.0);
|
||||
|
||||
Core::lightColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
Core::ambient = vec3(1.0f);
|
||||
sh->setParam(uLightColor, Core::lightColor);
|
||||
sh->setParam(uAmbient, Core::ambient);
|
||||
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
|
||||
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
|
||||
sh->setParam(uAmbient, Core::ambient);
|
||||
|
||||
Core::mModel.translate(offset);
|
||||
Core::mModel.translate(offset);
|
||||
|
||||
// render room geometry
|
||||
sh->setParam(uModel, Core::mModel);
|
||||
mesh->renderRoomGeometry(roomIndex);
|
||||
}
|
||||
// render room geometry
|
||||
sh->setParam(uModel, Core::mModel);
|
||||
mesh->renderRoomGeometry(roomIndex);
|
||||
|
||||
// render room sprites
|
||||
if (mesh->hasRoomSprites(roomIndex)) {
|
||||
PROFILE_MARKER("R_SPR");
|
||||
sh = shaders[shSprite];
|
||||
sh->bind();
|
||||
sh->setParam(uModel, Core::mModel);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -353,17 +360,17 @@ struct Level {
|
||||
if (idx > -1) {
|
||||
TR::Room::Light &light = level.rooms[room].lights[idx];
|
||||
float c = level.rooms[room].lights[idx].intensity / 8191.0f;
|
||||
Core::lightPos = vec3(light.x, light.y, light.z);
|
||||
Core::lightColor = vec4(c, c, c, (float)light.attenuation * (float)light.attenuation);
|
||||
Core::lightPos[0] = vec3(light.x, light.y, light.z);
|
||||
Core::lightColor[0] = vec4(c, c, c, (float)light.attenuation * (float)light.attenuation);
|
||||
} else {
|
||||
Core::lightPos = vec3(0);
|
||||
Core::lightColor = vec4(0, 0, 0, 1);
|
||||
Core::lightPos[0] = vec3(0);
|
||||
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
Core::ambient = vec3(1.0f - level.rooms[roomIndex].ambient / 8191.0f);
|
||||
Core::active.shader->setParam(uAmbient, Core::ambient);
|
||||
Core::active.shader->setParam(uLightPos, Core::lightPos);
|
||||
Core::active.shader->setParam(uLightColor, Core::lightColor);
|
||||
Core::active.shader->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
|
||||
Core::active.shader->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
|
||||
}
|
||||
|
||||
void renderEntity(const TR::Entity &entity) {
|
||||
|
118
src/mesh.h
118
src/mesh.h
@ -106,6 +106,20 @@ struct Mesh {
|
||||
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 {
|
||||
// rooms
|
||||
@ -252,13 +266,14 @@ struct MeshBuilder {
|
||||
|
||||
addQuad(indices, iCount, vCount, vStart, vertices, &t);
|
||||
|
||||
TR::Vertex n;
|
||||
CHECK_ROOM_NORMAL(n);
|
||||
|
||||
for (int k = 0; k < 4; 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].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = { 0, 0, 0, 1 };
|
||||
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
|
||||
vertices[vCount].color = { 255, 255, 255, intensity(v.lighting) };
|
||||
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
|
||||
vCount++;
|
||||
}
|
||||
}
|
||||
@ -269,13 +284,14 @@ struct MeshBuilder {
|
||||
|
||||
addTriangle(indices, iCount, vCount, vStart, vertices, &t);
|
||||
|
||||
TR::Vertex n;
|
||||
CHECK_ROOM_NORMAL(n);
|
||||
|
||||
for (int k = 0; k < 3; 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].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = { 0, 0, 0, 1 };
|
||||
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
|
||||
vertices[vCount].color = { 255, 255, 255, intensity(v.lighting) };
|
||||
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
|
||||
vCount++;
|
||||
}
|
||||
}
|
||||
@ -288,8 +304,7 @@ struct MeshBuilder {
|
||||
TR::Room::Data::Vertex &v = d.vertices[f.vertex];
|
||||
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);
|
||||
addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting));
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,21 +350,26 @@ struct MeshBuilder {
|
||||
|
||||
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++) {
|
||||
uint16 idx = f.vertices[k];
|
||||
TR::Vertex &v = mVertices[idx];
|
||||
TR::Vertex &v = mVertices[f.vertices[k]];
|
||||
|
||||
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
|
||||
|
||||
if (normals) {
|
||||
TR::Vertex &n = normals[idx];
|
||||
TR::Vertex &n = normals[f.vertices[k]];
|
||||
CHECK_NORMAL(n);
|
||||
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 {
|
||||
uint8 a = 255 - (lights[idx] >> 5);
|
||||
vertices[vCount].normal = { 0, 0, 0, 1 };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = normal;
|
||||
vertices[vCount].color = { 255, 255, 255, intensity(lights[f.vertices[k]]) };
|
||||
}
|
||||
vCount++;
|
||||
}
|
||||
@ -363,19 +383,25 @@ struct MeshBuilder {
|
||||
|
||||
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++) {
|
||||
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]];
|
||||
CHECK_NORMAL(n);
|
||||
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 {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
vertices[vCount].normal = { 0, 0, 0, 1 };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = normal;
|
||||
vertices[vCount].color = { 255, 255, 255, intensity(lights[f.vertices[k]]) };
|
||||
}
|
||||
vCount++;
|
||||
}
|
||||
@ -389,20 +415,26 @@ struct MeshBuilder {
|
||||
|
||||
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++) {
|
||||
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]];
|
||||
CHECK_NORMAL(n);
|
||||
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 {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
vertices[vCount].normal = { 0, 0, 0, 1 };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = normal;
|
||||
vertices[vCount].color = { c.r, c.g, c.b, intensity(lights[f.vertices[k]]) };
|
||||
}
|
||||
vCount++;
|
||||
}
|
||||
@ -419,17 +451,23 @@ struct MeshBuilder {
|
||||
for (int k = 0; k < 3; 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) {
|
||||
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]];
|
||||
CHECK_NORMAL(n);
|
||||
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 {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
vertices[vCount].normal = { 0, 0, 0, 1 };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = normal;
|
||||
vertices[vCount].color = { c.r, c.g, c.b, intensity(lights[f.vertices[k]]) };
|
||||
}
|
||||
vCount++;
|
||||
}
|
||||
@ -450,8 +488,8 @@ struct MeshBuilder {
|
||||
// build shadow spot
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Vertex &v = vertices[vCount + i];
|
||||
v.normal = { 0, 0, 0, 1 };
|
||||
v.color = { 255, 255, 255, 255 };
|
||||
v.normal = { 0, -1, 0, 0 };
|
||||
v.color = { 255, 255, 255, 0 };
|
||||
v.texCoord = { 32688, 32688, 0, 0 };
|
||||
|
||||
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].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 ty = (sprite.tile / 4) * 256;
|
||||
|
@ -1,9 +1,7 @@
|
||||
R"====(
|
||||
#ifndef SPRITE
|
||||
varying vec4 vNormal;
|
||||
varying vec3 vLightVec;
|
||||
varying vec3 vViewVec;
|
||||
#endif
|
||||
varying vec4 vNormal;
|
||||
varying vec3 vLightVec[MAX_LIGHTS];
|
||||
varying vec3 vViewVec;
|
||||
varying vec2 vTexCoord;
|
||||
varying vec4 vColor;
|
||||
|
||||
@ -11,11 +9,10 @@ varying vec4 vColor;
|
||||
uniform mat4 uViewProj;
|
||||
uniform mat4 uModel;
|
||||
uniform mat4 uViewInv;
|
||||
uniform vec4 uColor;
|
||||
uniform vec3 uLightPos[MAX_LIGHTS];
|
||||
uniform vec3 uViewPos;
|
||||
|
||||
#ifndef SPRITE
|
||||
uniform vec3 uViewPos;
|
||||
uniform vec3 uLightPos;
|
||||
#ifndef SPRITE
|
||||
uniform vec2 uAnimTexRanges[MAX_RANGES];
|
||||
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
||||
#endif
|
||||
@ -31,7 +28,7 @@ varying vec4 vColor;
|
||||
|
||||
void main() {
|
||||
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
|
||||
vColor = aColor * uColor;
|
||||
vColor = aColor;
|
||||
|
||||
#ifdef CAUSTICS
|
||||
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
|
||||
|
||||
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
||||
|
||||
vViewVec = uViewPos - coord.xyz;
|
||||
vLightVec = uLightPos - coord.xyz;
|
||||
vNormal = uModel * aNormal;
|
||||
#else
|
||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||
coord.xyz -= uViewInv[0].xyz * aTexCoord.z + uViewInv[1].xyz * aTexCoord.w;
|
||||
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
||||
#endif
|
||||
|
||||
vViewVec = uViewPos - coord.xyz;
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
vLightVec[i] = uLightPos[i] - coord.xyz;
|
||||
|
||||
gl_Position = uViewProj * coord;
|
||||
}
|
||||
#else
|
||||
uniform sampler2D sDiffuse;
|
||||
|
||||
#ifndef SPRITE
|
||||
uniform vec3 uAmbient;
|
||||
uniform vec4 uLightColor;
|
||||
#endif
|
||||
uniform vec4 uColor;
|
||||
uniform vec3 uAmbient;
|
||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
||||
|
||||
void main() {
|
||||
vec4 color = texture2D(sDiffuse, vTexCoord);
|
||||
if (color.w < 0.6)
|
||||
discard;
|
||||
|
||||
color *= vColor;
|
||||
#ifndef SPRITE
|
||||
color.xyz = pow(abs(color.xyz), vec3(2.2));
|
||||
vec3 normal = normalize(vNormal.xyz);
|
||||
vec3 lightVec = normalize(vLightVec);
|
||||
vec3 viewVec = normalize(vViewVec);
|
||||
float lum = dot(normal, lightVec);
|
||||
float att = max(0.0, 1.0 - dot(vLightVec, vLightVec) / uLightColor.w);
|
||||
vec3 light = uLightColor.xyz * max(vNormal.w, lum * att) + uAmbient;
|
||||
// apply backlight
|
||||
light *= max(vNormal.w, dot(normal, viewVec) * 0.5 + 0.5);
|
||||
color.xyz *= light;
|
||||
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2));
|
||||
#endif
|
||||
color *= uColor;
|
||||
color.xyz *= vColor.xyz;
|
||||
|
||||
// fog
|
||||
color.xyz = pow(abs(color.xyz), vec3(2.2)); // to linear space
|
||||
|
||||
// calc point lights
|
||||
vec3 normal = normalize(vNormal.xyz);
|
||||
vec3 viewVec = normalize(vViewVec);
|
||||
vec3 light = uAmbient;
|
||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||
vec3 lv = vLightVec[i];
|
||||
vec4 lc = uLightColor[i];
|
||||
float lum = max(0.0, dot(normal, normalize(lv)));
|
||||
float att = max(0.0, 1.0 - dot(lv, lv) / lc.w);
|
||||
light += lc.xyz * (lum * att);
|
||||
}
|
||||
// calc backlight
|
||||
light *= dot(normal, viewVec) * 0.5 + 0.5;
|
||||
|
||||
// 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);
|
||||
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
|
||||
)===="
|
@ -158,6 +158,7 @@ struct vec4 {
|
||||
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 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; }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user