mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-19 11:21:31 +02:00
#23 interpolation between shadow sources
This commit is contained in:
110
src/controller.h
110
src/controller.h
@@ -46,9 +46,9 @@ struct Controller {
|
|||||||
vec3 ambient[6];
|
vec3 ambient[6];
|
||||||
float specular;
|
float specular;
|
||||||
|
|
||||||
TR::Room::Light *lights[MAX_LIGHTS];
|
TR::Room::Light *targetLight;
|
||||||
vec3 mainLightPos;
|
vec3 mainLightPos;
|
||||||
float mainLightRadius;
|
vec4 mainLightColor;
|
||||||
|
|
||||||
struct MeshLayer {
|
struct MeshLayer {
|
||||||
uint32 model;
|
uint32 model;
|
||||||
@@ -75,7 +75,8 @@ struct Controller {
|
|||||||
frameIndex = -1;
|
frameIndex = -1;
|
||||||
specular = 0.0f;
|
specular = 0.0f;
|
||||||
ambient[0] = ambient[1] = ambient[2] = ambient[3] = ambient[4] = ambient[5] = vec3(intensityf(getRoom().ambient));
|
ambient[0] = ambient[1] = ambient[2] = ambient[3] = ambient[4] = ambient[5] = vec3(intensityf(getRoom().ambient));
|
||||||
updateLights();
|
targetLight = NULL;
|
||||||
|
updateLights(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Controller() {
|
virtual ~Controller() {
|
||||||
@@ -472,92 +473,47 @@ struct Controller {
|
|||||||
updateAnimation(true);
|
updateAnimation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MaxLight {
|
void updateLights(bool lerp = true) {
|
||||||
TR::Room::Light *light;
|
if (getModel()) {
|
||||||
float att;
|
TR::Room &room = getRoom();
|
||||||
};
|
|
||||||
|
|
||||||
void checkRoomLights(int roomIndex, int fromRoom, const vec3 &from, MaxLight *maxLights, vec3 &mainDir, float &mainRad, float &attSum, int deep) {
|
vec3 center = getBoundingBox().center();
|
||||||
TR::Room &room = level->rooms[roomIndex];
|
float maxAtt = 0.0f;
|
||||||
|
|
||||||
for (int i = 0; i < room.lightsCount; i++) {
|
for (int i = 0; i < room.lightsCount; i++) {
|
||||||
TR::Room::Light &light = room.lights[i];
|
TR::Room::Light &light = room.lights[i];
|
||||||
|
if (light.intensity > 0x1FFF) continue;
|
||||||
bool exists = false;
|
|
||||||
for (int m = 0; m < MAX_LIGHTS; m++)
|
|
||||||
if (maxLights[m].light == &light) {
|
|
||||||
exists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (exists) continue;
|
|
||||||
|
|
||||||
vec3 dir = vec3(float(light.x), float(light.y), float(light.z)) - from;
|
vec3 dir = vec3(float(light.x), float(light.y), float(light.z)) - center;
|
||||||
float att = max(0.0f, 1.0f - dir.length2() / float(light.radius) / float(light.radius)) * intensityf(light.intensity);
|
float att = max(0.0f, 1.0f - dir.length2() / float(light.radius) / float(light.radius)) * (intensityf(light.intensity));
|
||||||
|
|
||||||
for (int m = 0; m < MAX_LIGHTS; m++) {
|
if (att > maxAtt) {
|
||||||
if (maxLights[m].att < att) {
|
maxAtt = att;
|
||||||
for (int n = MAX_LIGHTS - 1; n > m; n--)
|
targetLight = &light;
|
||||||
maxLights[n] = maxLights[n - 1];
|
|
||||||
maxLights[m].light = &light;
|
|
||||||
maxLights[m].att = att;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
targetLight = NULL;
|
||||||
|
|
||||||
if (att > 0.0f) {
|
if (targetLight == NULL) {
|
||||||
// if (dir.y > 0.0f)
|
mainLightPos = vec3(0);
|
||||||
// att *= 1.0f - dir.y / float(light.radius);
|
mainLightColor = vec4(0, 0, 0, 1);
|
||||||
att = max(0.0f, att - dir.y / 8192.0f);
|
|
||||||
attSum += att;
|
|
||||||
mainDir += dir * att;
|
|
||||||
mainRad += float(light.radius) * att;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (--deep > 0)
|
|
||||||
for (int i = 0; i < room.portalsCount; i++)
|
|
||||||
if (room.portals[i].roomIndex != fromRoom)
|
|
||||||
checkRoomLights(room.portals[i].roomIndex, roomIndex, from, maxLights, mainDir, mainRad, attSum, deep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateLights() {
|
|
||||||
if (!getModel()) {
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
|
||||||
lights[i] = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaxLight maxLights[MAX_LIGHTS];
|
vec3 tpos = vec3(float(targetLight->x), float(targetLight->y), float(targetLight->z));
|
||||||
|
vec4 tcolor = vec4(vec3(intensityf(targetLight->intensity)), float(targetLight->radius));
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
if (lerp) {
|
||||||
maxLights[i].light = NULL;
|
float t = Core::deltaTime * 2.0f;
|
||||||
maxLights[i].att = 0.0f;
|
mainLightPos = mainLightPos.lerp(tpos, t);
|
||||||
|
mainLightColor = mainLightColor.lerp(tcolor, t);
|
||||||
|
} else {
|
||||||
|
mainLightPos = tpos;
|
||||||
|
mainLightColor = tcolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 p = getBoundingBox().center();
|
|
||||||
vec3 mainDir(0.0f);
|
|
||||||
float mainRad = 0.0f;
|
|
||||||
float attSum = 0.0f;
|
|
||||||
|
|
||||||
checkRoomLights(getRoomIndex(), -1, p, maxLights, mainDir, mainRad, attSum, 1);
|
|
||||||
|
|
||||||
if (attSum > 0.0f) {
|
|
||||||
attSum = 1.0f / attSum;
|
|
||||||
mainLightPos = mainDir * attSum + p;
|
|
||||||
mainLightRadius = mainRad * attSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
|
||||||
lights[i] = maxLights[i].light;
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void renderMesh(MeshBuilder *mesh, uint32 offsetIndex) {
|
|
||||||
return;
|
|
||||||
MeshBuilder::MeshInfo *mInfo = mesh->meshMap[offsetIndex];
|
|
||||||
if (!mInfo) return; // invisible mesh (offsetIndex > 0 && level.meshOffsets[offsetIndex] == 0) camera target entity etc.
|
|
||||||
mesh->renderMesh(mInfo);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
mat4 getMatrix() {
|
mat4 getMatrix() {
|
||||||
mat4 matrix;
|
mat4 matrix;
|
||||||
|
|
||||||
|
11
src/debug.h
11
src/debug.h
@@ -353,7 +353,6 @@ namespace Debug {
|
|||||||
void lights(const TR::Level &level, int room, Controller *lara) {
|
void lights(const TR::Level &level, int room, Controller *lara) {
|
||||||
// int roomIndex = level.entities[lara->entity].room;
|
// int roomIndex = level.entities[lara->entity].room;
|
||||||
// int lightIndex = getLightIndex(lara->pos, roomIndex);
|
// int lightIndex = getLightIndex(lara->pos, roomIndex);
|
||||||
lara->updateLights();
|
|
||||||
glPointSize(8);
|
glPointSize(8);
|
||||||
for (int i = 0; i < level.roomsCount; i++)
|
for (int i = 0; i < level.roomsCount; i++)
|
||||||
for (int j = 0; j < level.rooms[i].lightsCount; j++) {
|
for (int j = 0; j < level.rooms[i].lightsCount; j++) {
|
||||||
@@ -362,18 +361,16 @@ namespace Debug {
|
|||||||
vec3 p = vec3(l.x, l.y, l.z);
|
vec3 p = vec3(l.x, l.y, l.z);
|
||||||
vec4 color = vec4(a, a, a, 1);
|
vec4 color = vec4(a, a, a, 1);
|
||||||
|
|
||||||
if (&l == lara->lights[0]) color.y = color.z = 0; // r
|
|
||||||
if (&l == lara->lights[1]) color.x = color.z = 0; // g
|
|
||||||
if (&l == lara->lights[2]) color.x = color.y = 0; // b
|
|
||||||
if (&l == lara->lights[3]) color.y = 0; // a
|
|
||||||
|
|
||||||
// if (i == room) color.x = color.z = 0;
|
// if (i == room) color.x = color.z = 0;
|
||||||
Debug::Draw::point(p, color);
|
Debug::Draw::point(p, color);
|
||||||
//if (i == roomIndex && j == lightIndex)
|
//if (i == roomIndex && j == lightIndex)
|
||||||
// color = vec4(0, 1, 0, 1);
|
// color = vec4(0, 1, 0, 1);
|
||||||
Debug::Draw::sphere(p, l.radius, color);
|
Debug::Draw::sphere(p, l.radius, color);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 color = vec4(lara->mainLightColor.x, 0.0f, 0.0f, 1.0f);
|
||||||
|
Debug::Draw::point(lara->mainLightPos, color);
|
||||||
|
Debug::Draw::sphere(lara->mainLightPos, lara->mainLightColor.w, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void meshes(const TR::Level &level) {
|
void meshes(const TR::Level &level) {
|
||||||
|
@@ -949,7 +949,7 @@ namespace TR {
|
|||||||
stream.read(light.intensity);
|
stream.read(light.intensity);
|
||||||
stream.read(light.radius);
|
stream.read(light.radius);
|
||||||
|
|
||||||
// light.radius *= 2;
|
light.radius *= 2;
|
||||||
}
|
}
|
||||||
// meshes
|
// meshes
|
||||||
stream.read(r.meshesCount);
|
stream.read(r.meshesCount);
|
||||||
|
@@ -407,7 +407,7 @@ struct Lara : Character {
|
|||||||
|
|
||||||
if (level->extra.braid > -1)
|
if (level->extra.braid > -1)
|
||||||
braid = new Braid(this, vec3(-4.0f, 24.0f, -48.0f));
|
braid = new Braid(this, vec3(-4.0f, 24.0f, -48.0f));
|
||||||
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
|
reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, true); // gym (pool)
|
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, true); // gym (pool)
|
||||||
|
|
||||||
@@ -444,6 +444,7 @@ struct Lara : Character {
|
|||||||
animation.setAnim(ANIM_TO_ONWATER);
|
animation.setAnim(ANIM_TO_ONWATER);
|
||||||
}
|
}
|
||||||
updateEntity();
|
updateEntity();
|
||||||
|
updateLights(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wpnSet(Weapon::Type wType) {
|
void wpnSet(Weapon::Type wType) {
|
||||||
|
333
src/level.h
333
src/level.h
@@ -459,25 +459,9 @@ struct Level : IGame {
|
|||||||
camera->frustum = camFrustum; // pop camera frustum
|
camera->frustum = camFrustum; // pop camera frustum
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLights(Controller *controller, bool onlyFlashes = false) {
|
void setMainLight(Controller *controller) {
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
Core::lightPos[0] = controller->mainLightPos;
|
||||||
TR::Room::Light *light = controller->lights[i];
|
Core::lightColor[0] = vec4(controller->mainLightColor.xyz, 1.0f / controller->mainLightColor.w);
|
||||||
if (onlyFlashes && i && light && light->radius > 0.0f)
|
|
||||||
light = NULL;
|
|
||||||
|
|
||||||
if (light) {
|
|
||||||
float c = 1.0f - intensityf(light->intensity);
|
|
||||||
Core::lightPos[i] = vec3(float(light->x), float(light->y), float(light->z));
|
|
||||||
Core::lightColor[i] = vec4(c, c, c, 1.0f / float(light->radius));
|
|
||||||
} else {
|
|
||||||
Core::lightPos[i] = vec3(0);
|
|
||||||
Core::lightColor[i] = vec4(0, 0, 0, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::lightPos[0] = lara->mainLightPos;
|
|
||||||
if (lara->mainLightRadius > 0.0f)
|
|
||||||
Core::lightColor[0].w = 1.0f / lara->mainLightRadius;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderEntity(const TR::Entity &entity) {
|
void renderEntity(const TR::Entity &entity) {
|
||||||
@@ -520,7 +504,7 @@ struct Level : IGame {
|
|||||||
Core::active.shader->setParam(uAmbient, controller->ambient[0], 6);
|
Core::active.shader->setParam(uAmbient, controller->ambient[0], 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
setLights(controller);
|
setMainLight(controller);
|
||||||
} else { // sprite
|
} else { // 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);
|
||||||
@@ -587,7 +571,7 @@ struct Level : IGame {
|
|||||||
void renderRooms(int roomIndex) {
|
void renderRooms(int roomIndex) {
|
||||||
PROFILE_MARKER("ROOMS");
|
PROFILE_MARKER("ROOMS");
|
||||||
|
|
||||||
setLights(lara, true);
|
setMainLight(lara);
|
||||||
|
|
||||||
#ifdef LEVEL_EDITOR
|
#ifdef LEVEL_EDITOR
|
||||||
for (int i = 0; i < level.roomsCount; i++)
|
for (int i = 0; i < level.roomsCount; i++)
|
||||||
@@ -632,262 +616,12 @@ struct Level : IGame {
|
|||||||
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Box bRec, bCast, bCrop, bSplit;
|
|
||||||
/*
|
|
||||||
mat4 calcCropMatrix(const mat4 &viewProj, const Box &receivers, const Box &casters) {
|
|
||||||
mat4 cameraViewProjInv = (camera->getProjMatrix() * camera->mViewInv.inverse()).inverse();
|
|
||||||
// camera->mViewInv (mat4(camera->fov, float(Core::width) / Core::height, camera->znear, camera->zfar) * camera->mViewInv.inverse()).inverse();
|
|
||||||
Box frustumBox = Box(vec3(-1.0f), vec3(1.0f)) * cameraViewProjInv;
|
|
||||||
|
|
||||||
Box caster = casters;// * viewProj;
|
|
||||||
Box receiver = receivers * viewProj;
|
|
||||||
Box split = frustumBox * viewProj;
|
|
||||||
|
|
||||||
Box crop;
|
|
||||||
crop.min.x = max(max(caster.min.x, receiver.min.x), split.min.x);
|
|
||||||
crop.max.x = min(min(caster.max.x, receiver.max.x), split.max.x);
|
|
||||||
crop.min.y = max(max(caster.min.y, receiver.min.y), split.min.y);
|
|
||||||
crop.max.y = min(min(caster.max.y, receiver.max.y), split.max.y);
|
|
||||||
crop.min.z = min(caster.min.z, split.min.z);
|
|
||||||
crop.max.z = min(receiver.max.z, split.max.z);
|
|
||||||
|
|
||||||
mat4 m = camera->getProjMatrix();
|
|
||||||
Box cc = receivers * m;
|
|
||||||
cc = cc * m.inverse();
|
|
||||||
|
|
||||||
if (!Input::down[ikShift]) {
|
|
||||||
mat4 m = viewProj.inverse();
|
|
||||||
bRec = receivers;// * m;
|
|
||||||
bCast = casters;// * m;
|
|
||||||
bCrop = crop * m;
|
|
||||||
bSplit = split * m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// casterBox -= frustumBox * viewProj;
|
|
||||||
// crop.min.z = 0.0f;
|
|
||||||
|
|
||||||
vec3 scale = vec3(2.0f, 2.0f, 1.0f) / crop.size();
|
|
||||||
vec3 center = crop.center();
|
|
||||||
vec3 offset = vec3(center.x, center.y, crop.min.z) * scale;
|
|
||||||
|
|
||||||
return mat4(scale.x, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, scale.y, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, scale.z, 0.0f,
|
|
||||||
-offset.x, -offset.y, -offset.z, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool setupLightCamera() {
|
bool setupLightCamera() {
|
||||||
lara->updateLights();
|
|
||||||
vec3 pos = lara->getBoundingBox().center();
|
|
||||||
|
|
||||||
Core::mViewInv = mat4(lara->mainLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0));
|
|
||||||
Core::mView = Core::mViewInv.inverse();
|
|
||||||
Core::mProj = mat4(1.0f, 1.0f, camera->znear, camera->zfar);//lara->mainLightRadius * 2.0f);
|
|
||||||
|
|
||||||
mat4 mLightProj = Core::mProj * Core::mView;
|
|
||||||
|
|
||||||
Box casters = lara->getBoundingBox() * mLightProj;
|
|
||||||
|
|
||||||
float rq = lara->mainLightRadius * lara->mainLightRadius;
|
|
||||||
for (int i = 0; i < level.entitiesCount; i++) {
|
|
||||||
TR::Entity &e = level.entities[i];
|
|
||||||
Controller *controller = (Controller*)e.controller;
|
|
||||||
if (controller && TR::castShadow(e.type) && rq > (lara->mainLightPos - controller->pos).length2())
|
|
||||||
casters += controller->getBoundingBox() * mLightProj;
|
|
||||||
}
|
|
||||||
//casters.expand(vec3(128.0f));
|
|
||||||
|
|
||||||
Box lightBox = Box(lara->mainLightPos - vec3(lara->mainLightRadius), lara->mainLightPos + vec3(lara->mainLightRadius));
|
|
||||||
|
|
||||||
Core::mProj = calcCropMatrix(mLightProj, lightBox, casters) * Core::mProj;
|
|
||||||
|
|
||||||
mat4 bias;
|
|
||||||
bias.identity();
|
|
||||||
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
|
||||||
|
|
||||||
Core::mLightProj = bias * (Core::mProj * Core::mView);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* // --> XPSM
|
|
||||||
Box transformPointsBox(const vec3 *points, int count, const mat4 &matrix, float eps) {
|
|
||||||
Box box(vec3(+INF), vec3(-INF));
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
vec4 p = matrix * vec4(points[i], 1.0f);
|
|
||||||
if (p.w > eps)
|
|
||||||
box += p.xyz / p.w;
|
|
||||||
}
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setupLightCamera() {
|
|
||||||
lara->updateLights();
|
|
||||||
vec3 pos = lara->getBoundingBox().center();
|
|
||||||
|
|
||||||
mat4 mViewCamera = camera->mViewInv.inverse();
|
|
||||||
|
|
||||||
// get shadow casters (bbox corner points)
|
|
||||||
#define MAX_CASTER_POINTS (32 * 8)
|
|
||||||
|
|
||||||
vec3 cPoints[32 * 8];
|
|
||||||
int cPointsCount = 0;
|
|
||||||
|
|
||||||
vec3 rPoints[1 * 8];
|
|
||||||
int rPointsCount = 0;
|
|
||||||
|
|
||||||
float rq = lara->mainLightRadius * lara->mainLightRadius;
|
|
||||||
for (int i = 0; i < level.entitiesCount; i++) {
|
|
||||||
if (cPointsCount >= MAX_CASTER_POINTS)
|
|
||||||
break;
|
|
||||||
|
|
||||||
TR::Entity &e = level.entities[i];
|
|
||||||
Controller *controller = (Controller*)e.controller;
|
|
||||||
if (!controller || !TR::castShadow(e.type) || rq < (lara->mainLightPos - controller->pos).length2())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Box box = controller->getBoundingBoxLocal();
|
|
||||||
mat4 m = mViewCamera * controller->getMatrix();
|
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
cPoints[cPointsCount++] = m * box[j];
|
|
||||||
}
|
|
||||||
#undef MAX_CASTER_POINTS
|
|
||||||
|
|
||||||
{
|
|
||||||
mat4 cameraViewProjInv = (camera->getProjMatrix() * mViewCamera).inverse();
|
|
||||||
Box box(vec3(-1.0f), vec3(1.0f));
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
vec4 p = cameraViewProjInv * vec4(box[i], 1.0f);
|
|
||||||
rPoints[rPointsCount++] = mViewCamera * (p.xyz / p.w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mat4 mViewLight = mat4(mViewCamera * pos, mViewCamera * lara->mainLightPos, vec3(0, -1, 0)).inverse();
|
|
||||||
|
|
||||||
vec2 uP = mViewLight.dir.xy.normal();
|
|
||||||
|
|
||||||
float minCastersProj = 1.0f;
|
|
||||||
for (int i = 0; i < cPointsCount; i++) {
|
|
||||||
vec3 p = mViewLight * cPoints[i];
|
|
||||||
minCastersProj = min(minCastersProj, uP.dot(p.xy));
|
|
||||||
}
|
|
||||||
|
|
||||||
float minReceiversProj = 1.0f;
|
|
||||||
for (int i = 0; i < rPointsCount; i++) {
|
|
||||||
vec3 p = mViewLight * rPoints[i];
|
|
||||||
minReceiversProj = min(minReceiversProj, uP.dot(p.xy));
|
|
||||||
}
|
|
||||||
|
|
||||||
float eps = 0.85f;
|
|
||||||
float maxLengthP = (eps - 1.0f) / minCastersProj; //max(minCastersProj, minReceiversProj);
|
|
||||||
float lengthP = (0.05f * 0.06f) / uP.dot(mViewLight.dir.xy);
|
|
||||||
|
|
||||||
if (maxLengthP > 0.0f && lengthP > maxLengthP)
|
|
||||||
lengthP = maxLengthP;
|
|
||||||
|
|
||||||
mat4 mLProj(1, 0, 0, uP.x * lengthP,
|
|
||||||
0, 1, 0, uP.y * lengthP,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
0, 0, 0, 1);
|
|
||||||
|
|
||||||
mat4 mLZRot(uP.x, uP.y, 0, 0,
|
|
||||||
uP.y, -uP.x, 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
0, 0, 0, 1);
|
|
||||||
|
|
||||||
mat4 mProjLight = mLZRot * mLProj * mViewLight;
|
|
||||||
|
|
||||||
Box casters = transformPointsBox(cPoints, cPointsCount, mProjLight, eps);
|
|
||||||
Box receivers = transformPointsBox(rPoints, rPointsCount, mProjLight, eps);
|
|
||||||
Box focus = casters;//.intersection2D(receivers);
|
|
||||||
|
|
||||||
//focus.min.z = min(casters.min.z, receivers.min.z);
|
|
||||||
//focus.max.z = max(casters.max.z, receivers.max.z);
|
|
||||||
|
|
||||||
vec3 size = focus.size();
|
|
||||||
|
|
||||||
if (size.x < EPS || size.y < EPS || size.z < EPS)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
vec3 u = vec3(1.0f) / size;
|
|
||||||
|
|
||||||
mat4 mUnitCube(u.x, 0, 0, 0,
|
|
||||||
0, u.y, 0, 0,
|
|
||||||
0, 0, u.z, 0,
|
|
||||||
-focus.min.x * u.x, -focus.min.y * u.y, -focus.min.z * u.z, 1);
|
|
||||||
|
|
||||||
mat4 mUnitSpace( 2, 0, 0, 0,
|
|
||||||
0, 2, 0, 0,
|
|
||||||
0, 0, 2, 0,
|
|
||||||
-1, -1, -1, 1);
|
|
||||||
|
|
||||||
Core::mView = mViewLight * mViewCamera;
|
|
||||||
Core::mProj = mUnitSpace * mUnitCube * mLZRot * mLProj;
|
|
||||||
Core::mViewProj = Core::mProj * Core::mView;
|
|
||||||
|
|
||||||
mat4 bias;
|
|
||||||
bias.identity();
|
|
||||||
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
|
||||||
|
|
||||||
Core::mLightProj = bias * Core::mViewProj;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
<-- */
|
|
||||||
|
|
||||||
mat4 calcCropMatrix(const mat4 &viewProj, const Box &receivers, const Box &casters) {
|
|
||||||
mat4 cameraViewProjInv = (camera->getProjMatrix() * camera->mViewInv.inverse()).inverse();
|
|
||||||
// camera->mViewInv (mat4(camera->fov, float(Core::width) / Core::height, camera->znear, camera->zfar) * camera->mViewInv.inverse()).inverse();
|
|
||||||
Box frustumBox = Box(vec3(-1.0f), vec3(1.0f)) * cameraViewProjInv;
|
|
||||||
|
|
||||||
Box caster = casters;// * viewProj;
|
|
||||||
Box receiver = receivers * viewProj;
|
|
||||||
Box split = frustumBox * viewProj;
|
|
||||||
|
|
||||||
Box crop;
|
|
||||||
crop.min.x = max(max(caster.min.x, receiver.min.x), split.min.x);
|
|
||||||
crop.max.x = min(min(caster.max.x, receiver.max.x), split.max.x);
|
|
||||||
crop.min.y = max(max(caster.min.y, receiver.min.y), split.min.y);
|
|
||||||
crop.max.y = min(min(caster.max.y, receiver.max.y), split.max.y);
|
|
||||||
crop.min.z = min(caster.min.z, split.min.z);
|
|
||||||
crop.max.z = min(receiver.max.z, split.max.z);
|
|
||||||
|
|
||||||
mat4 m = camera->getProjMatrix();
|
|
||||||
Box cc = receivers * m;
|
|
||||||
cc = cc * m.inverse();
|
|
||||||
|
|
||||||
if (!Input::down[ikShift]) {
|
|
||||||
mat4 m = viewProj.inverse();
|
|
||||||
bRec = receivers;// * m;
|
|
||||||
bCast = casters;// * m;
|
|
||||||
bCrop = crop * m;
|
|
||||||
bSplit = split * m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// casterBox -= frustumBox * viewProj;
|
|
||||||
// crop.min.z = 0.0f;
|
|
||||||
|
|
||||||
vec3 scale = vec3(2.0f, 2.0f, 1.0f) / crop.size();
|
|
||||||
vec3 center = crop.center();
|
|
||||||
vec3 offset = vec3(center.x, center.y, crop.min.z) * scale;
|
|
||||||
|
|
||||||
return mat4(scale.x, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, scale.y, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, scale.z, 0.0f,
|
|
||||||
-offset.x, -offset.y, -offset.z, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setupLightCamera() {
|
|
||||||
lara->updateLights();
|
|
||||||
vec3 pos = lara->getBoundingBox().center();
|
vec3 pos = lara->getBoundingBox().center();
|
||||||
|
|
||||||
Core::mViewInv = mat4(lara->mainLightPos, pos, vec3(0, -1, 0));
|
Core::mViewInv = mat4(lara->mainLightPos, pos, vec3(0, -1, 0));
|
||||||
Core::mView = Core::mViewInv.inverse();
|
Core::mView = Core::mViewInv.inverse();
|
||||||
Core::mProj = mat4(120.0f, 1.0f, camera->znear, lara->mainLightRadius);
|
Core::mProj = mat4(90.0f, 1.0f, camera->znear, lara->mainLightColor.w * 1.5f);
|
||||||
|
|
||||||
mat4 bias;
|
mat4 bias;
|
||||||
bias.identity();
|
bias.identity();
|
||||||
@@ -898,7 +632,6 @@ struct Level : IGame {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void renderShadows(int roomIndex) {
|
void renderShadows(int roomIndex) {
|
||||||
PROFILE_MARKER("PASS_SHADOW");
|
PROFILE_MARKER("PASS_SHADOW");
|
||||||
Core::eye = 0.0f;
|
Core::eye = 0.0f;
|
||||||
@@ -917,48 +650,7 @@ struct Level : IGame {
|
|||||||
if (colorShadow)
|
if (colorShadow)
|
||||||
Core::setClearColor(vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
Core::setClearColor(vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void renderShadowVolumes() {
|
|
||||||
getLight(lara->pos, lara->getRoomIndex());
|
|
||||||
|
|
||||||
Core::setCulling(cfNone);
|
|
||||||
Core::setDepthWrite(false);
|
|
||||||
Core::setColorWrite(false, false, false, false);
|
|
||||||
|
|
||||||
Core::setStencilTest(true);
|
|
||||||
Core::setStencilTwoSide(128, true);
|
|
||||||
|
|
||||||
setShader(Core::passVolume, Shader::DEFAULT, false, false);
|
|
||||||
vec4 lp(Core::lightPos[0], 1.0f / Core::lightColor[0].w);
|
|
||||||
Core::active.shader->setParam(uLightPos, lp);
|
|
||||||
|
|
||||||
for (int i = 0; i < level.entitiesCount; i++) {
|
|
||||||
TR::Entity &e = level.entities[i];
|
|
||||||
if (e.flags.rendered && TR::castShadow(e.type)) {
|
|
||||||
Controller *controller = (Controller*)e.controller;
|
|
||||||
|
|
||||||
mat4 matrix = controller->getMatrix();
|
|
||||||
Box box = controller->animation.getBoundingBox(vec3(0.0f), 0);
|
|
||||||
matrix.translate(box.center());
|
|
||||||
|
|
||||||
Core::active.shader->setParam(uBasis, Basis(matrix) );
|
|
||||||
Core::active.shader->setParam(uPosScale, box.size() * 0.5);
|
|
||||||
|
|
||||||
mesh->renderShadowBox();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::setDepthWrite(true);
|
|
||||||
Core::setColorWrite(true, true, true, true);
|
|
||||||
|
|
||||||
Core::setStencilTwoSide(128, false);
|
|
||||||
|
|
||||||
// setShader(Core::passFilter, Shader::DEFAULT, false, false);
|
|
||||||
// mesh->renderQuad();
|
|
||||||
|
|
||||||
Core::setStencilTest(false);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void render() {
|
void render() {
|
||||||
Core::invalidateTarget(true, true);
|
Core::invalidateTarget(true, true);
|
||||||
params->clipHeight = NO_CLIP_PLANE;
|
params->clipHeight = NO_CLIP_PLANE;
|
||||||
@@ -1062,6 +754,8 @@ struct Level : IGame {
|
|||||||
glEnd();
|
glEnd();
|
||||||
Core::setDepthTest(true);
|
Core::setDepthTest(true);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@@ -1099,7 +793,7 @@ struct Level : IGame {
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
Core::setDepthTest(false);
|
Core::setDepthTest(false);
|
||||||
@@ -1110,15 +804,10 @@ struct Level : IGame {
|
|||||||
glEnd();
|
glEnd();
|
||||||
Core::setDepthTest(true);
|
Core::setDepthTest(true);
|
||||||
|
|
||||||
Debug::Draw::sphere(lara->mainLightPos, lara->mainLightRadius, vec4(1, 1, 0, 1));
|
Debug::Draw::sphere(lara->mainLightPos, lara->mainLightColor.w, vec4(1, 1, 0, 1));
|
||||||
|
|
||||||
Box bbox = lara->getBoundingBox();
|
Box bbox = lara->getBoundingBox();
|
||||||
Debug::Draw::box(bbox.min, bbox.max , vec4(1, 0, 1, 1));
|
Debug::Draw::box(bbox.min, bbox.max, vec4(1, 0, 1, 1));
|
||||||
Debug::Draw::box(bRec.min, bRec.max , vec4(1, 0, 0, 1));
|
|
||||||
Debug::Draw::box(bCast.min, bCast.max, vec4(0, 0, 1, 1));
|
|
||||||
Debug::Draw::box(bSplit.min, bSplit.max, vec4(0, 1, 1, 1));
|
|
||||||
Debug::Draw::box(bCrop.min, bCrop.max, vec4(0, 1, 0, 1));
|
|
||||||
|
|
||||||
|
|
||||||
Core::setBlending(bmAlpha);
|
Core::setBlending(bmAlpha);
|
||||||
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
||||||
|
@@ -338,17 +338,13 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
} else
|
} else
|
||||||
rShadow /= 4.0;
|
rShadow /= 4.0;
|
||||||
|
|
||||||
return rShadow;
|
return rShadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getShadow() {
|
float getShadow() {
|
||||||
vec3 p = vLightProj.xyz / vLightProj.w;
|
// min(dot(vNormal.xyz, lv), vLightProj.w) > 0.0
|
||||||
float fade = smoothstep(0.0, 0.9, p.z);// * (p.z < 1.0 ? 1.0 : 0.0);
|
// clamp(dot(lv, lv), 2.0), 0.0, 1.0);
|
||||||
float k = max(abs(p.x), abs(p.y));
|
return vLightProj.w > 0.0 ? getShadow(vLightProj) : 1.0;
|
||||||
fade *= 1.0 - smoothstep(0.5, 1.0, k);
|
|
||||||
fade *= 1.0 - smoothstep(0.999, 1.0, max(0.0, p.z));
|
|
||||||
|
|
||||||
return ( fade > 0.0001 && min(dot(vNormal.xyz, vLightVec), vLightProj.w) > 0.0) ? mix(1.0, getShadow(vLightProj), fade) : 1.0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -246,8 +246,16 @@ struct vec4 {
|
|||||||
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(const vec2 &xy, const vec2 &zw) : x(xy.x), y(xy.y), z(zw.x), w(zw.y) {}
|
vec4(const vec2 &xy, const vec2 &zw) : x(xy.x), y(xy.y), z(zw.x), w(zw.y) {}
|
||||||
|
|
||||||
|
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) const { return vec4(x - v.x, y - v.y, z - v.z, w - v.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) 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; }
|
||||||
|
|
||||||
|
vec4 lerp(const vec4 &v, const float t) const {
|
||||||
|
if (t <= 0.0f) return *this;
|
||||||
|
if (t >= 1.0f) return v;
|
||||||
|
return *this + (v - *this) * t;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct quat {
|
struct quat {
|
||||||
|
Reference in New Issue
Block a user