A game about forced loneliness, made by TACStudios
at master 864 lines 30 kB view raw
1#ifndef GRA_HLSL_3 2#define GRA_HLSL_3 0 3#endif 4 5#ifndef GRA_HLSL_4 6#define GRA_HLSL_4 0 7#endif 8 9#ifndef GRA_HLSL_5 10#define GRA_HLSL_5 0 11#endif 12 13#ifndef GRA_GLSL_120 14#define GRA_GLSL_120 0 15#endif 16 17#ifndef GRA_GLSL_130 18#define GRA_GLSL_130 0 19#endif 20 21#ifndef GRA_GLSL_330 22#define GRA_GLSL_330 0 23#endif 24 25#ifndef GRA_VERTEX_SHADER 26#define GRA_VERTEX_SHADER 0 27#endif 28 29#ifndef GRA_PIXEL_SHADER 30#define GRA_PIXEL_SHADER 0 31#endif 32 33#ifndef GRA_HQ_CUBEMAPPING 34#define GRA_HQ_CUBEMAPPING 0 35#endif 36 37#ifndef GRA_DEBUG_TILES 38#define GRA_DEBUG_TILES 0 39#endif 40 41#ifndef GRA_BGRA 42#define GRA_BGRA 0 43#endif 44 45#ifndef GRA_ROW_MAJOR 46#define GRA_ROW_MAJOR 1 47#endif 48 49#ifndef GRA_DEBUG 50#define GRA_DEBUG 1 51#endif 52 53#ifndef GRA_64BIT_RESOLVER 54#define GRA_64BIT_RESOLVER 0 55#endif 56 57#ifndef GRA_RWTEXTURE2D_SCALE 58#define GRA_RWTEXTURE2D_SCALE 16 59#endif 60 61#ifndef GRA_DISABLE_TEX_LOAD 62#define GRA_DISABLE_TEX_LOAD 0 63#endif 64 65#ifndef GRA_PACK_RESOLVE_OUTPUT 66#define GRA_PACK_RESOLVE_OUTPUT 1 67#endif 68 69// Temp workaround for some platforms's lack of unorm. 70#ifdef GRA_NO_UNORM 71 #define GRA_UNORM 72#else 73 #define GRA_UNORM unorm 74#endif 75 76#ifndef GRA_TEXTURE_ARRAY_SUPPORT 77 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) || (GRA_GLSL_330 == 1) 78 #define GRA_TEXTURE_ARRAY_SUPPORT 1 79 #else 80 #define GRA_TEXTURE_ARRAY_SUPPORT 0 81 #endif 82#endif 83 84#define GRA_HLSL_FAMILY ((GRA_HLSL_3 == 1) || (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)) 85#define GRA_GLSL_FAMILY ((GRA_GLSL_120 == 1) || (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)) 86 87#if GRA_HLSL_FAMILY 88 #define gra_Float2 float2 89 #define gra_Float3 float3 90 #define gra_Float4 float4 91 #define gra_Int3 int3 92 #define gra_Float4x4 float4x4 93 #define gra_Unroll [unroll] 94 #define gra_Branch [branch] 95#elif GRA_GLSL_FAMILY 96 #if (GRA_VERTEX_SHADER == 0) && (GRA_PIXEL_SHADER ==0) 97 #error GLSL requires knowledge of the shader stage! Neither GRA_VERTEX_SHADER or GRA_PIXEL_SHADER are defined! 98 #else 99 #define gra_Float2 vec2 100 #define gra_Float3 vec3 101 #define gra_Float4 vec4 102 #define gra_Int3 ivec3 103 #define gra_Float4x4 mat4 104 #define gra_Unroll 105 #define gra_Branch 106 #if (GRA_VERTEX_SHADER == 1) 107 #define ddx 108 #define ddy 109 #elif (GRA_PIXEL_SHADER == 1) 110 #define ddx dFdx 111 #define ddy dFdy 112 #endif 113 #define frac fract 114 #define lerp mix 115 /** This is not correct (http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod) but it is for our case */ 116 #define fmod mod 117 #endif 118#else 119 #error unknown shader architecture 120#endif 121 122#if (GRA_DISABLE_TEX_LOAD!=1) 123 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) || (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1) 124 #define GRA_LOAD_INSTR 1 125 #else 126 #define GRA_LOAD_INSTR 0 127 #endif 128#else 129 #define GRA_LOAD_INSTR 0 130#endif 131 132/** 133 a cross API texture handle 134*/ 135#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 136 struct GraniteTranslationTexture 137 { 138 SamplerState Sampler; 139 Texture2D Texture; 140 }; 141 struct GraniteCacheTexture 142 { 143 SamplerState Sampler; 144 145 #if GRA_TEXTURE_ARRAY_SUPPORT 146 Texture2DArray TextureArray; 147 #else 148 Texture2D Texture; 149 #endif 150 }; 151#elif (GRA_HLSL_3 == 1) || (GRA_GLSL_120 == 1) || (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1) 152 #define GraniteTranslationTexture sampler2D 153 154 #if GRA_TEXTURE_ARRAY_SUPPORT 155 #define GraniteCacheTexture sampler2DArray 156 #else 157 #define GraniteCacheTexture sampler2D 158 #endif 159 160#else 161 #error unknow shader archtecture 162#endif 163 164/** 165 Struct defining the constant buffer for each streaming texture. 166 Use IStreamingTexture::GetConstantBuffer to fill this struct. 167*/ 168struct GraniteStreamingTextureConstantBuffer 169{ 170 #define _grStreamingTextureCBSize 2 171 gra_Float4 data[_grStreamingTextureCBSize]; 172}; 173 174/** 175 Struct defining the constant buffer for each cube streaming texture. 176 Use multiple calls to IStreamingTexture::GetConstantBuffer this struct (one call for each face). 177 */ 178struct GraniteStreamingTextureCubeConstantBuffer 179{ 180 #define _grStreamingTextureCubeCBSize 6 181 GraniteStreamingTextureConstantBuffer data[_grStreamingTextureCubeCBSize]; 182}; 183 184/** 185 Struct defining the constant buffer for each tileset. 186 Use ITileSet::GetConstantBuffer to fill this struct. 187*/ 188struct GraniteTilesetConstantBuffer 189{ 190 #define _grTilesetCBSize 2 191 gra_Float4x4 data[_grTilesetCBSize]; 192}; 193 194/** 195 Utility struct used by the shaderlib to wrap up all required constant buffers needed to perform a VT lookup/sample. 196 */ 197struct GraniteConstantBuffers 198{ 199 GraniteTilesetConstantBuffer tilesetBuffer; 200 GraniteStreamingTextureConstantBuffer streamingTextureBuffer; 201}; 202 203/** 204 Utility struct used by the shaderlib to wrap up all required constant buffers needed to perform a Cube VT lookup/sample. 205 */ 206struct GraniteCubeConstantBuffers 207{ 208 GraniteTilesetConstantBuffer tilesetBuffer; 209 GraniteStreamingTextureCubeConstantBuffer streamingTextureCubeBuffer; 210}; 211 212/** 213 The Granite lookup data for the different sampling functions. 214*/ 215 216// Granite lookup data for automatic mip level selecting sampling 217struct GraniteLookupData 218{ 219 gra_Float4 translationTableData; 220 gra_Float2 textureCoordinates; 221 gra_Float2 dX; 222 gra_Float2 dY; 223}; 224 225// Granite lookup data for explicit level-of-detail sampling 226struct GraniteLODLookupData 227{ 228 gra_Float4 translationTableData; 229 gra_Float2 textureCoordinates; 230 float cacheLevel; 231}; 232//@IGNORE_END 233 234// public interface 235 236/* 237 END OF PUBLIC INTERFACE 238 Everything below this point should be treated as private to GraniteShaderLib.h 239*/ 240 241//@INSERT_DEFINES 242#define gra_TilesetBuffer grCB.tilesetBuffer 243#define gra_TilesetBufferInternal tsCB.data[0] 244#define gra_TilesetCacheBuffer tsCB.data[1] 245 246#define gra_StreamingTextureCB grCB.streamingTextureBuffer 247#define gra_StreamingTextureCubeCB grCB.streamingTextureCubeBuffer 248 249#define gra_Transform grCB.streamingTextureBuffer.data[0] 250#define gra_CubeTransform grCB.streamingTextureCubeBuffer.data 251 252#define gra_StreamingTextureTransform grSTCB.data[0] 253#define gra_StreamingTextureInfo grSTCB.data[1] 254 255#define gra_NumLevels gra_StreamingTextureInfo.x 256#define gra_AssetWidthRcp gra_StreamingTextureInfo.y 257#define gra_AssetHeightRcp gra_StreamingTextureInfo.z 258 259#if GRA_ROW_MAJOR == 1 260 261 #define gra_TranslationTableBias gra_TilesetBufferInternal[0][0] 262 #define gra_MaxAnisotropyLog2 gra_TilesetBufferInternal[1][0] 263 #define gra_CalcMiplevelDeltaScale gra_Float2(gra_TilesetBufferInternal[2][0], gra_TilesetBufferInternal[3][0]) 264 #define gra_CalcMiplevelDeltaScaleX gra_TilesetBufferInternal[2][0] 265 #define gra_CalcMiplevelDeltaScaleY gra_TilesetBufferInternal[3][0] 266 #define gra_LodBiasPow2 gra_TilesetBufferInternal[0][1] 267 #define gra_TrilinearOffset gra_TilesetBufferInternal[0][2] 268 #define gra_TileContentInTiles gra_Float2(gra_TilesetBufferInternal[0][2], gra_TilesetBufferInternal[1][2]) 269 #define gra_Level0NumTilesX gra_TilesetBufferInternal[0][3] 270 #define gra_NumTilesYScale gra_TilesetBufferInternal[1][3] 271 #define gra_TextureMagic gra_TilesetBufferInternal[2][3] 272 #define gra_TextureId gra_TilesetBufferInternal[3][3] 273 274 #define gra_RcpCacheInTiles(l) gra_Float2(gra_TilesetCacheBuffer[0][l], gra_TilesetCacheBuffer[1][l]) 275 #define gra_BorderPixelsRcpCache(l) gra_Float2(gra_TilesetCacheBuffer[2][l], gra_TilesetCacheBuffer[3][l]) 276 277#else 278 279 #define gra_TranslationTableBias gra_TilesetBufferInternal[0][0] 280 #define gra_MaxAnisotropyLog2 gra_TilesetBufferInternal[0][1] 281 #define gra_CalcMiplevelDeltaScale gra_Float2(gra_TilesetBufferInternal[0][2], gra_TilesetBufferInternal[0][3]) 282 #define gra_CalcMiplevelDeltaScaleX gra_TilesetBufferInternal[0][2] 283 #define gra_CalcMiplevelDeltaScaleY gra_TilesetBufferInternal[0][3] 284 #define gra_LodBiasPow2 gra_TilesetBufferInternal[1][0] 285 #define gra_TrilinearOffset gra_TilesetBufferInternal[2][0] 286 #define gra_TileContentInTiles gra_Float2(gra_TilesetBufferInternal[2][0], gra_TilesetBufferInternal[2][1]) 287 #define gra_Level0NumTilesX gra_TilesetBufferInternal[3][0] 288 #define gra_NumTilesYScale gra_TilesetBufferInternal[3][1] 289 #define gra_TextureMagic gra_TilesetBufferInternal[3][2] 290 #define gra_TextureId gra_TilesetBufferInternal[3][3] 291 292 #define gra_RcpCacheInTiles(l) gra_Float2(gra_TilesetCacheBuffer[l][0], gra_TilesetCacheBuffer[l][1]) 293 #define gra_BorderPixelsRcpCache(l) gra_Float2(gra_TilesetCacheBuffer[l][2], gra_TilesetCacheBuffer[l][3]) 294 295#endif 296 297#if (GRA_GLSL_120==1) 298 // Extension needed for texture2DLod 299 //extension GL_ARB_shader_texture_lod : enable 300 // Extensions needed fot texture2DGrad 301 //extension GL_EXT_gpu_shader4 : enable 302 // Extensions needed for bit manipulation 303 //extension GL_ARB_shader_bit_encoding : enable 304#endif 305 306 307#if (GRA_TEXTURE_ARRAY_SUPPORT==1) 308 gra_Float4 GranitePrivate_SampleArray(in GraniteCacheTexture tex, in gra_Float3 texCoord) 309 { 310 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 311 return tex.TextureArray.Sample(tex.Sampler, texCoord); 312 #elif (GRA_GLSL_330 == 1) 313 return texture(tex, texCoord); 314 #else 315 #error using unsupported function 316 #endif 317 } 318 319 gra_Float4 GranitePrivate_SampleGradArray(in GraniteCacheTexture tex, in gra_Float3 texCoord, in gra_Float2 dX, in gra_Float2 dY) 320 { 321 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 322 return tex.TextureArray.SampleGrad(tex.Sampler,texCoord,dX,dY); 323 #elif (GRA_GLSL_330 == 1) 324 return textureGrad(tex, texCoord, dX, dY); 325 #else 326 #error using unsupported function 327 #endif 328 } 329 330 gra_Float4 GranitePrivate_SampleLevelArray(in GraniteCacheTexture tex, in gra_Float3 texCoord, in float level) 331 { 332 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 333 return tex.TextureArray.SampleLevel(tex.Sampler, texCoord, level); 334 #elif (GRA_GLSL_330 == 1) 335 return textureLod(tex, texCoord, level); 336 #else 337 #error using unsupported function 338 #endif 339 } 340#else 341 gra_Float4 GranitePrivate_Sample(in GraniteCacheTexture tex, in gra_Float2 texCoord) 342 { 343 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 344 return tex.Texture.Sample(tex.Sampler,texCoord); 345 #elif (GRA_HLSL_3 == 1) 346 return tex2D(tex,texCoord); 347 #elif (GRA_GLSL_120 == 1) || (GRA_GLSL_130 == 1) 348 return texture2D(tex, texCoord); 349 #elif (GRA_GLSL_330 == 1) 350 return texture(tex, texCoord); 351 #endif 352 } 353 354 gra_Float4 GranitePrivate_SampleLevel(in GraniteCacheTexture tex, in gra_Float2 texCoord, in float level) 355 { 356 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 357 return tex.Texture.SampleLevel(tex.Sampler, texCoord, level); 358 #elif (GRA_HLSL_3 == 1) 359 return tex2Dlod(tex,gra_Float4(texCoord,0.0,level)); 360 #elif (GRA_GLSL_120 == 1) 361 return texture2DLod(tex, texCoord, level); 362 #elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1) 363 return textureLod(tex, texCoord, level); 364 #endif 365 } 366 367 gra_Float4 GranitePrivate_SampleGrad(in GraniteCacheTexture tex, in gra_Float2 texCoord, in gra_Float2 dX, in gra_Float2 dY) 368 { 369 #if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 370 return tex.Texture.SampleGrad(tex.Sampler,texCoord,dX,dY); 371 #elif (GRA_HLSL_3 == 1) 372 return tex2D(tex,texCoord,dX,dY); 373 #elif (GRA_GLSL_120 == 1) 374 return texture2DGrad(tex, texCoord, dX, dY); 375 #elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1) 376 return textureGrad(tex, texCoord, dX, dY); 377 #endif 378 } 379#endif //#if (GRA_TEXTURE_ARRAY_SUPPORT==1) 380 381#if (GRA_LOAD_INSTR==1) 382gra_Float4 GranitePrivate_Load(in GraniteTranslationTexture tex, in gra_Int3 location) 383{ 384#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 385 return tex.Texture.Load(location); 386#elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1) 387 return texelFetch(tex, location.xy, location.z); 388#elif (GRA_HLSL_3 == 1) || (GRA_GLSL_120 == 1) 389 #error using unsupported function 390#endif 391} 392#endif 393 394//work-around shader compiler bug 395//compiler gets confused with GranitePrivate_SampleLevel taking a GraniteCacheTexture as argument when array support is disabled 396//Without array support, GraniteCacheTexture and GraniteTranslationTexture are the same (but still different types!) 397//compiler is confused (ERR_AMBIGUOUS_FUNCTION_CALL). Looks like somebody is over enthusiastic optimizing... 398gra_Float4 GranitePrivate_SampleLevel_Translation(in GraniteTranslationTexture tex, in gra_Float2 texCoord, in float level) 399{ 400#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 401 return tex.Texture.SampleLevel(tex.Sampler, texCoord, level); 402#elif (GRA_HLSL_3 == 1) 403 return tex2Dlod(tex,gra_Float4(texCoord,0.0,level)); 404#elif (GRA_GLSL_120 == 1) 405 return texture2DLod(tex, texCoord, level); 406#elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1) 407 return textureLod(tex, texCoord, level); 408#endif 409} 410 411float GranitePrivate_Saturate(in float value) 412{ 413#if GRA_HLSL_FAMILY 414 return saturate(value); 415#elif GRA_GLSL_FAMILY 416 return clamp(value, 0.0f, 1.0f); 417#endif 418} 419 420#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) || (GRA_GLSL_330 == 1) 421uint GranitePrivate_FloatAsUint(float value) 422{ 423#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) 424 return asuint(value); 425#elif (GRA_GLSL_330 == 1) 426 return floatBitsToUint(value); 427#endif 428} 429#endif 430 431float GranitePrivate_Pow2(uint exponent) 432{ 433#if GRA_HLSL_FAMILY 434 return pow(2.0, exponent); 435#else 436 return pow(2.0, float(exponent)); 437#endif 438} 439 440gra_Float2 GranitePrivate_RepeatUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB) 441{ 442 return frac(uv); 443} 444 445gra_Float2 GranitePrivate_UdimUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB) 446{ 447 return uv; 448} 449 450gra_Float2 GranitePrivate_ClampUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB) 451{ 452 gra_Float2 epsilon2 = gra_Float2(gra_AssetWidthRcp, gra_AssetHeightRcp); 453 return clamp(uv, epsilon2, gra_Float2(1,1) - epsilon2); 454} 455 456gra_Float2 GranitePrivate_MirrorUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB) 457{ 458 gra_Float2 t = frac(uv*0.5)*2.0; 459 gra_Float2 l = gra_Float2(1.0,1.0); 460 return l-abs(t-l); 461} 462 463// function definitons for private functions 464gra_Float4 GranitePrivate_PackTileId(in gra_Float2 tileXY, in float level, in float textureID); 465 466gra_Float4 Granite_DebugPackedTileId64(in gra_Float4 PackedTile) 467{ 468#if GRA_64BIT_RESOLVER 469 gra_Float4 output; 470 471 const float scale = 1.0f / 65535.0f; 472 gra_Float4 temp = PackedTile / scale; 473 474 output.x = fmod(temp.x, 256.0f); 475 output.y = floor(temp.x / 256.0f) + fmod(temp.y, 16.0f) * 16.0f; 476 output.z = floor(temp.y / 16.0f); 477 output.w = temp.z + temp.a * 16.0f; 478 479 return gra_Float4 480 ( 481 (float)output.x / 255.0f, 482 (float)output.y / 255.0f, 483 (float)output.z / 255.0f, 484 (float)output.w / 255.0f 485 ); 486#else 487 return PackedTile; 488#endif 489} 490 491gra_Float3 Granite_UnpackNormal(in gra_Float4 PackedNormal, float scale) 492{ 493 gra_Float2 reconstructed = gra_Float2(PackedNormal.x * PackedNormal.a, PackedNormal.y) * 2.0f - 1.0f; 494 reconstructed *= scale; 495 float z = sqrt(1.0f - GranitePrivate_Saturate(dot(reconstructed, reconstructed))); 496 return gra_Float3(reconstructed, z); 497} 498 499gra_Float3 Granite_UnpackNormal(in gra_Float4 PackedNormal) 500{ 501 return Granite_UnpackNormal(PackedNormal, 1.0); 502} 503 504#if GRA_HLSL_FAMILY 505GraniteTilesetConstantBuffer Granite_ApplyResolutionOffset(in GraniteTilesetConstantBuffer INtsCB, in float resolutionOffsetPow2) 506{ 507 GraniteTilesetConstantBuffer tsCB = INtsCB; 508 gra_LodBiasPow2 *= resolutionOffsetPow2; 509 //resolutionOffsetPow2 *= resolutionOffsetPow2; //Square it before multiplying it in below 510 gra_CalcMiplevelDeltaScaleX *= resolutionOffsetPow2; 511 gra_CalcMiplevelDeltaScaleY *= resolutionOffsetPow2; 512 return tsCB; 513} 514 515GraniteTilesetConstantBuffer Granite_SetMaxAnisotropy(in GraniteTilesetConstantBuffer INtsCB, in float maxAnisotropyLog2) 516{ 517 GraniteTilesetConstantBuffer tsCB = INtsCB; 518 gra_MaxAnisotropyLog2 = min(gra_MaxAnisotropyLog2, maxAnisotropyLog2); 519 return tsCB; 520} 521#else 522void Granite_ApplyResolutionOffset(inout GraniteTilesetConstantBuffer tsCB, in float resolutionOffsetPow2) 523{ 524 gra_LodBiasPow2 *= resolutionOffsetPow2; 525 //resolutionOffsetPow2 *= resolutionOffsetPow2; //Square it before multiplying it in below 526 gra_CalcMiplevelDeltaScaleX *= resolutionOffsetPow2; 527 gra_CalcMiplevelDeltaScaleY *= resolutionOffsetPow2; 528} 529 530void Granite_SetMaxAnisotropy(inout GraniteTilesetConstantBuffer tsCB, in float maxAnisotropyLog2) 531{ 532 gra_MaxAnisotropyLog2 = min(gra_MaxAnisotropyLog2, maxAnisotropyLog2); 533} 534#endif 535 536gra_Float2 Granite_Transform(in GraniteStreamingTextureConstantBuffer grSTCB, in gra_Float2 textureCoord) 537{ 538 return textureCoord * gra_StreamingTextureTransform.zw + gra_StreamingTextureTransform.xy; 539} 540 541gra_Float4 Granite_MergeResolveOutputs(in gra_Float4 resolve0, in gra_Float4 resolve1, in gra_Float2 pixelLocation) 542{ 543 gra_Float2 screenPos = frac(pixelLocation * 0.5f); 544 bool dither = (screenPos.x != screenPos.y); 545 return (dither) ? resolve0 : resolve1; 546} 547 548gra_Float4 Granite_PackTileId(in gra_Float4 unpackedTileID) 549{ 550 return GranitePrivate_PackTileId(unpackedTileID.xy, unpackedTileID.z, unpackedTileID.w); 551} 552 553#if (GRA_HLSL_5 == 1) 554void Granite_DitherResolveOutput(in gra_Float4 resolve, in RWTexture2D<GRA_UNORM gra_Float4> resolveTexture, in gra_Float2 screenPos, in float alpha) 555{ 556 const uint2 pixelPos = int2(screenPos); 557 const uint2 pixelLocation = pixelPos % GRA_RWTEXTURE2D_SCALE; 558 bool dither = (pixelLocation.x == 0) && (pixelLocation.y == 0); 559 uint2 writePos = pixelPos / GRA_RWTEXTURE2D_SCALE; 560 561 if ( alpha == 0 ) 562 { 563 dither = false; 564 } 565 else if (alpha != 1.0) 566 { 567 // Do a 4x4 dither patern so alternating pixels resolve to the first or the second texture 568 gra_Float2 pixelLocationAlpha = frac(screenPos * 0.25f); // We don't scale after the frac so this will give coords 0, 0.25, 0.5, 0.75 569 int pixelId = (int)(pixelLocationAlpha.y * 16 + pixelLocationAlpha.x * 4); //faster as a dot2 ? 570 571 // Clamp 572 // This ensures that for example alpha=0.95 still resolves some tiles of the surfaces behind it 573 // and alpha=0.05 still resolves some tiles of this surface 574 alpha = min(max(alpha, 0.0625), 0.9375); 575 576 // Modern hardware supports array indexing with per pixel varying indexes 577 // on old hardware this will be expanded to a conditional tree by the compiler 578 const float thresholdMaxtrix[16] = { 1.0f / 17.0f, 9.0f / 17.0f, 3.0f / 17.0f, 11.0f / 17.0f, 579 13.0f / 17.0f, 5.0f / 17.0f, 15.0f / 17.0f, 7.0f / 17.0f, 580 4.0f / 17.0f, 12.0f / 17.0f, 2.0f / 17.0f, 10.0f / 17.0f, 581 16.0f / 17.0f, 8.0f / 17.0f, 14.0f / 17.0f, 6.0f / 17.0f}; 582 float threshold = thresholdMaxtrix[pixelId]; 583 584 if (alpha < threshold) 585 { 586 dither = false; 587 } 588 } 589 590 gra_Branch if (dither) 591 { 592#if (GRA_PACK_RESOLVE_OUTPUT==0) 593 resolveTexture[writePos] = Granite_PackTileId(resolve); 594#else 595 resolveTexture[writePos] = resolve; 596#endif 597 } 598} 599#endif 600 601float GranitePrivate_CalcMiplevelAnisotropic(in GraniteTilesetConstantBuffer tsCB, in GraniteStreamingTextureConstantBuffer grSTCB, in gra_Float2 ddxTc, in gra_Float2 ddyTc) 602{ 603 // Calculate the required mipmap level, this uses a similar 604 // formula as the GL spec. 605 // To reduce sqrt's and log2's we do some stuff in squared space here and further below in log space 606 // i.e. we wait with the sqrt untill we can do it for 'free' later during the log2 607 608 ddxTc *= gra_CalcMiplevelDeltaScale; 609 ddyTc *= gra_CalcMiplevelDeltaScale; 610 611 float lenDxSqr = dot(ddxTc, ddxTc); 612 float lenDySqr = dot(ddyTc, ddyTc); 613 float dMaxSqr = max(lenDxSqr, lenDySqr); 614 float dMinSqr = min(lenDxSqr, lenDySqr); 615 616 // Calculate mipmap levels directly from sqared distances. This uses log2(sqrt(x)) = 0.5 * log2(x) to save some sqrt's 617 float maxLevel = 0.5 * log2( dMaxSqr ); 618 float minLevel = 0.5 * log2( dMinSqr ); 619 620 // Calculate the log2 of the anisotropy and clamp it by the max supported. This uses log2(a/b) = log2(a)-log2(b) and min(log(a),log(b)) = log(min(a,b)) 621 float anisoLog2 = maxLevel - minLevel; 622 anisoLog2 = min( anisoLog2, gra_MaxAnisotropyLog2 ); 623 624 // Adjust for anisotropy & clamp to level 0 625 float result = max(maxLevel - anisoLog2 - 0.5f, 0.0f); //Subtract 0.5 to compensate for trilinear mipmapping 626 627 // Added clamping to avoid "hot pink" on small tilesets that try to sample past the 1x1 tile miplevel 628 // This happens if you for example import a relatively small texture and zoom out 629 return min(result, gra_NumLevels); 630} 631 632float GranitePrivate_CalcMiplevelLinear(in GraniteTilesetConstantBuffer tsCB, in GraniteStreamingTextureConstantBuffer grSTCB, in gra_Float2 ddxTc, in gra_Float2 ddyTc) 633{ 634 // Calculate the required mipmap level, this uses a similar 635 // formula as the GL spec. 636 // To reduce sqrt's and log2's we do some stuff in squared space here and further below in log space 637 // i.e. we wait with the sqrt untill we can do it for 'free' later during the log2 638 639 ddxTc *= gra_CalcMiplevelDeltaScale; 640 ddyTc *= gra_CalcMiplevelDeltaScale; 641 642 float lenDxSqr = dot(ddxTc, ddxTc); 643 float lenDySqr = dot(ddyTc, ddyTc); 644 float dMaxSqr = max(lenDxSqr, lenDySqr); 645 646 // Calculate mipmap levels directly from squared distances. This uses log2(sqrt(x)) = 0.5 * log2(x) to save some sqrt's 647 float maxLevel = 0.5 * log2(dMaxSqr) - 0.5f; //Subtract 0.5 to compensate for trilinear mipmapping 648 649 return clamp(maxLevel, 0.0f, gra_NumLevels); 650} 651 652gra_Float4 GranitePrivate_PackTileId(in gra_Float2 tileXY, in float level, in float textureID) 653{ 654#if GRA_64BIT_RESOLVER == 0 655 gra_Float4 resultBits; 656 657 resultBits.x = fmod(tileXY.x, 256.0f); 658 resultBits.y = floor(tileXY.x / 256.0f) + fmod(tileXY.y, 32.0f) * 8.0f; 659 resultBits.z = floor(tileXY.y / 32.0f) + fmod(level, 4.0f) * 64.0f; 660 resultBits.w = floor(level / 4.0f) + textureID * 4.0f; 661 662 const float scale = 1.0f / 255.0f; 663 664#if GRA_BGRA == 0 665 return scale * gra_Float4 666 ( 667 float(resultBits.x), 668 float(resultBits.y), 669 float(resultBits.z), 670 float(resultBits.w) 671 ); 672#else 673 return scale * gra_Float4 674 ( 675 float(resultBits.z), 676 float(resultBits.y), 677 float(resultBits.x), 678 float(resultBits.w) 679 ); 680#endif 681#else 682 const float scale = 1.0f / 65535.0f; 683 return gra_Float4(tileXY.x, tileXY.y, level, textureID) * scale; 684#endif 685 686} 687 688gra_Float4 GranitePrivate_UnpackTileId(in gra_Float4 packedTile) 689{ 690 gra_Float4 swiz; 691#if GRA_BGRA == 0 692 swiz = packedTile; 693#else 694 swiz = packedTile.zyxw; 695#endif 696 swiz *= 255.0f; 697 698 float tileX = swiz.x + fmod(swiz.y, 16.0f) * 256.0f; 699 float tileY = floor(swiz.y / 16.0f) + swiz.z * 16.0f; 700 float level = fmod(swiz.w, 16.0f); 701 float tex = floor(swiz.w / 16.0f); 702 703 return gra_Float4(tileX, tileY, level, tex); 704} 705 706gra_Float3 GranitePrivate_TranslateCoord(in GraniteTilesetConstantBuffer tsCB, in gra_Float2 inputTexCoord, in gra_Float4 translationData, in int layer, out gra_Float2 numPagesOnLevel) 707{ 708 // The translation table contains uint32_t values so we have to get to the individual bits of the float data 709 uint data = GranitePrivate_FloatAsUint(translationData[layer]); 710 711 // Slice Index: 7 bits, Cache X: 10 bits, Cache Y: 10 bits, Tile Level: 4 bits 712 uint slice = (data >> 24u) & 0x7Fu; 713 uint cacheX = (data >> 14u) & 0x3FFu; 714 uint cacheY = (data >> 4u) & 0x3FFu; 715 uint revLevel = data & 0xFu; 716 717 gra_Float2 numTilesOnLevel; 718 numTilesOnLevel.x = GranitePrivate_Pow2(revLevel); 719 numTilesOnLevel.y = numTilesOnLevel.x * gra_NumTilesYScale; 720 721 gra_Float2 tileTexCoord = frac(inputTexCoord * numTilesOnLevel); 722 723 gra_Float2 tileTexCoordCache = tileTexCoord * gra_TileContentInTiles + gra_Float2(cacheX, cacheY); 724 gra_Float3 final = gra_Float3(tileTexCoordCache * gra_RcpCacheInTiles(layer) + gra_BorderPixelsRcpCache(layer), slice); 725 726 numPagesOnLevel = numTilesOnLevel * gra_TileContentInTiles * gra_RcpCacheInTiles(layer); 727 728 return final; 729} 730 731gra_Float4 GranitePrivate_DrawDebugTiles(in gra_Float4 sourceColor, in gra_Float2 textureCoord, in gra_Float2 numPagesOnLevel) 732{ 733 // Calculate the border values 734 gra_Float2 cacheOffs = frac(textureCoord * numPagesOnLevel); 735 float borderTemp = max(cacheOffs.x, 1.0-cacheOffs.x); 736 borderTemp = max(max(cacheOffs.y, 1.0-cacheOffs.y), borderTemp); 737 float border = smoothstep(0.98, 0.99, borderTemp); 738 739 // White 740 gra_Float4 borderColor = gra_Float4(1,1,1,1); 741 742 //Lerp it over the source color 743 return lerp(sourceColor, borderColor, border); 744} 745 746gra_Float4 GranitePrivate_MakeResolveOutput(in GraniteTilesetConstantBuffer tsCB, in gra_Float2 tileXY, in float level) 747{ 748#if GRA_PACK_RESOLVE_OUTPUT 749 return GranitePrivate_PackTileId(tileXY, level, gra_TextureId); 750#else 751 return gra_Float4(tileXY, level, gra_TextureId); 752#endif 753} 754 755gra_Float4 GranitePrivate_ResolverPixel(in GraniteTilesetConstantBuffer tsCB, in gra_Float2 inputTexCoord, in float LOD) 756{ 757 float level = floor(LOD + 0.5f); 758 759 // Number of tiles on level zero 760 gra_Float2 level0NumTiles; 761 level0NumTiles.x = gra_Level0NumTilesX; 762 level0NumTiles.y = gra_Level0NumTilesX * gra_NumTilesYScale; 763 764 // Calculate xy of the tiles to load 765 gra_Float2 virtualTilesUv = floor(inputTexCoord * level0NumTiles * pow(0.5, level)); 766 767 return GranitePrivate_MakeResolveOutput(tsCB, virtualTilesUv, level); 768} 769 770void GranitePrivate_CalculateCubemapCoordinates(in gra_Float3 inputTexCoord, in gra_Float3 dVx, in gra_Float3 dVy, in GraniteStreamingTextureCubeConstantBuffer transforms, out int faceIdx, out gra_Float2 texCoord, out gra_Float2 dX, out gra_Float2 dY) 771{ 772 gra_Float2 contTexCoord; 773 gra_Float3 derivX; 774 gra_Float3 derivY; 775 776 float majorAxis; 777 if (abs(inputTexCoord.z) >= abs(inputTexCoord.x) && abs(inputTexCoord.z) >= abs(inputTexCoord.y)) 778 { 779 // Z major axis 780 if(inputTexCoord.z < 0.0) 781 { 782 faceIdx = 5; 783 texCoord.x = -inputTexCoord.x; 784 } 785 else 786 { 787 faceIdx = 4; 788 texCoord.x = inputTexCoord.x; 789 } 790 texCoord.y = -inputTexCoord.y; 791 majorAxis = inputTexCoord.z; 792 793 contTexCoord = gra_Float2(inputTexCoord.x, inputTexCoord.y); 794 derivX = gra_Float3(dVx.x, dVx.y, dVx.z); 795 derivY = gra_Float3(dVy.x, dVy.y, dVy.z); 796 } 797 else if (abs(inputTexCoord.y) >= abs(inputTexCoord.x)) 798 { 799 // Y major axis 800 if(inputTexCoord.y < 0.0) 801 { 802 faceIdx = 3; 803 texCoord.y = -inputTexCoord.z; 804 } 805 else 806 { 807 faceIdx = 2; 808 texCoord.y = inputTexCoord.z; 809 } 810 texCoord.x = inputTexCoord.x; 811 majorAxis = inputTexCoord.y; 812 813 contTexCoord = gra_Float2(inputTexCoord.x, inputTexCoord.z); 814 derivX = gra_Float3(dVx.x, dVx.z, dVx.y); 815 derivY = gra_Float3(dVy.x, dVy.z, dVy.y); 816 } 817 else 818 { 819 // X major axis 820 if(inputTexCoord.x < 0.0) 821 { 822 faceIdx = 1; 823 texCoord.x = inputTexCoord.z; 824 } 825 else 826 { 827 faceIdx = 0; 828 texCoord.x = -inputTexCoord.z; 829 } 830 texCoord.y = -inputTexCoord.y; 831 majorAxis = inputTexCoord.x; 832 833 contTexCoord = gra_Float2(inputTexCoord.z, inputTexCoord.y); 834 derivX = gra_Float3(dVx.z, dVx.y, dVx.x); 835 derivY = gra_Float3(dVy.z, dVy.y, dVy.x); 836 } 837 texCoord = (texCoord + majorAxis) / (2.0 * abs(majorAxis)); 838 839#if GRA_HQ_CUBEMAPPING 840 dX = /*contTexCoord **/ ((contTexCoord + derivX.xy) / ( 2.0 * (majorAxis + derivX.z)) - (contTexCoord / (2.0 * majorAxis))); 841 dY = /*contTexCoord **/ ((contTexCoord + derivY.xy) / ( 2.0 * (majorAxis + derivY.z)) - (contTexCoord / (2.0 * majorAxis))); 842#else 843 dX = ((/*contTexCoord **/ derivX.xy) / (2.0 * abs(majorAxis))); 844 dY = ((/*contTexCoord **/ derivY.xy) / (2.0 * abs(majorAxis))); 845#endif 846 847 // Now scale the derivatives with the texture transform scale 848 dX *= transforms.data[faceIdx].data[0].zw; 849 dY *= transforms.data[faceIdx].data[0].zw; 850} 851 852// Auto-level 853void GranitePrivate_CalculateCubemapCoordinates(in gra_Float3 inputTexCoord, in GraniteStreamingTextureCubeConstantBuffer transforms, out int faceIdx, out gra_Float2 texCoord, out gra_Float2 dX, out gra_Float2 dY) 854{ 855 gra_Float3 dVx = ddx(inputTexCoord); 856 gra_Float3 dVy = ddy(inputTexCoord); 857 858 GranitePrivate_CalculateCubemapCoordinates(inputTexCoord, dVx, dVy, transforms, faceIdx, texCoord, dX, dY); 859} 860 861gra_Float2 Granite_GetTextureDimensions(in GraniteStreamingTextureConstantBuffer grSTCB) 862{ 863 return gra_Float2(1.0 / gra_AssetWidthRcp, 1.0 / gra_AssetHeightRcp); //TODO(ddebaets) use HLSL rcp here 864}