YAMADA TAISHI’s diary

ゲームについてとか私の日記とか。このブログのあらゆるコードは好きにどうぞ。利用規約があるものは記事内のGitHubのRepositoryのリンクで貼られていると思うので、そちらを参照ください。

中度ADHD患者がADHDで悩む全ての人に贈る記事

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) | Twitter )です。
ADHDなのですが、薬をもらうまでは色んな方々の記事があるのですが、
その後、どうやってADHDの症状を緩和するのかという話が少ない気がしたので個人的なまとめを記事化しました。

目次


なぜ、この記事を書いたのか

ADHDかも知れないと思って、診断できる医者にいって、診断貰って、
薬貰って、6ヶ月通って、障害者手帳も貰って、会社にも相談したりしたけれど、
実際問題薬貰っても完全にADHDじゃなくなるわけじゃない。
ADHDは治らない。

男なので理解ある彼くんと出会うこともない。

つまり、ADHDと向き合い続ける必要がある。
集中できない、ケアレスミスする。だけど、仕事はしていく必要がある。
少しでも改善したい。そんな辛さを抱えることになる。

じゃあ、どうやればマシになるのか。
具体的にADHDとはなんなのか。
そんな話がまとまっているところが何処にもない。

なので書いてみた。

前提条件


過去調べた論文や、ニュース記事、私個人の考察を織り交ぜた結果を書きます。
元論文は何処から取得してきたか忘れたものも多いので、話半分に読んで頂きたいです。
また、私のブログ記事を鵜呑みにせずに自分で考え、お医者様の話をよく聞いて判断お願いします。

そもそもADHDとは


前頭前野を含む脳の働きに偏り、ドーパミン(ドパミン)やノルアドレナリン(ノルエピネフリン)の働きが
偏りが出てしまう病のことらしい。
「らしい」というのも原因は未だハッキリしないところがあるから。
(不足したり逆に出過ぎたりする?)

アドレナリン(エピネフリン)系の薬も効果があるらしいので、アドレナリンの分泌も関係ありそう?副腎髄質ホルモンらへん?

もしかしてADHDじゃなく、副腎が悪い(副腎疲労の)可能性もある?
特に疲れやすいとかなら副腎の可能性ありそう?

または似たような病に自閉スペクトラム症(ASD)がある。
ちなみに自閉スペクトラム症は(自閉症高機能自閉症アスペルガー症候群など)の総称。
こちらも副腎のホルモンが関係する部分があり。

鬱の人もADHDっぽい症状がでることがある。(そりゃドーパミンが少なくなるなら、そうなるだろうなぁ)


ADHDはホルモンに偏りがあるせいで常にやる気なく、ドーパミンが出ないので常に眠い。
気が散りやすいけど、ひとだび集中すると周りが見えなくなる程に没頭する。
なお、ADHD人によって出やすい症状が違うのはドーパミンなどの偏り方が違うからか……?
なにか別の原因でホルモンの分泌が偏っているか……?詳細は不明

ADHDの薬


ドーパミンの量を増やす効果があるものが多く、かなり依存性が高いものが一般的。
普通の人が処方するといわゆるハイになっちゃう。
いわゆる一種の覚醒剤ってこと。(メルカリなんかで売ったら多分捕まるよ)

なので、処方できる医者は限定されるみたい。
特に直接ホルモンを高める興奮剤(中枢神経刺激薬)はかなり医者が限定される。
精神科医でもADHDの薬が処方できないってことがあるみたい。

