1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-07-31 18:30:19 +02: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; int frameIndex;
vec3 ambient[6]; vec3 ambient[6];
float specular;
struct MeshLayer { struct MeshLayer {
uint32 model; uint32 model;
@@ -50,6 +51,7 @@ struct Controller {
TR::Model *m = getModel(); TR::Model *m = getModel();
joints = m ? new mat4[m->mCount] : NULL; joints = m ? new mat4[m->mCount] : NULL;
frameIndex = -1; frameIndex = -1;
specular = 0.0f;
} }
virtual ~Controller() { virtual ~Controller() {

View File

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

View File

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

View File

@@ -23,6 +23,9 @@
#define LARA_HANG_OFFSET 735.0f #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_GROUND 40
#define PICKUP_FRAME_UNDERWATER 16 #define PICKUP_FRAME_UNDERWATER 16
#define PUZZLE_FRAME 80 #define PUZZLE_FRAME 80
@@ -889,6 +892,8 @@ struct Lara : Character {
alignToWall(); alignToWall();
dst.y -= pos.y - infoDst.floor; dst.y -= pos.y - infoDst.floor;
pos = dst; // set new position pos = dst; // set new position
specular = LARA_WET_SPECULAR;
getEntity().room = infoCur.roomAbove; getEntity().room = infoCur.roomAbove;
updateEntity(); updateEntity();
@@ -1441,6 +1446,11 @@ struct Lara : Character {
virtual void updateAnimation(bool commands) { virtual void updateAnimation(bool commands) {
Controller::updateAnimation(commands); Controller::updateAnimation(commands);
updateWeapon(); 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() { virtual void updateVelocity() {

View File

@@ -176,6 +176,46 @@ struct Level {
} }
} *ambientCache; } *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) { Level(const char *name, bool demo, bool home) : level(name, demo), lara(NULL), time(0.0f) {
#ifdef _DEBUG #ifdef _DEBUG
Debug::init(); Debug::init();
@@ -613,21 +653,23 @@ struct Level {
void renderEntity(const TR::Entity &entity) { void renderEntity(const TR::Entity &entity) {
//if (entity.room != lara->getRoomIndex()) return; //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; if (Core::pass == Core::passShadow && !TR::castShadow(entity.type)) return;
ASSERT(entity.controller); ASSERT(entity.controller);
bool isModel = entity.modelIndex > 0;
Controller *controller = (Controller*)entity.controller;
TR::Room &room = level.rooms[entity.room]; TR::Room &room = level.rooms[entity.room];
if (!room.flags.rendered || entity.flags.invisible || entity.flags.rendered) if (!room.flags.rendered || entity.flags.invisible || entity.flags.rendered)
return; return;
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity; int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
setRoomParams(room, intensityf(lum)); setRoomParams(room, isModel ? controller->specular : intensityf(lum));
Controller *controller = (Controller*)entity.controller; if (isModel) { // model
if (entity.modelIndex > 0) { // model
vec3 pos = controller->pos; vec3 pos = controller->pos;
AmbientCache::Cube cube; AmbientCache::Cube cube;
if (Core::frameIndex != controller->frameIndex) { if (Core::frameIndex != controller->frameIndex) {
@@ -638,9 +680,7 @@ struct Level {
getLight(pos, entity.room); getLight(pos, entity.room);
Core::active.shader->setParam(uType, Shader::ENTITY); Core::active.shader->setParam(uType, Shader::ENTITY);
Core::active.shader->setParam(uAmbient, controller->ambient[0], 6); Core::active.shader->setParam(uAmbient, controller->ambient[0], 6);
} } else { // sprite
if (entity.modelIndex < 0) { // sprite
Core::active.shader->setParam(uType, Shader::SPRITE); Core::active.shader->setParam(uType, Shader::SPRITE);
Core::lightPos[0] = vec3(0); Core::lightPos[0] = vec3(0);
Core::lightColor[0] = vec4(0, 0, 0, 1); Core::lightColor[0] = vec4(0, 0, 0, 1);
@@ -684,6 +724,7 @@ struct Level {
sh->setParam(uViewInv, Core::mViewInv); sh->setParam(uViewInv, Core::mViewInv);
sh->setParam(uViewPos, Core::viewPos); sh->setParam(uViewPos, Core::viewPos);
sh->setParam(uTime, time); sh->setParam(uTime, time);
sh->setParam(uLightsCount, 3);
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount); sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount); sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
@@ -743,7 +784,7 @@ struct Level {
Core::mView = Core::mViewInv.inverse(); Core::mView = Core::mViewInv.inverse();
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar); Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
} }
bool setupLightCamera() { bool setupLightCamera() {
vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).getPos(); vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).getPos();

View File

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

View File

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

View File

@@ -99,6 +99,7 @@ uniform int uType;
uniform vec4 uColor; uniform vec4 uColor;
#ifdef PASS_COMPOSE #ifdef PASS_COMPOSE
uniform samplerCube sEnvironment; uniform samplerCube sEnvironment;
uniform int uLightsCount;
uniform vec3 uLightPos[MAX_LIGHTS]; uniform vec3 uLightPos[MAX_LIGHTS];
uniform vec4 uLightColor[MAX_LIGHTS]; uniform vec4 uLightColor[MAX_LIGHTS];
uniform vec3 uAmbient[6]; uniform vec3 uAmbient[6];
@@ -192,6 +193,13 @@ uniform int uType;
return color.xyz * (lum * att); 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 calcAmbient(vec3 n) {
vec3 sqr = n * n; vec3 sqr = n * n;
vec3 pos = step(0.0, n); vec3 pos = step(0.0, n);
@@ -242,7 +250,8 @@ uniform int uType;
if (uType == TYPE_ENTITY) { if (uType == TYPE_ENTITY) {
vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2)); vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2));
float rShadow = getShadow(vLightProj); 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) { if (uType == TYPE_MIRROR) {

View File

@@ -5,11 +5,11 @@
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX }; enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX }; 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 *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" };
const char *SamplerName[sMAX] = { "sDiffuse", "sShadow", "sEnvironment" }; 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 { struct Shader {
GLuint ID; GLuint ID;