mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-13 08:34:32 +02:00
add anaglyph (Red/Cyan) stereo support (WIP)
This commit is contained in:
@@ -110,6 +110,7 @@ struct ShaderCache {
|
|||||||
compile(Core::passFilter, Shader::FILTER_DOWNSAMPLE, fx, RS_COLOR_WRITE);
|
compile(Core::passFilter, Shader::FILTER_DOWNSAMPLE, fx, RS_COLOR_WRITE);
|
||||||
compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx, RS_COLOR_WRITE);
|
compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx, RS_COLOR_WRITE);
|
||||||
compile(Core::passFilter, Shader::FILTER_BLUR, fx, RS_COLOR_WRITE);
|
compile(Core::passFilter, Shader::FILTER_BLUR, fx, RS_COLOR_WRITE);
|
||||||
|
compile(Core::passFilter, Shader::FILTER_ANAGLYPH, fx, RS_COLOR_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareGUI(int fx) {
|
void prepareGUI(int fx) {
|
||||||
@@ -944,7 +945,7 @@ struct WaterCache {
|
|||||||
// render reflections frame
|
// render reflections frame
|
||||||
float sign = underwater ? -1.0f : 1.0f;
|
float sign = underwater ? -1.0f : 1.0f;
|
||||||
game->setClipParams(sign, waterLevel * sign);
|
game->setClipParams(sign, waterLevel * sign);
|
||||||
game->renderView(TR::NO_ROOM, false, roomsCount, roomsList);
|
game->renderView(TR::NO_ROOM, false, false, roomsCount, roomsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
game->setClipParams(1.0f, NO_CLIP_PLANE);
|
game->setClipParams(1.0f, NO_CLIP_PLANE);
|
||||||
|
@@ -511,8 +511,8 @@ struct Camera : ICamera {
|
|||||||
if (shake > 0.0f)
|
if (shake > 0.0f)
|
||||||
Core::mViewInv.setPos(Core::mViewInv.getPos() + vec3(0.0f, sinf(shake * PI * 7) * shake * 48.0f, 0.0f));
|
Core::mViewInv.setPos(Core::mViewInv.getPos() + vec3(0.0f, sinf(shake * PI * 7) * shake * 48.0f, 0.0f));
|
||||||
|
|
||||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON)
|
if (Core::settings.detail.stereo == Core::Settings::STEREO_SBS || Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH)
|
||||||
Core::mViewInv.setPos(Core::mViewInv.getPos() + Core::mViewInv.right().xyz() * (Core::eye * (firstPerson ? 8.0f : 32.0f) ));
|
Core::mViewInv.setPos(Core::mViewInv.getPos() + Core::mViewInv.right().xyz() * (Core::eye * 16.0f) );
|
||||||
|
|
||||||
if (reflectPlane) {
|
if (reflectPlane) {
|
||||||
Core::mViewInv = mat4(*reflectPlane) * Core::mViewInv;
|
Core::mViewInv = mat4(*reflectPlane) * Core::mViewInv;
|
||||||
|
@@ -74,7 +74,7 @@ struct IGame {
|
|||||||
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0, Core::Pass pass = Core::passAmbient) {}
|
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0, Core::Pass pass = Core::passAmbient) {}
|
||||||
virtual void renderModelFull(int modelIndex, bool underwater, Basis *joints) {}
|
virtual void renderModelFull(int modelIndex, bool underwater, Basis *joints) {}
|
||||||
virtual void renderCompose(int roomIndex) {}
|
virtual void renderCompose(int roomIndex) {}
|
||||||
virtual void renderView(int roomIndex, bool water, int roomsCount = 0, int *roomsList = NULL) {}
|
virtual void renderView(int roomIndex, bool water, bool showUI, int roomsCount = 0, int *roomsList = NULL) {}
|
||||||
virtual void renderGame(bool showUI) {}
|
virtual void renderGame(bool showUI) {}
|
||||||
virtual void setEffect(Controller *controller, TR::Effect::Type effect) {}
|
virtual void setEffect(Controller *controller, TR::Effect::Type effect) {}
|
||||||
|
|
||||||
|
10
src/core.h
10
src/core.h
@@ -230,7 +230,7 @@ namespace Core {
|
|||||||
|
|
||||||
struct Settings {
|
struct Settings {
|
||||||
enum Quality { LOW, MEDIUM, HIGH };
|
enum Quality { LOW, MEDIUM, HIGH };
|
||||||
enum Stereo { STEREO_OFF, STEREO_ON, STEREO_SPLIT, STEREO_VR };
|
enum Stereo { STEREO_OFF, STEREO_SBS, STEREO_ANAGLYPH, STEREO_SPLIT, STEREO_VR };
|
||||||
|
|
||||||
uint8 version;
|
uint8 version;
|
||||||
|
|
||||||
@@ -280,6 +280,10 @@ namespace Core {
|
|||||||
water = value;
|
water = value;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isStereo() {
|
||||||
|
return stereo == STEREO_SBS || stereo == STEREO_ANAGLYPH || stereo == STEREO_VR;
|
||||||
|
}
|
||||||
} detail;
|
} detail;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -509,6 +513,7 @@ struct MeshRange {
|
|||||||
E( FILTER_DOWNSAMPLE_DEPTH ) \
|
E( FILTER_DOWNSAMPLE_DEPTH ) \
|
||||||
E( FILTER_GRAYSCALE ) \
|
E( FILTER_GRAYSCALE ) \
|
||||||
E( FILTER_BLUR ) \
|
E( FILTER_BLUR ) \
|
||||||
|
E( FILTER_ANAGLYPH ) \
|
||||||
E( FILTER_EQUIRECTANGULAR ) \
|
E( FILTER_EQUIRECTANGULAR ) \
|
||||||
/* options */ \
|
/* options */ \
|
||||||
E( UNDERWATER ) \
|
E( UNDERWATER ) \
|
||||||
@@ -701,6 +706,7 @@ namespace Core {
|
|||||||
LOG("OpenLara (%s)\n", version);
|
LOG("OpenLara (%s)\n", version);
|
||||||
|
|
||||||
x = y = 0;
|
x = y = 0;
|
||||||
|
eyeTex[0] = eyeTex[1] = NULL;
|
||||||
|
|
||||||
memset(&support, 0, sizeof(support));
|
memset(&support, 0, sizeof(support));
|
||||||
support.texMinSize = 1;
|
support.texMinSize = 1;
|
||||||
@@ -897,6 +903,8 @@ namespace Core {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void deinit() {
|
void deinit() {
|
||||||
|
delete eyeTex[0];
|
||||||
|
delete eyeTex[1];
|
||||||
delete whiteTex;
|
delete whiteTex;
|
||||||
delete whiteCube;
|
delete whiteCube;
|
||||||
delete blackTex;
|
delete blackTex;
|
||||||
|
@@ -130,13 +130,13 @@ static const OptionItem optDetail[] = {
|
|||||||
#if defined(_OS_WIN) || defined(_OS_LINUX) || defined(_OS_PSP) || defined(_OS_RPI) || defined(_OS_PSV)
|
#if defined(_OS_WIN) || defined(_OS_LINUX) || defined(_OS_PSP) || defined(_OS_RPI) || defined(_OS_PSV)
|
||||||
OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_VSYNC, SETTINGS( detail.vsync ), STR_OFF, 0, 1 ),
|
OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_VSYNC, SETTINGS( detail.vsync ), STR_OFF, 0, 1 ),
|
||||||
#endif
|
#endif
|
||||||
#ifndef _OS_PSP
|
#if !defined(_OS_PSP) && !defined(_OS_PSV) && !defined(_OS_3DS)
|
||||||
OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_STEREO, SETTINGS( detail.stereo ), STR_OFF, 0,
|
OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_STEREO, SETTINGS( detail.stereo ), STR_NO_STEREO, 0,
|
||||||
#if /*defined(_OS_WIN) ||*/ defined(_OS_ANDROID)
|
#if /*defined(_OS_WIN) ||*/ defined(_OS_ANDROID)
|
||||||
3 /* with VR option */
|
4 /* with VR option */
|
||||||
#else
|
#else
|
||||||
2 /* without VR support */
|
3 /* without VR support */
|
||||||
#endif
|
#endif
|
||||||
),
|
),
|
||||||
#endif
|
#endif
|
||||||
OptionItem( ),
|
OptionItem( ),
|
||||||
@@ -1832,7 +1832,7 @@ struct Inventory {
|
|||||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR)
|
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR)
|
||||||
pos.z -= 256.0f;
|
pos.z -= 256.0f;
|
||||||
|
|
||||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON)
|
if (Core::settings.detail.stereo == Core::Settings::STEREO_SBS || Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH)
|
||||||
pos.x += Core::eye * 8.0f;
|
pos.x += Core::eye * 8.0f;
|
||||||
|
|
||||||
Core::mViewInv = mat4(pos, pos + vec3(0, 0, 1), vec3(0, -1, 0));
|
Core::mViewInv = mat4(pos, pos + vec3(0, 0, 1), vec3(0, -1, 0));
|
||||||
|
@@ -17,6 +17,9 @@ enum StringID {
|
|||||||
, STR_NO
|
, STR_NO
|
||||||
, STR_OFF
|
, STR_OFF
|
||||||
, STR_ON
|
, STR_ON
|
||||||
|
, STR_NO_STEREO
|
||||||
|
, STR_SBS
|
||||||
|
, STR_ANAGLYPH
|
||||||
, STR_SPLIT
|
, STR_SPLIT
|
||||||
, STR_VR
|
, STR_VR
|
||||||
, STR_QUALITY_LOW
|
, STR_QUALITY_LOW
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_DE[] = { ""
|
|||||||
, "NEIN"
|
, "NEIN"
|
||||||
, "Aus"
|
, "Aus"
|
||||||
, "An"
|
, "An"
|
||||||
|
, "Aus"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Geteilter Bildschirm"
|
, "Geteilter Bildschirm"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Niedrig"
|
, "Niedrig"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_EN[] = { ""
|
|||||||
, "NO"
|
, "NO"
|
||||||
, "Off"
|
, "Off"
|
||||||
, "On"
|
, "On"
|
||||||
|
, "Off"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Split Screen"
|
, "Split Screen"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Low"
|
, "Low"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_ES[] = { ""
|
|||||||
, "NO"
|
, "NO"
|
||||||
, "No"
|
, "No"
|
||||||
, "S)i"
|
, "S)i"
|
||||||
|
, "No"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Pantalla dividida"
|
, "Pantalla dividida"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Bajo"
|
, "Bajo"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_FI[] = { "Suomi"
|
|||||||
, "Ei"
|
, "Ei"
|
||||||
, "Off"
|
, "Off"
|
||||||
, "On"
|
, "On"
|
||||||
|
, "Off"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Jaettu Ruutu"
|
, "Jaettu Ruutu"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Alhainen"
|
, "Alhainen"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_FR[] = { ""
|
|||||||
, "NON"
|
, "NON"
|
||||||
, "Arret"
|
, "Arret"
|
||||||
, "Marche"
|
, "Marche"
|
||||||
|
, "Arret"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, ")Ecran Divis)e"
|
, ")Ecran Divis)e"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Bas"
|
, "Bas"
|
||||||
|
@@ -23,6 +23,9 @@ const char *STR_GR[] = { "Ελληνικά"
|
|||||||
, "ΟΧΙ"
|
, "ΟΧΙ"
|
||||||
, "Όχι"
|
, "Όχι"
|
||||||
, "Ναι"
|
, "Ναι"
|
||||||
|
, "Όχι"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Χωρισμένη Οθόνη"
|
, "Χωρισμένη Οθόνη"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Χαμηλό"
|
, "Χαμηλό"
|
||||||
@@ -376,6 +379,9 @@ const char *STR_GR[] = { "\x11\x01\x22\x01\x0F\x01\x0F\x01\x0E\x01\x06\x01\x04\x
|
|||||||
, "\x11\x01\x28\x01\x2A\x01\x30\xFF\xFF"
|
, "\x11\x01\x28\x01\x2A\x01\x30\xFF\xFF"
|
||||||
, "\x11\x01\x32\x01\x18\x01\x04\xFF\xFF"
|
, "\x11\x01\x32\x01\x18\x01\x04\xFF\xFF"
|
||||||
, "\x11\x01\x27\x01\x01\x01\x04\xFF\xFF"
|
, "\x11\x01\x27\x01\x01\x01\x04\xFF\xFF"
|
||||||
|
, "\x11\x01\x32\x01\x18\x01\x04\xFF\xFF"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "\x11\x01\x2A\x01\x16\x01\x07\x01\x04\x01\x09\x01\x0A\x01\x12\x01\x06\x01\x0E\xFF\xFF"" \x11\x01\x28\x01\x19\x01\x13\x01\x06\x01\x0E\xFF\xFF"
|
, "\x11\x01\x2A\x01\x16\x01\x07\x01\x04\x01\x09\x01\x0A\x01\x12\x01\x06\x01\x0E\xFF\xFF"" \x11\x01\x28\x01\x19\x01\x13\x01\x06\x01\x0E\xFF\xFF"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "\x11\x01\x2A\x01\x01\x01\x0A\x01\x0E\x01\x0F\x01\x13\xFF\xFF"
|
, "\x11\x01\x2A\x01\x01\x01\x0A\x01\x0E\x01\x0F\x01\x13\xFF\xFF"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_IT[] = { ""
|
|||||||
, "NO"
|
, "NO"
|
||||||
, "Off"
|
, "Off"
|
||||||
, "On"
|
, "On"
|
||||||
|
, "Off"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Schermo diviso"
|
, "Schermo diviso"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Basso"
|
, "Basso"
|
||||||
|
@@ -23,6 +23,9 @@ const char *STR_JA[] = { "日本語"
|
|||||||
, "いいえ"
|
, "いいえ"
|
||||||
, "オフ"
|
, "オフ"
|
||||||
, "オン"
|
, "オン"
|
||||||
|
, "オフ"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "画面分割"
|
, "画面分割"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "低"
|
, "低"
|
||||||
@@ -329,6 +332,9 @@ const char *STR_JA[] = { "\x11\x02\x70\x01\x97\x01\xD6\xFF\xFF"
|
|||||||
, "\x11\x01\x0C\x01\x0C\x01\x4B\xFF\xFF"
|
, "\x11\x01\x0C\x01\x0C\x01\x4B\xFF\xFF"
|
||||||
, "\x11\x01\x3B\x01\x47\xFF\xFF"
|
, "\x11\x01\x3B\x01\x47\xFF\xFF"
|
||||||
, "\x11\x01\x3B\x01\x02\xFF\xFF"
|
, "\x11\x01\x3B\x01\x02\xFF\xFF"
|
||||||
|
, "\x11\x01\x3B\x01\x47\xFF\xFF"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "\x11\x02\x69\x02\x66\x01\xCA\x02\x67\xFF\xFF"
|
, "\x11\x02\x69\x02\x66\x01\xCA\x02\x67\xFF\xFF"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "\x11\x02\x6C\xFF\xFF"
|
, "\x11\x02\x6C\xFF\xFF"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_PL[] = { ""
|
|||||||
, "NIE"
|
, "NIE"
|
||||||
, "Wy}l"
|
, "Wy}l"
|
||||||
, "W}l"
|
, "W}l"
|
||||||
|
, "Wy}l"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Podzielony ekran"
|
, "Podzielony ekran"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Niska"
|
, "Niska"
|
||||||
|
@@ -20,6 +20,9 @@ const char *STR_PT[] = { ""
|
|||||||
, "N+AO"
|
, "N+AO"
|
||||||
, "Desligado"
|
, "Desligado"
|
||||||
, "Ligado"
|
, "Ligado"
|
||||||
|
, "Desligado"
|
||||||
|
, "Side-By-Side"
|
||||||
|
, "Anaglyph"
|
||||||
, "Tela Separada"
|
, "Tela Separada"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "Baixo"
|
, "Baixo"
|
||||||
|
@@ -24,6 +24,9 @@ const char *STR_RU[] = { ""
|
|||||||
, "<EFBFBD><EFBFBD><EFBFBD>"
|
, "<EFBFBD><EFBFBD><EFBFBD>"
|
||||||
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
, "<EFBFBD><EFBFBD><EFBFBD>"
|
, "<EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD>{<7B> <20><><EFBFBD><EFBFBD><EFBFBD>"
|
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD>{<7B> <20><><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
, "VR"
|
, "VR"
|
||||||
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
232
src/level.h
232
src/level.h
@@ -42,7 +42,7 @@ struct Level : IGame {
|
|||||||
|
|
||||||
Lara *players[2], *player;
|
Lara *players[2], *player;
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
Texture *shadow;
|
Texture *shadow[2];
|
||||||
|
|
||||||
struct Params {
|
struct Params {
|
||||||
float time;
|
float time;
|
||||||
@@ -348,14 +348,16 @@ struct Level : IGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initShadow() {
|
void initShadow() {
|
||||||
delete shadow;
|
delete shadow[0];
|
||||||
|
delete shadow[1];
|
||||||
|
shadow[0] = shadow[1] = NULL;
|
||||||
|
|
||||||
if (Core::settings.detail.shadows > Core::Settings::LOW) {
|
if (Core::settings.detail.shadows > Core::Settings::LOW) {
|
||||||
if (level.isTitle())
|
if (level.isTitle())
|
||||||
shadow = new Texture(32, 32, 1, FMT_SHADOW); // init dummy shadow map
|
shadow[0] = new Texture(32, 32, 1, FMT_SHADOW); // init dummy shadow map
|
||||||
else
|
else
|
||||||
shadow = new Texture(SHADOW_TEX_SIZE, SHADOW_TEX_SIZE, 1, FMT_SHADOW, OPT_TARGET);
|
shadow[0] = new Texture(SHADOW_TEX_SIZE, SHADOW_TEX_SIZE, 1, FMT_SHADOW, OPT_TARGET);
|
||||||
} else
|
}
|
||||||
shadow = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void applySettings(const Core::Settings &settings) {
|
virtual void applySettings(const Core::Settings &settings) {
|
||||||
@@ -587,7 +589,10 @@ struct Level : IGame {
|
|||||||
Core::whiteTex->bind(sMask);
|
Core::whiteTex->bind(sMask);
|
||||||
Core::whiteTex->bind(sReflect);
|
Core::whiteTex->bind(sReflect);
|
||||||
Core::whiteCube->bind(sEnvironment);
|
Core::whiteCube->bind(sEnvironment);
|
||||||
if (shadow) shadow->bind(sShadow);
|
|
||||||
|
Texture *shadowMap = shadow[player->camera->cameraIndex];
|
||||||
|
if (shadowMap) shadowMap->bind(sShadow);
|
||||||
|
|
||||||
Core::basis.identity();
|
Core::basis.identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,7 +612,7 @@ struct Level : IGame {
|
|||||||
Core::pass = pass;
|
Core::pass = pass;
|
||||||
Texture *target = (targets[0]->opt & OPT_CUBEMAP) ? targets[0] : targets[i * stride];
|
Texture *target = (targets[0]->opt & OPT_CUBEMAP) ? targets[0] : targets[i * stride];
|
||||||
Core::setTarget(target, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR, i);
|
Core::setTarget(target, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR, i);
|
||||||
renderView(rIndex, false);
|
renderView(rIndex, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::pass = tmpPass;
|
Core::pass = tmpPass;
|
||||||
@@ -913,7 +918,7 @@ struct Level : IGame {
|
|||||||
mesh = new MeshBuilder(&level, atlasRooms);
|
mesh = new MeshBuilder(&level, atlasRooms);
|
||||||
initEntities();
|
initEntities();
|
||||||
|
|
||||||
shadow = NULL;
|
shadow[0] = shadow[1] = NULL;
|
||||||
camera = NULL;
|
camera = NULL;
|
||||||
ambientCache = NULL;
|
ambientCache = NULL;
|
||||||
waterCache = NULL;
|
waterCache = NULL;
|
||||||
@@ -981,7 +986,8 @@ struct Level : IGame {
|
|||||||
for (int i = 0; i < level.entitiesCount; i++)
|
for (int i = 0; i < level.entitiesCount; i++)
|
||||||
delete (Controller*)level.entities[i].controller;
|
delete (Controller*)level.entities[i].controller;
|
||||||
|
|
||||||
delete shadow;
|
delete shadow[0];
|
||||||
|
delete shadow[1];
|
||||||
delete ambientCache;
|
delete ambientCache;
|
||||||
delete waterCache;
|
delete waterCache;
|
||||||
delete zoneCache;
|
delete zoneCache;
|
||||||
@@ -2382,7 +2388,7 @@ struct Level : IGame {
|
|||||||
Core::fogParams = oldFog;
|
Core::fogParams = oldFog;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void renderView(int roomIndex, bool water, int roomsCount = 0, int *roomsList = NULL) {
|
virtual void renderView(int roomIndex, bool water, bool showUI, int roomsCount = 0, int *roomsList = NULL) {
|
||||||
PROFILE_MARKER("VIEW");
|
PROFILE_MARKER("VIEW");
|
||||||
|
|
||||||
if (water && waterCache)
|
if (water && waterCache)
|
||||||
@@ -2485,6 +2491,10 @@ struct Level : IGame {
|
|||||||
waterCache->blitTexture(screen);
|
waterCache->blitTexture(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showUI) {
|
||||||
|
renderUI();
|
||||||
|
}
|
||||||
|
|
||||||
Core::pass = pass;
|
Core::pass = pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2533,7 +2543,7 @@ struct Level : IGame {
|
|||||||
camera->frustum->calcPlanes(Core::mViewProj);
|
camera->frustum->calcPlanes(Core::mViewProj);
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
renderView(roomIndex, false);
|
renderView(roomIndex, false, false);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
void renderShadowEntity(int index, Controller *controller, Controller *player) {
|
void renderShadowEntity(int index, Controller *controller, Controller *player) {
|
||||||
@@ -2635,7 +2645,7 @@ struct Level : IGame {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
void renderShadows(int roomIndex) {
|
void renderShadows(int roomIndex, Texture *shadowMap) {
|
||||||
PROFILE_MARKER("PASS_SHADOW");
|
PROFILE_MARKER("PASS_SHADOW");
|
||||||
|
|
||||||
if (Core::settings.detail.shadows == Core::Settings::LOW)
|
if (Core::settings.detail.shadows == Core::Settings::LOW)
|
||||||
@@ -2647,11 +2657,11 @@ struct Level : IGame {
|
|||||||
Core::eye = 0.0f;
|
Core::eye = 0.0f;
|
||||||
|
|
||||||
Core::pass = Core::passShadow;
|
Core::pass = Core::passShadow;
|
||||||
shadow->unbind(sShadow);
|
shadowMap->unbind(sShadow);
|
||||||
bool colorShadow = shadow->fmt == FMT_RGBA ? true : false;
|
bool colorShadow = shadowMap->fmt == FMT_RGBA ? true : false;
|
||||||
if (colorShadow)
|
if (colorShadow)
|
||||||
Core::setClearColor(vec4(1.0f));
|
Core::setClearColor(vec4(1.0f));
|
||||||
Core::setTarget(shadow, NULL, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH));
|
Core::setTarget(shadowMap, NULL, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH));
|
||||||
//Core::setCullMode(cmBack);
|
//Core::setCullMode(cmBack);
|
||||||
Core::validateRenderState();
|
Core::validateRenderState();
|
||||||
|
|
||||||
@@ -2917,7 +2927,14 @@ struct Level : IGame {
|
|||||||
|
|
||||||
C3D_FrameDrawOn(GAPI::curTarget);
|
C3D_FrameDrawOn(GAPI::curTarget);
|
||||||
#else
|
#else
|
||||||
if (Core::settings.detail.stereo != Core::Settings::STEREO_VR) {
|
if (Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH || Core::settings.detail.stereo == Core::Settings::STEREO_VR) {
|
||||||
|
if (eye <= 0) {
|
||||||
|
Core::defaultTarget = Core::eyeTex[0];
|
||||||
|
} else {
|
||||||
|
Core::defaultTarget = Core::eyeTex[1];
|
||||||
|
}
|
||||||
|
Core::setTarget(Core::defaultTarget, NULL, 0);
|
||||||
|
} else {
|
||||||
switch (eye) {
|
switch (eye) {
|
||||||
case -1 : vp = Viewport(vX + vp.x - vp.x / 2, vY + vp.y, vp.width / 2, vp.height); break;
|
case -1 : vp = Viewport(vX + vp.x - vp.x / 2, vY + vp.y, vp.width / 2, vp.height); break;
|
||||||
case +1 : vp = Viewport(vX + vW / 2 + vp.x / 2, vY + vp.y, vp.width / 2, vp.height); break;
|
case +1 : vp = Viewport(vX + vW / 2 + vp.x / 2, vY + vp.y, vp.width / 2, vp.height); break;
|
||||||
@@ -2934,6 +2951,26 @@ struct Level : IGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void renderPrepare() {
|
void renderPrepare() {
|
||||||
|
#ifdef _OS_3DS
|
||||||
|
Core::settings.detail.stereo = osGet3DSliderState() > 0.0f ? Core::Settings::STEREO_SBS : Core::Settings::STEREO_OFF;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH) {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Texture *&tex = Core::eyeTex[i];
|
||||||
|
if (!tex || tex->origWidth != Core::width || tex->origHeight != Core::height) {
|
||||||
|
delete tex;
|
||||||
|
tex = new Texture(Core::width, Core::height, 1, FMT_RGBA, OPT_TARGET | OPT_NEAREST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (Core::settings.detail.stereo != Core::Settings::STEREO_VR) {
|
||||||
|
delete Core::eyeTex[0];
|
||||||
|
delete Core::eyeTex[1];
|
||||||
|
Core::eyeTex[0] = Core::eyeTex[1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
needRenderGame = !inventory->video && !level.isTitle() && ((inventory->phaseRing < 1.0f && inventory->titleTimer <= 1.0f) || needRedrawTitleBG);
|
||||||
|
|
||||||
if (inventory->video) {
|
if (inventory->video) {
|
||||||
inventory->render(1.0);
|
inventory->render(1.0);
|
||||||
|
|
||||||
@@ -2944,11 +2981,8 @@ struct Level : IGame {
|
|||||||
UI::renderSubs();
|
UI::renderSubs();
|
||||||
UI::end();
|
UI::end();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
needRenderGame = !inventory->video && !level.isTitle() && ((inventory->phaseRing < 1.0f && inventory->titleTimer <= 1.0f) || needRedrawTitleBG);
|
|
||||||
|
|
||||||
if (!needRenderGame)
|
if (!needRenderGame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2957,36 +2991,29 @@ struct Level : IGame {
|
|||||||
needRedrawReflections = false;
|
needRedrawReflections = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ambientCache)
|
if (ambientCache) {
|
||||||
ambientCache->processQueue();
|
ambientCache->processQueue();
|
||||||
|
}
|
||||||
|
|
||||||
if (shadow && player)
|
if (shadow[0] && players[0]) {
|
||||||
renderShadows(player->getRoomIndex());
|
player = players[0];
|
||||||
|
renderShadows(player->getRoomIndex(), shadow[0]);
|
||||||
|
|
||||||
|
if (players[1]) {
|
||||||
|
if (!shadow[1]) {
|
||||||
|
shadow[1] = new Texture(shadow[0]->origWidth, shadow[0]->origHeight, 1, shadow[0]->fmt, shadow[0]->opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
player = players[1];
|
||||||
|
renderShadows(player->getRoomIndex(), shadow[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderGame(bool showUI) {
|
void renderEye(int eye, bool showUI) {
|
||||||
//if (Core::settings.detail.stereo || Core::settings.detail.splitscreen) {
|
float oldEye = Core::eye;
|
||||||
// Core::setTarget(NULL, CLEAR_ALL);
|
Viewport oldViewport = Core::viewportDef;
|
||||||
// Core::validateRenderState();
|
GAPI::Texture *oldTarget = Core::defaultTarget;
|
||||||
//}
|
|
||||||
|
|
||||||
/* // catsuit test
|
|
||||||
lara->bakeEnvironment();
|
|
||||||
lara->visibleMask = Lara::BODY_HEAD | Lara::BODY_ARM_L3 | Lara::BODY_ARM_R3;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// EQUIRECTANGULAR PROJECTION test
|
|
||||||
if (!cube360)
|
|
||||||
cube360 = new Texture(1024, 1024, 1, Texture::RGBA, true, NULL, true, false);
|
|
||||||
renderEnvironment(camera->getRoomIndex(), camera->pos, &cube360, 0, Core::passCompose);
|
|
||||||
Core::setTarget(NULL, Core::CLEAR_ALL);
|
|
||||||
setShader(Core::passFilter, Shader::FILTER_EQUIRECTANGULAR);
|
|
||||||
cube360->bind(sEnvironment);
|
|
||||||
mesh->renderQuad();
|
|
||||||
return;
|
|
||||||
*/
|
|
||||||
Viewport vp = Core::viewportDef;
|
|
||||||
|
|
||||||
int viewsCount = players[1] ? 2 : 1;
|
int viewsCount = players[1] ? 2 : 1;
|
||||||
for (int view = 0; view < viewsCount; view++) {
|
for (int view = 0; view < viewsCount; view++) {
|
||||||
@@ -2996,99 +3023,45 @@ struct Level : IGame {
|
|||||||
setClipParams(1.0f, NO_CLIP_PLANE);
|
setClipParams(1.0f, NO_CLIP_PLANE);
|
||||||
params->waterHeight = params->clipHeight;
|
params->waterHeight = params->clipHeight;
|
||||||
|
|
||||||
if (shadow) {
|
|
||||||
if (view > 0/* && Core::settings.detail.shadows < Core::Settings::HIGH*/)
|
|
||||||
renderShadows(player->getRoomIndex()); // render shadows for player2 for all-in-one shadow technique
|
|
||||||
shadow->bind(sShadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::pass = Core::passCompose;
|
Core::pass = Core::passCompose;
|
||||||
|
|
||||||
if (view == 0 && Input::hmd.ready) {
|
setViewport(view, eye, false);
|
||||||
Core::settings.detail.stereo = Core::Settings::STEREO_VR;
|
setup();
|
||||||
|
renderView(camera->getRoomIndex(), true, showUI);
|
||||||
GAPI::Texture *oldTarget = Core::defaultTarget;
|
|
||||||
Viewport vp = Core::viewportDef;
|
|
||||||
|
|
||||||
Core::defaultTarget = Core::eyeTex[0];
|
|
||||||
Core::viewportDef = Viewport(0, 0, Core::defaultTarget->width, Core::defaultTarget->height);
|
|
||||||
Core::setTarget(NULL,Core::defaultTarget, 0); // changing to 0 and adding defaultTarget parameter
|
|
||||||
Core::eye = -1.0f;
|
|
||||||
setup();
|
|
||||||
renderView(camera->getRoomIndex(), true);
|
|
||||||
|
|
||||||
Core::defaultTarget = Core::eyeTex[1];
|
|
||||||
Core::viewportDef = Viewport(0, 0, Core::defaultTarget->width, Core::defaultTarget->height);
|
|
||||||
Core::setTarget(NULL, Core::defaultTarget, 0);
|
|
||||||
Core::eye = 1.0f;
|
|
||||||
setup();
|
|
||||||
renderView(camera->getRoomIndex(), true);
|
|
||||||
|
|
||||||
//Core::settings.detail.vr = false;
|
|
||||||
|
|
||||||
Core::defaultTarget = oldTarget;
|
|
||||||
Core::setTarget(NULL, Core::defaultTarget, 0);
|
|
||||||
Core::viewportDef = vp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _OS_3DS
|
|
||||||
Core::settings.detail.stereo = osGet3DSliderState() > 0.0f ? Core::Settings::STEREO_ON : Core::Settings::STEREO_OFF;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON) { // left/right SBS stereo
|
|
||||||
float oldEye = Core::eye;
|
|
||||||
|
|
||||||
setViewport(view, -1, false);
|
|
||||||
setup();
|
|
||||||
renderView(camera->getRoomIndex(), true);
|
|
||||||
|
|
||||||
setViewport(view, 1, false);
|
|
||||||
setup();
|
|
||||||
renderView(camera->getRoomIndex(), true);
|
|
||||||
|
|
||||||
Core::eye = oldEye;
|
|
||||||
} else {
|
|
||||||
setViewport(view, int(Core::eye), false);
|
|
||||||
setup();
|
|
||||||
renderView(camera->getRoomIndex(), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showUI) {
|
Core::setTarget(NULL, NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR);
|
||||||
Core::Pass pass = Core::pass;
|
Core::resetLights();
|
||||||
|
|
||||||
for (int view = 0; view < viewsCount; view++) {
|
if (!(level.isTitle() || inventory->titleTimer > 0.0f))
|
||||||
player = players[view];
|
inventory->renderBackground();
|
||||||
camera = player->camera;
|
|
||||||
|
|
||||||
setClipParams(1.0f, NO_CLIP_PLANE);
|
renderInventoryEye(eye);
|
||||||
params->waterHeight = params->clipHeight;
|
|
||||||
|
|
||||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON) { // left/right SBS stereo
|
Core::defaultTarget = oldTarget;
|
||||||
float oldEye = Core::eye;
|
Core::viewportDef = oldViewport;
|
||||||
|
Core::eye = oldEye;
|
||||||
setViewport(view, -1, false);
|
|
||||||
renderUI();
|
|
||||||
|
|
||||||
setViewport(view, 1, false);
|
|
||||||
renderUI();
|
|
||||||
|
|
||||||
Core::eye = oldEye;
|
|
||||||
} else {
|
|
||||||
setViewport(view, int(Core::eye), false);
|
|
||||||
renderUI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::pass = pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
Core::viewportDef = vp;
|
|
||||||
|
|
||||||
player = players[0];
|
player = players[0];
|
||||||
camera = player->camera;
|
camera = player->camera;
|
||||||
|
}
|
||||||
|
|
||||||
// lara->visibleMask = 0xFFFFFFFF; // catsuit test
|
void renderGame(bool showUI) {
|
||||||
|
if (Core::eye == 0.0f && Core::settings.detail.isStereo()) {
|
||||||
|
renderEye(-1, showUI);
|
||||||
|
renderEye(+1, showUI);
|
||||||
|
} else {
|
||||||
|
renderEye(int(Core::eye), showUI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH) {
|
||||||
|
Core::setTarget(NULL, NULL, RT_STORE_COLOR);
|
||||||
|
setShader(Core::passFilter, Shader::FILTER_ANAGLYPH, false, false);
|
||||||
|
Core::eyeTex[0]->bind(sDiffuse);
|
||||||
|
Core::eyeTex[1]->bind(sNormal);
|
||||||
|
Core::setDepthTest(false);
|
||||||
|
mesh->renderQuad();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderUI() {
|
void renderUI() {
|
||||||
@@ -3179,7 +3152,6 @@ struct Level : IGame {
|
|||||||
|
|
||||||
void renderInventory() {
|
void renderInventory() {
|
||||||
Core::setTarget(NULL, NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR);
|
Core::setTarget(NULL, NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR);
|
||||||
|
|
||||||
Core::resetLights();
|
Core::resetLights();
|
||||||
|
|
||||||
if (!(level.isTitle() || inventory->titleTimer > 0.0f))
|
if (!(level.isTitle() || inventory->titleTimer > 0.0f))
|
||||||
@@ -3187,7 +3159,7 @@ struct Level : IGame {
|
|||||||
|
|
||||||
float oldEye = Core::eye;
|
float oldEye = Core::eye;
|
||||||
|
|
||||||
if ((Core::settings.detail.stereo == Core::Settings::STEREO_ON) || (Core::settings.detail.stereo == Core::Settings::STEREO_SPLIT && players[1])) {
|
if ((Core::settings.detail.stereo == Core::Settings::STEREO_SBS) || (Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH) || (Core::settings.detail.stereo == Core::Settings::STEREO_SPLIT && players[1])) {
|
||||||
renderInventoryEye(-1);
|
renderInventoryEye(-1);
|
||||||
renderInventoryEye(+1);
|
renderInventoryEye(+1);
|
||||||
} else
|
} else
|
||||||
|
@@ -8,7 +8,7 @@ struct Shader : GAPI::Shader {
|
|||||||
enum Type {
|
enum Type {
|
||||||
DEFAULT = 0,
|
DEFAULT = 0,
|
||||||
SPRITE = 0, FLASH, ROOM, ENTITY, MIRROR,
|
SPRITE = 0, FLASH, ROOM, ENTITY, MIRROR,
|
||||||
FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE, FILTER_DOWNSAMPLE_DEPTH, FILTER_GRAYSCALE, FILTER_BLUR, FILTER_EQUIRECTANGULAR,
|
FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE, FILTER_DOWNSAMPLE_DEPTH, FILTER_GRAYSCALE, FILTER_BLUR, FILTER_ANAGLYPH, FILTER_EQUIRECTANGULAR,
|
||||||
WATER_DROP = 0, WATER_SIMULATE, WATER_CAUSTICS, WATER_RAYS, WATER_MASK, WATER_COMPOSE,
|
WATER_DROP = 0, WATER_SIMULATE, WATER_CAUSTICS, WATER_RAYS, WATER_MASK, WATER_COMPOSE,
|
||||||
SKY_TEXTURE = 0, SKY_CLOUDS, SKY_CLOUDS_AZURE,
|
SKY_TEXTURE = 0, SKY_CLOUDS, SKY_CLOUDS_AZURE,
|
||||||
MAX = 6
|
MAX = 6
|
||||||
|
@@ -17,19 +17,21 @@ uniform vec4 uParam;
|
|||||||
uniform sampler2D sDiffuse;
|
uniform sampler2D sDiffuse;
|
||||||
uniform sampler2D sNormal;
|
uniform sampler2D sNormal;
|
||||||
|
|
||||||
vec4 downsample() { // uParam (textureSize, unused, unused, unused)
|
#ifdef FILTER_DOWNSAMPLE
|
||||||
vec4 color = vec4(0.0);
|
vec4 downsample() { // uParam (textureSize, unused, unused, unused)
|
||||||
for (float y = -1.5; y < 2.0; y++)
|
vec4 color = vec4(0.0);
|
||||||
for (float x = -1.5; x < 2.0; x++) {
|
for (float y = -1.5; y < 2.0; y++)
|
||||||
vec4 p;
|
for (float x = -1.5; x < 2.0; x++) {
|
||||||
p.xyz = texture2D(sDiffuse, vTexCoord + vec2(x, y) * uParam.x).xyz;
|
vec4 p;
|
||||||
p.w = dot(p.xyz, vec3(0.299, 0.587, 0.114));
|
p.xyz = texture2D(sDiffuse, vTexCoord + vec2(x, y) * uParam.x).xyz;
|
||||||
p.xyz *= p.w;
|
p.w = dot(p.xyz, vec3(0.299, 0.587, 0.114));
|
||||||
color += p;
|
p.xyz *= p.w;
|
||||||
}
|
color += p;
|
||||||
|
}
|
||||||
|
|
||||||
return vec4(color.xyz / color.w, 1.0);
|
return vec4(color.xyz / color.w, 1.0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FILTER_DOWNSAMPLE_DEPTH
|
#ifdef FILTER_DOWNSAMPLE_DEPTH
|
||||||
vec4 downsampleDepth() {
|
vec4 downsampleDepth() {
|
||||||
@@ -44,24 +46,28 @@ uniform vec4 uParam;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec4 grayscale() { // uParam (factor, unused, unused, unused)
|
#ifdef FILTER_GRAYSCALE
|
||||||
vec4 color = texture2D(sDiffuse, vTexCoord);
|
vec4 grayscale() { // uParam (factor, unused, unused, unused)
|
||||||
vec3 gray = vec3(dot(color, vec4(0.299, 0.587, 0.114, 0.0)));
|
vec4 color = texture2D(sDiffuse, vTexCoord);
|
||||||
return vec4(mix(color.xyz, gray, uParam.w) * uParam.xyz, color.w);
|
vec3 gray = vec3(dot(color, vec4(0.299, 0.587, 0.114, 0.0)));
|
||||||
}
|
return vec4(mix(color.xyz, gray, uParam.w) * uParam.xyz, color.w);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vec4 blur() { // uParam (dirX, dirY, 1 / textureSize, unused)
|
#ifdef FILTER_BLUR
|
||||||
const vec3 offset = vec3(0.0, 1.3846153846, 3.2307692308);
|
vec4 blur() { // uParam (dirX, dirY, 1 / textureSize, unused)
|
||||||
const vec3 weight = vec3(0.2270270270, 0.3162162162, 0.0702702703);
|
const vec3 offset = vec3(0.0, 1.3846153846, 3.2307692308);
|
||||||
|
const vec3 weight = vec3(0.2270270270, 0.3162162162, 0.0702702703);
|
||||||
|
|
||||||
vec2 dir = uParam.xy;
|
vec2 dir = uParam.xy;
|
||||||
vec4 color = texture2D(sDiffuse, vTexCoord) * weight[0];
|
vec4 color = texture2D(sDiffuse, vTexCoord) * weight[0];
|
||||||
color += texture2D(sDiffuse, vTexCoord + dir * offset[1]) * weight[1];
|
color += texture2D(sDiffuse, vTexCoord + dir * offset[1]) * weight[1];
|
||||||
color += texture2D(sDiffuse, vTexCoord - dir * offset[1]) * weight[1];
|
color += texture2D(sDiffuse, vTexCoord - dir * offset[1]) * weight[1];
|
||||||
color += texture2D(sDiffuse, vTexCoord + dir * offset[2]) * weight[2];
|
color += texture2D(sDiffuse, vTexCoord + dir * offset[2]) * weight[2];
|
||||||
color += texture2D(sDiffuse, vTexCoord - dir * offset[2]) * weight[2];
|
color += texture2D(sDiffuse, vTexCoord - dir * offset[2]) * weight[2];
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FILTER_EQUIRECTANGULAR
|
#ifdef FILTER_EQUIRECTANGULAR
|
||||||
uniform samplerCube sEnvironment;
|
uniform samplerCube sEnvironment;
|
||||||
@@ -75,14 +81,24 @@ uniform vec4 uParam;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec4 upscale() { // https://www.shadertoy.com/view/XsfGDn
|
#ifdef FILTER_UPSCALE
|
||||||
vec2 uv = vTexCoord * uParam.xy + 0.5;
|
vec4 upscale() { // https://www.shadertoy.com/view/XsfGDn
|
||||||
vec2 iuv = floor(uv);
|
vec2 uv = vTexCoord * uParam.xy + 0.5;
|
||||||
vec2 fuv = fract(uv);
|
vec2 iuv = floor(uv);
|
||||||
uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv);
|
vec2 fuv = fract(uv);
|
||||||
uv = (uv - 0.5) / uParam.xy;
|
uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv);
|
||||||
return texture2D(sDiffuse, uv) * vColor;
|
uv = (uv - 0.5) / uParam.xy;
|
||||||
}
|
return texture2D(sDiffuse, uv) * vColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FILTER_ANAGLYPH
|
||||||
|
vec4 anaglyph() {
|
||||||
|
vec3 eyeL = texture2D(sDiffuse, vTexCoord).rgb;
|
||||||
|
vec3 eyeR = texture2D(sNormal, vTexCoord).rgb;
|
||||||
|
return vec4(eyeL.r, eyeR.g, eyeR.b, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vec4 process() {
|
vec4 process() {
|
||||||
#ifdef FILTER_DOWNSAMPLE
|
#ifdef FILTER_DOWNSAMPLE
|
||||||
@@ -105,7 +121,15 @@ uniform vec4 uParam;
|
|||||||
return equirectangular();
|
return equirectangular();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return upscale();
|
#ifdef FILTER_UPSCALE
|
||||||
|
return upscale();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FILTER_ANAGLYPH
|
||||||
|
return anaglyph();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return vec4(1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
Reference in New Issue
Block a user