イラスト、モデリング、Unity、VR関連

unityとかblenderとかvr関連の作業メモ

unity shader テクスチャの値をそのまま取得する方法

++テクスチャ作成C#コード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class OutTest : MonoBehaviour {
	int _Size = 512;
	Texture2D GetTexture2D(){
		Texture2D tex = new Texture2D(_Size,_Size, TextureFormat.ARGB32, false);
		Color c = new Color(0,1f,0,1f);
		//Color c = new Color(1f,0,0,1);
		for(int x=0;x<_Size;x++){
			for(int y=0;y<_Size;y++){
				tex.SetPixel(x,y,c);
			}
		}
		return tex;
	}

	void Start () {
		Texture2D tex = GetTexture2D();
		tex.SetPixel(0,0,new Color(1f,0,0,1));
		tex.Apply();
		byte [] testPng = tex.EncodeToPNG();
		string dirPath = EditorUtility.SaveFolderPanel("Save Texture", "", "");
		string fp = dirPath + "/test_tex.png";
		File.WriteAllBytes(fp,testPng);
	}

	// Update is called once per frame
	void Update () {

	}
}

これでuv座標(0,0)にのみ赤を、それ以外が緑のテクスチャが出来る。 出来たテクスチャを以下の設定にする

TextureType=>Sprite
wrap Mode=>Clamp
FilterMode=>Point
にして、テクスチャサイズは2の乗数倍である必要あり(多分)

f:id:arumogina:20191103114153p:plain

 

 

 

以下のシェーダで色を取得

Shader "Custom/Base" {
	Properties{
		_MainTex("MainTex",2D) = "white"{}
	}
	SubShader{
		Tags{"RenderType"="Opaque" "Queue" = "Geometry"}
		//透明部分のあるテクスチャを使う場合
		//Tags{"Queue" = "Transparent" "RenderType" = "Transparent"}
		//Blend SrcAlpha OneMinusSrcAlpha

		Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

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

			struct v2f {
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
			};

      float4 _MainTex_ST;
      sampler2D _MainTex;
			float4 _MainTex_TexelSize;

			v2f vert(appdata v){
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}

			float4 frag(v2f i) :SV_Target {
				float w = _MainTex_TexelSize.x;
				return tex2D(_MainTex,float2(0,0));
			}
			ENDCG
		}//Pass
	}//SubShader
	FallBack "Diffuse"
}
    

これでテクスチャのピクセルごとの素の色を取得出来る (0,0)以外のピクセルを取得したかったら_TexelSize*xという風に指定する テクスチャの設定をしないと、周囲の色と混ぜられた色になったりする。

 

注意

Texture2DでARGB32のテクスチャ生成してSetPixelで色をセットするとき、アルファ値を0にしてテクスチャを出力して、画像設定を2D,clamp:pointにしてtex2Dで読むと、float4(0.804,0.804,0.804,0)ぐらいの値を返すっぽい。これはテクスチャ生成時にrgbにどんな値を入れてても同じ。なので、アルファ値には0.01とかでもいいから何か数値を入れておく方がよい。