成分名:アトモキセチン(製品名:ストラテラ

指定された医者のみ処方可能。私が現在服用中。
薬を飲むことでノルアドレナリンあるいはドーパミンの再取り込みを阻止することで、
これらの神経伝達物質の濃度を脳内で上昇させる
劇的な効果はないが、数週間、数ヶ月でじわじわ効果が出てくる。

成分名:メチルフェニデート塩酸塩(製品名:コンサータ)(製品名:リタリン)(総称:メチルフェニデート徐放薬)

中枢神経刺激薬。いわゆる興奮剤。直接脳の中枢神経を刺激し神経伝達物質(ドパミンノルアドレナリン)の働きを活性化(増やす)させることでADHDの症状である不注意、多動・衝動性などの症状を改善する。

指定された医者のみ処方可能。私の医者は処方できない。依存性が高いらしい。
コンサータの処方は不適正な使用を防ぐため2019年12月より登録制になった。
病的な眠気を起こす「ナルコレプシー」にも効果あり。
脳の神経を活性化させ ハッキリ目覚めさせる作用がある。
劇的な効果あり。(服用したことが無いから知らんけど)30分ほどで効果が出るらしい。

約12時間効果が持続。重度な人はこれを服用。
カフェインと合わせた服用は危険かも?カフェインと合わせる場合は医者の指示にしたがって。

成分名:グアンファシン(製品名:インチュニブ)

ノルアドレナリンの神経受容体であるα2A受容体を選択的に刺激することにより神経伝達を増強させる。

最近出てきた。ドーパミンの分泌に影響が無いからか、あまり主流ではなさそう。子供にも処方できる。

成分名:リスデキサンフェタミン(製品名:ビバンセ)

全然聞かない。2019年3月に販売承認。一番最近のものかも。
6〜18歳の小児に承認された新しいADHD治療薬。
体内で「d-アンフェタミン」に変わることから、覚せい剤取締法に規定する覚せい剤原料みたい。
とはいえコンサータと同じ中枢神経刺激薬だが子供にも服用できる(登録制ではある)所をみると、安全度は高いのかも……?
薬理学的にドパミンノルアドレナリン再取り込み阻害・遊離促進薬とされることがあるらしいので、ストラテラとも似てるのかな?素人の私には分からん。
多分私の医者は処方できないんだろうなぁ。

関係あるホルモン


ドーパミン(ドパミン)

やる気や幸福感を得られるだけではなく、運動や学習、感情、意欲、ホルモンの調節など多くの生命活動に関与する。
不足すると無関心化、性機能低下、運動機能低下。
特にドーパミンは、感情、記憶、思考、理性、意識、理解などの心の機能に関与。
喜びや快楽、意欲をもたらす働きがある。

過剰になると過食や買い物依存、アルコール依存になったりする。
ADHDドーパミンが出やすい(依存性が出やすいもの)酒や煙草などを求めるのは無意識にドーパミンを求めるからか……?

yuk2.net

アドレナリン(エピネフリン)

交感神経の作用が高まると分泌され、血糖量の上昇、心拍数の増加などを起こす。
関連性はあるかも知れないが、具体的にどのように関連性があるかは分からなかったので割愛。

ノルアドレナリン(ノルエピネフリン)

アドレナリンと成分が近いが異なる。
末梢血管を収縮させて血圧を上昇させるように働く。

緊張や不安、集中、積極性をもたらし、ストレスに打ち勝とうとするときに働く。
不足すると無気力、意欲減衰。
過剰になると攻撃的になったり、ヒステリーを起こしたり、パニックになったりする。
ADHDの薬「アトモキセチン(ストラテラ」を飲んでイライラする人が多いのも、このノルアドレナリンが多くなりすぎるからだと思う。

セロトニン

ノルアドレナリンドーパミンの2つが過剰になって暴走しないように、調節機能がある。
逆に全然ノルアドレナリンドーパミンが出てない時は分泌を促す。
精神の安定を司り、気分を高揚させる働きから幸せ(幸福)ホルモンとも呼ばれる。筋トレすると分泌が促されるらしい。
なかやまきんに君のネタで「幸せホルモン受信中」ってあるのはこれだろうねw

アデノシン

これは睡眠を誘発するアデノシン。
アデノシンとレセプター(受容体)が合体するとドーパミンのレセプターと合体をブロックする働きがある。

gigazine.net

ドーパミンの働きが抑制されると人は物事に取り組むモチベーションが下がってしまう。
酒を飲んだり(お酒を飲んで眠くなるのは他の作用もありそうだけど)、運動すると眠くなるのはアデノシンが分泌されるかららしい。
ちなみにカフェインはアデノシンとレセプターがくっつくのを阻害するのでドーパミンがレセプターと合体しやすくなる。
ので、モチベーションアップ!詳細については後ほど解説。

Q.アデノシンがなくなれば眠くならないのでは?

睡眠物質は他にもあって、他にも眠くなる要素はありそうなのでなんとも言えない。
またアデノシンはアデノシンのリボースに3分子のリン酸がついたものアデノシン3リン酸(ATP)が分解されるときに出来るもの。

主にアデノシン3リン酸(ATP)が解説される時は、分解される工程で、1個だけリン酸が外れるとだけ解説される。
1個だけ外れるとアデノシン2リン酸(ADP)と呼ばれるものになるみたい。
だけど、アデノシン3リン酸(ATP)が分解されるときには正確には1個だけリン酸が外れるのではなく、分解されるたびに2個3個外れる。その時に出来上がるのがアデノシン一リン酸(アデニル酸)とアデノシン。

ちなみに筋トレとかで成分を調べる人は詳しいかもだけど、アデノシン2リン酸(ADP)クレアチンリン酸が使われ再合成されてアデノシン3リン酸(ATP)に戻る。

アデノシン3リン酸(ATP)の正体とは……

アデノシン3リン酸(ATP)とは本質はエネルギー源ってやつです。
分解する時にエネルギーが得られる。増えすぎると脂肪になる。
ちなみにATP 1分子から約12kcalのエネルギーが得られるらしいです。

つまり……?

アデノシン3リン酸は食べ物を食べてる限りなくすことはできないので、
必然的にアデノシンが脳内に分泌されるのも防ぐことは出来ない!アデノシンを消すのは無理!!!!!!

個人的な対処療法(正しいのかはともかく模索中)


音楽

個人的には論外。ある一定の効果はあるけど、集中の妨げにもなる気がする。というか音楽聞くという行動に移れるほどなら、多分まだマシ。
ADHDは聴覚過敏の人が多いから効果がないかも知れない。
しかしながら、人によっては音楽がないと作業ができないというレベルで効果を発揮してくれる場合もあるらしい。
音楽自体はドーパミンの発生を促す効果がある程度ある。

コーヒー(カフェイン)

効果あり。体質的なところも大きいだろうが、カフェインの効果は偉大。
アデノシンとレセプターがくっつくのを阻害するだけだが、アデノシンがくっついているとドーパミンがレセプターと合体しずらくなるらしい。
カフェインで阻害することでドーパミンが結合されやすくなるので、やる気が出る。
ただ、アデノシンが貯まると新しい受容体が現れてしまい、効果半減する。ので一時的なもの。
数日たてば余分にできたアデノシン受容体は元に戻るので数日に数回のブースト機能ぐらいに考えている。

食事

大事。ドーパミンカゼインとかタンパク質から出来る。
後、鉄分も必要。特に意識しないと鉄分は摂らないことが多い。とりすぎも良くないので量を取ればいいって話じゃないけど、必要。
貧血気味なら血流も増えるので疲れが取れるし、ドーパミン量が増えるのでやる気もでる。

睡眠

超大事。
睡眠が足りないと単純に頭の働きが悪くなり、判断力が鈍るのでただでさえケアレスミスするADHDの症状が悪化する。
また、さっき上でも出てきたアデノシンは睡眠で減るので、寝ることでドーパミンとレセプターくっつきやすくなり、やる気がある程度でる。

日光浴

ビタミンDの合成が関係してくる。
日光を浴びるとビタミンDが生成される。
ビタミンD神経伝達物質であるセロトニンのレベルを改善する働きがある。
つまり、セロトニンが出る→低いレベルのドーパミンノルアドレナリンが分泌される→ADHDの改善に効果ありという感じ。

テレワークでビタミンDは不足しがちなので、食べ物で摂取するのも良さそう。ミロはいいぞ。

運動

個人的には効果不明。
疲れたら活動できないし、有酸素、無酸素どちらも短期間では明確なやる気に繋がる効果を体感では感じられなかった。運動後、やる気が出たり出なかったり単純じゃない。

しかしながら、ADHDの改善効果はあるらしい。(どこかで論文を見かけましたが忘れました)
たった1度の20分以上のウォーキング、ジョギング、サイクリングといった有酸素運動によって、不注意症状や集中力、不適切な行動の抑制に効果が見られたという報告が数多くある。
運動によって、この前頭前皮質-線条体回路の神経伝達物質であるドーパミンノルアドレナリン、アドレナリン、セロトニンの分泌量が上昇するらしい。
では筋トレのような無酸素運動はというとアデノシンが分泌されてしまう反面、セロトニンの分泌効果もあるので、どの程度効果があるのか個人的に不明。どこかに論文あるのだろうか……?
強度によっても大きく異なりそう。まぁ、いろいろなネット記事を読む限り軽い有酸素運動なら効果がでそう? また外での運動なら日光浴効果(ビタミンDが増えることによりセロトニンの分泌)もありそうなので、運動自体が効果があるのかは個人的にはなんとも言えない。

まぁ、外で15分ウォーキングは少なくとも日光浴、運動、睡眠の質向上どれもいい効果なので、ある意味改善はしそう。やったほうが良さそう。

余談

時間間隔(体内時計)ってどうやら(科学的根拠はまだハッキリしないらしいが)ドーパミンが大きく関与するらしい。
コンサータ(リタリン)が、時間知覚とミリ秒単位の判断を向上させることを実証済みらしい。

www.news-postseven.com

https://www.amazon.co.jp/exec/obidos/ASIN/4772695397/ref=nosim?tag=maftracking54000-22&linkCode=ure&creative=6339

楽しいと時間があっという間に過ぎるのはこういうこと。
高齢になるほど、時間を短く感じるが、老化によりドーパミン分泌量が減るかららしい。

ADHDがソワソワするのは、ドーパミン分泌量が少なくて飽きてしまうからかも。

つまり?

リズム感が無いのはADHDのせいだったのか~~~~~~~~!?

他に効果がありそうなこと

ニューロフィードバック

脳波を見ながら集中するやつ。
こちらは論文あり。一種の認知療法として効果があるらしい。
個人的には試したことが無いのでなんとも言えない。

www.ncnp.go.jp

サウンドセラピー

サウンドセラピーで改善効果あるという話もあるらしい。科学的根拠はまだ薄そう。
そもそも、曲を聞くことでドーパミンが出るので何かしらはあるのかも?

インタラクティブメトロノームと呼ばれるセラピーがある。 …音に聴き入って反応することを学び、本人が「ビートに合わせられる」よう内蔵クロックを鍛錬すれば、これらの症状を抱えた子どもを変えることができるだろう

つまり、一種の認知療法っぽい?
yumemana.com

リズム感を鍛える

上であったとおりリズム感を鍛えればADHDの症状が改善するかも知れない可能性。
つまり、リズムゲーやればADHD改善するかも!?
いや、知らんけど。

読書

これはよくわからないが、効果があると見かけた。
私は割と読書好きですが、これに関してはホンマかいなという疑心ありますね。
科学的根拠は薄そう。

副腎をいたわる

これまで書いたとおり、ADHDの不足しやすいホルモンは副腎から作られる。
副腎をいたわることで良くなる可能性がある。心の不調がある方も副腎をいたわることで良くなるかも?
たんぱく質を多く含む食品を食べる。(ホルモンを作るためにたんぱく質が分解され、不足するので)
ビタミンCをとる。ビタミンAをとる。

ヨーグルトはカゼインもビタミンAもタンパク質も含まれるので嬉しいかも知れないですね。
ストレスは副腎皮質ホルモンであるコルチゾールを増やす。ストレスが大量にかかると副腎が大量にコレチゾールをつくることになるので副腎に負荷をかける。なのでストレスをかけないことも大事?

重い布団をつかう

マイアミ大学が行った実験では、人は体に圧迫が与えられた状態だと、ストレスホルモンの『コルチゾール』が31%低下し、幸せホルモンの『セロトニン』が28%増加することが分かっているらしい。睡眠の質も良くなるらしい。

diamond.jp

シナモン


シナモンにはCREBという特定のDNA配列に結合し、遺伝子の転写を増加させたり低下させたりするタンパク質を海馬で増加させる機能があるらしい。
CREBが活性化されると、BDNFが増えるらしい。
詳しい仕組みは専門家じゃないのでよくわからなかったが、そのBDNFがADHDに関連している可能性があるそうだ。(下の論文参照)
つまり、シナモンを摂れば脳機能が改善する可能性がある。
BDNFの不足改善は認知症予防や鬱改善にもなるらしい。
しかしながら、シナモン自体はクマリンという物質があまり良くないらしい。クマリンは肝障害が誘発されるとのこと。
シナモンはシナモンでもクマリンが少ないセイロンシナモンというのが良いかもしれない。

また、BDNFを増やす栄養として、葉酸DHA、フラボノイド、ペプチドなどが効果があるらしい。
有酸素運動により、BDNFが増えるという報告もあるらしので、個人的にはADHDの改善にはBDNFが必要不可欠なのではないかというふうに思った。
まだ科学的には証明されていない部分が多いため、なんとも言えないが、研究が進むことを祈るばかりである。

saigaiin.sblo.jp

diamond.jp

www.rushu.rush.edu

bibgraph.hpcr.jp

yuichirolfing.com

diamond.jp

トマト


リコピンが脳によいことは知られているが前記にあるBDNFの上昇に関連してくるらしい。
リコピンを摂ろう。

bibgraph.hpcr.jp

まとめ


以上が、私が個人的に調べたことの全てだ。
少しでも楽になる未来を目指して今後も模索していきたい。

関連記事


https://orotiyamatano.hatenablog.com/entry/2021/03/28/ADHD%E3%81%AE%E7%A7%81%E3%81%8C%E8%A8%BA%E6%96%AD%E3%81%95%E3%82%8C%E3%81%A6%E9%9A%9C%E5%AE%B3%E8%80%85%E6%89%8B%E5%B8%B3%E3%82%92%E8%B2%B0%E3%81%86%E3%81%BE%E3%81%A7?_ga=2.50780073.1036784398.1654593796-2059991404.1629450307

やまだたいしのシェーダー(GLSL)勉強まとめ!

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
以前からシェーダーを勉強していてある場所にまとめていたのですが、公開しないのも勿体ないと思い
今回は記事化することにしました。

もっと初歩的な記事についてはこちら↓

orotiyamatano.hatenablog.com

目次


なぜシェーダーを勉強し始めたか?


プログラムの勉強は見た目を派手にするような実装は少なく
進捗として見たときに地味。

シェーダー周りを勉強すると、見た目は派手だし、ゲームの表現も増すので勉強し始めました。

環境


twiGLを使用。
GLSLは書きやすいって聞いた。
クラシックで書いていくことに。

twigl.app

ちなみに他にはglslsandboxやShaderToyなどが有名だそうだ。
glslsandbox.com
www.shadertoy.com

何の勉強から始めるか


最初からかっこいい3Dのは難しい

notargs (@notargs) / Twitter さんに

まずは「ピクセルシェーダーで数式を解いて絵を描く」間隔をつかむのが大事ですね。
2Dで丸とかのプリミティブな形をつくるところからはじめてみるといいかも

って言われたので素直に、そのあたりから勉強。

最初に参考にしたリンクたち


thebookofshaders.com
setchi.hatenablog.com

作品集

1番最初の作品


precision highp float;
uniform vec2 resolution;
uniform vec2 mouse;
uniform sampler2D backbuffer;
void main(){
  vec2 r = resolution,p = (2.*gl_FragCoord.xy - r) / min(r.x,r.y);
  float pct = distance(p,vec2(0.));
  vec3 color = vec3(pct);
  float d = step(0.2,pct);
  gl_FragColor = vec4(vec3(d),1.0);
}

当時のメモ:
Shadertoyとtwiglじゃ若干記述が違う?

fragCoordは現在処理中のピクセルの座標
fragColorは現在処理中のPixelの最終的な色
iResolutionは解像度
step指定されたしきい値を元に0にするか1にするかきめるやつ

(lengthとdistanceの違いも分かってなかった)

2作品目


https://gyazo.com/8a2d007f9dedbf5d4dd5039d901757b5/max_size/1000

precision highp float;
uniform vec2 resolution;
uniform vec2 mouse;
uniform float time;
uniform sampler2D backbuffer;
void main(){
  vec2 r = resolution,p = (2.*gl_FragCoord.xy - r) / min(r.x,r.y);
  float pct = distance(p,vec2(cos(time*4.0)*0.5,0.0));
  vec3 color = vec3(pct);
  float d = step(sin(time*4.0)*0.5+0.7,pct);
  gl_FragColor = vec4(vec3(d),1.0);
}

当時のメモ
distanceってやつを使った。shader toyにはないみたい。→0を指定した場合、意味合い的にはlength(p)とほぼ同じ?
timeも利用。
sinとcosはよくあるやつ。

(とりあえず、time使ってみたかったのよね)

3作品目


https://gyazo.com/ad4a4670702e7047bf7f744192828a8c/max_size/1000

precision highp float;
uniform vec2 resolution;
uniform float time;
uniform sampler2D backbuffer;
mat2 rotate2d(float _angle){
    return mat2(cos(_angle),-sin(_angle),
    sin(_angle),cos(_angle));
}
float square(vec2 p) {
   return abs(p.x) + abs(p.y);
}
void main(){
  vec2 r = resolution,p = (2.*gl_FragCoord.xy - r) / min(r.x,r.y);
  float a = sin(time * 5.0) * 0.5 + 0.5;
  vec2 d = mix(vec2(distance(p,vec2(0.0)),0.7), vec2(square(p* rotate2d(radians(time*180.))),0.5), a);
  vec3 color = mix(vec3(1), vec3(0), step(d.x, d.y));
  gl_FragColor = vec4(color,1.0);
}

当時のメモ
線形直線→lerp(mix)を理解
2次元の回転行列をなんとなく理解

thebookofshaders.com

(参考にしたシェーダーのマルとシカク変換かっこいいと思ったんだよね)

4作品目


https://gyazo.com/d92a8b36ab6b5db331cab395d07f221c/max_size/1000

precision highp float;
uniform vec2 resolution;
uniform float time;
uniform sampler2D backbuffer;
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  float d = distance(p,vec2(0.0));
  d = (10.* d)+time*-10.;
  d = abs(sin(d));
  d = step(0.5,d);
  gl_FragColor = vec4(vec3(d,0.0,0.0),1.0);
}

当時のメモ
distance部分はlengthでも良さそう。
今回の重要ポイントはabs(sin(d))
geekestモードを使えば更に短くなると知った。

(某ペルなんとかってゲームを意識してた)

5作品目


https://gyazo.com/66ae9633c693792e5861156b4c1d1ceb/max_size/1000

precision highp float;
#define PI 3.14159
uniform vec2 resolution;
uniform float time;
uniform sampler2D backbuffer;
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  float a = atan(p.y, p.x);
  float d = distance(p,vec2(0.));
  if(d > 0.6){
    d = abs(cos(a * 5.+time)) + 0.1;
  }
  gl_FragColor = vec4((d < 0.6) ? vec3(1,.0,.0):vec3(1.),1);
}

