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では大きく変わってるのかなあ・・・
って事で、後日調査しますか。。