{"id":215,"date":"2024-08-16T14:33:51","date_gmt":"2024-08-16T06:33:51","guid":{"rendered":"http:\/\/chenglixue.top\/?p=215"},"modified":"2024-08-16T14:33:51","modified_gmt":"2024-08-16T06:33:51","slug":"%e5%b7%a5%e5%85%b7-%e5%ae%9e%e6%97%b6%e6%88%96%e7%a6%bb%e7%ba%bf%e7%94%9f%e6%88%90ramp%e5%9b%be","status":"publish","type":"post","link":"http:\/\/chenglixue.top\/?p=215","title":{"rendered":"\u5de5\u5177 \u5b9e\u65f6\u6216\u79bb\u7ebf\u751f\u6210Ramp\u56fe"},"content":{"rendered":"<p><div class=\"has-toc have-toc\"><\/div><\/p>\n<h1>\u95ee\u9898<\/h1>\n<p>\u5728\u505a\u98ce\u683c\u5316\u6548\u679c\u65f6\uff0c\u7ecf\u5e38\u4f1a\u7528\u5230Ramp Tex\uff0c\u4f46\u5148\u5728PS\u4e2d\u751f\u6210\u518d\u8f6c\u5230Unity\u53c8\u592a\u9ebb\u70e6\u4e86\u3002\u4e3a\u6b64\u672c\u7bc7\u5c55\u793a\u4e86\u4e00\u4e2a\u5b9e\u65f6\u751f\u6210Ramp Tex\u7684\u5de5\u5177\u3002\u8be5\u5de5\u5177\u6709\u4ee5\u4e0b\u7279\u6027\uff1a<\/p>\n<ol>\n<li>\u53ef\u4ee5\u548c\u6307\u5b9amaterial\u4e2d\u7684Texture2D\u5c5e\u6027\u7ed1\u5b9a\uff0c\u751f\u6210\u7684Ramp Tex\u4f1a\u5b9e\u65f6\u4f20\u9012\u7ed9\u8be5\u5c5e\u6027\u5bf9\u8c61<\/li>\n<li>\u5728GPU\u4e2d\u8ba1\u7b97Ramp Tex<\/li>\n<li>\u652f\u6301\u4e00\u4e2aRamp Tex\u4e2d\u7ed8\u5236\u591a\u4e2aRamp Color<\/li>\n<li>\u53ef\u4ee5\u624b\u52a8\u9009\u62e9\u6df7\u5408\u3001\u4e0d\u6df7\u5408Ramp Tex\uff1a\u7531\u4e8e\u4e00\u4e2aRamp Tex\u4e2d\u53ef\u80fd\u5305\u542b\u591a\u4e2aRamp Color\uff0c\u53ef\u4ee5\u624b\u52a8\u9009\u62e9\u662f\u5426\u5b83\u4eec\u6df7\u5408\uff08\u4ece\u4e0a\u5230\u4e0b\u5bf9ramp color lerp\uff09<\/li>\n<li>\u652f\u6301SRGB\u6a21\u578b<\/li>\n<li>\u53ef\u5b9e\u65f6\u9884\u89c8\u751f\u6210\u7684Ramp Tex<\/li>\n<li>\u53ef\u4ee5\u624b\u52a8\u63a7\u5236\u751f\u6210\u7684Ramp Tex\u7684\u5206\u8fa8\u7387\u5927\u5c0f\uff08Tex width\uff09<\/li>\n<li>\u53ef\u4ee5\u628a\u5f53\u524d\u5bf9\u5de5\u5177\u7684\u8bbe\u7f6e\u4fdd\u5b58\u5728unity\u4e2d\uff0c\u4e14\u4e0b\u6b21\u91cd\u65b0\u6253\u5f00\u53ef\u4ee5\u8bfb\u53d6\u4e0a\u6b21\u4fdd\u5b58\u7684\u8bbe\u7f6e<\/li>\n<\/ol>\n<h1>\u5b9e\u73b0<\/h1>\n<h2>\u7ed1\u5b9aMaterial\u53ca\u5176\u4e2d\u7684Texture2D<\/h2>\n<ul>\n<li>\u4e3a\u4e86\u65b9\u4fbf\uff0c\u8fd9\u91cc\u91c7\u7528\u4e86\u53f3\u952eMaterial\u9762\u677f\u7684\u65b9\u5f0f\u6765\u7ed1\u5b9aMaterial\n<p>\u5982\u4e0b\u56fe\u4e2d\u70b9\u51fb\"Generate Ramp Tex\"\u6765\u542f\u52a8\u5de5\u5177\u5e76\u7ed1\u5b9aMaterial<br \/>\n<img decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/pic.imgdb.cn\/item\/66bdb090d9c307b7e9335c18.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  alt=\"\" \/><\/p >\n<noscript><img decoding=\"async\" src=\"https:\/\/pic.imgdb.cn\/item\/66bdb090d9c307b7e9335c18.png\" alt=\"\" \/><\/p><\/noscript>\n<pre><code class=\"line-numbers\">[MenuItem(\"CONTEXT\/Material\/Elysia\/Generate Ramp Tex\", priority = 0)]\npublic static void MatShowWindow(MenuCommand menuCommand)\n{\n  if (Ins == null)\n  {\n      Ins = GetWindow&lt;RampWindow&gt;();\n      Ins.InitData();   \/\/ \u521d\u59cb\u5316\u5fc5\u8981\u6570\u636e\n      Ins.Show();       \/\/ \u663e\u793awindow\n  }\n\n  \/\/ \u7ed1\u5b9amaterial\n  Ins.targetMaterial = menuCommand.context as Material;\n  Ins.UpdateProperty(); \/\/ \u83b7\u5f97material\u7684tex Property\n}\n<\/code><\/pre>\n<\/li>\n<li>\u7531\u4e8e\u4e00\u4e2aMaterial\u4e2d\u5f88\u6709\u53ef\u80fd\u5b58\u5728\u591a\u5f20Texture 2D\uff0c\u56e0\u6b64\u9700\u8981\u63d0\u4f9b\u4e00\u4e2a\u4e0b\u62c9\u6846\u6765\u9009\u62e9\u9700\u8981\u7684Texture 2D\u5bf9\u8c61<br \/>\n<img decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/pic.imgdb.cn\/item\/66bd9ff8d9c307b7e91df610.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  alt=\"\" \/><\/p >\n<noscript><img decoding=\"async\" src=\"https:\/\/pic.imgdb.cn\/item\/66bd9ff8d9c307b7e91df610.png\" alt=\"\" \/><\/p><\/noscript>\n<pre><code class=\"line-numbers\">_targetPropertyIndex = EditorGUILayout.Popup(\"Target Ramp Tex\", _targetPropertyIndex, _texNames.ToArray());   \/\/ \u751f\u6210\u4e0b\u62c9\u8868\npropertyName = _texNames[_targetPropertyIndex];   \/\/ \u83b7\u5f97\u6307\u5b9a\u7684property\u5bf9\u8c61\n<\/code><\/pre>\n<\/li>\n<li>\u6700\u540e\u63d0\u4f9b\u4e00\u4e2a\u6309\u94ae\uff0c\u53ef\u4ee5\u624b\u52a8\u9009\u62e9\u662f\u5426\u548c\u6307\u5b9aTexture 2D\u8fde\u63a5\uff0c\u5b9e\u65f6\u5730\u5c06\u751f\u6210\u7684Ramp Tex\u4f20\u8fc7\u53bb<br \/>\n<img decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/pic.imgdb.cn\/item\/66bda38bd9c307b7e920d8ce.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  alt=\"\" \/><br \/ >\n<noscript><img decoding=\"async\" src=\"https:\/\/pic.imgdb.cn\/item\/66bda38bd9c307b7e920d8ce.png\" alt=\"\" \/><br \/><\/noscript>\n<img decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/pic.imgdb.cn\/item\/66bda3aad9c307b7e920f2c6.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  alt=\"\" \/><\/p >\n<noscript><img decoding=\"async\" src=\"https:\/\/pic.imgdb.cn\/item\/66bda3aad9c307b7e920f2c6.png\" alt=\"\" \/><\/p><\/noscript>\n<pre><code class=\"line-numbers\">if (GUILayout.Button(_isLinked ? \"Break Link\" : \"Link Target Texture2D\"))\n{\n  if (_isLinked)\n  {\n      DestoryLink();\n  }\n  else\n  {\n      StarLink();\n  }\n}\n\nvoid StarLink()\n{\n  _isLinked = true;\n  _oldTex = targetMaterial.GetTexture(propertyName) as Texture2D;\n}\n\nvoid DestoryLink()\n{\n_isLinked = false;\n}\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2>\u4f20\u9012Gradient<\/h2>\n<p>\u4e3a\u4e86\u63d0\u9ad8\u901f\u7387\uff0c\u672c\u7bc7\u9009\u62e9\u5c06Gradient\u4eceCPU\u4f20\u9012\u5230GPU\u8ba1\u7b97<\/p>\n<p>unity\u63d0\u4f9b\u4e86\u73b0\u6210\u7684Gradient\uff0c\u4e3b\u8981\u7531color\u548calpha\u6784\u6210\u3002\u56e0\u6b64\uff0c\u5728\u4f20\u9012\u65f6\uff0c\u9700\u8981\u4f20\u9012color array\u3001alpha array<\/p>\n<p>\u8fd9\u4e2aGradient\u7684\u6570\u91cf\u662f\u6709\u9650\u5236\u7684\uff0c\u6bcf\u4e2agradient\u7684color\u3001alpha\u7684\u4e2a\u6570\u4e0a\u9650\u90fd\u662f8\uff0c\u4f46\u56e0\u4e3a<strong>\u53ef\u80fd\u5b58\u5728key\u4e0d\u57280\u3001\u4e0d\u57281\u7684\u60c5\u51b5<\/strong>\uff0c\u6240\u4ee5\u9700\u8981\u63d0\u4f9b<strong>10<\/strong>\u4e2akey<\/p>\n<pre><code class=\"line-numbers\">\/\/\/ &lt;summary&gt;\n\/\/\/ \u4e3amaterial\u4f20\u9012\u6240\u6709gradient\n\/\/\/ &lt;\/summary&gt;\nvoid SetGradient()\n{\n    \/\/ \u6700\u591a8\u4e2aGradient\n    _tempColor = new Color[80];\n    _tempPoint = new float[80];\n\n    \/\/ \u8bbe\u7f6e\u6bcf\u4e2aGradient\n    for (var i = 0; i &lt; _ribbons.Count; ++i)\n    {\n        SetGradientArray(_ribbons[i], i);\n    }\n\n    \/\/ \u4f20\u9012\u7ed9GPU\n    _previewMat.SetColorArray(_Color_Array, _tempColor);\n    _previewMat.SetFloatArray(_Point_Array, _tempPoint);\n    _previewMat.SetFloat(_Real_Num, _ribbons.Count);\n}\n<\/code><\/pre>\n<p>\u56e0\u4e3a\u6bcf\u4e2aGradient\u6700\u5c11\u5b58\u57282\u4e2akeys\uff0c\u800c\u672c\u7bc7\u8bbe\u5b9a\u7684\u6bcf\u4e2aArray\u6700\u5927\u5bb9\u91cf\u4e3a10\uff0c\u6240\u4ee5\u9700\u8981\u5bf9\u5269\u4f59\u7684\u5730\u65b9\u8fdb\u884c\u586b\u8865\uff08<strong>\u8bf4\u7684\u662f8\u4e2aArray\uff0c\u4f46\u4f20\u9012\u7ed9GPU\u7684\u662f\u628a8\u4e2aArray\u5408\u5e76\u540e\u7684Array<\/strong>\uff09<\/p>\n<pre><code class=\"line-numbers\">\/\/\/ &lt;summary&gt;\n\/\/\/ \u5904\u7406\u6bcf\u4e2agradient,\u968f\u540e\u4f20\u9012\u7ed9shader\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=\"source\"&gt; \u5f85\u5904\u7406\u7684gradient &lt;\/param&gt;\n\/\/\/ &lt;param name=\"index\"&gt; \u5f85\u5904\u7406\u7684gradient\u7684\u7d22\u5f15 &lt;\/param&gt;\nvoid SetGradientArray(Gradient source, int index)\n{\n    \/\/ unity \u63d0\u4f9b\u7684gradient\uff0c\u6bcf\u4e2a\u6700\u591a\u67098\u4e2akeys\n    \/\/ \u4f46\u56e0\u4e3a\u53ef\u80fd\u5b58\u5728keys\u4e0d\u57280 \u548c 1\u7684\u60c5\u51b5,\u6240\u4ee5\u8bbe\u7f6ekeys\u7684\u6700\u5927\u4e2a\u6570\u4e3a10\n    var gradientOffset = index * 10;\n    var length = source.colorKeys.Length;   \/\/ \u81f3\u5c11\u5b58\u5728\u4e24\u4e2akeys\n\n    for (var i = 0; i &lt; 10; ++i)\n    {\n        \/\/ time\u4e0d\u57280\u5904,\u4e14\u4e3a\u5f00\u5934\u65f6,\u4e0d\u5bf9\u5b83\u4e4b\u524d\u7684color blend\n        if (i == 0 &amp;&amp; source.colorKeys[0].time != 0)\n        {\n            _tempColor[gradientOffset] = source.colorKeys[0].color;\n            _tempPoint[gradientOffset] = 0;\n            continue;\n        }\n\n        if (i &lt; length)\n        {\n            _tempColor[gradientOffset + i] = source.colorKeys[i].color;\n            _tempPoint[gradientOffset + i] = source.colorKeys[i].time;\n        }\n        else\n        {\n            \/\/ \u8d85\u51fa\u90e8\u5206\u53d6gradient\u7684\u672b\u5c3ekeys\n            _tempColor[gradientOffset + i] = source.colorKeys[length - 1].color;\n            _tempPoint[gradientOffset + i] = 1;\n        }\n    }\n}\n<\/code><\/pre>\n<h2>Lerp\u3001sRGB\u6a21\u5f0f<\/h2>\n<p>\u4e3a\u4e86\u53ef\u4ee5\u624b\u52a8\u9009\u62e9\u662f\u5426\u542f\u7528\u5bf9\u5e94\u6a21\u5f0f\uff0c\u9700\u8981\u5199GUI\uff0c\u5e76\u89c6\u60c5\u51b5\u662f\u5426\u542f\u7528keywords<\/p>\n<pre><code class=\"line-numbers\">lerpMode = EditorGUILayout.ToggleLeft(\"Mix Ramp Tex\", lerpMode);\ngammaMode = EditorGUILayout.ToggleLeft(\"sRGB\", gammaMode);\n\n\/\/ \u8bbe\u7f6ekey words\nif (_previewMat != null)\n{\n    if (lerpMode == true)\n    {\n        _previewMat.EnableKeyword(_Lerp_Mode);\n    }\n    else if(lerpMode == false)\n    {\n        _previewMat.DisableKeyword(_Lerp_Mode);\n    }\n\n    if (gammaMode == true)\n    {\n        _previewMat.EnableKeyword(_Gamma_Mode);\n    }\n    else if(gammaMode == false)\n    {\n        _previewMat.DisableKeyword(_Gamma_Mode);\n    }\n}\n<\/code><\/pre>\n<h2>GPU\u8ba1\u7b97\u591a\u4e2aColor\uff0c\u5e76\u4ece\u4e0a\u5230\u4e0blerp<\/h2>\n<p>\u4e3a\u4e86\u8ba9\u4e00\u4e2aRamp Tex\u4e2d\u80fd\u7ed8\u5236\u591a\u4e2aRamp Color\uff0c\u5e76\u80fd\u5bf9\u5b83\u4eeclerp\uff0c\u9700\u8981\u5728shader\u4e2d\u5b9e\u73b0\u5982\u4f55\u5bf9\u4f20\u9012\u5230GPU\u7684Gradient lerp<\/p>\n<p>\u53ef\u884c\u7684\u65b9\u6848\uff1a\u57fa\u4e8euv.y lerp\uff0c\u5148\u6a2a\u5411lerp\uff0c\u518d\u7eb5\u5411lerp<\/p>\n<pre><code class=\"line-numbers\">\/\/\/ &lt;summary&gt;\n\/\/\/ \u8ba1\u7b97\u5355\u4e2agradient\u7684\u989c\u8272\u503c\n\/\/\/ \u5728\u5355\u4e2agradient\u4e2d\u5b58\u5728\u591a\u4e2atime,\u9700\u8981\u4ece\u5de6\u5230\u53f3\u4f9d\u6b21\u8ba1\u7b97time,\u5e76\u4f9d\u6b21\u6839\u636etime\u8fdb\u884clerp\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;param name=\"num\"&gt; gradient index &lt;\/param&gt;\n\/\/\/ &lt;param name=\"u\"&gt; uv.u &lt;\/param&gt;\nfloat4 GetSingleGradient(float num, float u)\n{\n    int i = 0;\n    int l = 0, r = 7;\n\n    UNITY_UNROLL\n    for(i = 0; i &lt; 8; ++i)\n    {\n        \/\/ \u627e\u5230time,\u4e14\u8be5time\u4e3alerp\u7684\u6700\u53f3\u7aef\n        if(_PointArray[num * 10 + i] &gt;= u)\n        {\n            r = i;\n            break;\n        }\n    }\n    l = max(0, r - 1);\n\n    float4 resultColor = lerp(_ColorArray[num * 10 + l], _ColorArray[num * 10 + r],\n        RemapRange(u, _PointArray[num * 10 + l], _PointArray[num * 10 + r], 0, 1));\n\n    #if defined (_GAMMA_MODE)\n        return pow(resultColor, 2.2f);\n    #else\n        return resultColor;\n    #endif\n}\n\nPSOutput PS(PSInput i)\n{\n    PSOutput o;\n\n    int nums = _GradientNums;\n    #if defined(_LERP_MODE)\n        if(_GradientNums &gt; 1)\n        {\n            --nums;\n        }\n    #endif\n\n    float level = i.uv.y * nums;\n    #if defined (_LERP_MODE)\n        int next = ceil(level);\n        float balance = frac(level);\n\n        o.color = lerp(GetSingleGradient(floor(level), i.uv.x), GetSingleGradient(next, i.uv.x), saturate(balance));\n    #else\n        o.color = GetSingleGradient(floor(level), i.uv.x);\n    #endif\n\n    return o;\n}\n<\/code><\/pre>\n<p><img decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/pic.imgdb.cn\/item\/66bde009d9c307b7e96e5593.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  alt=\"\" \/><\/p >\n<noscript><img decoding=\"async\" src=\"https:\/\/pic.imgdb.cn\/item\/66bde009d9c307b7e96e5593.png\" alt=\"\" \/><\/p><\/noscript>\n<h2>\u5b9e\u65f6\u9884\u89c8<\/h2>\n<p>\u53ea\u9700\u628a\u8ba1\u7b97\u5f97\u5230\u7684Ramp Tex\u4f20\u9012\u56de\u6765\uff0c\u5e76\u5c55\u793a\u5373\u53ef<\/p>\n<pre><code class=\"line-numbers\">if (_RT != null &amp;&amp; _RT.IsCreated())\n{\n    var rect = EditorGUILayout.GetControlRect(true, 200);\n    rect.width = 200;\n    EditorGUI.DrawPreviewTexture(rect, _RT);\n}\n<\/code><\/pre>\n<h1>\u6700\u7ec8\u6548\u679c<\/h1>\n<p><img decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/pic.imgdb.cn\/item\/66bef176d9c307b7e9547b67.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  alt=\"\" \/><\/p >\n<noscript><img decoding=\"async\" src=\"https:\/\/pic.imgdb.cn\/item\/66bef176d9c307b7e9547b67.png\" alt=\"\" \/><\/p><\/noscript>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/github.com\/chenglixue\/Unity-Generate-Ramp-Tex\" target=\"_blank\"  rel=\"nofollow\" >\u9879\u76ee\u94fe\u63a5<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u95ee\u9898 \u5728\u505a\u98ce\u683c\u5316\u6548\u679c\u65f6\uff0c\u7ecf\u5e38\u4f1a\u7528\u5230Ramp Tex\uff0c\u4f46\u5148\u5728PS\u4e2d\u751f\u6210\u518d\u8f6c\u5230Unity\u53c8\u592a\u9ebb\u70e6\u4e86\u3002\u4e3a\u6b64\u672c\u7bc7\u5c55\u793a\u4e86\u4e00\u4e2a\u5b9e\u65f6\u751f\u6210Ramp &#8230;<\/p>","protected":false},"author":1,"featured_media":185,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"_links":{"self":[{"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/posts\/215"}],"collection":[{"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/chenglixue.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=215"}],"version-history":[{"count":2,"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/posts\/215\/revisions"}],"predecessor-version":[{"id":247,"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/posts\/215\/revisions\/247"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/chenglixue.top\/index.php?rest_route=\/wp\/v2\/media\/185"}],"wp:attachment":[{"href":"http:\/\/chenglixue.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=215"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/chenglixue.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=215"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/chenglixue.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=215"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}