Skip to content

Commit aebaced

Browse files
Support DGI mixed lights baking for HalfLuv and R11G11B10 radiance encodings. (#98)
1 parent 13fcc70 commit aebaced

File tree

2 files changed

+190
-5
lines changed

2 files changed

+190
-5
lines changed

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbeVolumeDynamicGI.cs

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Runtime.CompilerServices;
44
using System.Runtime.InteropServices;
5+
using Unity.Collections.LowLevel.Unsafe;
56
using UnityEngine.Experimental.Rendering;
67

78
using static UnityEngine.Rendering.HighDefinition.ProbePropagationBasis;
@@ -435,6 +436,157 @@ static Vector3 RgbFromLogluv(Vector3 vLogLuv)
435436
Mathf.Max(vRGB.z, 0f));
436437
}
437438

439+
static Vector3 LuvFromRgb(Vector3 vRGB)
440+
{
441+
Vector3 vResult;
442+
Vector3 Xp_Y_XYZp = LOG_LUV_ENCODE_MAT * vRGB;
443+
Xp_Y_XYZp = new Vector3(
444+
Mathf.Max(Xp_Y_XYZp.x, 1e-6f),
445+
Mathf.Max(Xp_Y_XYZp.y, 1e-6f),
446+
Mathf.Max(Xp_Y_XYZp.z, 1e-6f));
447+
vResult.x = Xp_Y_XYZp.x / Xp_Y_XYZp.z;
448+
vResult.y = Xp_Y_XYZp.y / Xp_Y_XYZp.z;
449+
float Le = Xp_Y_XYZp.y; // Raw range
450+
vResult.z = Le;
451+
return vResult;
452+
}
453+
454+
static Vector3 RgbFromLuv(Vector3 vLogLuv)
455+
{
456+
Vector3 Xp_Y_XYZp;
457+
Xp_Y_XYZp.y = vLogLuv.z; // Raw range
458+
Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;
459+
Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;
460+
Vector3 vRGB = LOG_LUV_DECODE_MAT * Xp_Y_XYZp;
461+
return new Vector3(
462+
Mathf.Max(vRGB.x, 0f),
463+
Mathf.Max(vRGB.y, 0f),
464+
Mathf.Max(vRGB.z, 0f));
465+
}
466+
467+
static uint EncodeSimpleUHalfFloat(float x)
468+
{
469+
x = Mathf.Clamp(x, Mathf.Pow(2f, -15f), Mathf.Pow(2f, 16f));
470+
471+
uint floatBits = UnsafeUtility.As<float, uint>(ref x);
472+
473+
uint floatFraction = floatBits & ((1u << 23) - 1u);
474+
uint floatExponent = floatBits >> 23;
475+
476+
uint halfFraction = floatFraction >> (23 - 11); // truncate.
477+
478+
// float bias: -127
479+
// half bias: -15
480+
// diff bias: -112.
481+
uint halfExponent = (floatExponent < 112u) ? 0u : (floatExponent - 112u);
482+
halfExponent = Math.Min(31u, halfExponent); // Clamp shouldnt be necessary.
483+
484+
return (halfExponent << 11) | halfFraction;
485+
}
486+
487+
static float DecodeSimpleUHalfFloat(uint halfBits)
488+
{
489+
uint halfExponent = halfBits >> 11;
490+
uint halfFraction = halfBits & ((1u << 11) - 1u);
491+
492+
uint floatFraction = halfFraction << (23 - 11);
493+
uint floatExponent = halfExponent + 112u;
494+
495+
uint floatBits = (floatExponent << 23) | floatFraction;
496+
497+
return UnsafeUtility.As<uint, float>(ref floatBits);
498+
}
499+
500+
static uint EncodeSimpleU10Float(float x)
501+
{
502+
x = Mathf.Clamp(x, Mathf.Pow(2f, -15f), Mathf.Pow(2f, 16f));
503+
504+
uint floatBits = UnsafeUtility.As<float, uint>(ref x);
505+
506+
uint floatFraction = floatBits & ((1u << 23) - 1u);
507+
uint floatExponent = floatBits >> 23;
508+
509+
uint halfFraction = floatFraction >> (23 - 5); // truncate.
510+
511+
// float bias: -127
512+
// half bias: -15
513+
// diff bias: -112.
514+
uint halfExponent = (floatExponent < 112u) ? 0u : (floatExponent - 112u);
515+
halfExponent = Math.Min(31u, halfExponent); // Clamp shouldnt be necessary.
516+
517+
return (halfExponent << 5) | halfFraction;
518+
}
519+
520+
static float DecodeSimpleU10Float(uint halfBits)
521+
{
522+
uint halfExponent = halfBits >> 5;
523+
uint halfFraction = halfBits & ((1u << 5) - 1u);
524+
525+
uint floatFraction = halfFraction << (23 - 5);
526+
uint floatExponent = halfExponent + 112u;
527+
528+
uint floatBits = (floatExponent << 23) | floatFraction;
529+
530+
return UnsafeUtility.As<uint, float>(ref floatBits);
531+
}
532+
533+
static uint EncodeSimpleU11Float(float x)
534+
{
535+
x = Mathf.Clamp(x, Mathf.Pow(2f, -15f), Mathf.Pow(2f, 16f));
536+
537+
uint floatBits = UnsafeUtility.As<float, uint>(ref x);
538+
539+
uint floatFraction = floatBits & ((1u << 23) - 1u);
540+
uint floatExponent = floatBits >> 23;
541+
542+
uint halfFraction = floatFraction >> (23 - 6); // truncate.
543+
544+
// float bias: -127
545+
// half bias: -15
546+
// diff bias: -112.
547+
uint halfExponent = (floatExponent < 112u) ? 0u : (floatExponent - 112u);
548+
halfExponent = Math.Min(31u, halfExponent); // Clamp shouldnt be necessary.
549+
550+
return (halfExponent << 6) | halfFraction;
551+
}
552+
553+
static float DecodeSimpleU11Float(uint halfBits)
554+
{
555+
uint halfExponent = halfBits >> 6;
556+
uint halfFraction = halfBits & ((1u << 6) - 1u);
557+
558+
uint floatFraction = halfFraction << (23 - 6);
559+
uint floatExponent = halfExponent + 112u;
560+
561+
uint floatBits = (floatExponent << 23) | floatFraction;
562+
563+
return UnsafeUtility.As<uint, float>(ref floatBits);
564+
}
565+
566+
static uint EncodeSimpleR11G11B10(Vector3 rgb)
567+
{
568+
uint r11 = EncodeSimpleU11Float(rgb.x);
569+
uint g11 = EncodeSimpleU11Float(rgb.y);
570+
uint b10 = EncodeSimpleU10Float(rgb.z);
571+
572+
return (r11 << 21)
573+
| (g11 << 10)
574+
| b10;
575+
}
576+
577+
internal static Vector3 DecodeSimpleR11G11B10(uint r11g11b10)
578+
{
579+
uint r11 = r11g11b10 >> 21;
580+
uint g11 = (r11g11b10 >> 10) & ((1u << 11) - 1u);
581+
uint b10 = r11g11b10 & ((1u << 10) - 1u);
582+
583+
return new Vector3(
584+
DecodeSimpleU11Float(r11),
585+
DecodeSimpleU11Float(g11),
586+
DecodeSimpleU10Float(b10)
587+
);
588+
}
589+
438590
internal static Vector3 DecodeLogLuv(uint value)
439591
{
440592
Vector3 logLuv;
@@ -444,6 +596,15 @@ internal static Vector3 DecodeLogLuv(uint value)
444596
return RgbFromLogluv(logLuv);
445597
}
446598

