Scriptによるレンダーテクスチャへの数値書き込みについて
以前に投稿した波動方程式を用いた波紋の作成という記事内のScriptにおいて、SetPixelによりR=0.5、G=0.5のレンダーテクスチャを作成しました。ただ、少し気になることがあり調べてみました。
問題点
GetPixelによって レンダーテクスチャの色を調べたところ0.50196・・・という数値が出てきました。そこで、Unityのドキュメントを見てみると”この関数の機能はARGB32、RGB32、Alpha8のテクスチャフォーマットのみに対応しています。”と記載されていました。つまり、SetPixel(0, 0, new Color(0.5f, 0.5f, 0.5f, 1))は8ビット(0~255)の内で一番近い数値(128/255=0.50196・・・ )へ自動的に変換されているようです。確認のために以下のScriptとShaderを作成し、実行してみました。
script
作成したScriptは以下の通りです。レンダーテクスチャへSetPixelを用いてColor(0.5f, 0.5f, 0.5f, 1)を書き込んだのちに、レンダーテクスチャの色をDebug.Logで出力しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GenerateGrayTexture : MonoBehaviour { public Material mat_gray_tex; private RenderTexture rTex; private int TextureSize = 256; // Start is called before the first frame update void Start() { rTex = new RenderTexture(TextureSize, TextureSize, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default); Texture2D texBuf = new Texture2D(1, 1); texBuf.SetPixel(0, 0, new Color(0.5f, 0.5f, 0.5f, 1)); texBuf.Apply(); Graphics.Blit(texBuf, rTex); Texture2D tex = new Texture2D(rTex.width, rTex.height, TextureFormat.RGBAFloat, false); RenderTexture.active = rTex; tex.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0); tex.Apply(); Debug.Log(tex.GetPixel(0, 0).ToString("f6")); } } |
実行結果
上記Scriptの実行結果は以下の通りです。
0.501961となり、128/255がレンダーテクスチャに書き込まれていることが分かります。
解決策
テクスチャへ目的の数値を書き込めるようShaderの作成及びScriptの変更を行いました。
Shader
作成したShaderは以下の通りです。RGBA=(0.5,0.5,0.5,1.0)を出力するだけのShaderです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
Shader "Unlit/GenerateGrayTexture" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; 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); return o; } fixed4 frag (v2f i) : SV_Target { float4 col; col.rgb = 0.5; col.a = 1.0; return col; } ENDCG } } } |
Scriptの変更及び結果
テクスチャの作成部分を変更し実行してみました。mat_gray_texは上記Shaderを割り当てたMaterialです。
1 2 3 4 |
Texture2D texBuf = new Texture2D(1, 1); texBuf.SetPixel(0, 0, new Color(1.0f, 1.0f, 1.0f, 1)); texBuf.Apply(); Graphics.Blit(texBuf, rTex, mat_gray_tex); |
結果は以下の通りです。
0.5が書き込まれていることが分かります。また、以下のように変更しても
1 2 3 4 5 |
RenderTexture buf = RenderTexture.GetTemporary(rTex.width, rTex.height, 0, RenderTextureFormat.ARGBFloat); Graphics.Blit(rTex, buf, mat_gray_tex); Graphics.Blit(buf, rTex); RenderTexture.ReleaseTemporary(buf); |
同様の結果となり、目的の数値をレンダーテクスチャへ書き込むことができました。
参考サイト
-
前の記事
ワールド座標でテクスチャの合成 2019.10.25
-
次の記事
キャラクターの移動とカメラコントローラー 2019.11.23
コメントを書く