mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 07:34:33 +02:00
15
src/core.h
15
src/core.h
@@ -139,9 +139,9 @@ namespace Core {
|
||||
vec4 lightColor[MAX_LIGHTS];
|
||||
vec4 color;
|
||||
|
||||
enum { passOpaque, passShadow } pass;
|
||||
enum Pass { passCompose, passShadow, passAmbient } pass;
|
||||
|
||||
GLuint RT;
|
||||
GLuint RT, RB;
|
||||
|
||||
struct {
|
||||
Shader *shader;
|
||||
@@ -246,6 +246,10 @@ namespace Core {
|
||||
// support.depthTexture = support.shadowSampler = false; // depth textures is not supported in Safari browser in fact :(
|
||||
|
||||
glGenFramebuffers(1, &RT);
|
||||
glGenRenderbuffers(1, &RB);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, RB);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 64, 64);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
Sound::init();
|
||||
|
||||
@@ -258,6 +262,11 @@ namespace Core {
|
||||
Sound::free();
|
||||
}
|
||||
|
||||
void resetStates() {
|
||||
memset(&active, 0, sizeof(active));
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void clear(const vec4 &color) {
|
||||
glClearColor(color.x, color.y, color.z, color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
@@ -316,6 +325,8 @@ namespace Core {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, RT);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, target->depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target->ID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, target->depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, target->dummy ? target->dummy->ID : 0, 0);
|
||||
if (!target->depth)
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RB);
|
||||
|
||||
bool mask = !target->depth;
|
||||
glColorMask(mask, mask, mask, mask);
|
||||
|
38
src/lara.h
38
src/lara.h
@@ -1559,20 +1559,42 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
void move() {
|
||||
TR::Entity &e = getEntity();
|
||||
TR::Level::FloorInfo info;
|
||||
|
||||
float f, c;
|
||||
bool canPassGap = true;
|
||||
/*
|
||||
if (velocity != 0.0f) {
|
||||
vec3 dir = velocity.normal() * 128.0f;
|
||||
vec3 p = pos + dir;
|
||||
level->getFloorInfo(e.room, (int)p.x, (int)p.y, (int)p.z, info);
|
||||
if (info.floor < p.y - (256 + 128) || info.ceiling > p.y - 768) { // wall
|
||||
vec3 axis = dir.axisXZ();
|
||||
vec3 normal = (p - vec3(int(p.x / 1024.0f) * 1024.0f + 512.0f, p.y, int(p.z / 1024.0f) * 1024.0f + 512.0f)).axisXZ();
|
||||
LOG("%f %f = %f %f = %f\n", axis.x, axis.z, normal.x, normal.z, abs(axis.dot(normal)));
|
||||
if (abs(axis.dot(normal)) > EPS) {
|
||||
canPassGap = false;
|
||||
} else {
|
||||
updateEntity();
|
||||
checkRoom();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
vec3 offset = velocity * Core::deltaTime * 30.0f;
|
||||
|
||||
vec3 p = pos;
|
||||
pos = pos + offset;
|
||||
|
||||
TR::Entity &e = getEntity();
|
||||
TR::Level::FloorInfo info;
|
||||
level->getFloorInfo(e.room, (int)pos.x, (int)pos.y, (int)pos.z, info);
|
||||
|
||||
// get frame to get height
|
||||
bool canPassGap = (info.floor - info.ceiling) >= (stand == STAND_GROUND ? 768 : 512);
|
||||
float f = info.floor - pos.y;
|
||||
float c = pos.y - info.ceiling;
|
||||
if (canPassGap) {
|
||||
level->getFloorInfo(e.room, (int)pos.x, (int)pos.y, (int)pos.z, info);
|
||||
canPassGap = (info.floor - info.ceiling) >= (stand == STAND_GROUND ? 768 : 512);
|
||||
}
|
||||
|
||||
f = info.floor - pos.y;
|
||||
c = pos.y - info.ceiling;
|
||||
/*
|
||||
TR::Animation *anim = animation;
|
||||
Box eBox = Box(pos - vec3(128.0f, 0.0f, 128.0f), pos + vec3(128.0, getHeight(), 128.0f)); // getBoundingBox();
|
||||
|
176
src/level.h
176
src/level.h
@@ -22,7 +22,7 @@ const char GUI[] =
|
||||
;
|
||||
|
||||
struct Level {
|
||||
enum { shDefault, shShadow, shGUI, shMAX };
|
||||
enum { shCompose, shShadow, shAmbient, shGUI, shMAX };
|
||||
|
||||
TR::Level level;
|
||||
Shader *shaders[shMAX];
|
||||
@@ -32,6 +32,7 @@ struct Level {
|
||||
Lara *lara;
|
||||
Camera *camera;
|
||||
Texture *shadow;
|
||||
Texture *ambient[4]; // 64, 16, 4, 1
|
||||
|
||||
float time;
|
||||
|
||||
@@ -42,6 +43,8 @@ struct Level {
|
||||
mesh = new MeshBuilder(level);
|
||||
|
||||
shadow = new Texture(1024, 1024, true);
|
||||
for (int i = 0; i < 4; i++)
|
||||
ambient[i] = new Texture(64 >> (i << 1), 64 >> (i << 1), false);
|
||||
|
||||
initAtlas();
|
||||
initShaders();
|
||||
@@ -154,6 +157,9 @@ struct Level {
|
||||
delete shaders[i];
|
||||
|
||||
delete shadow;
|
||||
for (int i = 0; i < 4; i++)
|
||||
delete ambient[i];
|
||||
|
||||
delete atlas;
|
||||
delete mesh;
|
||||
|
||||
@@ -214,11 +220,12 @@ struct Level {
|
||||
else
|
||||
strcat(ext, "#define SHADOW_COLOR\n");
|
||||
|
||||
sprintf(def, "%s#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_SHADOW_DIST %d.0\n", ext, MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount, MAX_SHADOW_DIST);
|
||||
shaders[shDefault] = new Shader(SHADER, def);
|
||||
sprintf(def, "%s#define PASS_COMPOSE\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_SHADOW_DIST %d.0\n", ext, MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount, MAX_SHADOW_DIST);
|
||||
shaders[shCompose] = new Shader(SHADER, def);
|
||||
sprintf(def, "%s#define PASS_SHADOW\n", ext);
|
||||
shaders[shShadow] = new Shader(SHADER, def);
|
||||
sprintf(ext, "%s#define SPRITE\n", def);
|
||||
sprintf(def, "%s#define PASS_AMBIENT\n", ext);
|
||||
shaders[shAmbient] = new Shader(SHADER, def);
|
||||
shaders[shGUI] = new Shader(GUI, "");
|
||||
}
|
||||
|
||||
@@ -323,13 +330,10 @@ struct Level {
|
||||
}
|
||||
#endif
|
||||
|
||||
void setRoomShader(const TR::Room &room, float intensity) {
|
||||
if (Core::pass == Core::passShadow) {
|
||||
shaders[shShadow]->bind();
|
||||
void setRoomParams(const TR::Room &room, float intensity) {
|
||||
if (Core::pass == Core::passShadow)
|
||||
return;
|
||||
}
|
||||
|
||||
shaders[shDefault]->bind();
|
||||
if (room.flags.water) {
|
||||
Core::color = vec4(0.6f, 0.9f, 0.9f, intensity);
|
||||
Core::active.shader->setParam(uCaustics, 1);
|
||||
@@ -347,7 +351,7 @@ struct Level {
|
||||
TR::Room &room = level.rooms[roomIndex];
|
||||
vec3 offset = vec3(float(room.info.x), 0.0f, float(room.info.z));
|
||||
|
||||
setRoomShader(room, intensityf(room.ambient));
|
||||
setRoomParams(room, intensityf(room.ambient));
|
||||
Shader *sh = Core::active.shader;
|
||||
|
||||
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
||||
@@ -396,7 +400,7 @@ struct Level {
|
||||
sh->setParam(uModel, Core::mModel);
|
||||
|
||||
// render room geometry
|
||||
if (Core::pass == Core::passOpaque) {
|
||||
if (Core::pass == Core::passCompose || Core::pass == Core::passAmbient) {
|
||||
mesh->renderRoomGeometry(roomIndex);
|
||||
}
|
||||
|
||||
@@ -493,7 +497,7 @@ struct Level {
|
||||
return;
|
||||
|
||||
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
|
||||
setRoomShader(room, intensityf(lum));
|
||||
setRoomParams(room, intensityf(lum));
|
||||
|
||||
if (entity.modelIndex > 0) { // model
|
||||
getLight(((Controller*)entity.controller)->pos, entity.room);
|
||||
@@ -512,7 +516,6 @@ struct Level {
|
||||
((Controller*)entity.controller)->render(camera->frustum, mesh);
|
||||
}
|
||||
|
||||
|
||||
void update() {
|
||||
time += Core::deltaTime;
|
||||
|
||||
@@ -529,7 +532,7 @@ struct Level {
|
||||
void setup() {
|
||||
PROFILE_MARKER("SETUP");
|
||||
|
||||
camera->setup(Core::pass != Core::passShadow);;
|
||||
camera->setup(Core::pass == Core::passCompose);
|
||||
|
||||
atlas->bind(0);
|
||||
|
||||
@@ -537,19 +540,16 @@ struct Level {
|
||||
mesh->bind();
|
||||
|
||||
// set frame constants for all shaders
|
||||
Core::active.shader = NULL;
|
||||
for (int i = 0; i < shMAX; i++) {
|
||||
shaders[i]->bind();
|
||||
shaders[i]->setParam(uViewProj, Core::mViewProj);
|
||||
shaders[i]->setParam(uLightProj, Core::mLightProj);
|
||||
shaders[i]->setParam(uViewInv, Core::mViewInv);
|
||||
shaders[i]->setParam(uViewPos, Core::viewPos);
|
||||
shaders[i]->setParam(uTime, time);
|
||||
shaders[i]->setParam(uLightTarget, lara->pos);
|
||||
shaders[i]->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
||||
shaders[i]->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
||||
}
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
Shader *sh = Core::active.shader;
|
||||
sh->bind();
|
||||
sh->setParam(uViewProj, Core::mViewProj);
|
||||
sh->setParam(uLightProj, Core::mLightProj);
|
||||
sh->setParam(uViewInv, Core::mViewInv);
|
||||
sh->setParam(uViewPos, Core::viewPos);
|
||||
sh->setParam(uTime, time);
|
||||
sh->setParam(uLightTarget, lara->pos);
|
||||
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
||||
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
||||
|
||||
Core::mModel.identity();
|
||||
|
||||
@@ -562,32 +562,50 @@ struct Level {
|
||||
room.meshes[j].flags.rendered = false; // clear visible flag for room static meshes
|
||||
}
|
||||
|
||||
for (int i = 0; i < level.entitiesCount; i++)
|
||||
level.entities[i].flags.rendered = false;
|
||||
if (Core::pass != Core::passAmbient)
|
||||
for (int i = 0; i < level.entitiesCount; i++)
|
||||
level.entities[i].flags.rendered = false;
|
||||
}
|
||||
|
||||
void renderRooms() {
|
||||
void renderRooms(int roomIndex) {
|
||||
PROFILE_MARKER("ROOMS");
|
||||
#ifdef LEVEL_EDITOR
|
||||
for (int i = 0; i < level.roomsCount; i++)
|
||||
renderRoom(i);
|
||||
#else
|
||||
renderRoom(camera->getRoomIndex());
|
||||
renderRoom(roomIndex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void renderEntities() {
|
||||
PROFILE_MARKER("ENTITIES");
|
||||
shaders[Core::pass == Core::passShadow ? shShadow : shDefault]->bind();
|
||||
for (int i = 0; i < level.entitiesCount; i++)
|
||||
renderEntity(level.entities[i]);
|
||||
}
|
||||
|
||||
void renderScene() {
|
||||
void renderScene(int roomIndex) {
|
||||
PROFILE_MARKER("SCENE");
|
||||
setup();
|
||||
renderRooms();
|
||||
renderEntities();
|
||||
renderRooms(roomIndex);
|
||||
if (Core::pass != Core::passAmbient)
|
||||
renderEntities();
|
||||
}
|
||||
|
||||
void setupCubeCamera(const vec3 &pos, int face) {
|
||||
vec3 up = vec3(0, 1, 0);
|
||||
vec3 dir;
|
||||
switch (face) {
|
||||
case 0 : dir = vec3( 1, 0, 0); break;
|
||||
case 1 : dir = vec3(-1, 0, 0); break;
|
||||
case 2 : dir = vec3( 0, 1, 0); up = vec3(1, 0, 0); break;
|
||||
case 3 : dir = vec3( 0, -1, 0); up = vec3(1, 0, 0); break;
|
||||
case 4 : dir = vec3( 0, 0, 1); break;
|
||||
case 5 : dir = vec3( 0, 0, -1); break;
|
||||
}
|
||||
|
||||
Core::mViewInv = mat4(pos, pos + dir, up);
|
||||
Core::mView = Core::mViewInv.inverse();
|
||||
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
||||
}
|
||||
|
||||
bool setupLightCamera() {
|
||||
@@ -600,48 +618,76 @@ struct Level {
|
||||
|
||||
TR::Room::Light &light = level.rooms[room].lights[idx];
|
||||
vec3 shadowLightPos = vec3(float(light.x), float(light.y), float(light.z));
|
||||
Core::mView = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0)).inverse();
|
||||
Core::mProj = mat4(120, 1.0f, camera->znear, camera->zfar);
|
||||
|
||||
Core::mViewProj = Core::mProj * Core::mView;
|
||||
Core::mViewInv = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0));
|
||||
Core::mView = Core::mViewInv.inverse();
|
||||
Core::mProj = mat4(120, 1.0f, camera->znear, camera->zfar);
|
||||
|
||||
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; // * ( * ) ?
|
||||
|
||||
Shader *sh = shaders[shShadow];
|
||||
sh->bind();
|
||||
sh->setParam(uViewProj, Core::mViewProj);
|
||||
sh->setParam(uLightProj, Core::mLightProj);
|
||||
Core::mLightProj = bias * Core::mProj * Core::mView;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderShadows() {
|
||||
if (!setupLightCamera()) return;
|
||||
void setPassShader(Core::Pass pass) {
|
||||
Core::pass = pass;
|
||||
Shader *sh = NULL;
|
||||
switch (pass) {
|
||||
case Core::passCompose : sh = shaders[shCompose]; break;
|
||||
case Core::passShadow : sh = shaders[shShadow]; break;
|
||||
case Core::passAmbient : sh = shaders[shAmbient]; break;
|
||||
}
|
||||
ASSERT(sh);
|
||||
sh->bind();
|
||||
}
|
||||
|
||||
void renderAmbient(int roomIndex, const vec3 &pos, vec3 *cube) {
|
||||
PROFILE_MARKER("PASS_AMBIENT");
|
||||
setupCubeCamera(pos, 4);
|
||||
|
||||
setPassShader(Core::passAmbient);
|
||||
Core::setBlending(bmAlpha);
|
||||
Core::setTarget(ambient[0]);
|
||||
Core::setViewport(0, 0, ambient[0]->width, ambient[0]->height);
|
||||
Core::clear(vec4(0, 0, 0, 1));
|
||||
renderScene(roomIndex);
|
||||
Core::setTarget(NULL);
|
||||
}
|
||||
|
||||
void renderShadows(int roomIndex) {
|
||||
PROFILE_MARKER("PASS_SHADOW");
|
||||
if (!setupLightCamera()) return;
|
||||
Texture::unbind(sShadow);
|
||||
Core::pass = Core::passShadow;
|
||||
Core::setBlending(bmNone);
|
||||
setPassShader(Core::passShadow);
|
||||
Core::setBlending(bmNone);
|
||||
Core::setTarget(shadow);
|
||||
Core::setViewport(0, 0, shadow->width, shadow->height);
|
||||
Core::clear(vec4(1.0));
|
||||
Core::setCulling(cfBack);
|
||||
renderScene();
|
||||
renderScene(roomIndex);
|
||||
Core::setCulling(cfFront);
|
||||
Core::setTarget(NULL);
|
||||
shadow->bind(sShadow);
|
||||
}
|
||||
|
||||
void render() {
|
||||
renderShadows();
|
||||
|
||||
Core::pass = Core::passOpaque;
|
||||
|
||||
void renderCompose(int roomIndex) {
|
||||
PROFILE_MARKER("PASS_COMPOSE");
|
||||
setPassShader(Core::passCompose);
|
||||
|
||||
Core::setBlending(bmAlpha);
|
||||
Core::clear(vec4(0.0f));
|
||||
Core::setViewport(0, 0, Core::width, Core::height);
|
||||
renderScene();
|
||||
shadow->bind(sShadow);
|
||||
renderScene(roomIndex);
|
||||
}
|
||||
|
||||
void render() {
|
||||
Core::resetStates();
|
||||
|
||||
vec3 cube[6];
|
||||
// renderAmbient(lara->getRoomIndex(), lara->pos - vec3(0, 512, 0), cube);
|
||||
renderShadows(lara->getRoomIndex());
|
||||
renderCompose(camera->getRoomIndex());
|
||||
|
||||
#ifdef _DEBUG
|
||||
static int modelIndex = 0;
|
||||
@@ -673,29 +719,29 @@ struct Level {
|
||||
|
||||
Debug::begin();
|
||||
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
||||
Debug::Level::lights(level, lara->getRoomIndex());
|
||||
// Debug::Level::lights(level, lara->getRoomIndex());
|
||||
// Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y);
|
||||
// Debug::Level::portals(level);
|
||||
// Debug::Level::meshes(level);
|
||||
// Debug::Level::entities(level);
|
||||
/*
|
||||
|
||||
glPushMatrix();
|
||||
glColor3f(1, 1, 1);
|
||||
glTranslatef(lara->pos.x, lara->pos.y, lara->pos.z);
|
||||
Texture::unbind(sShadow);
|
||||
shadow->bind(sDiffuse);
|
||||
ambient[0]->bind(sDiffuse);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0); glVertex3f( 0, 0, 0);
|
||||
glTexCoord2f(1, 0); glVertex3f(1024, 0, 0);
|
||||
glTexCoord2f(1, 1); glVertex3f(1024, -1024, 0);
|
||||
glTexCoord2f(0, 1); glVertex3f( 0, -1024, 0);
|
||||
glTexCoord2f(1, 1); glVertex3f( 0, 0, 0);
|
||||
glTexCoord2f(0, 1); glVertex3f(1024, 0, 0);
|
||||
glTexCoord2f(0, 0); glVertex3f(1024, -1024, 0);
|
||||
glTexCoord2f(1, 0); glVertex3f( 0, -1024, 0);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
*/
|
||||
|
||||
/*
|
||||
shaders[shGUI]->bind();
|
||||
Core::mViewProj = mat4(0, (float)Core::width, (float)Core::height, 0, 0, 1);
|
||||
|
127
src/shader.glsl
127
src/shader.glsl
@@ -2,12 +2,14 @@ R"====(
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
#ifndef PASS_SHADOW
|
||||
varying vec3 vCoord;
|
||||
varying vec4 vNormal;
|
||||
varying vec3 vViewVec;
|
||||
#ifndef PASS_AMBIENT
|
||||
varying vec3 vCoord;
|
||||
varying vec4 vNormal;
|
||||
varying vec3 vViewVec;
|
||||
varying vec4 vLightProj;
|
||||
varying float vLightTargetDist;
|
||||
#endif
|
||||
varying vec4 vColor;
|
||||
varying vec4 vLightProj;
|
||||
varying float vLightTargetDist;
|
||||
#endif
|
||||
|
||||
#define TYPE_SPRITE 0
|
||||
@@ -16,26 +18,34 @@ varying vec2 vTexCoord;
|
||||
#define TYPE_FLASH 3
|
||||
|
||||
uniform int uType;
|
||||
uniform int uCaustics;
|
||||
uniform float uTime;
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
uniform int uCaustics;
|
||||
uniform float uTime;
|
||||
#endif
|
||||
|
||||
#ifdef VERTEX
|
||||
uniform mat4 uViewProj;
|
||||
uniform mat4 uModel;
|
||||
uniform mat4 uViewInv;
|
||||
uniform mat4 uLightProj;
|
||||
uniform vec3 uLightTarget;
|
||||
|
||||
#ifndef PASS_SHADOW
|
||||
#ifndef PASS_AMBIENT
|
||||
uniform mat4 uViewInv;
|
||||
uniform mat4 uLightProj;
|
||||
uniform vec3 uLightTarget;
|
||||
#endif
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
uniform vec3 uViewPos;
|
||||
uniform vec2 uAnimTexRanges[MAX_RANGES];
|
||||
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
||||
#endif
|
||||
|
||||
|
||||
attribute vec4 aCoord;
|
||||
attribute vec4 aTexCoord;
|
||||
attribute vec4 aNormal;
|
||||
|
||||
#ifndef PASS_AMBIENT
|
||||
attribute vec4 aNormal;
|
||||
#endif
|
||||
|
||||
#ifndef PASS_SHADOW
|
||||
attribute vec4 aColor;
|
||||
@@ -45,32 +55,31 @@ uniform float uTime;
|
||||
|
||||
void main() {
|
||||
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
|
||||
|
||||
|
||||
if (uType != TYPE_SPRITE) {
|
||||
#ifndef PASS_SHADOW
|
||||
#ifdef PASS_COMPOSE
|
||||
if (uType != TYPE_SPRITE) {
|
||||
// animated texture coordinates
|
||||
vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count
|
||||
|
||||
float f = fract((aTexCoord.w + uTime * 4.0 - range.x) / range.y) * range.y;
|
||||
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
|
||||
|
||||
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
||||
vNormal = vec4((uModel * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w);
|
||||
#else
|
||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||
#endif
|
||||
} else {
|
||||
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
||||
#ifndef PASS_SHADOW
|
||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
||||
#endif
|
||||
}
|
||||
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
||||
vNormal = vec4((uModel * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w);
|
||||
} else {
|
||||
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
||||
}
|
||||
#else
|
||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||
#endif
|
||||
|
||||
#ifndef PASS_SHADOW
|
||||
vColor = aColor;
|
||||
#endif
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
if (uCaustics != 0) {
|
||||
float sum = coord.x + coord.y + coord.z;
|
||||
vColor.xyz *= abs(sin(sum / 512.0 + uTime)) * 1.5 + 0.5; // color dodge
|
||||
@@ -91,7 +100,7 @@ uniform float uTime;
|
||||
#else
|
||||
uniform sampler2D sDiffuse;
|
||||
uniform vec4 uColor;
|
||||
#ifndef PASS_SHADOW
|
||||
#ifdef PASS_COMPOSE
|
||||
uniform vec3 uLightPos[MAX_LIGHTS];
|
||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
||||
#endif
|
||||
@@ -106,7 +115,9 @@ uniform float uTime;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
#ifdef AMBIENT_CUBE
|
||||
uniform vec3 uAmbientCube[6];
|
||||
|
||||
@@ -180,7 +191,7 @@ uniform float uTime;
|
||||
poissonDisk[13] = vec2( -0.81409955, 0.91437590 );
|
||||
poissonDisk[14] = vec2( 0.19984126, 0.78641367 );
|
||||
poissonDisk[15] = vec2( 0.14383161, -0.14100790 );
|
||||
//return SHADOW(p);
|
||||
|
||||
float rShadow = 0.0;
|
||||
for (int i = 0; i < 16; i += 1)
|
||||
rShadow += SHADOW(p + vec3(poissonDisk[i] * 1.5, 0.0) * (1.0 / 1024.0));
|
||||
@@ -215,34 +226,38 @@ uniform float uTime;
|
||||
|
||||
color.xyz = pow(abs(color.xyz), vec3(2.2)); // to linear space
|
||||
|
||||
// calc point lights
|
||||
if (uType != TYPE_FLASH) {
|
||||
vec3 normal = normalize(vNormal.xyz);
|
||||
vec3 viewVec = normalize(vViewVec);
|
||||
vec3 light = vec3(0.0);
|
||||
#ifdef PASS_AMBIENT
|
||||
color.xyz *= vColor.w;
|
||||
#else
|
||||
// calc point lights
|
||||
if (uType != TYPE_FLASH) {
|
||||
vec3 normal = normalize(vNormal.xyz);
|
||||
vec3 viewVec = normalize(vViewVec);
|
||||
vec3 light = vec3(0.0);
|
||||
|
||||
for (int i = 1; i < MAX_LIGHTS; i++) // additional lights
|
||||
light += calcLight(normal, uLightPos[i], uLightColor[i]);
|
||||
for (int i = 1; i < MAX_LIGHTS; i++) // additional lights
|
||||
light += calcLight(normal, uLightPos[i], uLightColor[i]);
|
||||
|
||||
// apply lighting
|
||||
if (uType == TYPE_SPRITE) {
|
||||
light += vColor.w * uColor.w;
|
||||
// apply lighting
|
||||
if (uType == TYPE_SPRITE) {
|
||||
light += vColor.w * uColor.w;
|
||||
}
|
||||
|
||||
if (uType == TYPE_ROOM) {
|
||||
light += mix(min(uColor.w, vColor.w), vColor.w, getShadow(vLightProj));
|
||||
}
|
||||
|
||||
if (uType == TYPE_ENTITY) {
|
||||
float shadow = getShadow(vLightProj);
|
||||
vec3 lum = calcLight(normal, uLightPos[0], uLightColor[0]) * shadow + uColor.w;
|
||||
light += lum;
|
||||
light *= dot(normal, viewVec) * 0.2 + 0.8; // apply backlight
|
||||
}
|
||||
color.xyz *= light;
|
||||
} else {
|
||||
color.w = uColor.w;
|
||||
}
|
||||
|
||||
if (uType == TYPE_ROOM) {
|
||||
light += mix(min(uColor.w, vColor.w), vColor.w, getShadow(vLightProj));
|
||||
}
|
||||
|
||||
if (uType == TYPE_ENTITY) {
|
||||
float shadow = getShadow(vLightProj);
|
||||
vec3 lum = calcLight(normal, uLightPos[0], uLightColor[0]) * shadow + uColor.w;
|
||||
light += lum;
|
||||
light *= dot(normal, viewVec) * 0.2 + 0.8; // apply backlight
|
||||
}
|
||||
color.xyz *= light;
|
||||
} else {
|
||||
color.w = uColor.w;
|
||||
}
|
||||
#endif
|
||||
|
||||
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); // back to gamma space
|
||||
|
||||
|
@@ -133,6 +133,7 @@ struct vec3 {
|
||||
float length2() const { return dot(*this); }
|
||||
float length() const { return sqrtf(length2()); }
|
||||
vec3 normal() const { float s = length(); return s == 0.0f ? (*this) : (*this)*(1.0f/s); }
|
||||
vec3 axisXZ() const { return (fabsf(x) > fabsf(z)) ? vec3(sign(x), 0, 0) : vec3(0, 0, sign(z)); }
|
||||
|
||||
vec3 lerp(const vec3 &v, const float t) const {
|
||||
if (t <= 0.0f) return *this;
|
||||
|
Reference in New Issue
Block a user