599+
internal static Vector3 DecodeHalfLuv(uint value)
600+
{
601+
Vector3 luv;
602+
luv.x = ((value >> 0) & 255) / 255.0f;
603+
luv.y = ((value >> 8) & 255) / 255.0f;
604+
luv.z = DecodeSimpleUHalfFloat(value >> 16);
605+
return RgbFromLuv(luv);
606+
}
607+
447608
internal void Allocate(RenderPipelineResources resources)
448609
{
449610
Cleanup(); // To avoid double alloc.
@@ -566,6 +727,8 @@ private void SetBasisKeywords(ProbeVolumeDynamicGIBasis basis, ProbeVolumeDynami
566727
}
567728
}
568729

730+
internal static bool IsRadianceEncodedInUint(ProbeVolumeDynamicGIRadianceEncoding encoding) => encoding != ProbeVolumeDynamicGIRadianceEncoding.RGBFloat;
731+
569732
static void SetRadianceEncodingKeywords(ComputeShader shader, ProbeVolumeDynamicGIRadianceEncoding encoding)
570733
{
571734
switch (encoding)
@@ -1115,7 +1278,7 @@ static bool InitializePropagationBuffers(ProbeVolumeHandle probeVolume, ProbeVol
11151278
propagationPipelineData.radianceEncoding = radianceEncoding;
11161279
}
11171280

1118-
changed |= radianceEncoding == ProbeVolumeDynamicGIRadianceEncoding.LogLuv
1281+
changed |= IsRadianceEncodedInUint(propagationPipelineData.radianceEncoding)
11191282
? EnsurePropagationBuffers<uint>(ref propagationPipelineData, hitNeighborAxisLengthOrOne, numAxis)
11201283
: EnsurePropagationBuffers<Vector3>(ref propagationPipelineData, hitNeighborAxisLengthOrOne, numAxis);
11211284

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/ProbeVolume.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,14 +1309,36 @@ internal void CopyDirectLightingToMixed()
13091309
if (hitRadianceCache == null || !hitRadianceCache.IsValid() || hitRadianceCache.count != hits.Length)
13101310
return;
13111311

1312-
if (propagationPipelineData.radianceEncoding == ProbeVolumeDynamicGIRadianceEncoding.LogLuv)
1312+
if (ProbeVolumeDynamicGI.IsRadianceEncodedInUint(propagationPipelineData.radianceEncoding))
13131313
{
13141314
var hitRandiance = new uint[hits.Length];
13151315
hitRadianceCache.GetData(hitRandiance);
1316-
for (int i = 0; i < hits.Length; i++)
1316+
switch (propagationPipelineData.radianceEncoding)
13171317
{
1318-
var lighting = ProbeVolumeDynamicGI.DecodeLogLuv(hitRandiance[i]);
1319-
hits[i].mixedLighting = ProbeVolumeDynamicGI.PackEmission(lighting);
1318+
case ProbeVolumeDynamicGIRadianceEncoding.LogLuv:
1319+
for (int i = 0; i < hits.Length; i++)
1320+
{
1321+
var lighting = ProbeVolumeDynamicGI.DecodeLogLuv(hitRandiance[i]);
1322+
hits[i].mixedLighting = ProbeVolumeDynamicGI.PackEmission(lighting);
1323+
}
1324+
break;
1325+
case ProbeVolumeDynamicGIRadianceEncoding.HalfLuv:
1326+
for (int i = 0; i < hits.Length; i++)
1327+
{
1328+
var lighting = ProbeVolumeDynamicGI.DecodeHalfLuv(hitRandiance[i]);
1329+
hits[i].mixedLighting = ProbeVolumeDynamicGI.PackEmission(lighting);
1330+
}
1331+
break;
1332+
case ProbeVolumeDynamicGIRadianceEncoding.R11G11B10:
1333+
for (int i = 0; i < hits.Length; i++)
1334+
{
1335+
var lighting = ProbeVolumeDynamicGI.DecodeSimpleR11G11B10(hitRandiance[i]);
1336+
hits[i].mixedLighting = ProbeVolumeDynamicGI.PackEmission(lighting);
1337+
}
1338+
break;
1339+
default:
1340+
Debug.Assert(false);
1341+
return;
13201342
}
13211343
}
13221344
else

0 commit comments

Comments
 (0)