源自FrameDebuggerRenderTargetDisplay
发现一个很好玩的function---ProcessColor。
fixed4 ProcessColor (half4 tex)
{
half4 col = tex;
col -= _Levels.rrrr;
col /= _Levels.gggg-_Levels.rrrr;
col *= _Channels;
if (dot(_Channels,fixed4(1,1,1,1)) == 1.0)
{
half c = dot(col,half4(1,1,1,1));
col = c;
}
return col;
}
接下来就开始吹捧之路-----精源码分子
half4 col = tex;这行代码真是精美,增一分过美,减一分欠美。如此吹捧甚是美好,脑仁不疼,膝盖不酸。
首先要注意的是_Levels是个float2.也就是说只有rg有用。
我们先精简function
fixed4 ProcessColor(half4 tex)
{
half4 col = tex;
col -= _Levels.rrrr;
return col;
}
很明显,如果_Levels.x是1,那么col是黑色,如果是-1,则为白色。
接下来再把_Levels部分不全看一下
fixed4 ProcessColor(half4 tex)
{
half4 col = tex;
col -= _Levels.rrrr;
col /= _Levels.gggg-_Levels.rrrr;
return col;
}
貌似在哪里见过相同的或者说是相似的画面。。。。
_Levels..........难道就是色阶,毕竟色阶的英文就是Level.....
查了一圈也没有找到level的算法。。。哎没有找到。。。看来是我google的方式不对,或者看到了也看不懂。。。
就权当上述就是level算法的一个简易版吧,毕竟是太像了。
接下来继续吹捧源码之路。
_Channels。。。。通道,看到这个就不在迷糊了,rgba通道嘛,
把码再添点。
fixed4 ProcessColor(half4 tex)
{
half4 col = tex;
col -= _Levels.rrrr;
col /= _Levels.gggg-_Levels.rrrr;
// leave only channels we want to show
col *= _Channels;
return col;
}
源码真好,看人家还给留着注释。。。。牛逼牛逼。。。
翻译过来就是“留下我们想显示的那些通道”
是的,如果_Channels.r是1,那么结果就是
如果_Channels.rg是1,那么结果就是
哇,源码真是牛逼,一下子就分离的通道。呵呵。
似乎有些不妥,如果只显示R通道不应该是灰色的么。。。。这好像是美术的日常
fixed4 ProcessColor(half4 tex)
{
half4 col = tex;
col -= _Levels.rrrr;
col /= _Levels.gggg-_Levels.rrrr;
// leave only channels we want to show
col *= _Channels;
// if we're showing only a single channel, display that as grayscale
if (dot(_Channels,fixed4(1,1,1,1)) == 1.0)
{
half c = dot(col,half4(1,1,1,1));
col = c;
}
return col;
}
源码注释:如果只想显示一个通道,我们就让它以灰度图显示
dot(_Channels,fixed4(1,1,1,1)) 这个的意思就是判断是否只显示一个通道,并且显示的比重是1,这个一目了然。
如果_Channels是(0.5,0,0,0),那么,不好意思,还是红红地显示一个R通道的一半值
half c = dot(col,half4(1,1,1,1));这个也挺有意思的。如果_Channels的四个分量有且只有一个分量为1,其余为0的话,col在上一步col*=_Channles里已经摒弃了gba通道信息。那么这次dot的值就只是个r通道的值。
什么?什么?什么?你要问shader里if和step的问题?我眼睛近视,听不到。
写这么一篇不是为了什么,只是觉得山不在高,在于灵;水不在深,在于龙,码不在长,在于短。
接下来再把其余部分的知识点说一下,希望一起学习的人或者将要学习的人,有个方便之路。总之PBR我要放到最后,这个实在是我的小短腿。
和这一点
把_MainTex设置为any,然后uv是float3,这几点还是挺微秒的。微妙之处就不说了,说一下目的吧
就是为了通用。如此操作,可以是2D texture 可以是3Dtexture,可以是cubemap,所以uv可能是float2,也可能是float3.
再说一个Tags
这个Tag的意思就是只要你的显卡支持这个subshader,那么不管你怎么设置的,都会强制支持。
static ShaderLab::IntShader* ShaderFromParseShader (const ShaderLab::ParserShader* parsed, ShaderPtrVector& dependenciesTable, bool useDependenciesTable, ShaderErrors& outErrors)
{
AssertIf( !parsed );
#if UNITY_EDITOR
// In the editor, we want to mark up some shaders as "always will be supported",
// no matter what the graphics emulation options say. For those shaders,
// bump up the graphics caps here, and restore them after loading the shader.
bool forceSupported = false;
if (parsed && !parsed->m_SubShaders.empty() && parsed->m_SubShaders[0]->m_Tags.find (GetShaderTagID("ForceSupported")) != parsed->m_SubShaders[0]->m_Tags.end())
forceSupported = true;
GraphicsCaps oldGraphicsCaps;
if (forceSupported)
{
oldGraphicsCaps = gGraphicsCaps;
gGraphicsCaps.InitializeOriginalEmulationCapsIfNeeded(); // force initialization of gOriginalCaps
gGraphicsCaps = gOriginalCaps;
}
#endif
// create ShaderLab shader from the parser representation
IntShader* shader = IntShader::CreateFromParsedShader (*parsed, dependenciesTable, useDependenciesTable, outErrors);
#if UNITY_EDITOR
if (forceSupported)
{
gGraphicsCaps = oldGraphicsCaps;
}
#endif
if (!shader)
return NULL;
if (shader->GetSubShaders().empty())
{
if (!parsed->m_DisableNoSubshadersMessage)
{
outErrors.AddShaderError ("No subshaders can run on this graphics card", -1, true);
}
UNITY_DELETE( shader, kMemShader);
return NULL;
}
return shader;
}
这个shader最后一个知识点
这个是HLSLSupport里的。
额。。。好像从来没有用的2DTex Array。。。嗯。。要不就跳过吧。。。知识短板。
不知道该说什么,就是sample 2Dtexarray的方法,跟tex2D应该是一个层级的function吧