浏览代码

Implement new packing functionality

/RenderPassXR_Sandbox
Evgenii Golubev 7 年前
当前提交
0e475e7d
共有 3 个文件被更改,包括 85 次插入36 次删除
  1. 31
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  2. 5
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  3. 85
      Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl

31
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


{
// Use 16 bits to encode the thickness, and up to 8 bits to encode the profile ID.
// We need a lot of precision to minimize banding of NdotV-weighted thickness.
int ip = surfaceData.subsurfaceProfile; // [0, 255]
float ft = surfaceData.thickness; // [0, 1]
int it = int(ft * ((1 << 16) - 1)); // [0, 65535]
int lo = it & ((1 << 8) - 1); // 8 bit low
int hi = (it >> 8) & ((1 << 8) - 1); // 8 bit high
float y = saturate(lo * rcp((1 << 8) - 1));
float z = saturate(hi * rcp((1 << 8) - 1));
float w = saturate(ip * rcp((1 << 8) - 1));
outGBuffer2 = float4(surfaceData.subsurfaceRadius, y, z, w);
outGBuffer2 = float4(surfaceData.subsurfaceRadius,
PackFloatToR8G8(surfaceData.thickness),
PackByte(surfaceData.subsurfaceProfile));
}
else if (surfaceData.materialId == MATERIALID_LIT_SPECULAR)
{

}
else if (supportsSSS && bsdfData.materialId == MATERIALID_LIT_SSS)
{
float subsurfaceRadius = inGBuffer2.r;
float y = inGBuffer2.g;
float z = inGBuffer2.b;
float w = inGBuffer2.a;
int lo = int(y * ((1 << 8) - 1)); // 8 bit low
int hi = int(z * ((1 << 8) - 1)); // 8 bit high
int ip = int(w * ((1 << 8) - 1)); // [0, 255]
int it = lo + (hi << 8); // [0, 65535]
float ft = saturate(it * rcp((1 << 16) - 1)); // [0, 1]
float thickness = ft;
int subsurfaceProfile = ip;
float subsurfaceRadius = inGBuffer2.x;
float thickness = UnpackFloatFromR8G8(inGBuffer2.yz);
int subsurfaceProfile = UnpackByte(inGBuffer2.w);
FillMaterialIdSSSData(baseColor, subsurfaceProfile, subsurfaceRadius, thickness, bsdfData);
}

5
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


#ifndef INTRINSIC_BITFIELD_EXTRACT
// unsigned integer bit field extract implementation
uint BitFieldExtract(uint data, uint size, uint offset)
uint BitFieldExtract(uint data, uint numBits, uint offset)
return (data >> offset) & ((1 << size) - 1);
uint mask = 0xFFFFFFFFu >> (32u - numBits);
return (data >> offset) & mask;
}
#endif // INTRINSIC_BITFIELD_EXTRACT

85
Assets/ScriptableRenderPipeline/ShaderLibrary/Packing.hlsl


#ifndef UNITY_PACKING_INCLUDED
#define UNITY_PACKING_INCLUDED
#include "Common.hlsl"
//-----------------------------------------------------------------------------
// Normal packing
//-----------------------------------------------------------------------------

}
//-----------------------------------------------------------------------------
// Byte packing
// Integer packing
// Packs an integer stored using at most 'numBits' into a [0..1] float.
float PackInt(uint i, uint numBits)
{
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return saturate(i * rcp(maxInt));
}
// Unpacks a [0..1] float into an integer using at most 'numBits'.
uint UnpackInt(float f, uint numBits)
{
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return (uint)(f * maxInt + 0.5); // Round instead of truncating
}
// Packs a [0..255] integer into a [0..1] float.
float PackByte(uint i)
{
return PackInt(i, 8);
}
// Unpacks a [0..1] float into a [0..255] integer.
uint UnpackByte(float f)
{
return UnpackInt(f, 8);
}
// Packs a [0..65535] integer into a [0..1] float.
float PackShort(uint i)
{
return PackInt(i, 16);
}
// Unpacks a [0..1] float into a [0..65535] integer.
uint UnpackShort(float f)
{
return UnpackInt(f, 16);
}
// Packs 8 lowermost bits of a [0..65535] integer into a [0..1] float.
float PackShortLo(uint i)
{
uint lo = BitFieldExtract(i, 8, 0);
return PackInt(lo, 8);
}
// Packs 8 uppermost bits of a [0..65535] integer into a [0..1] float.
float PackShortHi(uint i)
{
uint hi = BitFieldExtract(i, 8, 8);
return PackInt(hi, 8);
}
float Pack2Byte(float2 inputs)
{
float2 temp = inputs * float2(255.0, 255.0);

}
//-----------------------------------------------------------------------------
// float packing to sint/uint
// Float packing
uint PackFloatToUInt(float src, uint size, uint offset)
uint PackFloatToUInt(float src, uint numBits, uint offset)
const float maxValue = float((1u << size) - 1u) + 0.5; // Shader compiler should be able to remove this
return uint(src * maxValue) << offset;
return UnpackInt(src, numBits) << offset;
float UnpackUIntToFloat(uint src, uint size, uint offset)
float UnpackUIntToFloat(uint src, uint numBits, uint offset)
const float invMaxValue = 1.0 / float((1 << size) - 1);
return float(BitFieldExtract(src, size, offset)) * invMaxValue;
uint maxInt = 0xFFFFFFFFu >> (32u - numBits);
return float(BitFieldExtract(src, numBits, offset)) * rcp(maxInt);
}
uint PackR10G10B10A2(float4 rgba)

return ouput;
}
// Both the input and the output are in the [0, 1] range.
float2 PackFloatToR8G8(float f)
{
uint i = UnpackShort(f);
return float2(PackShortLo(i), PackShortHi(i));
}
// Both the input and the output are in the [0, 1] range.
float UnpackFloatFromR8G8(float2 f)
{
uint lo = UnpackByte(f.x);
uint hi = UnpackByte(f.y);
uint cb = (hi << 8) + lo;
return PackShort(cb);
}
#endif // UNITY_PACKING_INCLUDED
正在加载...
取消
保存