当時のメモ
atanの使い方をなんとなく理解。
GLSLのatanはatan2と同じ?

(日章旗的な?なにか)

6作品目


https://gyazo.com/f7bf30030dc3825b9b180afd3916b901/max_size/1000

#define PI 3.14159
#define ANGLE 360.
precision highp float;
uniform vec2 resolution;
uniform float time;
uniform sampler2D backbuffer;
mat2 rotate2d(float _angle){
    return mat2(cos(_angle),-sin(_angle),
    sin(_angle),cos(_angle));
}
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  p = p*rotate2d(radians(((floor(time*45.)*22.5))));
  float b = length(p);
  b = step(0.4,b);
  float a = length(p);
  a = step(a,0.15);
  float d = max(a,b);
  float at = atan(p.y, p.x);
  float c = abs(cos(at * 8.)) + 0.1;
  float num = ((atan(p.y, p.x) / PI) *0.5)+0.5;
  float at2 = (floor((num*ANGLE)/11.25))*11.25/ANGLE;
  d = max(c,d);
  d = step(0.6,d);
  d = max(at2,d);
  gl_FragColor = vec4(vec3(d),1);
}

当時のメモ
これまでの知識を色々合わせた。
回転部分、グラデーションをどう実装するか分からなくて悩んだ。
ちゃんと書いて覚えよう。

こう書いたほうが良さそう。
float b = length(p)-0.4;
float a = length(p)-0.15;
float d = max(-a,b);
gl_FragColor = vec4(vec3(step(0.0,d)),1);

(逆に今書けないやw携わってるゲームでローディングを書いてるのがあったので書きたくなって書いてみたんだよね)

7作品目


https://gyazo.com/f94543dc1819337f9a8a1e434193a029/max_size/1000

precision highp float;
uniform vec2 resolution;
uniform float time;
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  p.x=(0.5*p.x)+0.5;
  p.y=(-0.5*p.y)+0.5;
  p.x+= 1.0 + 0.1 * sin(p.x * 5.0 + time) + 0.1 * sin(p.y * 3.0 + time);
  p.y+= 1.0 + 0.1 * sin(p.x * 5.0 + time) + 0.1 * sin(p.y * 3.0 + time);
  float t = abs(step(0.5, fract(p.x)) - step(0.5, fract(p.y)));
  gl_FragColor = vec4((t>0.)?vec3(0.0,.338,0.220):vec3(0.0),1.);
}

当時のメモ
ワープ処理、人気のあれ。

floorはに任意の数の整数をだすやつ。
つまり。floor(4.3) とかだったら 4.0 が取得できる。
そして前回つかったfactは n-floor(n) と同義なので fact(4.3) は 0.3

(某なんとかの刃を意識)

8作品目


https://gyazo.com/753bc0c0e981775d7c8927c0ce5c5b00/max_size/1000

#define PI 3.1415926
precision highp float;
uniform vec2 resolution;
uniform float time;

mat2 rotate2d(float _angle){
    return mat2(cos(_angle),-sin(_angle),
    sin(_angle),cos(_angle));
}

float polygon(vec2 p, int n, float size){
    float a = atan(p.x, p.y) + PI;
    float r = 2. * PI / float(n);
    return cos(floor(0.5 + a / r) * r - a) * length(p) - size; 
}

float star(vec2 p, int n, float t, float size){
    float a = 2. * PI / float(n)  / 2.;
    float c = cos(a);
    float s = sin(a);
    vec2 r = p * mat2(c, -s, s, c);
    return ( polygon(p, n, size) - polygon(r, n, size) * t ) / (1.- t);
}

void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  p*=4.;
  float y = ((mod(p.y,4.) > 2.)?1.:-1.);
  p.x += time * y;
  p = mod(p,2.)-1.;
  p = p * rotate2d(radians(time* y *45.));
  float l = length(p);
  l = star(p,5,4.,0.5);
  l= step(0.,l);
  gl_FragColor = vec4((l<1.)?vec3(1.,1.,204./255.):vec3(1.,204./255.,1.),1.);
}

当時のメモ
星型、五角形、繰り返しの理解。

(カービィー的な……?やっぱさ、星ってかわいいじゃん?)

9作品目


https://gyazo.com/3700c71da9b10902f4a15020e304516c/max_size/1000

precision highp float;
uniform vec2 resolution;
uniform float time;
uniform sampler2D _buffer;
float interpolat(float f){
    return f * f * f * (f * (6.0 * f - 15.0) + 10.0);
}
float random(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
vec2 random2(vec2 v){
    return vec2(random(v), random(v + vec2(0.5, 0.5)));
}
float animation(float f){
    return sin(f * 6.283 + time * 2.0) * 0.5 + 0.5;
}
vec2 animation2(vec2 v){
    return vec2(animation(v.x), animation(v.y));
}
float noise(vec2 p){
  vec2 i_uv = floor(p * 8.0);
    vec2 f_uv = fract(p * 8.0);
    vec2 v1 = animation2(random2(i_uv + vec2(0.0, 0.0))) * 2.0 - 1.0;
    vec2 v2 = animation2(random2(i_uv + vec2(1.0, 0.0))) * 2.0 - 1.0;
    vec2 v3 = animation2(random2(i_uv + vec2(0.0, 1.0))) * 2.0 - 1.0;
    vec2 v4 = animation2(random2(i_uv + vec2(1.0, 1.0))) * 2.0 - 1.0;
    float o = mix(
        mix(dot(v1, f_uv - vec2(0.0, 0.0)), dot(v2, f_uv - vec2(1.0, 0.0)), interpolat(f_uv.x)), 
        mix(dot(v3, f_uv - vec2(0.0, 1.0)), dot(v4, f_uv - vec2(1.0, 1.0)), interpolat(f_uv.x)), 
        interpolat(f_uv.y)) * 0.5 + 0.5;
    o = step(0.3,o);
  return o;
}
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  vec2 position = ( gl_FragCoord.xy / resolution.xy );
  texture2D(_buffer, position);
  float x = 2. * p.y + sin(time * 5.);
  float distort = sin(time * 10.) * 0.1 * sin(5. * x) * (- (x - 1.) * (x - 1.) + 1.);
     p.x += distort;
  float r_ = noise(vec2(p.x,p.y-distort*-0.3));
  float g  = noise(vec2(p.x+distort*-0.3,p.y));
  float b  = noise(vec2(p.x-distort*-0.3,p.y));
     vec3 color =vec3(0.);
  color.r = texture2D(_buffer, p + vec2(distort * -0.3, 0.)).r;
  color.g = texture2D(_buffer, p + vec2(0., distort * 0.3) ).g;
  color.b = texture2D(_buffer, p - vec2(0., distort * 0.3) ).b;
  gl_FragColor = vec4(vec3(r_,g,b),1.);
}

当時のメモ
RGBShiftとパーリングの理解。
あわせて、バリューノイズ、疑似ランダム、ホワイトノイズ、ブロックノイズを理解。

(一気に勉強したから忘れてる部分も多い)

9.5作品目(ほぼコピペコードだったので作品にはカウントしない)


https://gyazo.com/5118141adf27dc2bc303b9f3d283dc4d/max_size/1000

precision highp float;
uniform vec2 resolution;
uniform float time;

float interpolation(float f)
{
    return f * f * f * (f * (6.0 * f - 15.0) + 10.0);
}
float random(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
vec2 random2(vec2 v){
    return vec2(random(v), random(v + vec2(0.5, 0.5)));
}
vec2 animation2(vec2 v)
{
    return vec2(sin(v.x * 6.283 + time * 2.0) * 0.5 + 0.5, sin(v.y * 6.283 + time * 2.0) * 0.5 + 0.5);
}
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  vec2 position = ( gl_FragCoord.xy / resolution.xy );
  vec3 color = vec3(.0);
  vec2 i_uv = floor(p * 8.0);
    vec2 f_uv = fract(p * 8.0);
    vec2 v1 = animation2(random2(i_uv + vec2(0.0, 0.0)));
    vec2 m_neighbor;
    float m_dist = 1.;
    for (int y= -1; y <= 1; y++) {
    for (int x= -1; x <= 1; x++) {
        vec2 neighbor = vec2(float(x),float(y));
          vec2 v1 = animation2(random2(i_uv + neighbor));
          vec2 diff = v1-f_uv+neighbor;
        float dist = length(diff);
        m_dist=min(dist,m_dist);
    }
    }
  color += m_dist;
  //color -= step(.7,abs(sin(27.0*m_dist)))*.5;
  //color += 1.-step(.02, m_dist);
  //color.r += step(.96, f_uv.x) + step(.96, f_uv.y);
  gl_FragColor = vec4(color,1.);
}

当時のメモ
セルラーノイズの理解。↓をみたら分かりやすい
thebookofshaders.com

(ノイズ系、結構汎用性高いのでシェーダー使う人は覚えておくと便利かも)

10作品目


https://gyazo.com/a051f928d4159e768a511d936e09d6a3/max_size/1000

#define PI 3.1415926
precision highp float;
uniform vec2 resolution;
uniform float time;
float interpolation(float f)
{
    return f * f * f * (f * (6.0 * f - 15.0) + 10.0);
}
float random(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
vec2 random2(vec2 v){
    return vec2(random(v), random(v + vec2(0.5, 0.5)));
}
vec2 animation2(vec2 v){
    return vec2(sin(v.x * 6.283 + time * 2.0) * 0.5 + 0.5, sin(v.y * 6.283 + time * 2.0) * 0.5 + 0.5);
}
vec2 voronoi(in vec2 p,out vec2 m_point){
  vec2 i_uv = floor(p * 8.0);
    vec2 f_uv = fract(p * 8.0);
    vec2 v1 = animation2(random2(i_uv + vec2(0.0, 0.0)));
    vec2 m_neighbor;
  vec2 m_dist = vec2(8, 8);
    for (int y= -1; y <= 1; y++) {
    for (int x= -1; x <= 1; x++) {
        vec2 neighbor = vec2(float(x),float(y));
          vec2 v1 = animation2(random2(i_uv + neighbor));
          vec2 diff = v1-f_uv+neighbor;
        float dist = length(diff);
        if(dist < m_dist.x){
          m_dist.y = m_dist.x;
          m_dist.x= dist;
          m_point = v1;
        }else if(dist < m_dist.y){
          m_dist.y = dist;
        }
    }
    }
  return m_dist;
}
void main(){
  vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y);
  vec2 position = ( gl_FragCoord.xy / resolution.xy );
  vec3 color = vec3(.0);
  vec2 point;
  vec2 v = voronoi(p,point);
  vec2 c = sqrt(v);
  float dis = c.x - c.y;
  color = vec3(1.0-step(-.1,.05+(dis)*2.));
  color.rb -= point;
  gl_FragColor = vec4(color,1.);
}

当時のメモ
ボロノイ図らしき何か。境界線の出し方の理解が難しかったです。簡易版の境界線表示で対応しました。
参考リンク
thebookofshaders.com

(いまだにちゃんと理解してない)

11作品目


https://gyazo.com/2d48420100c801ca22c2c262b036a73e/max_size/1000

