3D Sensor Advent Calendar 2019 の20日目の記事です。
はじめに
同じ壁に当たる人が多そうなので記事にしてみます。
困ったこと
AzureKinectで取得したポイントクラウドのPointSize粒々のスケール)を変更できませんでした。
具体的には、VertexShaderのPSIZEの値を変更しても画面で何も変化が起きない…。困った…。
カメラが近づくとこんな感じにスカスカ。
PointSizeが1に固定されている感じ。
出来たこと
AzureKinectで取得したDepth画像のPointSizeを変更することができました。
こんなかんじ。分かりやすいようにPointSizeを5に設定してます。
どうやったか
うーん。
vertexの粒の大きさはPSIZEで変更できる認識で会っていたけどDX11以降では無効化される謎仕様変更で効いていなかった。Quest向けにOpenGLに変えたらいけた…。
— そいちろ@LookingGlass&AzureKinect (@asidys230) October 24, 2019
同じ悩みを抱えている人がいました。
DX11 PSIZE Bug, PLEASE HELP! - Unity Forum
DX11 doesn't support point mode rendering anymore according to the documentation, so I'm surprised it works at all. The idea behind that is that it is replaced by geometry shaders. So you'll have to generate a quad at every vertex yourself using a geometry shader.
あんまりよく分かってないけど、とりあえずDX11以降は素直には効いてくれなさそう。
ちなみにShaderはこんな感じ。
Shader "Custom/ColoredVertex" {
Properties{
_Size("ShaderSize", Float) = 1.000000
_PointSize("PointSize", Float) = 1.0
}
SubShader{
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#pragma multi_compile_fog
#define USING_FOG (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
float _Size;
float _PointSize;
// uniforms
// vertex shader input data
struct appdata {
float3 pos : POSITION;
half4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
// vertex-to-fragment interpolators
struct v2f {
float psize : PSIZE;
fixed4 color : COLOR0;
#if USING_FOG
fixed fog : TEXCOORD0;
#endif
float4 pos : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
// vertex shader
v2f vert(appdata IN) {
IN.pos.xyz = IN.pos.xyz * _Size;
v2f o;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
half4 color = IN.color;
float3 eyePos = mul(UNITY_MATRIX_MV, float4(IN.pos,1)).xyz;
half3 viewDir = 0.0;
o.color = saturate(color);
// compute texture coordinates
// fog
#if USING_FOG
float fogCoord = length(eyePos.xyz); // radial fog distance
UNITY_CALC_FOG_FACTOR_RAW(fogCoord);
o.fog = saturate(unityFogFactor);
#endif
// transform position
o.pos = UnityObjectToClipPos(IN.pos);
o.psize = _PointSize;
return o;
}
// fragment shader
fixed4 frag(v2f IN) : SV_Target {
fixed4 col;
col = IN.color;
// fog
#if USING_FOG
col.rgb = lerp(unity_FogColor.rgb, col.rgb, IN.fog);
#endif
return col;
}
ENDCG
}
}
}
さいごに
結構ハマってました。
もっとちゃんと根本的に解決したい気持ちはあるけど、とりあえず解決してよかったです。
明日は sirokujira さんの「Stereo Labs ZED Camera についての話」です。