1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-01-17 21:09:00 +01:00

#23 specular on wet Lara

This commit is contained in:
XProger 2016-12-27 03:32:21 +03:00
parent ec67b2ee79
commit d1bd39abfd
10 changed files with 80 additions and 17 deletions

Binary file not shown.

View File

@ -26,6 +26,7 @@ struct Controller {
int frameIndex;
vec3 ambient[6];
float specular;
struct MeshLayer {
uint32 model;
@ -50,6 +51,7 @@ struct Controller {
TR::Model *m = getModel();
joints = m ? new mat4[m->mCount] : NULL;
frameIndex = -1;
specular = 0.0f;
}
virtual ~Controller() {

View File

@ -103,6 +103,7 @@
#endif
#define MAX_LIGHTS 3
#define MAX_CACHED_LIGHTS 3
#define MAX_RENDER_BUFFERS 11
struct Shader;

View File

@ -29,10 +29,8 @@ uniform int uType;
p.xyz *= p.w;
color += p;
}
color.xyz /= color.w;
color.w = 1.0;
return color;
return vec4(color.xyz / color.w, 1.0);
}
vec4 filter() {

View File

@ -23,6 +23,9 @@
#define LARA_HANG_OFFSET 735.0f
#define LARA_WET_SPECULAR 0.5f
#define LARA_WET_TIMER (LARA_WET_SPECULAR / 16.0f) // 4 sec
#define PICKUP_FRAME_GROUND 40
#define PICKUP_FRAME_UNDERWATER 16
#define PUZZLE_FRAME 80
@ -889,6 +892,8 @@ struct Lara : Character {
alignToWall();
dst.y -= pos.y - infoDst.floor;
pos = dst; // set new position
specular = LARA_WET_SPECULAR;
getEntity().room = infoCur.roomAbove;
updateEntity();
@ -1441,6 +1446,11 @@ struct Lara : Character {
virtual void updateAnimation(bool commands) {
Controller::updateAnimation(commands);
updateWeapon();
if (stand == STAND_UNDERWATER)
specular = 0.0f;
else
if (specular > 0.0f)
specular = max(0.0f, specular - LARA_WET_TIMER * Core::deltaTime);
}
virtual void updateVelocity() {

View File

@ -176,6 +176,46 @@ struct Level {
}
} *ambientCache;
/*
struct LightCache {
struct Item {
int room;
int index;
float intensity;
} items[MAX_CACHED_LIGHTS];
void updateLightCache(const TR::Level &level, const vec3 &pos, int room) {
// update intensity
for (int i = 0; i < MAX_CACHED_LIGHTS; i++) {
Item &item = items[i];
if (c.intensity < 0.0f) continue;
TR::Room::Light &light = level.rooms[c.room].lights[i];
c.intensity = max(0.0f, 1.0f - (pos - vec3(float(light.x), float(light.y), float(light.z))).length2() / ((float)light.radius * (float)light.radius));
}
// check for new lights
int index = getLightIndex(pos, room);
if (index >= 0 && (items[0].room != room || items[0].index != index)) [
TR::Room::Light &light = level.rooms[room].lights[index];
float intensity = max(0.0f, 1.0f - (lara->pos - vec3(float(light.x), float(light.y), float(light.z))).length2() / ((float)light.radius * (float)light.radius));
int i = 0;
while (i < MAX_CACHED_LIGHTS && lightCache[i].intensity > intensity) // get sorted place
i++;
if (i < MAX_CACHED_LIGHTS) { // insert light
for (int j = MAX_CACHED_LIGHTS - 1; j > i; j--)
lightCache[j] = lightCache[j - 1];
lightCache[i].room = room;
lightCache[i].index = index;
lightCache[i].intensity = intensity;
}
}
}
} lightCache;
*/
Level(const char *name, bool demo, bool home) : level(name, demo), lara(NULL), time(0.0f) {
#ifdef _DEBUG
Debug::init();
@ -613,21 +653,23 @@ struct Level {
void renderEntity(const TR::Entity &entity) {
//if (entity.room != lara->getRoomIndex()) return;
if (entity.type == TR::Entity::NONE) return;
if (entity.type == TR::Entity::NONE || !entity.modelIndex) return;
if (Core::pass == Core::passShadow && !TR::castShadow(entity.type)) return;
ASSERT(entity.controller);
bool isModel = entity.modelIndex > 0;
Controller *controller = (Controller*)entity.controller;
TR::Room &room = level.rooms[entity.room];
if (!room.flags.rendered || entity.flags.invisible || entity.flags.rendered)
return;
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
setRoomParams(room, intensityf(lum));
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
setRoomParams(room, isModel ? controller->specular : intensityf(lum));
Controller *controller = (Controller*)entity.controller;
if (entity.modelIndex > 0) { // model
if (isModel) { // model
vec3 pos = controller->pos;
AmbientCache::Cube cube;
if (Core::frameIndex != controller->frameIndex) {
@ -638,9 +680,7 @@ struct Level {
getLight(pos, entity.room);
Core::active.shader->setParam(uType, Shader::ENTITY);
Core::active.shader->setParam(uAmbient, controller->ambient[0], 6);
}
if (entity.modelIndex < 0) { // sprite
} else { // sprite
Core::active.shader->setParam(uType, Shader::SPRITE);
Core::lightPos[0] = vec3(0);
Core::lightColor[0] = vec4(0, 0, 0, 1);
@ -684,6 +724,7 @@ struct Level {
sh->setParam(uViewInv, Core::mViewInv);
sh->setParam(uViewPos, Core::viewPos);
sh->setParam(uTime, time);
sh->setParam(uLightsCount, 3);
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
@ -743,7 +784,7 @@ struct Level {
Core::mView = Core::mViewInv.inverse();
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
}
bool setupLightCamera() {
vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).getPos();

View File

@ -3,7 +3,7 @@ cls
set SRC=main.cpp
set PROJ=OpenLara
set FLAGS=-O3 -Wno-deprecated-register --llvm-opts 2 -fmax-type-align=2 -std=c++11 -I../../
set PRELOAD=./GYM.PSX
set PRELOAD=./LEVEL2.PSX
echo.
call em++ %SRC% %FLAGS% -o %PROJ%.js --preload-file %PRELOAD%
gzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem

View File

@ -102,5 +102,7 @@
};
</script>
<audio autoplay loop><source src="05.ogg" type="audio/ogg"></audio>
</body>
</html>

View File

@ -99,6 +99,7 @@ uniform int uType;
uniform vec4 uColor;
#ifdef PASS_COMPOSE
uniform samplerCube sEnvironment;
uniform int uLightsCount;
uniform vec3 uLightPos[MAX_LIGHTS];
uniform vec4 uLightColor[MAX_LIGHTS];
uniform vec3 uAmbient[6];
@ -192,6 +193,13 @@ uniform int uType;
return color.xyz * (lum * att);
}
vec3 calcSpecular(vec3 normal, vec3 viewVec, vec3 pos, vec4 color, float intensity) {
vec3 rv = reflect(-viewVec, normal);
vec3 lv = normalize(pos - vCoord.xyz);
float spec = pow(max(0.0, dot(rv, lv)), 8.0) * intensity;
return vec3(spec);
}
vec3 calcAmbient(vec3 n) {
vec3 sqr = n * n;
vec3 pos = step(0.0, n);
@ -242,7 +250,8 @@ uniform int uType;
if (uType == TYPE_ENTITY) {
vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2));
float rShadow = getShadow(vLightProj);
light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient;
light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient;
color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], uColor.w * rShadow + 0.03);
}
if (uType == TYPE_MIRROR) {

View File

@ -5,11 +5,11 @@
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX };
enum UniformType { uType, uCaustics, uTime, uViewProj, uViewInv, uModel, uLightProj, uColor, uAmbient, uViewPos, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX };
enum UniformType { uType, uCaustics, uTime, uViewProj, uViewInv, uModel, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX };
const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" };
const char *SamplerName[sMAX] = { "sDiffuse", "sShadow", "sEnvironment" };
const char *UniformName[uMAX] = { "uType", "uCaustics", "uTime", "uViewProj", "uViewInv", "uModel", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" };
const char *UniformName[uMAX] = { "uType", "uCaustics", "uTime", "uViewProj", "uViewInv", "uModel", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" };
struct Shader {
GLuint ID;