You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
- MSM_Substrate - MCT_Substrate - FStrataMaterialInput #rb charles.derousiers [CL 27563163 by marc audy in ue5-main branch]
168 lines
5.0 KiB
Plaintext
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 |