Files
UnrealEngineUWP/Engine/Shaders/Private/Substrate/SubstrateTile.ush
marc audy 65de35fdfb Lof elements that were not renamed yet.
- MSM_Substrate
- MCT_Substrate
- FStrataMaterialInput

#rb charles.derousiers

[CL 27563163 by marc audy in ue5-main branch]
2023-09-01 15:06:19 -04:00

168 lines
5.0 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "/Engine/Private/Common.ush"
#include "/Engine/Shared/SubstrateDefinitions.h"
#include "Substrate.ush"
#if SUBSTRATE_ENABLED
#ifndef USE_8BIT_TILE_COORD
#error USE_8BIT_TILE_COORD needs to be defined
#define USE_8BIT_TILE_COORD 0
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Substrate material type tile
uint2 SubstrateUnpackTile(uint In)
{
#if USE_8BIT_TILE_COORD
return uint2(In & 0xFF, In >> 8);
#else
return uint2(In & 0xFFFF, In >> 16);
#endif
}
uint SubstratePackTile(uint2 TileCoord)
{
#if USE_8BIT_TILE_COORD
return TileCoord.x | (TileCoord.y << 8);
#else
#if COMPILER_SUPPORTS_PACK_INTRINSICS
return PackUInt2ToUInt(TileCoord.x, TileCoord.y);
#else
return TileCoord.x | (TileCoord.y << 16); // assumes 16bit is enough to represent a tiled resolution up to 65,535 :)
#endif
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Substrate BSDF tile
// For tile whose conatins at least 1 pixel with several BSDF, we store a list of 'overflow' tiles
//
// For handling material with several BSDF per pixel we extend the original texture (primary space)
// with an overflow space. Pixels with more than one BSDF data will write BSDF 2/3/... data into
// the overflow space
// ________________
// | |
// | Primary space |
// |________________|
// | Overflow space |
// |________________|
//
// The primary & overflow spaces are divided into tiles, and one primary-space tile refers a list
// of tiles in overflow-space, if the tile contains at least one pixel with has more than 1 BSDF
// If several tiles are needed, they are contigously stored in overflow space
// ________________
// |_:_:_:_:_:_:_:_:|
// |_:_:_:_:_:_:_:_:| Primary space
// |_:_:_:_:_:_:_:_:|
// ----------------
// |_:_:_:_:_:_: | Overflow space
// |________________|
struct FSubstrateBSDFTile
{
uint2 TileCoord; // If Index == 0, points to the first 'overflow' tiles. If Index != 0, points towards the 'parent'/primary space tile
uint Index;
uint Count;
};
uint PackBSDFTile(FSubstrateBSDFTile In)
{
// Tile coord are encoded onto 10bits. Max resolution 8k x 8k. Max 8 tiles.
return (In.TileCoord.x & 0x3FF) | ((In.TileCoord.y & 0x3FF) << 10) | ((In.Index & 0x7) << 20) | ((In.Count & 0x7) << 23);
}
FSubstrateBSDFTile UnpackBSDFTile(uint In)
{
FSubstrateBSDFTile Out;
Out.TileCoord.x = In & 0x3FF;
Out.TileCoord.y = (In >> 10u) & 0x3FF;
Out.Index = (In >> 20u) & 0x7;
Out.Count = (In >> 23u) & 0x7;
return Out;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Substrate BSDF offset
// Store the material slice index offset for each BSDF, for pixels containing several BSDFs
struct FSubstrateBSDFOffset
{
uint BSDFOffsets[SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET];
uint BSDFCount;
};
uint PackBSDFOffset(FSubstrateBSDFOffset In)
{
// Packed as relative cumulative offsets of N bits, stored into 32 bits
// | N bits | N bits | N bits | N bits | ... | N bits |
// BSDF 0 BSDF 1 BSDF 2 BSDF 3 ... BSDF (2^N - 1)
uint Out = 0;
const uint BSDFCount = min(In.BSDFCount, SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET);
if (BSDFCount > 0)
{
Out = In.BSDFOffsets[0] & SUBSTRATE_BSDF_OFFSET_BIT_MASK;
UNROLL_N(SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET-1)
for (uint i = 1; i < BSDFCount; i++)
{
const uint Curr = In.BSDFOffsets[i];
const uint Prev = In.BSDFOffsets[i-1];
Out = Out | (((Curr - Prev) & SUBSTRATE_BSDF_OFFSET_BIT_MASK) << (SUBSTRATE_BSDF_OFFSET_BIT_COUNT * i));
}
}
return Out;
}
FSubstrateBSDFOffset UnpackBSDFOffset(uint In, uint InBSDFCount)
{
FSubstrateBSDFOffset Out = (FSubstrateBSDFOffset)0;
if (InBSDFCount > 0)
{
Out.BSDFCount = min(InBSDFCount, SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET);
Out.BSDFOffsets[0] = (In & SUBSTRATE_BSDF_OFFSET_BIT_MASK);
UNROLL_N(SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET-1)
for (uint i = 1; i < Out.BSDFCount; i++)
{
Out.BSDFOffsets[i] = Out.BSDFOffsets[i-1] + ((In>>(SUBSTRATE_BSDF_OFFSET_BIT_COUNT * i)) & SUBSTRATE_BSDF_OFFSET_BIT_MASK);
}
}
return Out;
}
uint UnpackBSDFOffsetAtIndex(uint In, uint InIndex, uint InBSDFCount)
{
uint Out = 0;
if (InBSDFCount > 0)
{
const uint BSDFCount = min(InBSDFCount, SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET);
UNROLL_N(SUBSTRATE_MAX_BSDF_COUNT_FOR_BDSFOFFSET)
for (uint i = 0; i <= InIndex; i++)
{
Out += ((In >> (SUBSTRATE_BSDF_OFFSET_BIT_COUNT * i)) & SUBSTRATE_BSDF_OFFSET_BIT_MASK);
}
}
return Out;
}
void SubstrateSeekBSDF(inout FSubstrateAddressing Addressing, uint AddressOffset)
{
Addressing.CurrentIndex = AddressOffset;
Addressing.ReadBytes = Addressing.CurrentIndex * 4;
}
void SubstrateSeekBSDF(inout FSubstrateAddressing Addressing, FSubstrateBSDFOffset Offsets, uint BSDFIndex)
{
if (BSDFIndex < Offsets.BSDFCount)
{
Addressing.CurrentIndex = Offsets.BSDFOffsets[BSDFIndex];
Addressing.ReadBytes = Addressing.CurrentIndex * 4;
}
}
#endif // SUBSTRATE_ENABLED