Skip to content

Commit

Permalink
Add optional texture variation to hide obvious texture tiling in a fe…
Browse files Browse the repository at this point in the history
…w Q3A maps.
  • Loading branch information
jpcy committed Jul 13, 2017
1 parent 69602b8 commit 0d39a4a
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ r_dynamicLightIntensity | Make dynamic lights brighter/dimmer.
r_dynamicLightScale | Scale the radius of dynamic lights.
r_lerpTextureAnimation | Use linear interpolation on texture animation - flames, explosions.
r_maxAnisotropy | Enable [anisotropic filtering](https://en.wikipedia.org/wiki/Anisotropic_filtering).
r_textureVariation | Hide obvious texture tiling in a few Q3A maps.
r_waterReflections | Show planar water reflections. Only enabled on q3dm2 for now.

### Console Commands
Expand Down
13 changes: 7 additions & 6 deletions code/renderer_bgfx/Main.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,19 @@ struct GenericShaderProgramVariant
{
enum
{
None = 0,
None = 0,

// Fragment
AlphaTest = 1 << 0,
Bloom = 1 << 1,
AlphaTest = 1 << 0,
Bloom = 1 << 1,
DynamicLights = 1 << 2,
SoftSprite = 1 << 3,
SoftSprite = 1 << 3,
TextureVariation = 1 << 4,

// Vertex
DepthRange = 1 << 4,
DepthRange = 1 << 5,

Num = 1 << 5
Num = 1 << 6
};
};

Expand Down
6 changes: 6 additions & 0 deletions code/renderer_bgfx/Main_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,12 @@ static void RenderCamera(const RenderCameraArgs &args)
s_main->uniforms->bloom_Write_Scale.set(vec4(stage.bloom ? 1.0f : 0.0f, 0, 0, 0));
}

if (g_cvars.textureVariation.getBool() && stage.textureVariation)
{
shaderVariant |= GenericShaderProgramVariant::TextureVariation;
//bgfx::setTexture(TextureUnit::Noise, s_main->uniforms->noiseSampler.handle, Texture::getNoise()->getHandle());
}

bgfx::setState(state);

if (args.flags & RenderCameraFlags::UseStencilTest)
Expand Down
1 change: 1 addition & 0 deletions code/renderer_bgfx/Main_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ void ConsoleVariables::initialize()
railSegmentLength = interface::Cvar_Get("r_railSegmentLength", "32", ConsoleVariableFlags::Archive);
softSprites = interface::Cvar_Get("r_softSprites", "1", ConsoleVariableFlags::Archive);
screenshotJpegQuality = interface::Cvar_Get("r_screenshotJpegQuality", "90", ConsoleVariableFlags::Archive);
textureVariation = interface::Cvar_Get("r_textureVariation", "0", ConsoleVariableFlags::Archive);
waterReflections = interface::Cvar_Get("r_waterReflections", "0", ConsoleVariableFlags::Archive | ConsoleVariableFlags::Latch);
wireframe = interface::Cvar_Get("r_wireframe", "0", ConsoleVariableFlags::Cheat);

Expand Down
32 changes: 32 additions & 0 deletions code/renderer_bgfx/Meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,22 @@ static const char * s_bloomWhitelist[] =
"textures/sfx2/swirl_r*"
};

static const char * s_textureVariationWhitelist[] =
{
// q3dm7
"textures/organics/dirt",
"textures/organics/dirt2",
"textures/organics/dirt_trans",
// q3dm16
"textures/base_wall/metalfloor_wall_14_specular",
// q3dm17
"textures/base_wall/metalfloor_wall_15",
// q3dm18
"textures/base_wall/metalfloor_wall_11",
// q3dm19
"textures/base_floor/metaltechfloor01final"
};

void Initialize()
{
s_meta = Meta();
Expand Down Expand Up @@ -335,6 +351,20 @@ void OnMaterialCreate(Material *material)
s_meta.plasmaExplosionMaterial = material;
}

// Enable texture variation.
bool textureVariation = false;

for (int k = 0; k < BX_COUNTOF(s_textureVariationWhitelist); k++)
{
const char *entry = s_textureVariationWhitelist[k];
const char *wildcard = strstr(entry, "*");

if (!util::Stricmp(material->name, entry) || (wildcard && !util::Stricmpn(material->name, entry, int(wildcard - entry))))
{
textureVariation = true;
}
}

