Skip to content

Instantly share code, notes, and snippets.

@jeferwang
Last active November 4, 2024 11:18
Show Gist options
  • Save jeferwang/9aa05aecad78e2cac90ea1a6b27fa179 to your computer and use it in GitHub Desktop.
Save jeferwang/9aa05aecad78e2cac90ea1a6b27fa179 to your computer and use it in GitHub Desktop.
Unity C# Decode RGBM Texture
Shader "Unlit/DecodeLightmap"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"RenderType"="Opaque"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
#define LIGHTMAP_RGBM_MAX_GAMMA half(5.0)
#define LIGHTMAP_RGBM_MAX_LINEAR half(34.493242)
// #define LIGHTMAP_HDR_MULTIPLIER LIGHTMAP_RGBM_MAX_GAMMA
// #define LIGHTMAP_HDR_EXPONENT half(1.0)
#define LIGHTMAP_HDR_MULTIPLIER LIGHTMAP_RGBM_MAX_LINEAR
#define LIGHTMAP_HDR_EXPONENT half(2.2)
half4 frag(v2f i) : SV_Target
{
half4 decodeInstructions = half4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h);
half3 col = DecodeLightmapRGBM(tex2D(_MainTex, i.uv), decodeInstructions);
return half4(col, 1.0);
}
ENDCG
}
}
}
private static Texture2D DecodeLightmap(Texture2D lightmap)
{
// Decode RGBM Reference
// Library/PackageCache/[email protected]/ShaderLibrary/EntityLighting.hlsl LIGHTMAP_RGBM_MAX_GAMMA
// UnityCG.cginc DecodeLightmapRGBM
var tmpRT = RenderTexture.GetTemporary(lightmap.width, lightmap.height, 0, RenderTextureFormat.Default, lightmap.isDataSRGB ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear);
tmpRT.wrapMode = TextureWrapMode.Clamp;
tmpRT.filterMode = FilterMode.Point;
tmpRT.anisoLevel = 0;
// Graphics.Blit(lightmap, tmpRT);
// Shader Decode RGBM, Blit to RGB
Graphics.Blit(lightmap, tmpRT, new Material(AssetDatabase.LoadAssetAtPath<Shader>("Assets/Tools/DecodeLightmap.shader")));
var previous = RenderTexture.active;
RenderTexture.active = tmpRT;
var tmpTex = new Texture2D(lightmap.width, lightmap.height, TextureFormat.RGBA32, false, !lightmap.isDataSRGB);
tmpTex.ReadPixels(new Rect(0, 0, tmpRT.width, tmpRT.height), 0, 0);
tmpTex.Apply();
// Decode RGBM, Calculate RGB
// const float rgbmMaxGamma = 5.0f;
// const float hdrExponent = 2.2f;
// var rgbmMaxLinear = Mathf.Pow(rgbmMaxGamma, 2.2f);
//
// var pixels = tmpTex.GetPixels();
// for (var i = 0; i < pixels.Length; i++)
// {
// var pixel = pixels[i].linear;
// var m = rgbmMaxLinear * Mathf.Pow(pixel.a, hdrExponent);
// pixel.r *= m;
// pixel.g *= m;
// pixel.b *= m;
// pixel.a = 1;
// pixels[i] = pixel.gamma;
// }
//
// tmpTex.SetPixels(pixels);
// tmpTex.Apply();
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(tmpRT);
return tmpTex;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment