読者です 読者をやめる 読者になる 読者になる

げぇむぷろぐらみんぐ

日々の生活で得た知識、経験を書きます

OpenGL(GLSL)のvarying,attribute,in,outについて

OpenGLのストレージ修飾子(inとかoutとか)についてです。

これもあんまりまとまった記事がなさそうだったので自分用メモ

前の記事同様OpenGL学び初めたばかりで、しかもネットの情報のみという浅い知識しか持ち合わせていないので、間違いがあったら教えてもらえるとうれしいです。

OpenGL2.x系では、頂点属性の定義はattributeを付けて行っていました。

また、バーテックスシェーダからフラグメントシェーダに内容を渡したいときはvaryingをつけて宣言を行っていました。

↓多分こんな感じ(バーテックスシェーダの例)

attribute vec3 position;
uniform vec4 color;
varying vec4 vColor;

void main() {
vColor = color;
gl_Position = position;
}

しかし、OpenGL3.0以降ではattribute,varyingは使用されなくなりました。

attributeはinに置き換え、varyingはinとoutに置き換えされるようになりました。

以下に例を示します。

OpenGL3.0以降のバーテックスシェーダの例

#version 150 core

in vec3 position;
in vec3 normal;
in vec4 color;
uniform mat4 mvpMatrix;
uniform mat4 mMatrix;
out vec3 vPosition;
out vec3 vNormal;
out vec4 vColor;

void main() {
vPosition = (mMatrix * vec4(position, 1.0)).xyz;
vNormal = normal;
vColor = color;
gl_Position = mvpMatrix * vec4(position, 1.0);
}

OpenGL3.0以降のフラグメントシェーダの例

#version 150 core
precision mediump float;

out vec4 fragment;
uniform mat4 invMatrix;
uniform vec3 lightPosition;
uniform vec4 ambientColor;
uniform vec3 eyeDirection;
in vec3 vPosition;
in vec4 vColor;
in vec3 vNormal;

void main() {
vec3 lightVec = lightPosition - vPosition;
vec3 invLight = normalize(invMatrix * vec4(lightVec, 0.0)).xyz;
vec3 invEye = normalize(invMatrix * vec4(eyeDirection, 0.0)).xyz;
vec3 halfLE = normalize(invLight + invEye);
float diffuse = clamp(dot(vNormal, invLight), 0.0, 1.0) + 0.2;
float specular = pow(clamp(dot(vNormal, halfLE), 0.0, 1.0), 50.0);
fragment = vColor * vec4(vec3(diffuse), 1.0) + vec4(vec3(specular), 1.0) + ambientColor;
}

 

上記のように、バーテックスシェーダのattributeはinに置き換えられました。

また、varying変数は、バーテックスシェーダ側にout,フラグメントシェーダ側にinと修飾子を付けて、変数名を同名にするようになりました。

 

OpenGLの記事は古いものも多いので、そういった古い記事のシェーダを読むときに知っているとすんなり理解しやすいのかなと思います。

OpenGL2.x系とOpenGL3.0以降の違いでもう一つ大事そうなのは、テクスチャマッピングをする際のビルトイン関数texture2Dが、textureという名前になっているのとかがあります。

他にもなんかありそうですが、僕は今のところ困っていないのでわからないですw

 

関係ないですが、色や法線情報のinとoutの前にflatっていう修飾子をつけると、ラスタライザでの線形補間を行わなくなるみたいで、結構面白いです。

flatなし

f:id:siguma_sig:20170425203010p:plain

flatあり

f:id:siguma_sig:20170425203037p:plain

まだまだわからないことだらけですが、毎日少しずつ理解できているような…気がします。そうだといいな。

OpenGLでテクスチャマッピングをする際の注意点

最近、ふと思い立ってOpenGLを使って簡単なゲーム作れるくらいの知識はつけておきたいな〜と考えて勉強しているのですが、いかんせん日本語の情報が少なく、あったとしてもかなり古いものであり、今とはだいぶ違ったりしていて大変です。

そんな感じでさぐりさぐりやっているわけですが、せっかくなので自分用のメモとしてハマったところをメモっておきます。

 間違っていたら何かしらの方法で教えてもらえるととっても喜びます…!

 

OpenGLテクスチャマッピングをする際には大体以下のような感じになるかと思います。

GLuint tex;
//テクスチャオブジェクトの生成
glGenTextures(1, &tex);

//テクスチャのバインド
glBindTexture(GL_TEXTURE_2D, tex);

//画像の読み込み
cv::Mat img = cv::imread("texture0.png", cv::IMREAD_UNCHANGED);
//BGRAからRGBAへ変換
cv::cvtColor(img, img, cv::COLOR_BGRA2RGBA);

//テクスチャにデータを紐付ける
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.cols, img.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE,
img.data);

//テクスチャユニットを指定
glActiveTexture(GL_TEXTURE0);

//テクスチャをバインド
glBindTexture(GL_TEXTURE_2D, tex);

//指定したユニット番号をシェーダに送る
glUniform1i(uniLocation[6], 0);

 

画像の読み込みに関しては、いまいち何を使うのが良いのかわからなかったのでとりあえずOpenCVのimreadを使用しています。

実はここでもハマりました…(OpenCVがBGRAの順なのを完全に忘れてた…)

これで描画できる!やった!!!と思って実行したらなぜか真っ黒に…

その後色々調べて

glGenerateMipmap(GL_TEXTURE_2D);

これを、テクスチャにデータを紐付けたあとに呼んでやればうまいこと描画されました。

このとき僕は、glTexImage2Dの第二引数でミップマップ使わない設定にしてあるから呼ばなくていいはずなのに…って思ってました。

でもこれ、呼ばないとだめなんですね。

理由は、テクスチャパラメータのデフォルトの指定が、ミップマップを使うものになっているから。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

どうやら縮小の際の設定のデフォルト値が上記のようになっているらしい。

これのせいで、ミップマップを生成しないと、生成されていないミップマップを読み込みに行ってしまい、真っ黒になってしまうみたいです。

つまり、ミップマップを生成する必要が無いなら、先にテクスチャパラメータを指定してしまえば、glGenerateMipmapを呼んでやらなくてもうまく表示されるわけです。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

よって、上のような設定をテクスチャオブジェクトごとにしてやればおっけーです。

テクスチャパラメータの指定はどうやらテクスチャオブジェクトごとにするようなので、その点だけ注意が必要ですね。

多分これで、うまく描画出来ると思います。

 

正直全く自身がないので、本当に間違っていたら教えてもらえるとうれしいです…

あと、参考にする方がもしいれば、間違っていても構わないという気持ちでお願いします。

部内Unityハンズオンした話とその資料

12/10と12/14で二回、同じ内容で部内Unityハンズオンしました。

その資料の公開と、感想について書きます。

 

コンピュータ倶楽部NITMic(トップ | NITMic - 名古屋工業大学 コンピュータ倶楽部)では、定期的に部員同士で主にゲーム制作に関する講座(プログラミング、デザイン、作曲など)や紹介を行っています。

今回は、僕が学祭後で時間が有ったのと、3年生はもう部活動は引退なので後輩に知識を伝えて行きたかったので、企画しました。

ちなみに僕はハンズオンというものに参加したことがないので普通はどんな感じにやるのかわからなかったです…

まあ、資料見ながら手を動かしてもらえれば良いかなと思って今回はやってみました。

 

具体的な資料は以下です。

github.com

対象としては、部内の人で聞きたい人は誰でもということにしましたが、プログラムの知識がある程度ないとソースコードで一部理解しづらいところがあったかもしれません。

内容としては、Unityにおける3Dゲーム開発の基礎が出来るようにということを目標に作成しました。

各ウィンドウの説明から始まり、プリミティブの作成、マテリアルの作成、Prefabの作成…と続いていきます。

基本的には、目次を見てもられば何があるのかはわかるかと思います。

 

今回この資料を作成するにあたって、まず何で作るか悩みました。

そこで我が部の元部長に相談して、Githubならマークダウンで書けるしソースコードのハイライトもできるし、公開しやすいよと教えてもらってこうなりました。

実際やってみた感じ、すごく作りやすかったので感謝しています。

 

また、内容として何を含めるかも悩みました。

正直どこまで話せば良いのかもわからなかったですが、僕がUnityを触り始めたときに知っていたら良かっただろうなという知識を詰めたつもりです。(ショートカットキーとかも)

 

やってみた感じとしては、まあ大まかには理解してくれたかなといった感じです。

ハンズオン自体は6時間程度で終わったのですが、その後も残って自分独自のゲーム性や機能を追加している子もいました。

これでUnityに興味を持って、面白いゲームを作ってくれる子がいれば幸いです。

 

資料については、結構作るのに時間が掛かったので、せっかくだし公開しようと言った感じです。

正直、間違いや非常にわかりづらい部分(Animatorの章とか…)があると思いますがある程度まとまってはいると思うので、Unityやってみたいけど中々手を出せない方とかは一度目を通してもらえると嬉しかったりです。

 

こんな感じで部内で需要があれば今後も何か資料作ったりして、外部にも公開していきたいです。

 

VisualStudioCode(VSCode)でUnity開発をする際のフォーマッターの設定方法

備忘録として書いておきます。

VSCodeを使ってUnityで開発を行う際に、通常の状態だとスクリプトをフォーマッターがご丁寧に以下のようにしてくれます。

 でも、僕としては下のような感じでフォーマットして欲しかったわけです。

 

ずっとやり方がわからなかったのですが、Facebook上のUnity助け合い所にてほぼ同様の質問があり、そこの回答のおかげでわかったので、メモとして残しておきます。

以下のやり方はMacOSにおける方法です。

が、Windowsの場合もディレクトリ等が変わるだけかと思います。

そもそも、Windowsの人は本家VSを使えば良いような気もしますが…

 

