diff options
Diffstat (limited to '3rdparty/bgfx/examples/40-svt/virtualtexture.sh')
-rw-r--r-- | 3rdparty/bgfx/examples/40-svt/virtualtexture.sh | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/3rdparty/bgfx/examples/40-svt/virtualtexture.sh b/3rdparty/bgfx/examples/40-svt/virtualtexture.sh new file mode 100644 index 00000000000..7bf584c7ed1 --- /dev/null +++ b/3rdparty/bgfx/examples/40-svt/virtualtexture.sh @@ -0,0 +1,86 @@ +/* + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +/* + * Reference(s): + * - Based on Virtual Texture Demo by Brad Blanchard + * http://web.archive.org/web/20190103162638/http://linedef.com/virtual-texture-demo.html + */ + +uniform vec4 u_vt_settings_1; +uniform vec4 u_vt_settings_2; + +#define VirtualTextureSize u_vt_settings_1.x +#define AtlasScale u_vt_settings_1.y +#define BorderScale u_vt_settings_1.z +#define BorderOffset u_vt_settings_1.w + +#define MipBias u_vt_settings_2.x +#define PageTableSize u_vt_settings_2.y + +SAMPLER2D(s_vt_page_table, 0); +SAMPLER2D(s_vt_texture_atlas, 1); + +// This function estimates mipmap levels +float MipLevel( vec2 uv, float size ) +{ + vec2 dx = dFdx( uv * size ); + vec2 dy = dFdy( uv * size ); + float d = max( dot( dx, dx ), dot( dy, dy ) ); + + return max( 0.5 * log2( d ), 0 ); +} + +// This function samples the page table and returns the page's +// position and mip level. +vec3 SampleTable( vec2 uv, float mip ) +{ + vec2 offset = fract( uv * PageTableSize ) / PageTableSize; + return texture2DLod( s_vt_page_table, uv - offset, mip ).xyz; +} + +// This functions samples from the texture atlas and returns the final color +vec4 SampleAtlas( vec3 page, vec2 uv ) +{ + float mipsize = exp2( floor( page.z * 255.0 + 0.5 ) ); + + uv = fract( uv * PageTableSize / mipsize ); + + uv *= BorderScale; + uv += BorderOffset; + + vec2 offset = floor( page.xy * 255.0 + 0.5 ); + + return texture2D( s_vt_texture_atlas, ( offset + uv ) * AtlasScale ); +} + +// Ugly brute force trilinear, look up twice and mix +vec4 VirtualTextureTrilinear( vec2 uv ) +{ + float miplevel = MipLevel( uv, VirtualTextureSize ); + miplevel = clamp( miplevel, 0.0, log2( PageTableSize )-1.0 ); + + float mip1 = floor( miplevel ); + float mip2 = mip1 + 1.0; + float mipfrac = miplevel - mip1; + + vec3 page1 = SampleTable( uv, mip1 ); + vec3 page2 = SampleTable( uv, mip2 ); + + vec4 sample1 = SampleAtlas( page1, uv ); + vec4 sample2 = SampleAtlas( page2, uv ); + + return mix( sample1, sample2, mipfrac ); +} + +// Simple bilinear +vec4 VirtualTexture( vec2 uv ) +{ + float mip = floor( MipLevel( uv, VirtualTextureSize ) ); + mip = clamp( mip, 0, log2( PageTableSize ) ); + + vec3 page = SampleTable( uv, mip ); + return SampleAtlas( page, uv ); +} |