precision mediump float;
uniform float time;
uniform vec2  mouse;
uniform vec2  resolution;
const float sphereSize = 1.0; // 球の半径
float distanceFunc(vec3 p){
    return length(p) - sphereSize;
}
vec3 normal(vec3 pos) {
    float v = 0.001;
    return normalize(
      vec3(distanceFunc(pos) - distanceFunc(vec3(pos.x - v, pos.y, pos.z)),
      distanceFunc(pos) - distanceFunc(vec3(pos.x, pos.y - v, pos.z)),
      distanceFunc(pos) - distanceFunc(vec3(pos.x, pos.y, pos.z - v)))
      );
}
void main(void){
    // fragment position
    vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
    // camera
    vec3 cPos = vec3(0.0,  0.0,  3.0);
    vec3 cDir = vec3(0.0,  0.0, -1.0);
    vec3 cUp  = vec3(0.0,  1.0,  0.0);
    vec3 cSide = cross(cDir, cUp);
    float targetDepth = 1.0;
    // ray
    vec3 ray = normalize(cSide * p.x + cUp * p.y + cDir * targetDepth);
    // marching loop
    float distance = 0.0; // レイとオブジェクト間の最短距離
    float rLen = 0.0;     // レイに継ぎ足す長さ
    vec3  rPos = cPos;    // レイの先端位置
    for(int i = 0; i < 99; i++){
        distance = distanceFunc(rPos);
        rLen += distance;
        rPos = cPos + ray * rLen;
    }
    vec3 lightDirection = normalize(vec3(sin(time), 0.0, 1.));
    // hit check
    if(abs(distance) < 0.001){
        vec3 nomal = normal(rPos);
        float differ = dot(nomal,lightDirection);
        gl_FragColor = vec4(vec3(differ), 1.0);
    }else{
        gl_FragColor = vec4(vec3(0.0), 1.0);
    }
}

当時のメモ
初レイマーチング

wgld.org

qiita.com

qiita.com

(この辺からグッと数学レベルが上ってきてキツい)
(ポストエフェクトレベルならココまでの知識である程度かける箇所が多いハズ)

12作品目


https://gyazo.com/9b1c4dfbdb74b1bce1a2441b90000230/max_size/1000

precision mediump float;
uniform float time;
uniform vec2  mouse;
uniform vec2  resolution;
const float sphereSize = 1.0; // 球の半径
vec3 trans(vec3 p){
    return mod(p, 8.0) - 4.0;
}
float distanceFunc(vec3 p){
    return length(trans(p)) - sphereSize;
}
vec3 normal(vec3 pos) {
    float v = 0.001;
    return normalize(
      vec3(distanceFunc(pos) - distanceFunc(vec3(pos.x - v, pos.y, pos.z)),
      distanceFunc(pos) - distanceFunc(vec3(pos.x, pos.y - v, pos.z)),
      distanceFunc(pos) - distanceFunc(vec3(pos.x, pos.y, pos.z - v)))
      );
}
void main(void){
    // fragment position
    vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
    // camera
    vec3 cPos = vec3(0.0,  0.0, 10.0);
    vec3 cDir = vec3(0.0,  0.0, -1.0);
    vec3 cUp  = vec3(0.0,  -1.0,  0.0);
    vec3 cSide = cross(cDir, cUp);
    float targetDepth = 1.0;
    // ray
    vec3 ray = normalize(cSide * p.x + cUp * p.y + cDir * targetDepth-cPos);
    // marching loop
    float distance = 0.0; // レイとオブジェクト間の最短距離
    float rLen = 0.0;     // レイに継ぎ足す長さ
    vec3  rPos = cPos;    // レイの先端位置
    for(int i = 0; i < 99; i++){
        distance = distanceFunc(rPos);
        if (distance < 0.001) {
            break;
        }
      rLen += distance;
      rPos = cPos + ray * rLen;
    }
    vec3 lightDirection = normalize(vec3(sin(time), 0.0, 1.));
    // hit check
    if(abs(distance) < 0.001){
        vec3 nomal = normal(rPos);
        float differ = dot(nomal,lightDirection);
        gl_FragColor = vec4(vec3(differ)+vec3(1,0,0), 1.0);
    }else{
        gl_FragColor = vec4(vec3(0.0), 1.0);
    }
}

当時のメモ
レイマーチングの修行中。前回のサイトの途中から。

(何か四角のやつも作ってた↓)

このサイトとか参考になる。
Inigo Quilez :: computer graphics, mathematics, shaders, fractals, demoscene and more

終了


ココからは忙しくなって書けてませんでした。
とはいえ、大分シェーダーを読むのには抵抗がなくなりました。
凄い人たちには微塵も及ばないけれど、なんとなく遊ぶ程度にはできるようになりました。

最近は業務寄りのシェーダーいじりしてます


ちなみに更にGLSLを学ぶなら


今から更にGLSLを学ぶなら、私は画像処理周りと数学的な部分を学ぶと思います。
(格子点、胞体、傍距、京都距離(マンハッタン距離)、ノルム、特徴点)
全然覚えてない……。

後、日本にもDEMOと呼ばれるシェーダーイベントがあります。ヤバい奴らがいます。
その人達の実況とか参考に勉強をすすめるかも?
tokyodemofest.jp

後、元ピクサーのやばい人のブログとかシェーダーが勉強になりそうです。
やべーシェーダーだって思ったらだいたいこの人w
twitter.com

あとはTwitterで #つぶやきGLSL で検索するといっぱいコードが出てきます。
短く書くことに特化したコードなのでちょっと読みづらいですが、読めれば勉強になると思います。

今は他のことに興味あり


シェーダーはシェーダーでも業務寄りに今は興味あります。
法線をイジったり、デプスとってきたりね。ポストエフェクトとか、VFXとか。

Unityまわりならかもそばさんの本とか参考になります。
zenn.dev

後、KENTOさんのも、いいかも。
zenn.dev

もちろんUnity公式でやってるのもめっちゃ参考になる。
(簡単なやつだとUnityJapanの公式動画が上がってたと思う)
特にKeijiroさんのは、やばばあばば。(Githubリポジトリも読もうね)
twitter.com

まとめ


個人的にあの処理ってなんだったっけって見返すことも多いので、今回書き出してみました。
これが、みんなのシェーダーのコードを学ぶ足がかりのコードになればいいなぁと思います。

以上、やまだたいしでした!

【備忘録】サブスタンスペインターの購入についてと使い方リンク集

こんにちは、やまだたいし( https://twitter.com/OrotiYamatano )です。
最近ゲーム用素材を用意するために3Dの作成の練習をしています。
今回はその時のサブスタンスペインターの使い方の知見を備忘録として残しておこうと思い記事化しました。

目次


サブスタンスペインターとは……?


そもそもサブスタンスペインターとは何でしょう?
それはAdobe社より出ている3Dのマテリアルを作成するソフトウェアです。(元々はAllegorithmic社によって作られたがAdobe社に買収された)
UnityやUEにも対応しており、ゲームエンジンでそのまま利用することが可能です。
ノーマルマップやテクスチャの生成が行なえます。
特にモデルに直接描き込むようにテクスチャーやノーマルマップのペイントが出来るのが魅力です。
また、大量のマテリアル素材が提供されているためソコも魅力です。

サブスクリプション型か買いきりか?


サブスタンスペインターの利用を考えた場合、
1ヶ月は無料で体験できるのですが、その後は買い切りでの購入かサブスクリプションサービスに入っての利用どちらかを検討することになります。

それぞれ利点がありますがそれぞれの特徴をあげておこうと思います。

買い切り

買い切りの場合はSteamより購入することになります。
また2024年末でSteamでの販売は終了するようです。
価格は約1万6千円。

store.steampowered.com

特に商用利用には制限はないのですが、自動アップデートは入らず、その年のバージョンしか利用できません。
また、サブスクリプション型に含まれるSubstance Sourceという大量のクラウドアセットにもアクセス権がありません。
しかしながら一度買ってしまえばずっと使うことが出来ます。
ちなみにハロウィン頃に少しだけ安くなるセールがあったりします。
ハロウィンセールはSteamでしなくなったのでウィンターセールあたりで割引してるかも?(知らんけど)

サブスクリプション

こちらは毎月または年に1回支払いが発生します。
法人と個人では利用料金が異なります。
(Substance 3D Texturingの場合)個人では月プランだと月に2398円
年間プランだと月に2235円ほど。
(※ドル円換算比率が変わると変わります)

www.adobe.com

こちらはサブスタンスペインターだけでなく、
マテリアルの素材(3Dアセット)を作れるサブスタンスデザイナーと
マテリアルとライトの作成が出来るサブスタンス3Dサンプラーも一緒です。

また、アセットのダウンロード(Substance Source)と毎月100GBのクラウドストレージもついてきます。
サブスクの料金を払い続けることで利用可能。
アセットについては一度ダウンロードしてしまえば永久に利用可能。

結局どっちが良いのか?


たまにしか使わないユーザーは買い切り、
本職はサブスク。

本職の方によると
買い切りだとアップデートできないから結果的にサブスクの方が安上がりだそうです。
またサブスタンスペインターを利用する利点がSubstance Sourceである部分も多いらしく、
サブスクのほうがお得らしいです。

ペイント機能のみが使いたくてマテリアルがいらないのなら買い切り、
マテリアルが基本的に欲しいならサブスクという感じが良さそうかなと個人的には思います。

(ハイブリットという方法もあるらしいです)
www.yamato-tsukasa.com

私は、基本的にセルルックな表現が好きなため、
マテリアルを大量に利用することはないと思ったので、買い切りにしようと思っています。

ベイク設定


テクスチャの影を焼き込むことが出来るが、私がよく使いそうな設定を貼っておく。(忘れそうなので)

ワイヤーフレームの表示


表示設定のメッシュのワイヤーフレームを表示のチェックを入れる

summering26.com

シェーディングToカラー


Baked Lighting Skyedのフィルタの追加(シェーディングをグレースケールに変換)

グラデーションマップ(Gradient)フィルターの追加で色合い調整

レイヤー統合


現状(2022/02/27)出来ないっぽい。
なので、一度テクスチャとしてエクスポートしてから、
ソレに対して処理をかけるようにするなどやり方の工夫が必要そう

ペンタブの筆圧が効かない?


Windowsの場合はWindows lnk(Windows公式のペンタブ認識機能)を使用することを想定して作られているので、
Windows lnkをOnにする必要がある。

Substance Painter トラブル:「筆圧利かない」Wacomタブレット – TNMCBlog

テクスチャをまとめるツール


summering26.com

余談


Substance painterのココが良い

・PBR対応のモデルが作成しやすい
・ベイクがいい感じに出来る
・3D上でのペインティングがやりやすい

Substance painterのココがムカつく

・ペイントソフトでは出来る切り取り貼り付けが出来ない(輪投げ選択などもない)
・バケツ塗りつぶしも無理
・マテリアル=UVになってしまう(Blender側で複数マテリアルをつかい、参照するUVは一つにしていてもマテリアルごとにテクスチャが生成されてしまう)
・マテリアル描画順が変更できない(DisplayOrder変更させてくれ)

使い方などを紹介してあるリンク集


使い方を良さげにまとめてくれてるサイトみつけました。
安心安定のmodelinghappyさん

modelinghappy.com

www.youtube.com

summering26.com

bookyakuno.com

www.take-model.com

まとめ


まだ私も触り始めた段階なので、随時記入し、もう少し内容を充実させたいです。

社内勉強会主催して3年目突入(社内Wikiを立ち上げました)

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) | Twitter )です。
社内勉強会を主催して2年経ったので振り返りをしていこうと思います。