for (int i = 0; i < Material::maxStages; i++)
{
MaterialStage &stage = material->stages[i];
Expand All @@ -360,6 +390,8 @@ void OnMaterialCreate(Material *material)
stage.bloom = true;
}
}

stage.textureVariation = textureVariation;
}
}

Expand Down
7 changes: 6 additions & 1 deletion code/renderer_bgfx/Precompiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct ConsoleVariables
ConsoleVariable railSegmentLength;
ConsoleVariable screenshotJpegQuality;
ConsoleVariable softSprites;
ConsoleVariable textureVariation;
ConsoleVariable waterReflections;
ConsoleVariable wireframe;

Expand Down Expand Up @@ -815,6 +816,7 @@ struct MaterialStage
MaterialStageType type = MaterialStageType::ColorMap;
MaterialLight light = MaterialLight::None;
bool bloom = false;
bool textureVariation = false;

vec4 normalScale;
vec4 specularScale;
Expand Down Expand Up @@ -1315,6 +1317,7 @@ struct Texture
static Texture *get(const char *name);
static const Texture *getDefault();
static const Texture *getIdentityLight();
static const Texture *getNoise();
static const Texture *getWhite();
static Texture *getScratch(size_t index);
static void alias(Texture *from, Texture *to);
Expand Down Expand Up @@ -1343,7 +1346,8 @@ struct TextureUnit
Depth = TU_DEPTH,
DynamicLightCells = TU_DYNAMIC_LIGHT_CELLS,
DynamicLightIndices = TU_DYNAMIC_LIGHT_INDICES,
DynamicLights = TU_DYNAMIC_LIGHTS
DynamicLights = TU_DYNAMIC_LIGHTS,
Noise = TU_NOISE
};
};

Expand Down Expand Up @@ -1457,6 +1461,7 @@ struct Uniforms
Uniform_int textureSampler = "u_TextureSampler";

Uniform_int bloomSampler = "u_BloomSampler";
Uniform_int noiseSampler = "u_NoiseSampler";
Uniform_int smaaColorSampler = "u_SmaaColorSampler";
Uniform_int smaaEdgesSampler = "u_SmaaEdgesSampler";
Uniform_int smaaAreaSampler = "u_SmaaAreaSampler";
Expand Down
20 changes: 20 additions & 0 deletions code/renderer_bgfx/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ struct TextureCache
uint8_t whiteImageData[defaultImageDataSize];
uint8_t identityLightImageData[defaultImageDataSize];
TextureImpl *defaultTexture, *identityLightTexture, *whiteTexture;
static const int noiseImageSize = 256;
static const uint32_t noiseImageDataSize = noiseImageSize * noiseImageSize * 4;
uint8_t noiseImageData[noiseImageDataSize];
TextureImpl *noiseTexture;
static const size_t nScratchTextures = 32;
uint8_t scratchImageData[nScratchTextures][defaultImageDataSize];
std::array<TextureImpl *, nScratchTextures> scratchTextures;
Expand All @@ -138,6 +142,17 @@ struct TextureCache

defaultTexture = createTexture("*default", CreateImage(defaultImageSize, defaultImageSize, 4, defaultImageData), TextureFlags::Mipmap, bgfx::TextureFormat::RGBA8);

// Noise texture.
for (uint32_t x = 0; x < noiseImageDataSize; x++)
{
auto r = uint8_t(rand() % 255);
auto g = uint8_t(rand() % 255);
auto b = uint8_t(rand() % 255);
noiseImageData[x] = (255 << 24) | (b << 16) | (g << 8) | r;
}

noiseTexture = createTexture("*noise", CreateImage(noiseImageSize, noiseImageSize, 4, noiseImageData), TextureFlags::None, bgfx::TextureFormat::RGBA8);

// White texture.
memset(whiteImageData, 255, defaultImageDataSize);
whiteTexture = createTexture("*white", CreateImage(defaultImageSize, defaultImageSize, 4, whiteImageData), 0, bgfx::TextureFormat::RGBA8);
Expand Down Expand Up @@ -394,6 +409,11 @@ const Texture *Texture::getIdentityLight()
return s_textureCache->textureFromImpl(s_textureCache->identityLightTexture);
}

