WSL2のポートをlocalhostに公開する
WSL2で開発する時、Dockerなどを使わなくともポートをWindows側から叩くことができる
これでWeb開発がよりスムーズになる
また、WSL2に使うメモリやプロセッサ数、Swapなども細かく設定し、PCリソースを管理することも可能
URP10.2.2 URPシェーダーをShaderLabで書いてみる
URPのシェーダーを作ろうとすると、UNITYからは全部ShaderGraphになる
ので、テキストエディタでShaderを書く事は推奨されていないようだし
実際に仕事でも、アーティストと会話するために、ノードエディタのShaderGraphを使う方が良いと思うが
勉強のためにあえてShaderLabで書いてみる
URP UnlitShaderを調査
まずは、最も簡単なはずのUnlitから書いてみる
テンプレートからはShaderLabは作れないので、ShaderGraphのUnlitを新規で作成します
床に適用してみた。テクスチャも影もなくなった
作成されたUnlitShaderGraphからShaderLabのコードを取得するには、Inspectorから ViewGeneratedShader を選択するとコードが表示される
パスは、通常パス、ShadowCaster、DepthOnlyの3つで、それがTransparent、Opaqueの両方あるので合計6個のパスがあります
おそらく、SRP Batchingのために、TransparentとOpaqueの両方のシェーダをまとめているんだと思う
Feature関連
// Pragmas #pragma target 2.0 #pragma only_renderers gles gles3 glcore #pragma multi_compile_instancing #pragma multi_compile_fog #pragma vertex vert #pragma fragment frag // DotsInstancingOptions: <None> // HybridV1InjectedBuiltinProperties: <None> // Keywords #pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma shader_feature _ _SAMPLE_GI // GraphKeywords: <None> // Defines #define ATTRIBUTES_NEED_NORMAL #define ATTRIBUTES_NEED_TANGENT #define FEATURES_GRAPH_VERTEX /* WARNING: $splice Could not find named fragment 'PassInstancing' */ #define SHADERPASS SHADERPASS_UNLIT /* WARNING: $splice Could not find named fragment 'DotsInstancingVars' */
色々と書いてあるが、おおざっぱに
Instancing、Fog、dots instancing、ライトマップ系、アトリビュート、そしてshaderpass unlit
等設定しています
dots instancingとか、最近のUNITYの高速化、Data-Oriented Technology Stackの事でしょう
今度ちゃんと調べてみたいです
Includes
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
これらのコードをIncludeしています
BuiltIn-Shaderではなく、URPのシェーダーを見に行ってますね
入出力
struct Attributes { float3 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; #if UNITY_ANY_INSTANCING_ENABLED uint instanceID : INSTANCEID_SEMANTIC; #endif }; struct Varyings { float4 positionCS : SV_POSITION; #if UNITY_ANY_INSTANCING_ENABLED uint instanceID : CUSTOM_INSTANCE_ID; #endif #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE))) uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0; #endif #if (defined(UNITY_STEREO_INSTANCING_ENABLED)) uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex; #endif #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE) FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC; #endif };
おそらく入力パラメータAttributesは #defineで有効にしたものが入ってくるのだろう
それにInstancing用のID
Varyingsは、InstancingやVR等で条件コンパイルされてるが、ポジション程度しかない
それらの入力値を使い、データを抽象化しているのか、シェーダーライブラリ内で使う構造体に変換しているのだと思われる
SurfaceDescriptionInputs、VertexDescriptionInputs、PackedVaryingsと変換関数がある
実際の処理
#include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl" #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl" #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl"
実際の処理はシェーダーライブラリの中だ
その中でも実際にシェーダーの中身は下記になる
PackedVaryings vert(Attributes input) { Varyings output = (Varyings)0; output = BuildVaryings(input); PackedVaryings packedOutput = PackVaryings(output); return packedOutput; } half4 frag(PackedVaryings packedInput) : SV_TARGET { Varyings unpacked = UnpackVaryings(packedInput); UNITY_SETUP_INSTANCE_ID(unpacked); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); #if _AlphaClip half alpha = surfaceDescription.Alpha; clip(alpha - surfaceDescription.AlphaClipThreshold); #elif _SURFACE_TYPE_TRANSPARENT half alpha = surfaceDescription.Alpha; #else half alpha = 1; #endif #ifdef _ALPHAPREMULTIPLY_ON surfaceDescription.BaseColor *= surfaceDescription.Alpha; #endif return half4(surfaceDescription.BaseColor, alpha); }
まあ、ここだけ見ると単純です
シンプルなUnlitシェーダー
白く塗りつぶすだけの非常に簡単なシェーダーを作った
Shader "MyShader/URPUnlit" { SubShader { Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque" "UniversalMaterialType" = "Unlit" "Queue" = "Geometry" } Pass { Name "Pass" // Render State Cull Back Blend One Zero ZTest LEqual ZWrite On HLSLPROGRAM // Pragmas #pragma target 4.5 #pragma exclude_renderers gles gles3 glcore #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" struct Attributes { float3 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; }; struct Varyings { float4 positionCS : SV_POSITION; }; float3 TransformObjectToWorld(float3 positionOS) { return mul(unity_ObjectToWorld, float4(positionOS, 1.0)).xyz; } float4 TransformWorldToHClip(float3 positionWS) { return mul(unity_MatrixVP, float4(positionWS, 1.0)); } Varyings vert(Attributes input) { Varyings output = (Varyings)0; output.positionCS = TransformWorldToHClip(TransformObjectToWorld(input.positionOS)); return output; } half4 frag(Varyings input) : SV_TARGET { return half4(1,1,1,1); } ENDHLSL } } }
includeは2個あるが、UNITYのシェーダーのCORE的なものと、RPから入ってくるUNITY定数の宣言
思ったより簡単に書けたが、色々な処理を無視しているし
影とかは難しそうな気配・・
PS,XBOX,Switch等の対応とかも考えると、ShaderGraphで書く方が楽だろうなあ・・・
テクスチャマッピングする
これは非常に簡単だった
今までのBuiltIn-Shaderの作法にのっとり
Texture2DをPropertiesに出し、Texture2DとSamplerを宣言し
AttributesとVaryingsに TEXCOORD0を入れて
SAMPLE_TEXTURE2Dでマッピングした結果をリターンすればいい
意外と素直
影を落とす
"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
をIncludeすることにした
そして今回はメインライトからの影のみを取るので
pragma multi_compile _ _MAIN_LIGHT_SHADOWS
をつけた
shadowAttenuationを計算するのだが、ShadowMapをSampleするには、ワールド座標のPositionが必要なので
positionWSを計算することに
TransformObjectToWorld(input.positionOS)
で簡単に取得できた
ワールド座標系のオブジェクトポジションを使い
TransformWorldToShadowCoord(input.positionWS)
をすると、ShadowCoordが取得できるので、そこから
GetMainLightを使い、メインライトの情報、影の情報が取れる
今回はライトカラーなどは使わずshadowAttenuationだけを使い、テクスチャにそのまま乗算した
とりあえず影はできた
今回の完成シェーダコード
Shader "MyShader/URPUnlit" { Properties { [NoScaleOffset] MainTex("_MainTex", 2D) = "white" {} [HideInInspector][NoScaleOffset]unity_Lightmaps("unity_Lightmaps", 2DArray) = "" {} [HideInInspector][NoScaleOffset]unity_LightmapsInd("unity_LightmapsInd", 2DArray) = "" {} [HideInInspector][NoScaleOffset]unity_ShadowMasks("unity_ShadowMasks", 2DArray) = "" {} } SubShader { Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Opaque" "UniversalMaterialType" = "Unlit" "Queue" = "Geometry" } Pass { Name "Pass" // Render State Cull Back Blend One Zero ZTest LEqual ZWrite On HLSLPROGRAM // Pragmas #pragma target 4.5 #pragma exclude_renderers gles gles3 glcore #pragma vertex vert #pragma fragment frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" TEXTURE2D(MainTex); SAMPLER(samplerMainTex); struct Attributes { float3 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float4 uv0 : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float4 texCoord0 : TEXCOORD0; float3 positionWS: TEXCOORD1; }; Varyings vert(Attributes input) { Varyings output = (Varyings)0; output.positionCS = TransformWorldToHClip(TransformObjectToWorld(input.positionOS)); output.texCoord0 = input.uv0; output.positionWS = TransformObjectToWorld(input.positionOS); return output; } half4 frag(Varyings input) : SV_TARGET { half4 o = SAMPLE_TEXTURE2D(MainTex, samplerMainTex, input.texCoord0.xy); Light l = GetMainLight(TransformWorldToShadowCoord(input.positionWS)); return o*l.shadowAttenuation; } ENDHLSL } } }
Instancingやメイン以外のライト等、いろいろすっ飛ばしているので実用性はないが
URPのシェーダーは、こんな感じで書く事は可能だ
ShadowCasterやDepthOnlyパスは消してしまったが同じように簡単に作る事ができそう
ただし、URPはバージョンアップで色々変わってしまうので
ShaderGraphを使う方が楽と思う
URP10.2.2でBuiltin Shaderに沿って影を出すのはかなり難しい
UNITY URPのお勉強。URP対応の簡単なシェーダー作ってみる
UNITYちゃんを表示
URPのプロジェクトに旧来のUNITYちゃんを表示してみると
シェーダーが対応していないよね
もちろん、シェーダーをURPのものにすれば、とりあえずエラーは解消されるし
URPやHDRPに対応したUNITYちゃんもダウンロード可能なので
そちらを使うのが良いが
ちょうどいいので、これでシェーダーを試してみようと思う
GUI関連もエラーが出ているなあ・・・
簡単なURPシェーダー
先日の調査でURPのパスはDeferredやDepthOnly等複数のパスが存在した
が、推測ではForwardLitパスだけで、簡単な表示は出来そうだ
テンプレート
UNITYのメニューから、Create->Shader->Unlitでデフォルトのシェーダーを作成し貼り付ける
ライティング無し、テクスチャのみ、半透明に対応してないのでチークは変になってるが
最低限のシェーダーは作れた
影もない
仮に一部のマテリアルをURPのLitに差し替えると
影は表示されている
Templateで生成されたものをみると
Shader "MyShader/URPTest" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #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); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
特に名前のないパスがあるだけで、ShadowCaster等のパスもないので当然
一応?礼儀正しく? Passの名前をちゃんとしていし、動きが同じことを確認
Pass { Name "ForwardLit" Tags { "LightMode" = "UniversalForward" } CGPROGRAM
ShadowCaster Pass
古よりのUNITYのシェーダーパス、ShadowCasterを追加すれば影を落とす事ができる
Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual CGPROGRAM #pragma target 3.0 #pragma vertex vertShadowCaster #pragma fragment fragShadowCaster struct VertexInput { float4 vertex : POSITION; }; struct VertexOutput { float4 pos : SV_POSITION; }; VertexOutput vertShadowCaster(VertexInput v) { VertexOutput o = (VertexOutput)0; o.pos = UnityObjectToClipPos(v.vertex); return o; } float4 fragShadowCaster(VertexOutput i) : SV_TARGET { return 0; } ENDCG }
あえて、古いシェーダーを書いている
URPのシェーダーを読んでいると今はCGPROGRAMではなくHLSLPROGRAMを使い
CG言語ではなくHLSLでシェーダーを書くのが主流っぽい?し
GPU Instancing等が入っているが、今回は古のシェーダーで調査だ
このとおり、ShadowCasterはうまくいった(ただし、Shadowを受け取る側はできていないので、床はURPのシェーダーを使っている)
ShadowRecieve
昔のUNITYではShadowRecieveパスがあったような記憶があるけど今はライトのパスで行っている
まずは古のシェーダーで書いてみる
過去に書いた自分の記事の通りに
murasame-labo.hatenablog.com
この通りに書くが影が表示されない
SHADOW_ATTENUATION、LIGHT_ATTENUATIONがきかない(1,1,1) が帰ってきてるようなかんじ
UNITYの質問で同じような事があったので調べる
forum.unity.com
pragma multi_compile _ _MAIN_LIGHT_SHADOWS
pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
を書けばいいというようなことを書いているが、それでもダメ
色々なフラグを追加してもダメ
該当部分のコードをみてみると
void MainLight_half(float3 WorldPos, out half3 Direction, out half3 Color, out half DistanceAtten, out half ShadowAtten) { #if SHADERGRAPH_PREVIEW Direction = half3(0.5, 0.5, 0); Color = 1; DistanceAtten = 1; ShadowAtten = 1; #else #if SHADOWS_SCREEN half4 clipPos = TransformWorldToHClip(WorldPos); half4 shadowCoord = ComputeScreenPos(clipPos); #else half4 shadowCoord = TransformWorldToShadowCoord(WorldPos); #endif Light mainLight = GetMainLight(shadowCoord); Direction = mainLight.direction; Color = mainLight.color; DistanceAtten = mainLight.distanceAttenuation; #if !defined(_MAIN_LIGHT_SHADOWS) || defined(_RECEIVE_SHADOWS_OFF) ShadowAtten = 1.0h; #endif #if SHADOWS_SCREEN ShadowAtten = SampleScreenSpaceShadowmap(shadowCoord); #else ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData(); half shadowStrength = GetMainLightShadowStrength(); ShadowAtten = SampleShadowmap(shadowCoord, TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), shadowSamplingData, shadowStrength, false); #endif #endif }
該当部分がちゃんと計算されるようなパスになるようにしたつもりだけど上手く動かない
シェーダーをコンパイルすると下記のエラー
'ComputeScreenPos': no matching 1 parameter function Compiling Vertex program with DIRECTIONAL SHADOWS_SCREEN VERTEXLIGHT_ON _MAIN_LIGHT_SHADOWS_CASCADE Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_RGBM_ENCODING Disabled keywords: FOG_LINEAR FOG_EXP FOG_EXP2 LIGHTPROBE_SH SHADOWS_SHADOWMASK DYNAMICLIGHTMAP_ON LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING DIRLIGHTMAP_COMBINED UNITY_NO_DXT5nm UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 UNITY_PBS_USE_BRDF3 UNITY_NO_FULL_STANDARD_SHADER UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_COLORSPACE_GAMMA UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_LIGHTMAP_DLDR_ENCODING UNITY_LIGHTMAP_FULL_HDR UNITY_VIRTUAL_TEXTURING UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_ASTC_NORMALMAP_ENCODING SHADER_API_GLES30 invalid subscript 'pos' Compiling Vertex program with DIRECTIONAL SHADOWS_SCREEN VERTEXLIGHT_ON _MAIN_LIGHT_SHADOWS_CASCADE Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_RGBM_ENCODING Disabled keywords: FOG_LINEAR FOG_EXP FOG_EXP2 LIGHTPROBE_SH SHADOWS_SHADOWMASK DYNAMICLIGHTMAP_ON LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING DIRLIGHTMAP_COMBINED UNITY_NO_DXT5nm UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 UNITY_PBS_USE_BRDF3 UNITY_NO_FULL_STANDARD_SHADER UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_COLORSPACE_GAMMA UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_LIGHTMAP_DLDR_ENCODING UNITY_LIGHTMAP_FULL_HDR UNITY_VIRTUAL_TEXTURING UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_ASTC_NORMALMAP_ENCODING SHADER_API_GLES30
ちょっと影関連の計算はURPでは大きく変わってるのかなあ・・・
って事で、後日調査しますか。。
URPの勉強をする。概要
趣旨
Unityが従来の固定レンダリングパイプライン(BuiltIn RP)の後継にURPを指名した
ので、早急にURPを調査する必要がある
UNITYのレンダリングパイプライン
SRP
UNITYのレンダリングは下記のようなパイプラインで行われる
- カリング
- オブジェクトのレンダリング
- ポストプロセッシング
それらのパイプラインは、UNITYエンジンでハードコーディングされており、BuiltIn RPと呼ばれる
UNITY2018より、PreviewとしてScriptable Render Pipeline(SRP)がテスト実装された
SRPでは、レンダリングパイプラインをプログラマが自由に変更できるようになった
LWRP, HDRP, URP
レンダリングパイプラインを変更すると、シェーダーも全部作り直す必要があり
非常にコストが高いため
ある程度汎用的な2つのパイプラインをUNITY社は用意をした
ハイクオリティーなレンダリング用途のHDRP(High Definition Render Pipeline)と
低スペック端末用のLWRP(Light Wait Render Pipeline)
そして、従来LWRPと呼んでいたものを、UNITY2020からURP(Universal Render Pipeline)と改名し
BuiltIn RPの後継に指名した
コードリポジトリ
BuiltIn Shaderのコードリポジトリは見つけられなかったが、下記でバージョンごとにダウンロードできる
ダウンロードタブを押すと、ビルトインシェーダーを選択できる
unity3d.com
レンダーパイプラインはリポジトリが公開されているので、対象のバージョンをTagで指定してダウンロードできる
github.com
使っているUNITYのRenderPipelineのバージョンを調べるには、UnityPackageManagerでRP等で検索してバージョンを調べる
例えば、Unity2020.2.1 だと、v10.2.2である
シェーダーの書き方
UNITYのシェーダーはHLSLベースの、ShaderLabという言語で書く
テキストエディタで作る
シェーダーのフル機能を使う事が出来る
私の知る限りだが、ビジュアルスクリプティングでは一部の表現が出来ない
ビジュアルスクリプティング
以前より優良アセットとして、ShaderForge、Amplify Shader Editorがある(あった)
ShaderForgeは開発中止されたが、Amplifyは今でも使われていて、URPにも対応しているらしい
UNITY社はShaderGraphを無料で提供し、当然URPにも対応している
一部出来ないことはあるかもしれないが、ノードベースでシェーダーを書きたい人の選択肢になればと
URP プロジェクトを作ってみる
プロジェクトの作成は簡単
UnityHubで新規プロジェクト作成時にURPプロジェクトのテンプレートがあるので作成する
そこに、仮に独自シェーダーのモデルをImportすると
URPに対応していないシェーダーなのか、シェーダーエラーになる
仮に、URP/Unlitシェーダーを適用すれば、テクスチャがはられたのみのモデルが表示される
URP/Unlitシェーダーを覗く
チラ見で気になるのが、SRP batching
軽くみたかんじ、BuiltIn RPでは同じマテリアルでしかBatchingが出来なかったが
SRP(URP)では、異なるマテリアルであっても、シェーダーが同じであればInstancing出来るようだ
そのため、他のシェーダーとも共通化してあるのかな
// SRP batching compatibility for Clear Coat (Not used in Lit) [HideInInspector] _ClearCoatMask("_ClearCoatMask", Float) = 0.0 [HideInInspector] _ClearCoatSmoothness("_ClearCoatSmoothness", Float) = 0.0
URPには、 "RenderPipeline" = "UniversalPipeline" Tagが必要そう
独自のシェーダーパスも簡単に作れそうだ
qiita.com
今度は簡単なURP対応シェーダーを作ろうと思う
Windowsネイティブにも開発環境作る
理由
私の今のPC環境は
超スペックのWindowsデスクトップ
ハイスペックWindowsノートPC(ただしバッテリー爆発)
低スペックMacbookPro(ProではあるがWindowsマシンと比較するとスペックが酷い。値段は同じなのに・・)
仕事が落ち着いたら、AWS Cloud9でリモート開発環境を作る予定だが、それまでのつなぎ。
いや、WindowsデスクトップはAWSよりスペックいいはずなので、こっちではPCで開発するかもしれない
Windowsデスクトップの問題
WSL2+Docker for Windowsの開発環境が最強すぎて、満足しているが
まだ技術の過渡期なのか、WindowsUpdateで頻繁にエラーが出る
ので、安定した環境を考えている
もちろん、VirtualBoxにLinux入れてそこにDocker入れれば問題ないんだけどね
ただ、VirtualBoxとHyper-Vとの相性の悪さもある
ただ、ネイティブのWindowsでの開発もわりと最近便利になっているので、それの調査も兼ねて、ローカル環境を構築する
コマンドプロンプト、PowerShellを使うのも面倒だけど、最近はGitBashなりもあるし、何とかなるかな・・・
今回の開発環境
AWS Client系、node.js関連の構築と行い、AWS Amplify、AWS SAM、ServerlessFramework、ServerlessOffline等のテストをしてみたいと思う
フロントはionicフレームワークを試す。こちらはMacのみ正式対応だが、Windowsでどこまで出来るかも試したい(結局iPhoneビルドでMacは必要だが)
node環境
nodist
Windowsの場合はnodeのバージョン管理ツールとしてnodistを使う事が多いと思われる
Releases · nullivex/nodist · GitHub
ここからダウンロードしインストールを行う。
ここで問題が一つおきた。
PATH not updated, original length 1040 > 1024
というエラーが出て、結果的にインストールはできたものの、nodistにパスが通っておらず使いにくい
Windowsのパスの制限は色々と話はあるが、まずは不要になったPathを捨てたり、User環境変数で良いものはそちらに移したりした
で、細かい仕様は調べてもらうとして・・
大雑把にいうと、環境変数の文字数は
結論から言うと、nodistインストーラではsetxを使っているので1024文字制限があるが、環境変数を自分で設定すれば
システムとユーザで約2000文字ずつ環境変数の設定が可能なので、自力で
C:\Program Files (x86)\Nodist\bin
これをPathに追加すればよい
Pathの環境変数をどうしても2000文字以内に出来ない場合は、VisualStudioのように
環境変数をカスタマイズしたコマンドプロンプトの起動バッチを作るのがWindows流
nodeバージョン
Amplify Cliでは、node 10.x以上、npm6.x以上が推奨 Install & Configs :: title
ionicは node10.3以降(最新LTS推奨)との事
Ionic CLI - Ionic Framework 日本語ドキュメンテーション
AWS Lambdaでは、Nodeは 12.x、10.xのランタイムで動く
AWS Lambda ランタイム - AWS Lambda
という事で、12.19.0をインストールした(14xをインストールしたら、ionicがエラー吐いたので)
npmも更新し、npxも入れる(nodistはnpxが入らないらしい)
$ nodist 12.19.0 $ nodist npm 6.14.8 $ npm i npx -g
Java環境
AmplifyはMockingが出来て便利だ
Mockを使うとサーバにUploadせずにローカルで動かすことが出来て非常に便利だ
前に試したところ、AmplifyをPushすると5分ほどはデプロイに時間がかかり、開発が辛かった
その、MockingにはJavaが必要
Javaは OpenJDK 1.8以降が必要
ただし、Javaを取り巻く状況は、SunがOracleに買収されてから急激に変化し
Oracleが提供するOracleJavaは有償化したため
Javaの互換性のあるOpenなJavaが必要だ
Oracleの提供するOpenJDKは無償だが、リリースが遅い、サポート期間が短いなどで、セキュリティ的に非常に使いにくい
もちろん、業務としてならOracleJavaを有償で使うのもあるが、今回は無償で行いたい
現在利用できる OpenJDKとして
AdoptOpenJDK、AmazonCorreto等がある
今回はAWSメインで使うのでAmazonCorretoを使うが、こちらは32ビットに対応していない、対応OSが少ない等の問題があるので
そのうちAdoptOpenJDKにするかも
とりあえずAmazonCorreto11をインストールする
Windowsの場合はmsiファイルからインストールする
Downloads for Amazon Corretto 11 - Amazon Corretto
java -version
で、正しくバージョンが表示されればOK
ionic
ionicフレームワークはnpmからインストールする
ionicパッケージは今は古く、@ionic/cliのほうが新しいのでこちらをインストールする
$ npm install -g @ionic/cli
Amplifyクライアント
npm install -g @aws-amplify/cli
サンプルなプロジェクト作成
ionic
ionicアプリはテンプレートから簡単に作成できる
今回は amplify_testという名前で作る
ionicではAngularで作るのがデフォルトだ(ReactやVueも追加されているが)
ionic start amplify_test
とコマンドプロンプトからうち
Angular、tabsと選択し、Capacitorにするか聞かれるので Yを選んでみる
テンプレート作成したら
ionic serve
コマンドでトランスパイルされブラウザに表示される
ionicの説明はしない
コードを変更したら即座にLiveReloadも行われる
ばっちり
amplify作成
npx amplify init
入力はデフォルトのままでOK
Frameworkはionicを選び、AWSのAccessIDを設定
これでAmplifyがAWS上に作成される
amplify push
を行うと、コードをAWS上にPushできる(5分ぐらいかかる)
npx amplify add auth
で、Cognitoでの認証を作成できる
amplify mock
を使うと、Amplifyをローカル実行できるので試したが
Cognitoに関しては、Mocking出来ず、AWSのサーバが必要な気がする
amplify add api
で、GraphQLあるいはREST APIを作成できる
今回はGraphQLを作成する
作成されたAPIの下に schema.graphqlファイルがある。これがスキーマだ
type Todo @model { id: ID! name: String! description: String }
デフォルトでは上記のようなかんじになっている
amplify mock
amplify mock
で、Amplifyをローカル実行できる!!
毎度 amplify pushするとデプロイに5分かかるしデバッグもし辛い
どうやらCognito以外はMockできるらしいので非常に便利だ
Mockを実行するとURLが表示されるので、ブラウザで開くと
GraphQLのデバッグ画面が表示される
ちょっと引っかかったのが
src/graphql/queries.js
に、SQLあるいはGraphQLのQLが作成されるという情報がある
export const getTodo = `query GetTodo($id: ID!) { getTodo(id: $id) { id name description } } `; export const listTodos = `query ListTodos( $filter: ModelTodoFilterInput $limit: Int $nextToken: String ) { listTodos(filter: $filter, limit: $limit, nextToken: $nextToken) { items { id name description } nextToken } } `;
が、探しても見つからないのだが
おそらく下記に変更されたと思われる
src/app/API.service.ts
export class APIService { async CreateTodo( input: CreateTodoInput, condition?: ModelTodoConditionInput ): Promise<CreateTodoMutation> { const statement = `mutation CreateTodo($input: CreateTodoInput!, $condition: ModelTodoConditionInput) { createTodo(input: $input, condition: $condition) { __typename id name description createdAt updatedAt } }`; const gqlAPIServiceArguments: any = { input }; if (condition) { gqlAPIServiceArguments.condition = condition; } const response = (await API.graphql( graphqlOperation(statement, gqlAPIServiceArguments) )) as any; return <CreateTodoMutation>response.data.createTodo; } ...
JSよくしらんけど、Angular的な書き方なんかな?
そしておなじみAngularの不具合、Globalが定義されてないので、polifil.tsに追加
(window as any).global = window;
GraphQLをせっかくなので呼んでみる
Serviceを作る
$ ionic g service services/viewTodo
ionicコマンドで作成する コードの方は、先ほど作成された、API.service.tsのListTodoを呼べばよさそう
viewTodo.service.ts
import { Injectable } from '@angular/core'; import { APIService } from 'src/app/API.service'; @Injectable({ providedIn: 'root' }) export class ViewTodoService { public async listTodos() { var api = new APIService(); return api.ListTodos(); } constructor() { } }
戻り値はどうやら、ListTodosQuery型のようだ
今回は table1にボタンを置いてデバッグ表示させる
tab1.page.html
<ion-content [fullscreen]="true"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Tab 1</ion-title> </ion-toolbar> </ion-header> <ion-fab-button (click)="debug()"> <ion-icon name="list"></ion-icon> </ion-fab-button> </ion-content>
ion-icon#nameにアイコン名を指定すれば、プラットフォーム毎に適切なアイコンが表示される
Ionicons
今回は debug()関数を呼ぶことにした
Viewから呼ばれる関数は、tab1.page.tsに書く
import { ViewTodoService } from '../services/viewTodo.service'; export class Tab1Page { constructor(public viewTodoService: ViewTodoService) {} async debug(){ (await this.viewTodoService.listTodos()).items.forEach (elm => console.log(elm.name)); } }
ListTodosQuery型からはこんな感じでデータを取る事が出来る
これでGraphQLを呼べるはずだが残念ながら、
Error: No credentials
認証が必要だね
サーバレス(主にAWS Lambda)の開発環境を調べる
昔から環境が変わったので調査中
まず今回調べるのは、サーバレス開発時の手法である
過去
わたしはLambdaが出始めた時には下記のような開発を行っていた
API Gatewayを設定する
nodeでコードを書く
トランスパイルを行う
Lambdaのエミュレートイメージ DockerLambdaを使いローカルデバッグ
Lambdaへのデプロイスクリプトを叩きデプロイ
しかし現在は色々と便利なものがある
AWS SAM
単純なFunctionであればこれがベストマッチ
APIGatewayの作成も行う事が出来る
また、AWSが公式のLambdaエミュレートDockerを出していて
ローカルテストまで出来る
主にAPIGatewayを使ったRestAPIの作成に向いている
非常に万能である
AWS Amplify
Lambdaだけでなく、Cognito、DB、S3、GraphQL等の実行環境をコンテナの中で開発するようなもの
SAMと比べて非常に色々な事が出来るので
フロントのHTMLやDBやらが必要なWebホスティングあるいはスマホでのサービス等
Lambdaだけじゃない大掛かりなシステムに向いている
主に画面をともなうGraphQLのソフトウェアに向いていると思われる
ServerlessFramework
AWS以外の、AzureやGCP、Ali Cloud、TencentCloud等にも対応している
Serverless-offlineプラグインを入れると、オフラインでも実行させることが出来る
AWS以外で実行する可能性があるときは、こちらを使うのがベストかもしれない