↓去年の記事
orotiyamatano.hatenablog.com

目次


あれからどうなったのか


社内Wikiを立ち上げました。

具体的になんで、そういう流れになったのか色々ありますが、
とりあえず、現在の活動について書いていこうと思います。

現在やっていること


内容:座談会・LT会・ランチ会・飲み会
小規模の勉強会:6~15人(運営合わせて)
参加募集先:社内全員にメール(約250人)
運営:4人(+アドバイザー1人)
枠:40分昼休み時間(2週間にまたは1ヶ月に1回、水曜日)
場所:オンライン,Zoomでの開催(飲み会はgather)
スタンス:有志

正直勉強会の内容はあまり変わっていませんが、社内勉強会の運営メンバーの頑張る方向性が変わりました。
社内の勉強会というよりは、社内コミュニケーションの活発化にも力を入れて活動したり、社内Wikiの立ち上げを行ったりしました。

そもそも、どの時間帯に皆が参加したいのかを調べた


去年1月当初、勉強会への主催を続けるうちに参加者が限られてきており、マンネリ化してきました。
色々、試行錯誤はしたのですが、やはり大変です。

せめて皆が参加しやすい時間帯に主催してはどうかと思いアンケートをとりました。
すると、以外にも金曜夜参加がしやすい方が多かったです。
そこで、金曜夜などに主催時間を変えたりしましたが、集まる人は変わりませんでした。
というか、むしろ減りました。

アンケートに答えてくれたからといって、実際にその人が参加してくれるとは限らない、
建前だけで参加しないなどという本質的なところが見えてきました。

アンケートをするとしてもフラットな意見が言える状況でないとする意味がないなと痛感しました。
なので、結局会の主催はこれまでと変わらず、運営が主催しやすい水曜日での主催にするようにしました。

雰囲気作り


会への参加のモチベーションを上げるためには、「社員で知ってるメンバーが話している」や
「自分も参加したい(参加に憧れる)」「勉強したい」という内部的モチベーションが大事だと考えました。
そこで、いくつか考えて取り組んだりしました。
・座談会などの主催をテーマ化し、デザイナーメインの話になるようにしよう
・LTでほか事業部の人の話を聞けるようにしよう
・お昼に集まって気軽にランチをしよう
・知ってる人を増やすために自己紹介LTをしよう
などなど。
また新入社員研修中に時間を設けて貰って、参加呼びかけを行ったりもしました。

参加の意義


現在会の参加はスタンス有志&業務時間外となっており、
ぶっちゃけ、業務時間外での参加はしたくない人がほとんどだと思いました。
特に社内勉強会となると、参加メンバーによって勉強内容が偏ってしまう恐れがあります。

誰でも分かるような勉強会にしてしまうとそもそも勉強会に参加する意義みたいなのが薄れてしまいますし、
かといって、難しい題材にしてしまうと、ついていけなくなる人が増えてしまいます。
時間取って皆で勉強となると人によってスピードも違いますし、結構時間がかかってしまい勉強会の利点の他の方の意見を聞く時間が短くなってしまう難点です。
誰かが教えるとなると負荷が高いしもはやソレは授業。
その点、誰かが教える、プレゼンの練習にもなるLTは優秀ですが、参加者にスライドを作ってくるように促したり、スライド作ってくるのは、こちらもかなりの負荷……。

そこで、社員共通知識のベースとなる資料置き場の必要性があると思いました。
一応資料置き場的なものはあったのですが、一覧性や検索性が悪く、Wikiの構造になっていませんでした。

社内Wiki立ち上げ


そこで、社員共通知識のベースを築き上げることで社内の知識レベルの向上やコミュニケーションの円滑化につながると思い
社内勉強会運営が動き社内Wikiを立ち上げに動くことにしました。

そもそも、社内勉強会運営チームはモチベーションの根本として社内勉強会をしたいというよりは、
社内で技術を教え合ったりする文化がほしいというモチベーションを持っていたため、一旦会の主催を頻度を少なくして、
Wiki立ち上げに注力しました。

この時点では社内勉強会は会社からは半非公式的存在でWikiにお金を出してもらうためにどうすれば会社の経営陣を説得できるかが問題となりました。

社内Wikiの立ち上げにあたって何をしたのか


使用Wiki選定


会社を説得するにしても何が会社にとってベストか知る必要があると考え、
まず良さそうな情報共有Wikiサービスなどを調べました。

↓選定はこのあたり。
オンプレ
https://growi.org/ja/
https://pukiwiki.osdn.jp/
クラウド
https://esa.io/
https://kibe.la/
https://www.notion.so/
https://docbase.io/

判断基準
→オンプレか、クラウド
→サービスの料金
→使いやすさ

案として持っていけるように使用目的や運営方法などの具体化


大体決めたら、Wikiを立ち上げたとしてどのように運営していくかを決めました。
また会社から予算を請求するためにWikiにはどのような意義があるのかを纏め提案する必要があると思いました。
それらを決めつつ、
早い段階で、各上長に軽く相談してました。

そもそも、会社ではオンプレ機材の提供をしてくれるのか、
申請すればあっさりWikiを立ち上げさせてくれるのか、
そのへんも含めて知らないことだらけだったため、
情シスに問い合わせたり、環境開発基盤をよく担当してくれる事業部の方に聞いてみたりなどしていました。

ちなみに上司に投げた文章はこんな↓感じ

社内勉強会運営で情報共有ために社内勉強会をやっていたのですが、課題が出てきまして
> 1.知識を持っている人がこない
> 2.知識をある程度持ってる分野の話をしようと思っても、他社員の理解度がわからないため、どの程度のレベルの話をすれば良いのか分からない
という2つが出てきました。
そこで社内勉強会運営で話をして

皆が好きなタイミングで見られる資料などを作成し、
閲覧してもらえるようにして貰えれば、それベースに話が出来るので、
社内Wikiのようなものが作れば良いのではないかという話になりました。

情シスにサーバー利用が出来ないか相談した所、
> 情シスにはPCのストックはあるので上司を通し依頼はできる
とのことでしたので、デスクトップPCの使用申請をしてオンプレでwikiのようなサービスを入れて行いたいと思っています。

(上司の名前)〇〇さんに申請の方をお願いしたいです。

話が回り回ってクラウド上にサーバーを建てることに


技術選定したときにオンプレで行こうと思ったのですが、
情シスや環境開発基盤をよく担当してくれる事業部の方にPCの設定はできるが、
出社の必要があったり、人員コストのほうが高くつく可能性が出てきたため、
クラウド上にサーバーを立てて運用したほうが良いのではないかと指摘をうけ、
結果的に無料ではなく有料でクラウドサーバーで借りる方向で動く流れになりました。

(ちなみにここで相談にのってくれた方はコチラの記事で喋られてる方)
www.itmedia.co.jp

提案資料の作成


申請の問い合わせをしつつ、会社を説得するための資料の雛形をつくっていきました。

・運営は何人でやっていく予定なのか?
・記事、情報の更新ペースはどのくらいを考えているのか?
・どんな内容を更新しようと考えているか?
・今あるGoogleドライブでやっていくのは難しいのか?
・業務時間中にやっていくのか?
・業務時間内にやっていくなら従来の業務に影響が出ないか?
・年間費は?
・運営メンバーは情報を書いていくのか、書いてもらったものをまとめていくのかどちらに比重を置くのか?(運営メンバーのスタンスについて)
・情報を充実させるためにはできるだけ多くの社員に協力してもらう必要があると考えられるが、どうやって運営メンバー以外に情報を書いてもら予定なのか? 

最初資料は大まかに↓のような内容だったのですが、いくつか指摘をされました。

スライド
・サービスの説明
・やる理由
・なぜ有料か
・他社比較
・価格・今後の運用
・まとめ

指摘された内容は以下↓の通りです。経営陣はセキュリティに詳しくない部分もあり説得にはセキュリティ部分を詳しく分かりやすく書く必要性がありました。

・セキュリティの担保についての資料

どうやってセキュリティ担保するかはもっと詳細に書いてほしい

・なぜこのサービスを使うのかという妥当性についてもっと分かりやすく詳細に

無料サービスでは無理なのか 有料でやるとして他サービスと比べて具体的にどこがどういいのか料金比較表は必要

Wiki自体を導入する根拠については、現状に対する否定的な書き方が多かったのでもっと好印象になる書き方に変更

また、会社に提案する資料にWiki作成に社内Wikiを作成して欲しいメンバー一覧を書くことで需要があることを強調しました。
(事前に応援してくれる人たちをメールなどで募集)

なぜここまで慎重にことを進めたのか


ぶっちゃけ、予算としては月々(確か)6千円程度で大した額ではないのですが、
なぜ私が慎重になったのかというと訳があります。

それは事業部につかない予算申請となると会社としては少し慎重になります。
例外的な予算、つまりそれは、会社として例外的なお金の使い方を認めることになりますし、
だいぶ大々的に社内勉強会運営活動を認めることになります。

ちっぽけな予算ですが、0→1に活動を広げるためには大事な一歩になると考えたからです。

で、予算がおりた


資料を色んな方々にレビューいただき、経営層への予算取得も出来ました🎉

週に2回(会の主催があるときは週3回お昼が潰れる)お昼の時間に社内勉強会の会の内容を決めつつ、
Wikiの話し合いを進めていたため、資料作りや事前調査に数ヶ月ぐらいかけた気がしますが、なんだかんだ形になってよかったです。

説得に利用した資料に関しては、そこまで興味ないと思ったので詳細な内容は伏せますが、
とても興味深く自社でも立ち上げたいという無謀な方は、別途私が大事な部分を伏せた上で資料共有しますので、
Twitterなりで声をかけてくれればと思います。

声をかけてくれる人が多いようなら、ここでの共有も別途考えたいと思います。

Wikiセットアップをしていよいよ公開した


Wikiの使い方を運営で調べつつ、使用利用の社内ルールの策定などを行いました。
「この辺はぶっちゃけ会社がやってくれてもいいのになぁ」と思いながらも、かなり細かくルール決めなどを行った気がします。

WikiのReadmeを作成し、使い方の資料も用意して、社内勉強会の時間帯にWikiの使い方について共有を行いました。

定期的に使ってくれる人は一定数いるもののやはりまだ使い慣れていない感じがするので、
今後は書いてくれた人の資料を社内勉強会にて紹介したりする会を開ければいいなぁと思っています。

去年のまとめ


正直業務が忙しかったこともあり、Wikiを立ち上げるので精一杯でした。
試行錯誤の連続で会がうまく出来ているのかどうかも分からなくなってきてますが、会の主催の行動力などは経営層などから買ってくださってるように感じます。(知らんけど)
また、去年は政治的なコネの回し方など動き方を学べたいい機会だったと思います。

会社に社内Wikiを作れたのは良いことだと思うので今後も運用メンテ、執筆啓蒙活動、社内勉強会などなど頑張っていこうと思います。

今後の方針


ぶっちゃけた話、
かなり社内勉強会の運営が負荷になってきています。
運営活動3年目なのに未だに草の根運動をやってる感じがします。
息も絶え絶え。

また業務時間外だと共有資料の作成をしてくれる方が少なかったり、
会への参加もためらう人が少なくないように感じています。

