1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-25 16:03:31 +01:00

#22 add crystal lighting

This commit is contained in:
XProger 2017-10-15 15:41:02 +03:00
parent a50e0ccf61
commit 30c15b33af
3 changed files with 46 additions and 6 deletions

View File

@ -921,6 +921,38 @@ struct Level : IGame {
controller->render(camera->frustum, mesh, type, room.flags.water);
}
void updateLighting() {
camera->setup(true);
// update crystal lighting (TODO: make it per-room instead of global)
int index = -1;
float minDist = 1000000000.f;
for (int i = 0; i < level.entitiesBaseCount; i++) {
TR::Entity &e = level.entities[i];
if (e.type == TR::Entity::CRYSTAL) {
Crystal *crystal = (Crystal*)e.controller;
if (crystal->activeState != Controller::asActive && !level.rooms[crystal->getRoomIndex()].flags.visible)
continue;
if (camera->frustum->isVisible(crystal->lightPos, CRYSTAL_LIGHT_RADIUS + 1024.0f)) { // 1024.0f because of vertex lighting
float d = (lara->pos - crystal->pos).length();
if (d < minDist) {
index = i;
minDist = d;
}
};
}
}
if (index > -1) {
Crystal *crystal = (Crystal*)level.entities[index].controller;
Core::lightPos[3] = crystal->lightPos;
Core::lightColor[3] = CRYSTAL_LIGHT_COLOR;
} else
Core::lightColor[3] = Core::lightColor[3] = vec4(0, 0, 0, 1);
}
void update() {
if (isCutscene() && (lara->health > 0.0f && !sndSoundtrack))
return;
@ -956,6 +988,8 @@ struct Level : IGame {
camera->update();
updateLighting();
if (waterCache)
waterCache->update();

View File

@ -180,9 +180,9 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#endif
lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
vec4 light = max(vec4(0.0), lum) * max(vec4(0.0), vec4(1.0) - att);
#ifdef UNDERWATER
@ -205,7 +205,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
vLight = light;
#else
vLight.w = 0.0;
vLight.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z;
vLight.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z + uLightColor[3].xyz * light.w;
#ifdef TYPE_ENTITY
vLight.xyz += ambient + uLightColor[0].xyz * light.x;
@ -438,7 +438,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#endif
#ifdef OPT_SHADOW
vec3 light = uLightColor[1].xyz * vLight.y + uLightColor[2].xyz * vLight.z;
vec3 light = uLightColor[1].xyz * vLight.y + uLightColor[2].xyz * vLight.z + uLightColor[3].xyz * vLight.w;
#if defined(TYPE_ENTITY) || defined(TYPE_ROOM)
float rShadow = getShadow();

View File

@ -678,8 +678,13 @@ struct Drawbridge : Controller {
}
};
#define CRYSTAL_LIGHT_RADIUS 1024.0f
#define CRYSTAL_LIGHT_COLOR vec4(0.1, 0.1, 3.0, 1.0f / CRYSTAL_LIGHT_RADIUS)
struct Crystal : Controller {
Texture *environment;
vec3 lightPos;
Crystal(IGame *game, int entity) : Controller(game, entity) {
environment = new Texture(64, 64, Texture::RGBA, true, NULL, true, true);
@ -692,10 +697,11 @@ struct Crystal : Controller {
virtual void update() {
updateAnimation(false);
lightPos = animation.getJoints(getMatrix(), 0, false).pos - vec3(0, 256, 0);
}
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) {
Core::active.shader->setParam(uMaterial, vec4(0.5, 0.5, 2.0, 1.0f)); // blue color dodge for crystal
Core::active.shader->setParam(uMaterial, vec4(0.5, 0.5, 3.0, 1.0f)); // blue color dodge for crystal
environment->bind(sEnvironment);
Controller::render(frustum, mesh, type, caustics);
}