12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Unity]シェーダでテクスチャを張る

Posted at

VRChatのおかげでシェーダについていろいろ教わったのでとりあえず記録
もし自作シェーダを作りたい人がいたらその人の参考になれるように

しかし猫並みの脳なので間違ってることも多いと思われます

まず初回はテクスチャを張ってみます
#シェーダの作り方#
次の章でコードについて触れるので知ってたら飛ばしてください~

1.まずunityのProject欄で右クリック
2.Create → Shader → UnlitShader をクリック
1.png

これでシェーダ(unlit)が完成
2.png

次にテスト用にシェーダと同じようにマテリアルを作成
3.png
4.png

このままだとこのマテリアルのシェーダはStandardなので さっき作ったシェーダをマテリアルにドラッグ&ドロップ
右のInspectorの上のほうにShedarがあるので そこがStandardではなければ完成
5.png

##テスト##
6.png
マテリアルに髪の毛のテクスチャを入れてキューブやスフィアに適用しました
テクスチャが表示されているので ちゃんとできてます

#コード#
長くなりましたがコードを見てみましょう

Shader "Unlit/unlit"
{
	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
		}
	}
}

けっこうC言語の形があるので 知らない場合は少し勉強してみてもいいかも(構造体とか関数の形とか)
昔知りたかったこととかをゆる~く解説します

(もっと詳しくてわかりやすいサイト様)

Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた
Unity Shader まとめ
Unityのシェーダーまとめスライドを作ってみた

##シェーダの名前##

Shader "Unlit/unlit"
{

ここは このシェーダがさっきのInspector上でどのように表示されるかです
Unlit/  はどこに分類されているかを表していて
unlit  というのがこのシェーダの名前になっています
7.png

名前は最初にシェーダを作った時の名前になります
自分は unlit という名前で作った後、 Shader_unlit という名前に変えたため unlit となっています

##Inspector上での変数##

Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}

ここはInspector上で値を変更したり、テクスチャを追加するときに使います
_MainTex がこの変数の名前
"Texture" がInspector上で表示される名前
2D  がこの変数の種類
= から右側が初期値となっています(たぶん)
8.png
(自分はInspector上で値を変えることが多いのでこれからたくさん出てくるかもしれません...)

##シェーダ内部##

SubShader
	{
		...
		Pass
		{

ここはPass内に処理を書いていくぐらいの認識しか...
複数の処理をするときにPassを何個か書きます
詳しくは上のURLの凹みさんやリファレンスを参照してください

Tags { "RenderType"="Opaque" }
		LOD 100

Tagは結構重要なのでいつか記事で書きます 多分

LODとはLevel of Detailの略でレベルの低いハードウェアでは表示させないみたいな認識...?
あんまり使わないしわからないです;;
詳しくはリファレンス! Debugging DirectX 11 shaders with Visual Studio シェーダ LOD

CGPROGRAM
...
ENDCG

ここからシェーダの処理を書いていく ~ 処理終わり みたいな宣言です

#pragma vertex vert
#pragma fragment frag

頂点シェーダやフラグメントシェーダを使うときに書きます
vert が頂点シェーダ使うときの名前になります(fragはフラグメントシェーダの)
これを変えるときは関数の名前も変えましょう

FOGはいま勉強中です...

#include "UnityCG.cginc"

シェーダで使う関数などまとめて書かれています
そのほかいろいろ定義されていたり

##構造体や変数##

struct appdata
{
	float4 vertex : POSITION;
	float2 uv : TEXCOORD0;
};

構造体です C言語をやったことがある人はなんとなくわかるかもしれません
いろいろな変数をまとめておくみたいな

この構造体ではUnityからどのような値をもらってくるかを宣言しています
たとえば float4 vertex : POSITION; は
float4 vertex にローカル座標の値を入れるみたいな

struct v2f
{
		float2 uv : TEXCOORD0;
		UNITY_FOG_COORDS(1)
		float4 vertex : SV_POSITION;
};

もう一つの構造体です
これは頂点シェーダで決めた値をフラグメントシェーダに渡すときに使う箱ですね

初心者の時に一番知りたかったこととして v2f が謎だったんですが ただの vertex to fragment だったんですね
変えても大丈夫なので読みにくい人は変えましょう()

sampler2D _MainTex;
float4 _MainTex_ST;

Propertiesで宣言した変数を使いたい場合はここらへんで宣言しときましょう

##頂点シェーダ##

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;
}

これが頂点シェーダですね
appdata型の変数を受け取って v2f型の変数を返す(さっき定義した構造体)
構造体を作って それぞれの変数に値を入れて returnしてます

UnityObjectToClipPos : 同次座標において、オブジェクト空間からカメラのクリップ空間へ点を変換します。これは、mul(UNITY_MATRIX_MVP, float4(pos, 1.0)) と同等に使用されます。(リファレンスより)
TRANSFORM_TEX : 使うテクスチャ(_MainTex)とのuv座標を関連づける

##フラグメントシェーダ##

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;
}

これがフラグメントシェーダです
処理としてはtex2Dを行ってその値をreturnしてます

そしてそのreturnする対象ですが : SV_Target と書かれてます
これはセマンティクスと言って返す対象をきめます
種類については Unityのシェーダーセマンティクスまとめ 様で

最初はセマンティクスはこのまま覚えればよいと思います あとその型がfixed4なのも

受け取る構造体は v2f型 で名前を i としています(初心者なりの注意としては i なのでfor文使うときに二重に宣言しないように)

tex2D については vertでテクスチャとuv座標を関係づけているので それに合わせて色を塗る みたいな
詳しくは Unity Shaderの基礎 part 2

#終わりに#
はじめてQiitaを書くテストとして書きました
とても長くて見にくいと思います;;

自分もまだまだ初心者なので間違ったことを書いていたら教えていただければ光栄です

次記事を書くとしたら ランバート反射 と Propertiesの例 を書きたいですね

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?