ということで、今年は業務内活動として認められるようにまずは動いて
会議の時間帯を業務時間内に納められるようにしたいと思っています。

ちなみに既にジャブ打ちはしているのですが、結構好反応なのでなんとかなると思っています。

今年は運営負荷を下げるために頑張るぞ!!
以上、やまだたいしでした。

文系のためにプログラムの厄介さや設計の仕方を"文"で表してみる

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) | Twitter )です。
つくづくプログラムは読んでわかるように書かなきゃならないということを痛感しているのですが、
それには文系的なセンスが必要だと思っているので、それを言語化しようと思ったので本記事を書くことにしました。

目次


なぜプログラムはカオス化するのか


私は大体プログラムコードがカオス化するのは
最初に書いたコードが最初から悪いのではなく、
変更が重なりコードを付け加えられ続けた時、
つまり、思想がごちゃまぜになった時にカオス化すると思っています。

プログラムがカオス化するとは……?


このブログでは意味が理解しづらいコードの状態をカオス(混沌)化と呼んでいこうと思っています。
プログラムの変更をするとき、既存の意味合いを変えず、出来るだけ元のものを変更せずに書き加えることで修正が入ることが多いです。
なぜ既存の部分を変更しないかというと、変更後に処理の内容が変わってしまう危険性が伴うからです。
もちろん、動作を検証するためのテストなどもあったりするのですが、
まだ不完全で私が所属するゲーム業界では処理に時間も関係してくるため、まだ有用なテスト方法がなかったりします。

ちなみに世間一般的には、このような理解しづらくなってしまったコードを「レガシーコード」、「スパゲッティコード」、「ダーティーコード」などと呼んだりします。

カオス化する流れを文に例えて言い表してみる


例えば、

やまだたいしは目玉焼きにマヨネーズをかける

という文章をプログラムのコードに見立てた場合。

「あ、やっぱり、塩コショウ使うときもあるな」と気付き修正が加えられた場合は

やまだたいしは目玉焼きにマヨネーズをかけるが、塩コショウを使うこともある

という文章に内容が変わります。
先程も言ったようにプログラムは「出来るだけ元のものを変更せずに書き加えることで修正が入る」ことが多いためです。

これぐらいならまだ許せます。
しかし、「周りに合わせて醤油かけるときもあるな」と更に気づいた場合、

やまだたいしは目玉焼きにマヨネーズをかけるが、塩コショウを使うこともあり、周りに合わせて醤油を使うこともある

というように変更が加えられる場合が多いです。
こうなってしまうと中身の理解がしづらくなってしまいます。

更に「連続して同じ調味料は使わない」というような条件が入ったらどうなるでしょうか。

やまだたいしは目玉焼きにマヨネーズをかけるが、塩コショウを使うこともあり、周りに合わせて醤油を使うこともある。連続して同じ調味料を使うことはない

このような文章になってしまうと、もう何が言いたいのかわからないと思います。
はい。適当な変更が加わった結果、プログラム自体の意味を曖昧にし、理解しづらいものに変化させてしまうのだと皆さんお気づきだと思います。
つまり、プログラムが最初意図されたものと異なる状態になってしまうことが、いわゆるカオス化(スパゲッティコード、レガシーコード)と呼ばれる状態を引き起こしてしまうのだと私は考えます。

では、「既存の文章にも手を加え書き換えたら良いじゃないか」という意見があると思います。
私もそう思います。意味はそのままに書き換えること、人はソレをリファクタリング(リファクタ)と呼びます。

例えば、上の文章をリファクタすると以下のような文になります。

やまだたいしは目玉焼きを食べる時につける調味料はマヨネーズ、塩コショウ、醤油それぞれを状況に応じて使い分ける。調味料は連続して同じものは使わないが、気分によって変えることがあるし、周りが目玉焼きを食べているときは周りに合わせることもある。

スッキリしていますね。コレがコードが最適化された状態です。
最初から文章に必要な要素が分かっていた場合はこのような内容(文)で書かれる(実装)されると思います。
しかし、更に変更が加える必要が出た場合は文章全体を修正する必要が出てきます。
この状態をプログラミングでは結合度が高いと言います。

結合度が高くとも変更がなければ構わないのですが、
綿密に必要な要素を調べ設計しても最初から全ての要素が見えた状態でスタートが出来ない場合が多いです。
また、大規模案件ほど既存の出来上がってるものに対して手を加えるのが許されない場合が多いです。
では、どうすればいいでしょうか。

抽象的に組み立てる


プログラミングでは抽象的に組み立てることで、後からの変更を許容できるように作ることが多いです。
俗に言われるInterfaceや継承と呼ばれるものを利用します。

例として上であげた文章↓を抽象的に組み立てた場合どうなるでしょうか?

やまだたいしは目玉焼きにマヨネーズをかける

抽象化した場合↓

やまだたいしは目玉焼きを以下の調味料で食べる
・マヨネーズ

のようになります。
プログラムで言い表すと食事クラスから、食べ方クラスとして分離して、Interfaceとして実装し食べ方クラスを継承したマヨネーズクラスを定義したといえば良いでしょうか。

こうかけるなら、いくら調味料が増えても既存の文章を書き換えること無く調味料を追加することが出来ます。

やまだたいしは目玉焼きを以下の調味料で食べる
・マヨネーズ
・気分によって塩コショウ
・周りに合わせて醤油

このように書き換えることを「関心の分離をした」と言ったりします。
「じゃあ、全部抽象化してしまえば、プログラムにいくらでも変更が加えられていいじゃないか!」と思う方がいるかも知れませんが、それはソレで「凝集性」が失われてしまうため危険です。

分離されすぎたコード


抽象化されすぎたコードがどのように危険か具体的にピンと来ない方もいると思うのでここでも文で言い表してみます。
また↓の文章を抽象化し過ぎた例を紹介しようと思います。

やまだたいしは目玉焼きにマヨネーズをかける

この文章を抽象化し過ぎた場合は以下のようになります。

1の人物は2の食べ物を3の調味料で食べる
1→やまだたいし
2→目玉焼き
3→マヨネーズ

どうでしょうか?
複雑性が増し上と下の文章を見比べる回数が増え、理解に時間がかかってしまい冗長な内容になってしまったように感じませんでしょうか?
コレをプログラミングでは凝集性が下がった状態と呼びます。

つまり、プログラミングで抽象した実装をする場合、
最初から「だいたいこの辺が変更が掛かりそうだ」と理解している箇所を抽象的にすることでコードの変更を少なくすることが可能になってくるということです。
変更がかからない箇所を不用意に抽象化してしまうのはあまりいいことではありません。

適切な変更手順


とはいえ最初から変更箇所は予測できません。
では、どのようにクラスに対して変更をかけていけば良いでしょうか?
私はこのような順番で変更がかけられると良いと考えます。

やまだたいしは目玉焼きにマヨネーズをかける

やまだたいしは目玉焼きにマヨネーズをかけるが、塩コショウを使うこともある

↓ この時点で「まだ増えそうかも?」と予測することができるので抽象度の高い書き方に書き変えられます。

やまだたいしは目玉焼きを以下の調味料で食べる
・マヨネーズ
・塩コショウ

やまだたいしは目玉焼きを以下の調味料で食べる
・マヨネーズ
・気分によって塩コショウ
・周りに合わせて醤油

というふうに順序を追って変えられると良いなと私は考えます。

つまり定期的に構造を見直し、リファクタ、クラス設計の変更を行っていくことが大事。
考えなしに内容を変更し続けてしまうと、既存の内容が理解できない状態になってしまい、プログラムも変更できない状態になってしまいます。
エンジニアからリファクタしたいと要望が入ったときにはもう既に遅く、既に理解しづらい状態になっていると思われます。
そもそもエンジニアは日々リファクタをできる状態なのが適切であり、
理解できる状態のうちにプログラムをリファクタしクラス設計を変えることが大事だと私は考えます。

リファクタをしたいという要望が入るということはプログラムがカオス化している&日常的に書き換えが許されていないということなので、改めたほうが良いと思います。
もし、エンジニアからリファクタしたいと要望が入ってしまった場合は「運用をしないプロジェクト」かつ「プロジェクト後期」なら、もうリファクタを諦めて作りきってしまうことをオススメします。

ちなみにゲームはレイヤードアーキテクチャを採用しないことが多いですが、
ウェブのようにソレ以外に作りようがないという場合が少ないため
そのような実装になってしまいます。

もしレイヤードアーキテクチャを採用するならUIなどの部分が一部採用できるかなと思います。

プログラムを変更することの大変さ


文系の方に設計などを理解してもらうため書いてみましたが、コレで大変さが少しは理解してもらえたのなら嬉しいです。
エンジニアの方に対して、機能変更として変更してほしいという場合は、一行だけしか変えてないのに凄い時間がかかる場合があります。
それは文章でいうと、小説の中で前後関係を全て理解した上で文章に違和感ない一文を追加するようなもので、
いわゆる伏線など不整合が起こらないように読み返したり、適切な文章を考えたりしているため時間がかかってしまう状態なのです。

抽象度の高い実装をしている箇所なら、書き加えるだけで済む場合もありますが、
そうではない場合、大規模な変更を強いられることもあります。

この文章を見ているアナタがクライアントなら少し多めにみてやって欲しいと私は思います。

まとめ


思いつきで文でプログラムを表すことが出来るのではないかと思い書いた内容でしたが、案外書き表すことが出来驚きました。
プログラミングは数学的要素を問われるため理数系と捉えられがちですが、
今ある既存の内容を言語化し理論整然とした内容に書き換え文章化するという意味では、かなり文系要素が多いと私は考えます。
理数系だからプログラムが得意だとか文系だからプログラムが苦手とかそういうのはないと個人的には思います。

このブログが少しでも文系エンジニア(プログラマ)の助けになれば良いなと思います。
以上、やまだたいしでした。

2021年の振り返りと2022年の抱負(ポエム)

今年もよろしくお願いします。2022年がやってきました!
こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) | Twitter )です!
2021年、忙しくは無かったはずなのに、もはや何をしたのか思い出せません。
本記事では何をしたのか振り返り、今年は何をしていくのか考えていこうと思います。

去年の記事

orotiyamatano.hatenablog.com

目次


振り返り

初登壇


技術的なことは何も言えませんでしたが、初登壇しました。
何事も思い切りだとは思うが、もう少し練習しておけば良かったなぁ。

社内勉強会主催


今年も社内勉強会を去年に引き続きやっていました。
それ関連で社内Wikiも立ち上げました。
会社にWikiを使うための説得をして会社の費用を捻出させました。
絶賛稼働中。去年一番頑張ったこと。
詳しい内容は別途勉強会のふりかえりの記事を書こうと思います。

orotiyamatano.hatenablog.com

小学生ぶりに歯医者行った


虫歯に生まれて初めてなりました。
怖くなって最近ではしっかり歯磨きしてます。

後、ついでに歯並びの矯正をはじめました。
歯並びが悪いと虫歯になりやすいとも聞くし、歯並びが良くなって悪いことはないだろうと思い決心したんですよね。
歯並びがちゃんと良くなるまで2年半かかるらしいですが、今のところ順調です。
(時々出血したりして痛いけど……)

歯がガタガタでスペースがない場合、フェイスラインを良くするためには、単純に並べ直すだけではなく、歯を抜いてあげないといけないというのには驚きました。
そうなんですね。

障害者手帳をもらった


世の中には障害者って書くな!
障がい者 or 障碍者って書けよ」ってうるさい人も居ます。
「障害者の人は障害者言われると嫌なのかもなぁ?」って思ってましたが、いざ障害者になって分かりました。
心底どうでもいい。

エヴァみた


放映版エヴァ、旧作劇場版も履修済みだったので、どうなるかと思ったのですが、綺麗に終わりましたね。
個人的に衝撃的だった。

物申しツイートってバズりやすいんだろうなって思った


はい。

姉貴が死んだ


4月に姉貴が死んだ。コロナとかじゃなく、病気。
長くはないと思ってたけど3月時点では後3年は生きると思ってた。
近年身内が死にすぎて私の精神が死にそう。
2親等以下の身内が5年連続で死んでる。

母方と父方の爺さんそれぞれと、母親、姉貴ふたりが死んだ。
2親等以下は親父だけになってしまった。

7年前くらい前、母親、姉貴ふたり、父親で爺さんの米寿を祝った。
その時の家族で笑っている写真が今、実家の食卓に飾られている。
「もう既に過去になってしまったんだなぁ」としみじみする思いと日常の中で家族の記憶が薄れていく恐怖のような虚無感のようなものに苛まれる。
これが寂しさというものなのだろう。

いとこは生きてるけど、私は連絡先も持ってないし関わりは薄い。
実質、父親が死ぬと私は実質身寄りがない状態になってしまう。
こう何年も連続で身内が死んでいると、「その場合、私のアパートの保証人は誰になるのだろうか」などと変に冷静に考えてしまう。

↓姉貴にリプしたツイートとか

色々学ぶ


シェーダーとかFMODとか、Blenderとか、アフィニティデザイナーの使い方とか色々。

コンシューマー開発


詳しく言えないですが、どちゃくそ頑張ってます。

バーに行ったり


人生で初めて1人でバーに行きました。
色々お酒を飲んだりして嗜むことを増やしました。

振り返りまとめ


2021年、ツイートを振り返ると何だか精神的にまいって、お酒に頼りきりになってるなと思いました。
酒は好きだけど、このままじゃ良くないなーと思ってます。
かといって、仕事も自分の夢も頑張り続けられるほど、愚直にもなれない。
何かいい気晴らしでも作りたいなと思いました。

後、個人的には創作活動が例年と比べて出来ていないのが気になりました。

2021年目標達成度


去年の目標に対してどのぐらい達成できたでしょうか。

去年の目標は
・何かしらゲームをリリースする
でした。

出来たのか?

全く出来ませんでした。(またか)
正直、自分で目処を立ててちゃんと、毎日進捗出すのがこんなに大変だとは思いませんでした。

一日あたりできる時間は大体1時間半なのですが、
昨日以前のことを振り返って、作業が波にのるまで、かなりの時間がかかることが分かりました。
そうなると、なかなか厳しいですね。

息抜きをちゃんとして集中できるようにした方がいいのかも知れません。

2022年の目標


今年も目標をたてて生きたいと思います。
今年の目標はコチラ!
・ちゃんと筋トレする
・本を読む
・映画を30本以上観る
・緩く恋活していく
・何かしらゲームをリリースする

詳しい内容について述べていこうと思います。

ちゃんと筋トレする


緩く続けていた筋トレですが、最近リモートワークが続き贅肉が増えてきたような気がします。
一人でやっていると手抜きがちになってしまうため、今年は目標立ててしっかり筋トレしていきたいと思います。
早速、パーソナルトレーニングの体験の申込みをしてみました。

本を読む


去年は創作活動をしていくなかで色々余裕がなく全然やれていなかった割には創作活動が進まなかったので、
息抜き方法などが悪かったのではないかと推測。
息抜き案として読書を選定。
いい息抜きになるといいなぁ。とりあえず青空文庫あたりを攻めていきたい。

映画を30本以上観る


こちらも息抜き関連。
後、ゲーム制作関係者は意外と映画を見ているという発見があったので、私も負けじと見たいと思ったからです。
感想とかをブログに書いていけたら良いですね。

緩く恋活していく


婚活、実は続けてたんですが、ひどく消耗しては放置という繰り返しでした。
辞めてしまうと一生女性とは関わりが持てないような気がするので、精神耐性を上げるためにも緩くでいいから続けていくことを目標にします。

何かしらゲームをリリースする


はい。今年は本気ですよ。
いや、去年まで本気じゃなかったわけじゃないですが、今年は本気も本気。本年度の会社での目標設定にしたぐらいには本気です。
作るジャンルも何か決めたし、大したものを作ろうとせず、プライドなんか持たず完了を目指していこうと思います。
もくもく会にも積極的に参加していきたいと思います。
頑張るぞ~~~!!

まとめ


去年はこれといって目立った活動が出来なかった気がするので、今年は振り返った時に楽しかったと言えるようにしたいと思います。
気が重いことがほぼなくなったので、今年は忙しくなる気がするぞ!
面白いこと挑戦して生きたいですね!
今年もよろしくお願いします!
以上、やまだたいしでした!

【アドカレ】ゲーム業界とIT業界の違い

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) | Twitter )です。

本記事はUnityゲーム開発者ギルドアドベントカレンダーの22日目の記事です。

adventar.org

今回はゲーム業界とIT業界の違いやゲーム業界の現在についてです。

目次


なぜ、ゲーム業界とIT業界の違いを書こうと思ったのか


ゲーム業界は現在中途募集はスマホ関連以外、大体がゲーム業界経験者を募集しているところが多い気がします。
つまり、ゲーム業界人として現在活躍している人の殆どが根っからのゲーム業界人である場合が多いです。
しかしながら、私はIT業界を2年半経験し、その後ゲームプログラマーとして4年ほど働きました。
つまり、ゲーム業界もIT業界もそこそこ知る珍しい人間。

これは私の知識を披露しないと勿体ないと思ったので本記事を書くことにしました。
ちょっとポエミーな記事になってしまうかもしれないですが、ご了承いただきたいです。
IT業界のことを忘れないうちにIT業界とゲーム業界の違いや現在のゲーム業界について語っていきたいと思います。

前提


何を語るにもゲーム業界、IT業界どちらに、どの程度足を突っ込んでいたか話しておく必要があると思います。
ゲーム業界とIT業界の違いを語る前に私の経験をざっくり書きます。

私: 現在28歳

IT業界に就職後システムエンジニアとして、
受託開発で、共済金システムや治験薬配送システムなどを作り、
部署異動してSIerとして客先常駐で某コンビニポイントサービスのスマホアプリの設計とか、
◯電力会社の土地の管理システムとかのシステム改修を行っていました。
なので、クライアントサイドからサーバーサイド、客対応までやった。
言語はJavaPHPなど。後フロントサイドもやったのでJavaScriptとHTMLも少々。
後、謎ツール(?)のMagic Unipaasとかも使える。

その後、転職しゲーム業界に入る。
言える範囲では
スマホのゲームアプリのクライアントサイドのUIとか、
コンシューマーゲーム(棋士藤井聡太の将棋トレーニング)とかに携わる
いわゆる中規模~大規模の間のデベロッパー会社
ちなみにUnity、UE4どちらも業務経験あり。
得意なのはUnity。

IT業界とゲーム業界の違い


早速違いについて書いていこうと思います。

1.資料について


IT系:資料作成は必須。納品資料であったりもする。
ゲーム系:資料はあるけれど結構適当

IT系では口酸っぱく資料作成しろと言われます。
炎上系案件では資料が存在しないこともザラだが、何かしら仕様書や要件定義書、DB設計書などが作られます。

ゲーム系に来て驚いたのは仕様書に相当するものが無いことです。
確かに仕様書と呼ばれるものはあるのだけれど、詳細には書いておらず、こういう動きにして欲しい、
などと書いてあるばかりで、システム系ならば少なくとも画面ごとに存在しそうな仕様書が存在しないです。
強いて言うなら、要件定義書に近い仕様書がゲーム系では存在しています。
しかも、会社ごとにフォーマットもあまり無いようで、好き勝手に書いてあることが多いです。

(もちろん、システム系にもフォーマットはない場合が多いが、大体が画面ベースで画面設計書が存在する、ゲームにはない場合も多い)
DB設計書もゲーム会社では見たことがない。(もちろん、内部では作ってあることがあるが、型名など厳密なものを見たことがないという意味)

2.フレームワークについて


IT系:言語ごとに様々なframeworkが存在
ゲーム系:ライブラリはあってもframeworkは殆どない

IT系ではシステム系でもフレームワークは無い場合が多いが、Web系では必ずと言っていいほど、フレームワークを利用します。
Springframework、Zendframework、BootStrapなどなど……。
しかし、ゲーム系ではライブラリは存在するが、frameworkはほぼ全くと言っていいほど存在しないです。
O/R Mapperでさえ海外の怪しいライブラリか有志が作ったものぐらいしかないです。
特に、ソシャゲなんかはタップして画面遷移みたいな流れが多いのでframeworkが少なくとも会社独自のものが存在しているのではないかと思いましたが、
そこそこ大きい会社にも関わらず存在していない場合が多いようです。(もちろん作ってあるところもあるがそういったところは技術力があるところ)

3.設計について


IT系:結構厳密に定義
ゲーム系:ほとんどどない。

ゲーム系にはframeworkが無いと聞いて嫌な予感がした人がいるかも知れない。
frameworkどころかしっかりした設計思想もないようです。
もちろん、個々の技術者はある程度の設計理念を持っていることが多いが、プロジェクト単位で統一といったことをしないため、
あちらこちらにプログラムが散乱してしまっているのが現状のプロジェクトが多みたいです。

4.仕様書を書く人について


IT系:上級SE(エンジニア)が書く
ゲーム系:プランナー(非エンジニア職)が書く

IT系において、仕様書は俗に言う上級SEが行います。
しかし、ゲーム系ではプログラマーが仕様書を書かないし、テストもしないです。
プログラマーは本当にコードを書くだけ。

じゃあ、誰が仕様書を書くのかと言うと、プランナーです。
プランナーはディレクターから要望を聞き、こうなったら面白いんじゃないかと想像しつつ詳細を仕様書に書くことになります。
もちろん、プランナーはプログラムは出来ないので、粗のある仕様書が出来ます。
プログラマーは随時プランナーに確認をしつつ、ある程度補完してプログラムを完成させることになります。

普通のIT系では設計書書く人が偉く、設計書が間違っていても、毎回お伺いをたてて作ることになります。
例え仕様書に矛盾が発生していても仕様書書く人が正と言えば正になることが多いです。

ゲーム系は逆でプランナーには権力がなく、作るプログラマーが偉く扱われる場合がほとんどです。
なので、仕様書をかいたプランナーはプログラマーから責められる……。
もちろんプランナーはプログラムを書いたことがないため、デザイナーからも責められ、ディレクターからも責められ大半が可愛そうな目にあう事が多いきがします。
話が逸れるがプランナーを目指す人はドMが良いと個人的には思う。
プランナーは、いわゆるバンド演る人で例えると「当方ボーカル他募集」のような美味しいところばかりをやりたがりプログラムもデザインも出来ない人がなる場合が多いです。
(超マレに総てに挑戦し実現したが自分が出来ることに限りがあると悟りプランナーを目指す人がいるらしいと聞いたが見たことがない)
それもあってかゲーム業界ではプランナーを軽視する人は少なくないとかなんとか……。
それも相まってか、若干酷く当たられるし、楽観的では叩き潰されてしまう。鬱になって辞める人も少なくないと聞きます。

私としては「どれも出来ないのにプランナーを目指すなんて、どうしてわざわざ修羅の道を……」という気がしてなりません。
とは言いつつもディレクターに化けれる人も居るので、プランナーになってからプログラムを勉強したりして付加価値をつけれる人は強そうだと思いました。

5.テストを行う人


IT系:エンジニアが行う
ゲーム系:テスター(デバッガー・QA)&受け入れ先が行う

IT系において、テストはSEが行います。
お硬い案件ではエビデンスと称して、意味のないテスト結果をスクリーンショットを残し、エクセルに貼り付ける作業を行うことになります。
IT系のSEは自分でテストを行うことを嫌い、自動化出来るようにだんだんとしてきている。
テストをプログラムでするなどは日常茶飯事です。

しかしながら、ゲーム系では(小規模案件なら自分たちでやるが)特に大規模なところでは、テスター(デバッガー・QA)を雇うことが多いです。
プランナーの仕様書とプログラマーが示してきたチェック観点を元に想像しながらゲームをプレイし、チェックリストを淡々と消化していく形になります。
チェックリスト自体は残す場合もあるが、こなした証拠などは残さないことが多いです。(バグ洗い出し様に稀に動画を撮っておくことがあるぐらい?)
このテスターはゲーム好きだが、プランナーにもプログラマーにもデザイナーにも慣れなかった人がなる場合や、一時のアルバイトがなる場合があるので、
一番扱いが酷いし、バックレ率もかなり高いです。(可哀相)

ゲーム系においてそうやって役割分担されている場合が多いように感じます。
テストにおいてはゲーム業界はすごく工数を気にしない節があるように感じます。(もちろん全く気にしないというわけではないがIT会社よりは気にしていないように思う)
そもそもゲーム自体がバグが出ても人死や破産する人は出ないからかもしれないです。

個人的には工数のムダがかなり多いので、ゲーム業界にもテストがもっと導入されればいいのになと思っています。

6.知識のインプット


IT系:人によって様々。ウェブ系は結構流行に敏感
ゲーム系:ウェブ系と比べると遅い。特にコンシューマーは遅い

IT系にも知識が古いところは少なくないです。特に業務系アプリケーションなどは既存アプリを変更するのを嫌がる方も少なくないです。
Web系はかなりの最新技術をキャッチアップしている方が多い気がします。海外の記事を読み自らもコーディングをします。
しかしながら、ゲーム系は(特にコンシューマー)は開発年数が長く5年などザラです。
開発するのもゲームエンジンが対応してからのことが多いため、キャッチアップが総じて遅い印象があります。
そもそもゲーム系の場合は技術を学びたくてゲームをつくるのではなく、ゲームを実現するために技術を学ぶので総じて受け身の様な印象があります。

7.エンドクライアント


IT系:パソコンもまともに使えない方がクライアントだったりするので納期や価格に厳しい
ゲーム系:デベロッパーの場合はパブリッシャーという同じゲーム会社が顧客になるため事情に比較的優しい

コレばかりは場合にもよるが、オタクで構成されているからか、IT系の場合は非エンジニアクライアントである場合がおおく、
業務用語は愚か賃金や工数に対しても渋い人が少なくない様に思います。
ゲーム業界の場合パブリッシャーはゲーム業界の厳しさをわかっており、どのぐらい工数がかかるのか温度感をわかっている場合も多く比較的要望が通ることがあります。
(もちろんおかしな事を言う人もいるが。)
IT系だとサービス提供が遅れることは大きな問題になるがゲーム系ではさほど大きな問題にはならないというのもあるのかなと個人的には思います。

8.客対応について


IT系:エンジニアも駆り出されることがある
ゲーム系:ほとんどエンジニアが駆り出されることはない。駆り出されてもプランナーなどの企画職

これは会社の規模感にもよるとは思うが、前職のとあるサービスを作っていたとき私は電話番をさせられていました。
忙しい日では部署に10件以上の電話がかかってきて対応を迫られました。
やれPCが壊れただの、やれエクセルが変だのこんなのエンジニアがすることじゃないという面倒まで見させられた。
部署を移動した際は電話番が無くなったが、相変わらず客先に対して窓口業務をするエンジニアが必要でした。
ゲーム業界では一切エンジニアが対応しなくても良いという訳ではないが、基本的に技術的観点や工数観点から意見を求められるだけで、
折衝経験を積むようなことにはならない様子……。

9.スーツについて


IT系:カジュアルなところは必要ないが、結局フォーマルな場があったりするので一着は必要だったりする
ゲーム系:一着も必要ない

ゲーム系は面接でさえもスーツじゃなくていいです。
私は転職活動のときスーツで行動していましたが、ご丁寧にどうもと言われてしまいました。
スーツで対応するのは人事の人ぐらいのようです。
ウェブ系でもスーツを着なくてもいい場合はありますが客先対応の場合はスーツを着る場合もあります。
ゲーム業界では着ている方が不自然のようです。

ゲーム業界に入って感じていること


長くなりますが語ります。

ゲーム業界は特異な人が多い?


結構エンジニアが好き勝手やっててのびのびしているのですが、給与は少ないような感じがします。
実際良い給料を貰っているのは大手パブリッシャーさんだけだと思います。

正直IT系から転職する際に給料は減りました。
大手パブリッシャー>大手スマホデベロッパー>コンシューマーデベロッパ
ゲーム系は目指すのが難しい割に給与は割りに合わないです。
それなのに目指す人がその職につきます。となると全体比率で奇特な方が多い気がします。

開発の流れが古い?


売れないとお金にならないというのもあると思いますが、全体的に無駄が多い気がしています。
仕様の策定や開発の流れが洗練されていないように感じました。

また、ゲーム業界はソフトウェアを作りきりで保守してきた経験がなかったがゆえに、テストや依存性が少ないコードの書き方に慣れていない様に感じました。
スマホゲームが浸透し始めてようやく足並みが揃った感ある気がしています。

ちょっと昔までは、自社エンジンベースのシステムが多く、
システムも作りきりのものが多い時代でした。
社外には情報を出さず、秘匿化し資産として運用する時代。

しかしながら、スマホが入ってきた時に時代が変わりました。
スマホなんかゲームじゃねぇ!と高をくくっていた人たちも今はほとんどがスマホゲームを作っている現状です。
スマホゲーム市場が出来たての頃はゲーム業界の参入が少なく、普通のシステムも作っているIT系の人たちの参入してきたのが多い空気感があります。
ウェブ系は自分の知識となるものは共有し業界全体を盛り上げるとともに、自信の技術力をアピールする文化があります。
ゲーム業界は真逆でした。
そのお陰かスマホバイスに特化していたUnity界隈は現在割りと情報共有が多い様に感じます。
UE界隈の共有も無いわけじゃないですが、スマホなんかゲームじゃねぇと高をくくっていた人たちが手を出したゲームエンジンだからか若干、情報共有が薄いような気がします。
(そもそもどこまでコードについて言及していいか分からないというのもあるとは思いますが……)

ともかく、何が言いたいかというと未だにゲーム業界は情報共有の流れが薄いんじゃないかという話です。
せっかくゲームエンジンが皆同じものを使うようになり、人員の流動性が増したのに
共通の知識を共有する文化が薄いのは勿体ないと感じました。

誰しもが分かるようにコードを書いてライブラリ化したり、するのもいいでしょう。
とにかく人にコードを見せる時代が来たのだから、わかりやすいコードを書くように心がけるようにして欲しいです。
今は機器性能面も上がってきており、極端に速度に特化し分かりづらいコードを書く必要はなくなってきました。

今後ゲーム業界は作りきりの時代ではなくサブスクリプションでゲームを提供する時代に変化していきます。
運用保守に特化したプログラムや開発の流れを行う必要があります。

IT系の世界開発標準にPMBOKというのがあるんですが、
PMBOKには見積もりの方法とか色々載っていて、日本の国家資格にも参考にされる
教科書的な由緒あるものなんですが、ゲーム開発もIT系に追従する節があるので注目したい所です。
IT系ではPMBOKが最近大幅改変されたのでチョットした騒ぎになっている。

それに追従するならゲーム系も大きく働き方が変わってくる。
何がどう変わったかと言うと、ウォータフォールベースで何をどうやれば開発できるよと言った手順書の様な内容だったのが
大幅に改変され開発する上で気をつけるべきことみたいな内容になってアジャイル、ウォータフォール関係ない内容に変わり、本の重さが重量が2kgから800gに激減したそうです。
つまり、アジャイルに内容が書き換わったという感じです。

アジャイルの根本思想
agilemanifesto.org

プロセスやツールよりも個人と対話を、
包括的なドキュメントよりも動くソフトウェアを、
契約交渉よりも顧客との協調を、
計画に従うことよりも変化への対応を、
価値とする。

つまり、断続的に開発するように考えられるようになった。
とすると、初めからコンテンツが全部そろっていない物が売られるのが一般的になりそう。
今でも分作やアップデートでの配信が増えてきていますが今後はその流れが加速化しそうっていうのが見て取れるわけですね。
そうなるとパッケージ買いきりじゃなく、
サブスクリプション型が主流に移ってくるのかなって考えると
クラウドゲーミングが相性が良い。
ニンテンドーサブスクリプションクラウドゲーミング取り入れ初めてますが、戦略の布石としてはすごく正しいなって思います。
因みにいま遊べるものでクラウドゲーミングで良さそうなのはXBOXクラウドゲーミング。
japanese.engadget.com

今後、ゲームを遊べるサブスクリプション型のストアが主流になってくる可能性もある。
だって、昔はDVDも買うだけだったのが、レンタル出てきて、
今はネットでのサブスクリプションサービスが主流です。
ゲームもそれに追従しないわけがない。
クラウドゲーミングの利点は処理が別の所にあるので、
FullHDの映像とコントローラーの情報だけリアルタイムに通信出来るようになれば
レンダリング処理が手元の端末で要らないという所。
つまり、スマホで遊ぼうが、ゲーム機で遊ぼうが通信速度さえ担保できれば体験が変わらない。
5Gでその流れが加速化するでしょう。

しいて追従出来ないのではないかという懸念点もあります。通信環境が整っていないような国があることです。
PCの様な高スペックのものを買うことも出来ないような国は
低単価で動作が保証されているコンシューマが未だに根強く売れているそうです。

そういった懸念がありつつも、サブスクリプションが主流になれば開発も断続ないし継続的になるでしょう。
ゲーム業界のエンジニアにはGoToがなぜ駄目なのかがわかっていないエンジニアも少なくないです。
そう言った現状を私は変えたいです。
一歩一歩情報共有し共にいい環境でいいゲームを日本から発信できるようにしていきたいですね。

まとめ


なんか、余計な話をメインで語ってしまったように思いますが、アドカレでもない限りこんな話は書かない気がしたので話題にあげさせてもらいました。
ゲーム業界以外ではゲーム業界は残業ばかりと思われている節があります。
現在働き方改革含めゲーム業界は変わってきています。(ちなみに私の先月の残業時間は一桁です)
勤務時間は減り、在宅ワークが定常化してきました。弊社も在宅ワークが定常制度として認められました。
今後変わりゆく中で日本ゲーム業界も変わっていかないと海外には絶対追いつけなくなると肌身に感じています。

弱小な私がいうのも何なんですが、皆さん頑張っていきましょう!
以上!やまだたいしでした。