UnityのHLSLを読んでいると
HLSL
1 float sw = uv.x < _Config.x;
という式がありました。uv.x
と_Config.x
がfloatの値だとするならば、上記の式の「<」はどのような演算でsw
にはどのような結果がはいるのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
おそらく「uv.x < _Config.x
の結果はbool
型となり、それをfloat
に変換することでsw
は1.0
か0.0
のいずれかになる」...つまり、uv.x
が_Config.x
未満ならsw
は1.0
、そうでなければ0.0
ということでいいんじゃないかと思います。
リファレンスに載っているに違いない...と思ったのですが、Comparison Operatorsの節を見てみても「比較演算の結果の型は○○である」と明言している文章はなさそうに見えました。ですが...
To use comparison operators with vector and matrix types, use the all or any intrinsic function.
This operation fails because the if statement requires a single bool but receives a bool4:
if (A4 < B4)
These operations succeed:
if ( any(A4 < B4) ) if ( all(A4 < B4) )
ベクトル型や行列型に対して比較演算子を使いたい場合、組み込み関数のallやanyを使用してください。
この演算は、if
文に対しては単一のbool
が必要であるのに反して、bool4
が与えられているため失敗します:
if (A4 < B4)
これらの演算なら成功します:
if ( any(A4 < B4) ) if ( all(A4 < B4) )
といった文章がありました。
A4
やB4
はたぶん4成分の値なんでしょう。4成分同士の比較演算の結果がbool4
になると解釈できますので、類推すると1成分同士の比較演算を行なった場合にはbool
が得られると考えるのが自然じゃないかと思います。
また他にも、節の最初の方ではスカラー同士の比較演算の例が挙げられていますが、先ほど引用しました「if
文に対しては単一のbool
が必要」という文章と矛盾しないためには、スカラー同士の比較演算結果はbool
型であるべきだと思います。
そしてCasting and Conversion - Win32 apps | Microsoft Docsの記事では、bool
型をint
型やfloat
型に移そうとするとfalse
は0に、true
は1に変換されるとの記述がありました。DXSASの記事ではありますが、たぶんHLSLでもこのルールに従うだろうと思います。
念のための確認として、Unity上で下記のマテリアルを作成して...
ShaderLab
1Shader "Unlit/ComparisonOperationToFloat" 2{ 3 Properties 4 { 5 } 6 SubShader 7 { 8 Tags { "RenderType"="Opaque" } 9 10 Pass 11 { 12 CGPROGRAM 13 #pragma vertex vert 14 #pragma fragment frag 15 #include "UnityCG.cginc" 16 17 struct appdata 18 { 19 float4 vertex : POSITION; 20 float2 uv : TEXCOORD0; 21 }; 22 23 struct v2f 24 { 25 float2 uv : TEXCOORD0; 26 float4 vertex : SV_POSITION; 27 }; 28 29 v2f vert (appdata v) 30 { 31 v2f o; 32 o.vertex = UnityObjectToClipPos(v.vertex); 33 o.uv = v.uv; 34 return o; 35 } 36 37 fixed4 frag(v2f i) : SV_Target 38 { 39 float result = 0.5 < i.uv.x; 40 return fixed4(result, 0.0, 0.0, 1.0); 41 } 42 ENDCG 43 } 44 } 45}
Quadに割り当てたところ、UV座標が0.5
以下になる左半分は黒く、0.5
よりも大きい右半分は赤くなりました。
コンパイル結果のフラグメントシェーダー部分を抜粋すると...
-- Hardware tier variant: Tier 1 -- Fragment shader for "d3d11": // Stats: 2 math, 1 temp registers Shader Disassembly: // // Generated by Microsoft (R) D3D Shader Disassembler // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // TEXCOORD 0 xy 0 NONE float x // SV_POSITION 0 xyzw 1 POS float // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_0 dcl_input_ps linear v0.x dcl_output o0.xyzw dcl_temps 1 0: lt r0.x, l(0.500000), v0.x 1: and o0.x, r0.x, l(0x3f800000) 2: mov o0.yzw, l(0,0,0,1.000000) 3: ret // Approximately 0 instruction slots used
となっており、ltによる大小比較(真なら0xFFFFFFFF
、偽なら0x0000000
)の結果に対してandによる0x3f800000
とのビット積をとることで、比較結果が真なら0x3f800000
(浮動小数点数に直すと1.0
)、偽なら0x0000000
(浮動小数点数に直すと0.0
)の値を得ているようです。
投稿2020/07/03 20:46
総合スコア10811
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/05 04:39