まず、この設定を行うには二つの方法があります。

  1. slnファイルが存在するところに、omnisharp.jsonファイルを作ってそこに設定を書く
  2. VSCode上の拡張機能のOmnisharp(C#)のフォルダ内にあるconfig.jsonに設定を書く

僕は、常に先程の例の下のような感じでフォーマットをしてくれればよいと思っているので、今回は2の方法を選択しました。

人によっては、会社のプロジェクトの規約や一緒に開発する人に合わせるために、フォーマットのスタイルをUnityプロジェクトによって変えたい場合があるかと思うので、1の方法を選択したほうが良いかもしれません。

 

どちらも記述する内容は同じで、場所が違うだけなのでここからはそれぞれで読み替えて下さい。

2の方法を取る場合、/Users/ユーザ名/.vscode/extensions/ディレクトリ以下に、ms-vscode.csharpといったようなフォルダがあると思います。

その中の、bin/omnisharp/config.jsonを編集します。

僕は以下のように設定しました。

こうすることで、先程のコードでいう下のようなフォーマットにすることが出来ました。

細かい設定等は僕自身もまだ分かっていませんが、スペースを挿入するかどうかなども細かく決めれるらしいので、気になる人は調べてみて下さい。

 

部活動の引退と学祭で作ったゲーム

なんとなく記事が書きたくなったので、書きます。

つい先日行われた名古屋工業大学の工大祭で、僕が所属していたコンピュータ倶楽部NITMicは、毎年恒例のゲームセンターブースを展示しました。

ゲームセンターブースでは、コンピュータクラブの部員が作ったゲームを展示し、実際にお客さんに来ていただいて遊んでもらい、フィードバックを頂く、と言ったことを行っています。

個人的に、うちの部活で最も大事にしている(少なくとも僕は)イベントで、毎年たくさんの面白いゲームが出来ています。

今年は、全部で20を超えるゲームが作られました!

その中で僕は、BalloonCoins!という2~4人対戦のゲームを作りました。

 

このゲームは、ごくごく単純で、空中に散らばるコインを自分のキャラクターを操作しながら集めて、一番多く集めた人の勝ち!というルールです。

ゲーム的な要素としては、まず、操作が風船の浮上とキャラの移動しかないため操作感が独特であるという点があります。

あとは、相手の上からぶつかることで相手の風船を割ると同時にコインを落とさせ、奪うことができるという点があります。

僕がこのゲームを思いついたときに一番重視したかったのが二つ目の奪い合いという点でした。

結果的に、工大祭のアンケートで、いい感じに友情が破壊できそうなゲームでした。とかコイン無視してお互い倒し合っていた。と言った感想が貰えたので、それなりに達成できたのかなと思います。

 

さて、僕達3年生は今年の学祭でコンピュータ倶楽部は引退となってしまうので、このBalloonCoins!が最後の作品であったわけです。

その割に、ゲーム自体ものすごく単純で、作ること自体もそこまで難しそうでなかったため、単純だねとか、3年のくせに作ってるもの簡単そうとか思われたかもしれません。

ただ、僕は1,2年次の学祭での経験から出来る限り多くの人に遊んでもらいたかったら、

なるべく単純で、かつ、多人数で遊べるようなものが良いことを学んでいたので、今回はこのようなゲームを作りました。

 

学祭では、毎年お客さんからのアンケートを集計して、人気ゲームトップ3が発表されます。

結果的に、僕のゲームは今年も3位以内にランクインすることはできませんでした。

また、今年の1位はぼうバトという、2人プレイの格闘ゲームでした。

これはものすごいことで、基本的にうちの部活のアンケートは4人組のお客さんなら4人ひとりひとりに書いてもらうため、例年1~3位は4人プレイ用のゲームが占めていました。

また、格闘ゲームというプレイする敷居が高めのゲームで1位ということが偉業でした。

ただ、部内でのデバッグ期間でも最も遊ばれていたゲームはぼうバトで、僕もとてもおもしろいと思っていました。

 

なんにしても、また負けてしまった上に、自分が考えていた学祭で勝つためにはこういうゲームでないといけない!という前提が覆されてしまったため、とても悔しかったのと同時に、改めて面白いゲームを作る、お客さんに楽しんでもらえるものを作ることの難しさを感じました。

ぼうバトは、製作者も言っていましたが、初心者はガチャプレイでも楽しめて、上級者は極めることができるゲームでした。

インターン中のゲーム制作でも、上手い人と下手な人の差が出る部分は大事だということは言われて、学んでいたので、それをしっかりと表現してるのがぼうバトなのかな、と思いました。

 

部活動も引退になり、以前にも増してさらに自由な時間が増えたので、今後は後輩に対して技術を教えていったり、自分で自信を持って面白いと言えるゲームを作れるように日々技術力と、アイデア力を磨いていきたいです。

 

久しぶりに文章書いたらめちゃくちゃまとまりなくなってしまった上にものすごく時間がかかってしまった…

結局何が言いたかったかというと、面白いゲーム作るのは難しい!でも楽しい!それだけです。

 

nitmic.club.nitech.ac.jp

【2016夏】サマーインターン感想(コロプラ、GREE、サイバーエージェント)

ブログを作って、記事を書こうとしたのは良いものの、特にまだ書くようなものもなく…

せっかくなので、今年の夏のインターンの感想を書き残しておこうと思います。

どこまで書いていいものなのか分からないので、もしだめな内容があればこそっとメッセとかで教えてください…m(_ _)m

 目次

 株式会社コロプラ

内容

5DAYS REAL WORK -GAME- という、ゲームジャム形式のインターンに参加しました。

ほぼ名前の通りで、5日間で、エンジニア3人 + 社員デザイナーさん1人 + 社員エンジニアさん1人で、1本カジュアルゲームを制作するという内容でした。

開発環境は、Unity C# + Git にて開発を行いました。

感想

個人的に一番悔しかったインターンでした。

インターンの途中で、悔しくて泣いてしまいそうにもなりました。

そう思えるくらい一生懸命になって取り組める内容のインターンで、5日間とは思えないくらい充実していて、たくさんの思い出が残りました。

また、ゲーム制作に対する姿勢が大きく変わるようなインターンだと思います。

技術面についても、初対面の人達と、どう制作を進めていくかという練習にもなるし、Unityのさらなる学習にも繋がりました。

また、意外とUnity自体をあまり触ったことのない人や、ゲームをあまり作ったことがない人が多くいる印象でした。

社員さんがチームに入って制作のお手伝いをしてくれて、現場のデザイナーさんの絵でゲームが作れて、困ったらいつでも現場のエンジニアさんがサポートしてくれるという環境がとても良かったです。

おまけ

VRゲームハッカソンが12/3(土),12/10(土),12/11(日)の3日間かけて行われるそうです!

be-ars.colopl.co.jp

グリー株式会社

内容

GREE Campというゲームジャム形式のインターンに参加しました。

期間は2日間で、エンジニア1人+クリエイター1人+ビジネス/ゲームプランナー1人で、1本カジュアルゲームのモックを制作するという内容でした。

開発環境は、エンジニアはUnity C# でした。

感想

とにかく開発時間が短い!!!!!です。

色んなコンテンツを用意してくれているので、実質的な開発時間は8~9時間程度です。

普段から1dayハッカソンとかに参加しているので、作業時間の配分などは分かっていたつもりでしたが、完全に失敗してしまいました。

メンターさんについては、非常に人数が多かったような印象があります。

あと、ひたすら気にかけてくれていて、質問したり、ゲームの内容に関しての相談がとってもしやすかったです。

技術面についても、いくつか新しいことにもトライしてみたので、個人開発の2日間とは比べ物にならないくらい成長できたかなと思いました。

あとは、社員さんと普段やってるゲームがほぼ同じだったりで、お話がすっごく盛り上がりましたw

おまけ

GREE Campは、8月,9月,10月と開催回数が多く、また冬以降にも開催されるそうなので、是非是非!

jobs.gree.net

株式会社サイバーエージェント(株式会社アプリボット)

内容

 WORKという就業型インターンに参加しました。

期間は1ヶ月で、関われるプロジェクトは60以上!(だったはず)の中から、自分に最も合いそうなプロジェクトを人事さんとの面談や、現場の社員さんとの面談ですり合わせながら決めて、実際にそこで働くというものです。

期間についても、7月頭~9月末の中で好きな期間1ヶ月程度で、とても参加しやすいと思います。

僕は、子会社の株式会社アプリボットで、新規ゲーム開発プロジェクトに参加しました。

開発環境はUnityC# + Git でした。

感想

ひたすら学べる1ヶ月間でした。

技術に関してはもちろん、現場の開発がどのように行われているか、プロジェクトの人数はどれくらいなのか、環境はどんななのか、ということがはっきりとわかりました。

もちろん、これは会社やプロジェクトによってまちまちではあると思いますが、一つの指針ができただけでも非常に大きいと思います。

技術力に関しても、自分が本当にまだまだであるということが実感でき、どこが足りないのかということもはっきりと感じることができました。

あとは、現場の社員さんに自分の書いたコードを見てもらって、アドバイスをもらって…というのがとても新鮮で、非常に勉強にもなりました。

実際、このインターンに行く前と行った後の自分のコードを見比べるとだいぶ変わっている(ような気がする)。

他にも、ランチに連れて行ってもらったり、社内勉強会にも行ったり、ゲームを一緒にしたりとすっごく楽しかったです。

おまけ

秋、冬も長期インターンはまだまだやっているようです!

また、長期にかかわらずサイバーエージェントは非常にインターンが多いので、

是非どうぞ〜!

www.cyberagent.co.jp

www.cyberagent.co.jp

まとめ

どのインターンに参加しても、絶対に損はないと思います!

自分と同じ世代でこんな凄い奴がいるのか…とか、もっと技術力があれば…という経験をして、これからのモチベーションにも繋がると思いますし、横の繋がりも広げることができます。

まだまだ秋、冬のインターンもあると思うので、バシバシ参加していきましょー!

 

 

 

(全く関係ないですが、名古屋でもできそうなゲーム開発のアルバイトとか、お仕事あれば紹介してほしいです…)