UnityShader源码2017---学习笔记与自我拓展011

源自TextureUV

if (_StaticUV1)
o.uv.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
else
o.uv.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;

这个就顾名思义吧,如果bake了lightmap就使用第二套uv,如果没有bake,就使用第三套uv。

为啥这样做,如果bake了,大家都知道第二套uv是留给lightmap的,但是没有bake的时候,第二套uv可能是我们自己自定义用于别的目的,但是我们可能没有第三套uv啊,难道unity自己给我们copy了一份?

_Decode_HDR这个参数没有找到出处,估计是unity引擎里封装了之后,传值过来的吧。

接下来看一下

result = LinearToGammaSpace (result);

这个LineraToGammaSpace方法顾名思义了

inline half3 LinearToGammaSpace ( half3 linRGB)
{
linRGB = max (linRGB, half3 ( 0. h, 0. h, 0. h));
// An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return max ( 1. 055h * pow (linRGB, 0. 416666667h) - 0. 055h, 0. h);

// Exact version, useful for debugging.
//return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));
}

一个几乎完美的近似公式。

上面那根是pow(x,1/2.2)的曲线

下面那根是近似公式的曲线。

我截图的x范围是0-12,也就是说在0-1的范围能两个曲线基本上完美相似。

从这个公式中可以看出点什么呢?

反正我一头雾水,使用近似公式的普遍目的是什么?绝大多数是我了减少运算量。

但是这里我并没有看出来(1/2.2=0.45454545454545454545454545454545)。

1.055*pow(x,0.416666667)-0.055 与 pow(x,0.454545455)显然是后者的更少。

这么一来,我只能怀疑自己的认知了。

于是我有找了找GammaSpace与LinearSpace的资料重新翻读。

But But But。。。一圈下来可能是我google的方式不对,大家好像都是这么认为的。

冷不丁的。。。对,布丁挺冷的。。。哎,开了一个冷笑话。。

inline float LinearToGammaSpaceExact ( float value)
{
if (value <= 0. 0F)
return 0. 0F;
else if (value <= 0. 0031308F)
return 12. 92F * value;
else if (value < 1. 0F)
return 1. 055F * pow (value, 0. 4166667F) - 0. 055F;
else
return pow (value, 0. 45454545F);
}

看到了源码中的这个精确的版本。

也就是说这个才是精确版本,所以近似版的优化还是挺多的

我先重新贴一下之前那两个方法的曲线图吧


接下来是Exact精确的计算方式的图



然后是三种方式的比较图


对于人眼这种极为感性的观察器官来说,几乎很难去察觉这一点的变化。,但是官方却用1.055*pow(x,0.416666667)-0.055,

x=0的时候,返回值是-0.055;

虽然两个很接近,差那点运算量也微乎其微。难道unity。。。。嗯。。。。







http://filmicworlds.com/blog/linear-space-lighting-i-e-gamma/

猜你喜欢

转载自blog.csdn.net/u012871784/article/details/80512215