const Texture *Texture::getNoise()
{
return s_textureCache->textureFromImpl(s_textureCache->noiseTexture);
}

const Texture *Texture::getWhite()
{
return s_textureCache->textureFromImpl(s_textureCache->whiteTexture);
Expand Down
3 changes: 2 additions & 1 deletion premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ newaction
{ "AlphaTest", "USE_ALPHA_TEST" },
{ "Bloom", "USE_BLOOM" },
{ "DynamicLights", "USE_DYNAMIC_LIGHTS" },
{ "SoftSprite", "USE_SOFT_SPRITE" }
{ "SoftSprite", "USE_SOFT_SPRITE" },
{ "TextureVariation", "USE_TEXTURE_VARIATION" }
}

local genericVertexVariants =
Expand Down
49 changes: 49 additions & 0 deletions shaders/Generic_fragment.sc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,51 @@ vec3 ClosestPointOnLineSegment(vec3 A, vec3 B, vec3 P)
return A + AB * saturate(distance);
}

#if defined(USE_TEXTURE_VARIATION)
// https://www.shadertoy.com/view/4tyGWK
// http://www.iquilezles.org/www/articles/texturerepetition/texturerepetition.htm
// Modification by huwb. Original shader by iq: https://www.shadertoy.com/view/lt2GDd
// Created by inigo quilez - iq/2015
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

// utilities for randomizing uvs
vec4 hash4( vec2 p ) { return fract(sin(vec4( 1.0+dot(p,vec2(37.0,17.0)), 2.0+dot(p,vec2(11.0,47.0)), 3.0+dot(p,vec2(41.0,29.0)), 4.0+dot(p,vec2(23.0,31.0))))*103.); }
vec2 transformUVs( vec2 iuvCorner, vec2 uv )
{
// random in [0,1]^4
vec4 tx = hash4( iuvCorner );
// scale component is +/-1 to mirror
tx.zw = sign( tx.zw - 0.5 );
// random scale and offset
return tx.zw * uv + tx.xy;
}

// here is a derivative-free version of the 4 samples algorithm from iq
vec4 textureNoTile_4weights(vec2 uv)
{
// compute per-tile integral and fractional uvs.
// flip uvs for 'odd' tiles to make sure tex samples are coherent
vec2 fuv = mod( uv, 2. ), iuv = uv - fuv;
vec3 BL_one = vec3(0.,0.,1.); // xy = bot left coords, z = 1
if( fuv.x >= 1. ) fuv.x = 2.-fuv.x, BL_one.x = 2.;
if( fuv.y >= 1. ) fuv.y = 2.-fuv.y, BL_one.y = 2.;

// smoothstep for fun and to limit blend overlap
vec2 b = smoothstep(0.25,0.75,fuv);

// fetch and blend
vec4 res = mix(
mix( texture2D( u_DiffuseSampler, transformUVs( iuv + BL_one.xy, uv ) ),
texture2D( u_DiffuseSampler, transformUVs( iuv + BL_one.zy, uv ) ), b.x ),
mix( texture2D( u_DiffuseSampler, transformUVs( iuv + BL_one.xz, uv ) ),
texture2D( u_DiffuseSampler, transformUVs( iuv + BL_one.zz, uv ) ), b.x),
b.y );

return res;
}

#endif

void main()
{
if (u_PortalClip.x == 1.0)
Expand All @@ -137,7 +182,11 @@ void main()
texCoord0 = gl_FragCoord.xy * u_viewTexel.xy;
}

#if defined(USE_TEXTURE_VARIATION)
vec4 diffuse = textureNoTile_4weights(texCoord0);
#else
vec4 diffuse = texture2D(u_DiffuseSampler, texCoord0);
#endif

if (int(u_Animation_Enabled_Fraction.x) == 1.0)
{
Expand Down
1 change: 1 addition & 0 deletions shaders/SharedDefines.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@
#define TU_DYNAMIC_LIGHT_CELLS 4
#define TU_DYNAMIC_LIGHT_INDICES 5
#define TU_DYNAMIC_LIGHTS 6
#define TU_NOISE 7

#define USE_HALF_LAMBERT

0 comments on commit 0d39a4a

Please sign in to comment.