1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-10 23:24:06 +02:00

downsample filter for depth (WIP)

This commit is contained in:
XProger
2019-01-13 08:45:54 +03:00
parent 7b104d6631
commit e1b9b9d2c1
7 changed files with 59 additions and 42 deletions

View File

@@ -321,7 +321,7 @@ struct AmbientCache {
for (int j = 0; j < 6; j++) { for (int j = 0; j < 6; j++) {
Texture *src = textures[j * 4 + i - 1]; Texture *src = textures[j * 4 + i - 1];
Texture *dst = textures[j * 4 + i]; Texture *dst = textures[j * 4 + i];
Core::setTarget(dst, RT_STORE_COLOR); Core::setTarget(dst, NULL, RT_STORE_COLOR);
src->bind(sDiffuse); src->bind(sDiffuse);
game->getMesh()->renderQuad(); game->getMesh()->renderQuad();
} }
@@ -329,7 +329,7 @@ struct AmbientCache {
// get result color from 1x1 textures // get result color from 1x1 textures
for (int j = 0; j < 6; j++) { for (int j = 0; j < 6; j++) {
Core::setTarget(textures[j * 4 + 3], RT_LOAD_COLOR); Core::setTarget(textures[j * 4 + 3], NULL, RT_LOAD_COLOR);
colors[j] = Core::copyPixel(0, 0); colors[j] = Core::copyPixel(0, 0);
} }
@@ -719,7 +719,7 @@ struct WaterCache {
Core::active.shader->setParam(uParam, vec4(p.x, p.z, drop.radius * DETAIL, -drop.strength)); Core::active.shader->setParam(uParam, vec4(p.x, p.z, drop.radius * DETAIL, -drop.strength));
item.data[0]->bind(sDiffuse); item.data[0]->bind(sDiffuse);
Core::setTarget(item.data[1], RT_STORE_COLOR); Core::setTarget(item.data[1], NULL, RT_STORE_COLOR);
Core::setViewport(0, 0, int(s.x + 0.5f), int(s.y + 0.5f)); Core::setViewport(0, 0, int(s.x + 0.5f), int(s.y + 0.5f));
game->getMesh()->renderQuad(); game->getMesh()->renderQuad();
swap(item.data[0], item.data[1]); swap(item.data[0], item.data[1]);
@@ -738,7 +738,7 @@ struct WaterCache {
while (item.timer >= SIMULATE_TIMESTEP) { while (item.timer >= SIMULATE_TIMESTEP) {
// water step // water step
item.data[0]->bind(sDiffuse); item.data[0]->bind(sDiffuse);
Core::setTarget(item.data[1], RT_STORE_COLOR); Core::setTarget(item.data[1], NULL, RT_STORE_COLOR);
Core::setViewport(0, 0, int(s.x + 0.5f), int(s.y + 0.5f)); Core::setViewport(0, 0, int(s.x + 0.5f), int(s.y + 0.5f));
game->getMesh()->renderQuad(); game->getMesh()->renderQuad();
swap(item.data[0], item.data[1]); swap(item.data[0], item.data[1]);
@@ -760,7 +760,7 @@ struct WaterCache {
Core::whiteTex->bind(sReflect); Core::whiteTex->bind(sReflect);
item.data[0]->bind(sNormal); item.data[0]->bind(sNormal);
Core::setTarget(item.caustics, RT_CLEAR_COLOR | RT_STORE_COLOR); Core::setTarget(item.caustics, NULL, RT_CLEAR_COLOR | RT_STORE_COLOR);
Core::setViewport(1, 1, item.caustics->width - 2, item.caustics->width - 2); // leave 1px for black border Core::setViewport(1, 1, item.caustics->width - 2, item.caustics->width - 2); // leave 1px for black border
game->getMesh()->renderPlane(); game->getMesh()->renderPlane();
#ifdef BLUR_CAUSTICS #ifdef BLUR_CAUSTICS
@@ -869,9 +869,9 @@ struct WaterCache {
x = y = 0; x = y = 0;
if (screen) { // only for iOS devices if (screen) { // only for iOS devices
Core::setTarget(refract, RT_LOAD_DEPTH | RT_STORE_COLOR | RT_STORE_DEPTH); Core::setTarget(refract, NULL, RT_LOAD_DEPTH | RT_STORE_COLOR | RT_STORE_DEPTH);
blitTexture(screen); blitTexture(screen);
Core::setTarget(screen, RT_LOAD_COLOR | RT_LOAD_DEPTH | RT_STORE_COLOR); Core::setTarget(screen, NULL, RT_LOAD_COLOR | RT_LOAD_DEPTH | RT_STORE_COLOR);
} else } else
Core::copyTarget(refract, 0, 0, x, y, Core::viewportDef.width, Core::viewportDef.height); // copy framebuffer into refraction texture Core::copyTarget(refract, 0, 0, x, y, Core::viewportDef.width, Core::viewportDef.height); // copy framebuffer into refraction texture
} }
@@ -907,7 +907,7 @@ struct WaterCache {
} }
// render mirror reflection // render mirror reflection
Core::setTarget(reflect, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR); Core::setTarget(reflect, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR);
Camera *camera = (Camera*)game->getCamera(); Camera *camera = (Camera*)game->getCamera();
game->setupBinding(); game->setupBinding();

View File

@@ -483,11 +483,12 @@ struct MeshRange {
E( WATER_MASK ) \ E( WATER_MASK ) \
E( WATER_COMPOSE ) \ E( WATER_COMPOSE ) \
/* filter types */ \ /* filter types */ \
E( FILTER_UPSCALE ) \ E( FILTER_UPSCALE ) \
E( FILTER_DOWNSAMPLE ) \ E( FILTER_DOWNSAMPLE ) \
E( FILTER_GRAYSCALE ) \ E( FILTER_DOWNSAMPLE_DEPTH ) \
E( FILTER_BLUR ) \ E( FILTER_GRAYSCALE ) \
E( FILTER_EQUIRECTANGULAR ) \ E( FILTER_BLUR ) \
E( FILTER_EQUIRECTANGULAR ) \
/* options */ \ /* options */ \
E( UNDERWATER ) \ E( UNDERWATER ) \
E( ALPHA_TEST ) \ E( ALPHA_TEST ) \
@@ -939,19 +940,19 @@ namespace Core {
renderState &= ~RS_DEPTH_TEST; renderState &= ~RS_DEPTH_TEST;
} }
void setTarget(GAPI::Texture *target, int op, int face = 0) { void setTarget(GAPI::Texture *color, GAPI::Texture *depth, int op, int face = 0) {
if (!target) if (!color)
target = defaultTarget; color = defaultTarget;
bool color = !target || (target->fmt != FMT_DEPTH && target->fmt != FMT_SHADOW); bool isColor = !color || (color->fmt != FMT_DEPTH && color->fmt != FMT_SHADOW);
setColorWrite(color, color, color, color); setColorWrite(isColor, isColor, isColor, isColor);
if (target == defaultTarget) // backbuffer if (color == defaultTarget) // backbuffer
setViewport(viewportDef); setViewport(viewportDef);
else else
setViewport(0, 0, target->origWidth, target->origHeight); setViewport(0, 0, color->origWidth, color->origHeight);
reqTarget.texture = target; reqTarget.texture = color;
reqTarget.op = op; reqTarget.op = op;
reqTarget.face = face; reqTarget.face = face;
renderState |= RS_TARGET; renderState |= RS_TARGET;
@@ -1016,7 +1017,7 @@ namespace Core {
void endFrame() { void endFrame() {
if (active.target != defaultTarget) { if (active.target != defaultTarget) {
GAPI::setTarget(NULL, 0); GAPI::setTarget(NULL, NULL, 0);
validateRenderState(); validateRenderState();
} }
GAPI::endFrame(); GAPI::endFrame();

View File

@@ -1378,21 +1378,21 @@ struct Inventory {
// //
#else #else
// vertical blur // vertical blur
Core::setTarget(background[1], RT_STORE_COLOR); Core::setTarget(background[1], NULL, RT_STORE_COLOR);
game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false); game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false);
Core::active.shader->setParam(uParam, vec4(0, 1.0f / INVENTORY_BG_SIZE, 0, 0)); Core::active.shader->setParam(uParam, vec4(0, 1.0f / INVENTORY_BG_SIZE, 0, 0));
background[0]->bind(sDiffuse); background[0]->bind(sDiffuse);
game->getMesh()->renderQuad(); game->getMesh()->renderQuad();
// horizontal blur // horizontal blur
Core::setTarget(background[0], RT_STORE_COLOR); Core::setTarget(background[0], NULL, RT_STORE_COLOR);
game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false); game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false);
Core::active.shader->setParam(uParam, vec4(1.0f / INVENTORY_BG_SIZE, 0, 0, 0)); Core::active.shader->setParam(uParam, vec4(1.0f / INVENTORY_BG_SIZE, 0, 0, 0));
background[1]->bind(sDiffuse); background[1]->bind(sDiffuse);
game->getMesh()->renderQuad(); game->getMesh()->renderQuad();
// grayscale // grayscale
Core::setTarget(background[1], RT_STORE_COLOR); Core::setTarget(background[1], NULL, RT_STORE_COLOR);
game->setShader(Core::passFilter, Shader::FILTER_GRAYSCALE, false, false); game->setShader(Core::passFilter, Shader::FILTER_GRAYSCALE, false, false);
Core::active.shader->setParam(uParam, vec4(0.75f, 0.75f, 1.0f, 1.0f)); Core::active.shader->setParam(uParam, vec4(0.75f, 0.75f, 1.0f, 1.0f));
background[0]->bind(sDiffuse); background[0]->bind(sDiffuse);

View File

@@ -577,7 +577,7 @@ struct Level : IGame {
setupCubeCamera(pos, i); setupCubeCamera(pos, i);
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, 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);
} }
@@ -2151,7 +2151,7 @@ struct Level : IGame {
Texture *screen = NULL; Texture *screen = NULL;
if (water) { if (water) {
screen = (waterCache && waterCache->visible) ? waterCache->getScreenTex() : NULL; screen = (waterCache && waterCache->visible) ? waterCache->getScreenTex() : NULL;
Core::setTarget(screen, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR | (screen ? RT_STORE_DEPTH : 0)); // render to screen texture (FUCK YOU iOS!) or back buffer Core::setTarget(screen, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR | (screen ? RT_STORE_DEPTH : 0)); // render to screen texture (FUCK YOU iOS!) or back buffer
setupBinding(); setupBinding();
} }
@@ -2188,7 +2188,7 @@ struct Level : IGame {
Core::Pass pass = Core::pass; Core::Pass pass = Core::pass;
if (water && waterCache && waterCache->visible && screen) { if (water && waterCache && waterCache->visible && screen) {
Core::setTarget(NULL, RT_STORE_COLOR); Core::setTarget(NULL, NULL, RT_STORE_COLOR);
waterCache->blitTexture(screen); waterCache->blitTexture(screen);
} }
@@ -2358,7 +2358,7 @@ struct Level : IGame {
bool colorShadow = shadow->fmt == FMT_RGBA ? true : false; bool colorShadow = shadow->fmt == FMT_RGBA ? true : false;
if (colorShadow) if (colorShadow)
Core::setClearColor(vec4(1.0f)); Core::setClearColor(vec4(1.0f));
Core::setTarget(shadow, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH)); Core::setTarget(shadow, NULL, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH));
//Core::setCullMode(cmBack); //Core::setCullMode(cmBack);
Core::validateRenderState(); Core::validateRenderState();
@@ -2848,7 +2848,7 @@ struct Level : IGame {
} }
void renderInventory() { void renderInventory() {
Core::setTarget(NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR); Core::setTarget(NULL, NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR);
Core::resetLights(); Core::resetLights();
@@ -2877,7 +2877,7 @@ struct Level : IGame {
needRedrawTitleBG = false; needRedrawTitleBG = false;
if (isEnded) { if (isEnded) {
Core::setTarget(NULL, RT_CLEAR_COLOR | RT_STORE_COLOR); Core::setTarget(NULL, NULL, RT_CLEAR_COLOR | RT_STORE_COLOR);
UI::begin(); UI::begin();
UI::updateAspect(float(Core::width) / float(Core::height)); UI::updateAspect(float(Core::width) / float(Core::height));
UI::textOut(vec2(0, 480 - 16), STR_LOADING, UI::aCenter, UI::width); UI::textOut(vec2(0, 480 - 16), STR_LOADING, UI::aCenter, UI::width);

View File

@@ -8,7 +8,7 @@ struct Shader : GAPI::Shader {
enum Type { enum Type {
DEFAULT = 0, DEFAULT = 0,
/* shader */ SPRITE = 0, FLASH, ROOM, ENTITY, MIRROR, /* shader */ SPRITE = 0, FLASH, ROOM, ENTITY, MIRROR,
/* filter */ FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE, FILTER_GRAYSCALE, FILTER_BLUR, FILTER_EQUIRECTANGULAR, /* filter */ FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE, FILTER_DOWNSAMPLE_DEPTH, FILTER_GRAYSCALE, FILTER_BLUR, FILTER_EQUIRECTANGULAR,
/* water */ WATER_DROP = 0, WATER_SIMULATE, WATER_CAUSTICS, WATER_RAYS, WATER_MASK, WATER_COMPOSE, /* water */ WATER_DROP = 0, WATER_SIMULATE, WATER_CAUSTICS, WATER_RAYS, WATER_MASK, WATER_COMPOSE,
MAX = 6 MAX = 6
}; };

View File

@@ -58,18 +58,12 @@ float4 uPosScale[2] : register( c92 );
FLAGS_TYPE uFlags[4] : register( FLAGS_REG ); FLAGS_TYPE uFlags[4] : register( FLAGS_REG );
float4 uContacts[MAX_CONTACTS] : register( c98 ); float4 uContacts[MAX_CONTACTS] : register( c98 );
#define TYPE_SPRITE uFlags[0].x
#define TYPE_FLASH uFlags[0].y
#define TYPE_ROOM uFlags[0].z
#define TYPE_ENTITY uFlags[0].w
#define TYPE_MIRROR uFlags[1].x
#define FILTER_DEFAULT uFlags[0].x #define FILTER_DEFAULT uFlags[0].x
#define FILTER_DOWNSAMPLE uFlags[0].y #define FILTER_DOWNSAMPLE uFlags[0].y
#define FILTER_GRAYSCALE uFlags[0].z #define FILTER_DOWNSAMPLE_DEPTH uFlags[0].z
#define FILTER_BLUR uFlags[0].w #define FILTER_GRAYSCALE uFlags[0].w
#define FILTER_EQUIRECTANGULAR uFlags[1].x #define FILTER_BLUR uFlags[1].x
#define FILTER_EQUIRECTANGULAR uFlags[1].y
#define WATER_DROP uFlags[0].x #define WATER_DROP uFlags[0].x
#define WATER_SIMULATE uFlags[0].y #define WATER_SIMULATE uFlags[0].y
@@ -79,6 +73,11 @@ float4 uContacts[MAX_CONTACTS] : register( c98 );
#define WATER_COMPOSE uFlags[1].y #define WATER_COMPOSE uFlags[1].y
// options for compose, shadow, ambient passes // options for compose, shadow, ambient passes
#define TYPE_SPRITE uFlags[0].x
#define TYPE_FLASH uFlags[0].y
#define TYPE_ROOM uFlags[0].z
#define TYPE_ENTITY uFlags[0].w
#define TYPE_MIRROR uFlags[1].x
#define UNDERWATER uFlags[1].y #define UNDERWATER uFlags[1].y
#define ALPHA_TEST uFlags[1].z #define ALPHA_TEST uFlags[1].z
#define CLIP_PLANE uFlags[1].w #define CLIP_PLANE uFlags[1].w

View File

@@ -36,6 +36,19 @@ uniform vec4 uParam;
return vec4(color.xyz / color.w, 1.0); return vec4(color.xyz / color.w, 1.0);
} }
#ifdef FILTER_DOWNSAMPLE_DEPTH
vec4 downsampleDepth() {
vec2 t = vTexCoord.xy;
vec3 o = vec3(uParam.x, uParam.y, 0.0);
float d0 = texture2D(sDiffuse, t + o.zz).x;
float d1 = texture2D(sDiffuse, t + o.xz).x;
float d2 = texture2D(sDiffuse, t + o.zy).x;
float d3 = texture2D(sDiffuse, t + o.xy).x;
gl_FragDepth = max(max(d0, d1), max(d2, d3));
return vec4(0.0);
}
#endif
vec4 grayscale() { // uParam (factor, unused, unused, unused) vec4 grayscale() { // uParam (factor, unused, unused, unused)
vec4 color = texture2D(sDiffuse, vTexCoord); vec4 color = texture2D(sDiffuse, vTexCoord);
vec3 gray = vec3(dot(color, vec4(0.299, 0.587, 0.114, 0.0))); vec3 gray = vec3(dot(color, vec4(0.299, 0.587, 0.114, 0.0)));
@@ -81,6 +94,10 @@ uniform vec4 uParam;
return downsample(); return downsample();
#endif #endif
#ifdef FILTER_DOWNSAMPLE_DEPTH
return downsampleDepth();
#endif
#ifdef FILTER_GRAYSCALE #ifdef FILTER_GRAYSCALE
return grayscale(); return grayscale();
#endif #endif