{"id":6635,"date":"2020-06-05T17:00:15","date_gmt":"2020-06-05T08:00:15","guid":{"rendered":"https:\/\/virtualcast.jp\/blog\/?p=6635"},"modified":"2024-10-22T19:22:00","modified_gmt":"2024-10-22T10:22:00","slug":"the-reason-unity-is-overwriting-your-shader-code","status":"publish","type":"post","link":"https:\/\/blog.virtualcast.jp\/blog\/2020\/06\/the-reason-unity-is-overwriting-your-shader-code\/","title":{"rendered":"Unity \u304c\u52dd\u624b\u306b\u30b7\u30a7\u30fc\u30c0\u30fc\u30b3\u30fc\u30c9\u3092\u66f8\u304d\u63db\u3048\u308b\uff1f\uff01"},"content":{"rendered":"<p>\u3053\u3093\u306b\u3061\u306f\u3001\u30d0\u30fc\u30c1\u30e3\u30eb\u30ad\u30e3\u30b9\u30c8\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u958b\u767a\u8005\u306e t-kuhn \u3067\u3059\u3002<\/p>\n<p><img src=\"https:\/\/virtualcast.jp\/blog\/wp-content\/uploads\/2020\/06\/ShaderCodeBeforeAndAfterCompile.gif\" alt=\"\" \/><\/p>\n<p>\u4e0a\u56f3\u306e\u3088\u3046\u306b Unity \u304c\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b\u52dd\u624b\u306b\u30b7\u30a7\u30fc\u30c0\u30fc\u30b3\u30fc\u30c9\u3092\u66f8\u304d\u63db\u3048\u308b\u3053\u3068\u304c\u3042\u308b\u3053\u3068\u306f\u3054\u5b58\u77e5\u3067\u3057\u305f\u304b\uff1f\u300c\u4f55\u3067\u66f8\u304d\u63db\u3048\u308b\u3093\u3060\u308d\u3046\uff1f\u300d\u3068\u6c17\u306b\u306a\u3063\u3066\u66f8\u304d\u63db\u3048\u308b\u7406\u7531\u306b\u3064\u3044\u3066\u8abf\u3079\u307e\u3057\u305f\u3002<\/p>\n<h3>\u30b3\u30fc\u30c9\u306e\u78ba\u8a8d<\/h3>\n<p>\u307e\u305a\u3001\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b\u4e0a\u66f8\u304d\u3055\u308c\u308b\u7b87\u6240\u3092\u78ba\u8a8d\u3057\u3088\u3046\u3002<\/p>\n<pre><code>v2f vert (appdata v)\r\n{\r\n    v2f o;\r\n\r\n    o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  \/\/ \u2190 \u3053\u3053\u3067\u3059\r\n\r\n    o.uv = v.uv;\r\n    return o;\r\n}<\/code><\/pre>\n<p>vertex shader \u306e\u4e2d\u306e<br \/>\n<code>mul(UNITY_MATRIX_MVP, v.vertex)<\/code> \u304c <code>UnityObjectToClipPos(v.vertex)<\/code> \u306b\u66f8\u304d\u63db\u3048\u3089\u308c\u307e\u3059\u3002<\/p>\n<p>\u300c\u305d\u3082\u305d\u3082\u3053\u306e\u30b3\u30fc\u30c9\u3001\u4f55\u3092\u3059\u308b\u30b3\u30fc\u30c9\u306a\u306e\uff1f\u66f8\u304d\u63db\u3048\u3089\u308c\u308b\u524d\u3068\u5f8c\u3068\u3067\u3084\u3063\u3066\u308b\u51e6\u7406\u306f\u4e00\u7dd2\u306a\u306e\uff1f\u300d\u3068\u7591\u554f\u3092\u6301\u3063\u3066\u3044\u308b\u65b9\u3082\u3044\u308b\u304b\u3082\u3057\u308c\u306a\u3044\u3002\u3053\u3053\u3067\u4e00\u5ea6\u305d\u308c\u305e\u308c\u306e\u51e6\u7406\u5185\u5bb9\u306b\u3064\u3044\u3066\u78ba\u8a8d\u3057\u3088\u3046\u3002<\/p>\n<h4>mul(UNITY_MATRIX_MVP, v.vertex)<\/h4>\n<p>\u307e\u305a\u306f <code>mul(UNITY_MATRIX_MVP, v.vertex)<\/code>\u3002<\/p>\n<ul>\n<li><code>mul(x, y)<\/code> \u306f\u884c\u5217 x, y \u306e\u639b\u3051\u7b97\u3092\u3057\u3066\u304f\u308c\u308b<a title=\"\u95a2\u6570\" href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/direct3dhlsl\/dx-graphics-hlsl-mul\">\u95a2\u6570<\/a>\u3002<\/li>\n<li><code>UNITY_MATRIX_MVP<\/code> \u306f\u73fe\u5728\u306e model <em> view <\/em> projection \u884c\u5217\u3002<\/li>\n<li><code>v.vertex<\/code> \u306f vertex shader \u306b\u6e21\u3055\u308c\u305f\u9802\u70b9\u3002<\/li>\n<\/ul>\n<p>Q: \u3067\u3001\u7d50\u5c40\u4f55\u306e\u305f\u3081\u306e\u51e6\u7406\uff1f<br \/>\nA: vertex shader \u306e\u30e1\u30a4\u30f3\u306e\u304a\u4ed5\u4e8b\u306f\u30a4\u30f3\u30d7\u30c3\u30c8\u3055\u308c\u308b model space \u306e\u9802\u70b9\u4f4d\u7f6e\u3092 clip space \u306b\u5909\u63db\u3059\u308b\u51e6\u7406\u3067\u3059\u3002<\/p>\n<p><img src=\"https:\/\/virtualcast.jp\/blog\/wp-content\/uploads\/2020\/06\/MVP-diagram.png\" alt=\"\u56f3\uff11\" \/><br \/>\n<strong>\u56f3\uff11<\/strong><\/p>\n<p>\u3057\u304b\u3057\u3001\u5b9f\u969b\u306e\u51e6\u7406\u3068\u3057\u3066\u69d8\u3005\u306a\u30d1\u30bf\u30fc\u30f3\u304c\u8003\u3048\u3089\u308c\u307e\u3059\u3002\u30eb\u30fc\u30c8 <strong>A<\/strong> \u3067\u884c\u304f\u3068<\/p>\n<ul>\n<li>\u9802\u70b9\u4f4d\u7f6e\u3092\u307e\u305a wold space \u306b\u5909\u63db\u3059\u308b<\/li>\n<li>\u6b21\u306b view space \u306b\u5909\u63db\u3059\u308b<\/li>\n<li>\u6700\u5f8c\u306b clip space \u306b\u5909\u63db\u3059\u308b<\/li>\n<\/ul>\n<p>\u3068\u3044\u3046\u6d41\u308c\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u4e00\u65b9\u3001\u30eb\u30fc\u30c8 <strong>B<\/strong> \u3067\u306f\u305d\u308c\u305e\u308c\u306e\u5909\u63db\u884c\u5217\uff08model matrix, view matrix, projection matrix\uff09\u3092\u304b\u3051\u5408\u308f\u305b\u308b\u3053\u3068\u306b\u3088\u3063\u3066\u76f4\u63a5\u306b model space \u304b\u3089 clip space \u3078\u3068\u5909\u63db\u3059\u308b\u884c\u5217\uff08MVP matrix\uff09\u3092\u4f5c\u6210\u3057\u3066\u304a\u304d\u3001model space \u306e\u9802\u70b9\u4f4d\u7f6e\u3092\u3053\u306e\u884c\u5217\u306b\u304b\u3051\u308b\u3053\u3068\u3067 clip space \u3078\u306e\u5909\u63db\u3092\u884c\u3044\u307e\u3059\u3002<\/p>\n<p><code>mul(UNITY_MATRIX_MVP, v.vertex)<\/code> \u306e\u3084\u3063\u3066\u3044\u308b\u51e6\u7406\u306f\u30eb\u30fc\u30c8 <strong>B<\/strong> \u306b\u8a72\u5f53\u3059\u308b\u51e6\u7406\u3067\u3059\u3002<\/p>\n<h4>UnityObjectToClipPos(v.vertex)<\/h4>\n<p>Q: \u3058\u3083\u3042\u3001<code>UnityObjectToClipPos(v.vertex)<\/code> \u306f\u3069\u3046\u9055\u3046\uff1f<br \/>\nA: UnityShaderUtilities.cginc \u3067 <code>UnityObjectToClipPos()<\/code> \u306e\u5b9a\u7fa9\u3092\u78ba\u8a8d\u3057\u3088\u3046\u3002<\/p>\n<pre><code>\/\/ Tranforms position from object to homogenous space\r\ninline float4 UnityObjectToClipPos(in float3 pos)\r\n{\r\n#if defined(STEREO_CUBEMAP_RENDER_ON)\r\n    return UnityObjectToClipPosODS(pos);\r\n#else\r\n    \/\/ More efficient than computing M*VP matrix product\r\n    return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));\r\n#endif\r\n}<\/code><\/pre>\n<p>\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b <code>UnityObjectToClipPos(pos)<\/code> \u304c <code>mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)))<\/code> \u306b\u7f6e\u304d\u63db\u3048\u3089\u308c\u307e\u3059\u306d\u3002\u3053\u308c\u3067 <code>UnityObjectToClipPos(pos)<\/code> \u306e\u6b63\u4f53\u304c\u5206\u304b\u3063\u305f\u3002\u3057\u304b\u3057\u3001\u56f3\uff11\u3067\u3044\u3046\u30eb\u30fc\u30c8 <strong>A<\/strong> \u3067\u3082\u30eb\u30fc\u30c8 <strong>B<\/strong> \u3067\u3082\u306a\u3044\u3068\u3044\u3046\u3053\u3068\u306b\u6ce8\u76ee\u3057\u3066\u307b\u3057\u3044\u3002<\/p>\n<p><img src=\"https:\/\/virtualcast.jp\/blog\/wp-content\/uploads\/2020\/06\/Route-C-diagram.png\" alt=\"\" \/><br \/>\n<strong>\u56f3\uff12<\/strong><\/p>\n<p><code>UnityObjectToClipPos(v.vertex)<\/code> \u306e\u51e6\u7406\u306f\u56f3\uff12\u4e0a\u306e\u30eb\u30fc\u30c8 <strong>C<\/strong> \u3067\u3059\u3002\u4e00\u65e6\u9802\u70b9\u4f4d\u7f6e\u3092 world space \u306b\u5909\u63db\u3057\u3066\u304b\u3089 <code>UNITY_MATRIX_VP<\/code>\u3092\u7528\u3044\u3066 clip space \u306b\u5909\u63db\u3057\u307e\u3059\u3002<\/p>\n<h3>\u7406\u7531\u306b\u3064\u3044\u3066\u8abf\u3079\u308b<\/h3>\n<p>\u3053\u3053\u307e\u3067\u6765\u3066\u3084\u3063\u3068\u7f6e\u304d\u63db\u3048\u3089\u308c\u308b\u7406\u7531\u306b\u3064\u3044\u3066\u306e\u8a71\u3057\u306b\u306a\u308a\u307e\u3059\u3002\u5b9f\u306f\u65e2\u306b\u30d2\u30f3\u30c8\u304c\u51fa\u3066\u3044\u307e\u3057\u305f\u3002<code>UnityObjectToClipPos(pos)<\/code> \u306e\u5b9a\u7fa9\u306e\u30b3\u30fc\u30c9\u306b\u7740\u76ee\u3057\u3066\u307b\u3057\u3044\u3002<\/p>\n<pre><code>\/\/ Tranforms position from object to homogenous space\r\ninline float4 UnityObjectToClipPos(in float3 pos)\r\n{\r\n#if defined(STEREO_CUBEMAP_RENDER_ON)\r\n    return UnityObjectToClipPosODS(pos);\r\n#else\r\n    \/\/ More efficient than computing M*VP matrix product\r\n    return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));\r\n#endif\r\n}<\/code><\/pre>\n<p><code>\/\/ More efficient than computing M*VP matrix product<\/code> \u3068\u3044\u3046\u30b3\u30e1\u30f3\u30c8\u304c\u66f8\u3044\u3066\u3042\u308a\u307e\u3059\u3002\u3053\u308c\u304c\u7f6e\u304d\u63db\u3048\u3089\u308c\u308b\u7406\u7531\u3067\u3059\u3002<\/p>\n<h3>\u7406\u7531\u306e\u78ba\u8a8d<\/h3>\n<p>Q: more efficient\uff08\u52b9\u7387\u7684\uff09 \u3063\u3066\u8a00\u308f\u308c\u3066\u3082\u6e80\u8db3\u3067\u304d\u306a\u3044\u3002\u5177\u4f53\u7684\u306b\u3069\u3053\u304c more efficient \u3060\u308d\u3046\uff1f<br \/>\nA: \u305d\u308c\u305e\u308c\u306e\u5834\u5408\u3001\u5b9f\u969b\u306b\u3069\u3093\u306a\u8a08\u7b97\u304c\u884c\u308f\u308c\u308b\u304b\u3092\u898b\u3066\u3044\u304f\u3068\u5206\u304b\u308a\u307e\u3059\u3002<\/p>\n<h4>mul(UNITY_MATRIX_MVP, v.vertex)\u3092\u4f7f\u3063\u305f\u3068\u304d\u306e\u8a08\u7b97\u91cf\u3092\u78ba\u8a8d<\/h4>\n<p>\u307e\u305a\u306f <code>mul(UNITY_MATRIX_MVP, v.vertex)<\/code> \u3067\u3059\u3002 UnityShaderVariables.cginc \u3067<code>UNITY_MATRIX_MVP<\/code> \u306e define \u3092\u78ba\u8a8d\u3059\u308b\u3068<\/p>\n<pre><code>static float4x4 unity_MatrixMVP = mul(unity_MatrixVP, unity_ObjectToWorld);\r\n#define UNITY_MATRIX_MVP unity_MatrixMVP<\/code><\/pre>\n<p><code>UNITY_MATRIX_MVP<\/code> \u304c\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b <code>mul(unity_MatrixVP, unity_ObjectToWorld)<\/code> \u306b\u7f6e\u304d\u63db\u3048\u3089\u308c\u308b\u3053\u3068\u304c\u5206\u304b\u308b\u3002\u3088\u3063\u3066\u3001\u5b9f\u969b\u306b\u884c\u308f\u308c\u308b\u8a08\u7b97\u306b\u3053\u308c\u3082\u542b\u3081\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002<\/p>\n<p>\u307e\u305a\u306f $\\boldsymbol{M}_{\\tiny{MVP}}$ \u3092\u8a08\u7b97\u3057\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044\u3002\u3053\u3053\u3067\u3001 $\\boldsymbol{M}_{\\tiny{M}}$ \u304c model space \u2192 world space \u306e\u5909\u63db\u884c\u5217\u3001$\\boldsymbol{M}_{\\tiny{VP}}$ \u304c world space \u2192 clip space \u306e\u5909\u63db\u884c\u5217\u3060\u3068\u3059\u308b\u3002<br \/>\n$$<br \/>\n\\begin{align}<br \/>\n\\boldsymbol{M}_{\\tiny{MVP}} = \\boldsymbol{M}_{\\tiny{VP}} \\boldsymbol{M}_{\\tiny{M}}<br \/>\n\\tag{1.0}<br \/>\n\\end{align}<br \/>\n$$<\/p>\n<p>\u6b21\u306b (1.0) \u3067\u6c42\u307e\u3063\u305f\u3000$\\boldsymbol{M}_{\\tiny{MVP}}$\u3000\u3092\u7528\u3044\u3066 model space \u306e\u9802\u70b9\u4f4d\u7f6e $\\boldsymbol{P}_{model}$ \u3092 clip space \u306e\u9802\u70b9\u4f4d\u7f6e $\\boldsymbol{P}_{clip}$ \u306b\u5909\u63db\u3057\u307e\u3059\u3002<\/p>\n<p>$$<br \/>\n\\begin{align}<br \/>\n\\boldsymbol{P}_{clip} = \\boldsymbol{M}_{\\tiny{MVP}} \\boldsymbol{P}_{model}<br \/>\n\\tag{1.1}<br \/>\n\\end{align}<br \/>\n$$<\/p>\n<p>\u8a08\u7b97\u91cf\u3092\u898b\u3066\u307f\u308b\u3068<\/p>\n<ul>\n<li>(1.0) \u884c\u5217*\u884c\u5217<\/li>\n<li>(1.1) \u884c\u5217*\u30d9\u30af\u30c8\u30eb<\/li>\n<\/ul>\n<p>\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<h4>UnityObjectToClipPos(pos)\u3092\u4f7f\u3063\u305f\u3068\u304d\u306e\u8a08\u7b97\u91cf\u3092\u78ba\u8a8d<\/h4>\n<p>\u6b21\u306f <code>UnityObjectToClipPos(pos)<\/code> \u306e\u6b63\u4f53\u304c<br \/>\n<code>mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)))<\/code> \u3067\u3042\u308b\u3053\u3068\u3092\u601d\u3044\u51fa\u3057\u3066\u3001\u3053\u3061\u3089\u306e\u8a08\u7b97\u91cf\u3092\u898b\u3066\u307f\u3088\u3046\u3002<\/p>\n<p><code>mul(unity_ObjectToWorld, float4(pos, 1.0)<\/code> \u3092\u6570\u5b66\u7684\u306b\u8868\u73fe\u3059\u308b\u3068<\/p>\n<p>$$<br \/>\n\\begin{align}<br \/>\n\\boldsymbol{P}_{world} = \\boldsymbol{M}_{\\tiny{M}} \\boldsymbol{P}_{model}<br \/>\n\\tag{2.0}<br \/>\n\\end{align}<br \/>\n$$<\/p>\n<p>\u3068\u66f8\u3051\u307e\u3059\u3002\u6b21\u306b <code>UNITY_MATRIX_VP<\/code> \u306b (2.0) \u3067\u5f97\u3089\u308c\u305f\u30d9\u30af\u30c8\u30eb\u3092\u304b\u3051\u308b\u304b\u3089<\/p>\n<p>$$<br \/>\n\\begin{align}<br \/>\n\\boldsymbol{P}_{clip} = \\boldsymbol{M}_{\\tiny{VP}} \\boldsymbol{P}_{world}<br \/>\n\\tag{2.1}<br \/>\n\\end{align}<br \/>\n$$<\/p>\n<p>\u306b\u306a\u308a\u307e\u3059\u3002\u8a08\u7b97\u91cf\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<ul>\n<li>(2.0) \u884c\u5217*\u30d9\u30af\u30c8\u30eb<\/li>\n<li>(2.1) \u884c\u5217*\u30d9\u30af\u30c8\u30eb<\/li>\n<\/ul>\n<h4>\u7d50\u8ad6<\/h4>\n<p>\u4e0a\u8a18\u306e\u8a08\u7b97\u91cf\u306e\u30c7\u30fc\u30bf\u3092\u6bd4\u8f03\u3059\u308b\u3068 <code>\/\/ More efficient than computing M*VP matrix product<\/code> \u306e more efficient \u306e\u7406\u7531\u304c\u5206\u304b\u308a\u307e\u3059\u3002\u3064\u307e\u308a\u3001<\/p>\n<p><strong>\u884c\u5217*\u30d9\u30af\u30c8\u30eb<\/strong> + <strong>\u884c\u5217*\u30d9\u30af\u30c8\u30eb<\/strong>\u306e\u8a08\u7b97\u91cf &lt; <strong>\u884c\u5217*\u884c\u5217<\/strong> + <strong>\u884c\u5217*\u30d9\u30af\u30c8\u30eb<\/strong>\u306e\u8a08\u7b97\u91cf<\/p>\n<p>\u3068\u3044\u3046\u3053\u3068\u3067\u3059\u306d\u3002Unity \u304c\u52dd\u624b\u306b\u30b7\u30a7\u30fc\u30c0\u30fc\u30b3\u30fc\u30c9\u3092\u4e0a\u66f8\u304d\u3059\u308b\u7406\u7531\u304c\u300c\u8a08\u7b97\u91cf\u3092\u6e1b\u3089\u3057\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u3088\u308a\u826f\u304f\u3057\u305f\u3044\u300d\u3067\u3057\u305f\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3053\u3093\u306b\u3061\u306f\u3001\u30d0\u30fc\u30c1\u30e3\u30eb\u30ad\u30e3\u30b9\u30c8\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u958b\u767a\u8005\u306e t-kuhn \u3067\u3059\u3002 \u4e0a\u56f3\u306e\u3088\u3046\u306b Unity \u304c\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b\u52dd\u624b\u306b\u30b7\u30a7\u30fc\u30c0\u30fc\u30b3\u30fc\u30c9\u3092\u66f8\u304d\u63db\u3048\u308b\u3053\u3068\u304c\u3042\u308b\u3053\u3068\u306f\u3054\u5b58\u77e5\u3067\u3057\u305f\u304b\uff1f\u300c\u4f55\u3067\u66f8\u304d\u63db\u3048\u308b\u3093\u3060\u308d\u3046\uff1f\u300d\u3068\u6c17\u306b\u306a\u3063...<\/p>\n","protected":false},"author":35,"featured_media":6644,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[105,26],"tags":[23],"_links":{"self":[{"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/posts\/6635"}],"collection":[{"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/comments?post=6635"}],"version-history":[{"count":126,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/posts\/6635\/revisions"}],"predecessor-version":[{"id":14466,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/posts\/6635\/revisions\/14466"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/media\/6644"}],"wp:attachment":[{"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/media?parent=6635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/categories?post=6635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.virtualcast.jp\/blog\/wp-json\/wp\/v2\/tags?post=6635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}