■ [作業履歴][unity]カメラ・デプステクスチャ関連
カメラをスクリプトから制御することで、デプステクスチャや、デプスと法線をセットで焼きこんだものが生成できる
Camera.depthTextureMode 変数を使って、カメラのDepth Textureをスクリプトから有効にすることが出来ます。
二つの使用可能なデプステクスチャモードがあります:
•DepthTextureMode.Depth: Depth Texture です。
•DepthTextureMode.DepthNormals: デプスおよびビュー空間法線がひとつのテクスチャにパックされています。
UnityCG.cginc include file にはヘルパー関数DecodeDepthNormal があり、デプスおよび法線をエンコードされたピクセルの値よりデコードします。戻されるデプスは0から1の範囲です。
デプスや法線テクスチャの使用方法については、Shader Replacementのサンプルプロジェクトのエッジ検出イメージエフェクトあるいはSSAO Image Effect を参照して下さい。
Shader上で深度値を取得する方法
・Shader上の処理
深度バッファ値を格納してあるテクスチャー情報を取得する。
そのためには以下のようにShader用のグローバルな固定変数がある
sampler2D _CameraDepthTexture;
sampler2D _CameraDepthNormalsTexture;
■ [作業履歴][unity]ポストフィルタ関連
ポストフィルタの最小のサンプルに近いものは、Edge Ditection(Color)
ソースも短いので読みやすい
これとSSAOを合わせて読めば、だいたいのフィルタは書けそう
基本はImageEffectBaseクラスを継承して、シェーダーを割り当てるだけ。割り当てるシェーダーはデフォルトのものでも通る。
SSAOのスクリプトより
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
[AddComponentMenu("Image Effects/Screen Space Ambient Occlusion")]
EditModeでも動く、Cameraコンポーネントを自動で取得、メニューに追加
GlobalFogを参考に、とりあえずデプスからワールド座標を再計算
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
public class TestFilter : ImageEffectBase {
public float threshold = 0.2F;
private float CAMERA_NEAR = 0.5f;
private float CAMERA_FAR = 50.0f;
private float CAMERA_FOV = 60.0f;
private float CAMERA_ASPECT_RATIO = 1.333333f;
void OnEnable () {
camera.depthTextureMode |= DepthTextureMode.Depth;
camera.depthTextureMode |= DepthTextureMode.DepthNormals;
}
// Called by camera to apply image effect
void OnRenderImage (RenderTexture source, RenderTexture destination)
{
CAMERA_NEAR = camera.nearClipPlane;
CAMERA_FAR = camera.farClipPlane;
CAMERA_FOV = camera.fieldOfView;
CAMERA_ASPECT_RATIO = camera.aspect;
Matrix4x4 frustumCorners = Matrix4x4.identity;
float fovWHalf = CAMERA_FOV * 0.5f;
Vector3 toRight = camera.transform.right * CAMERA_NEAR * Mathf.Tan (fovWHalf * Mathf.Deg2Rad) * CAMERA_ASPECT_RATIO;
Vector3 toTop = camera.transform.up * CAMERA_NEAR * Mathf.Tan (fovWHalf * Mathf.Deg2Rad);
Vector3 topLeft = (camera.transform.forward * CAMERA_NEAR - toRight + toTop);
float CAMERA_SCALE = topLeft.magnitude * CAMERA_FAR/CAMERA_NEAR;
topLeft.Normalize();
topLeft *= CAMERA_SCALE;
Vector3 topRight = (camera.transform.forward * CAMERA_NEAR + toRight + toTop);
topRight.Normalize();
topRight *= CAMERA_SCALE;
Vector3 bottomRight = (camera.transform.forward * CAMERA_NEAR + toRight - toTop);
bottomRight.Normalize();
bottomRight *= CAMERA_SCALE;
Vector3 bottomLeft = (camera.transform.forward * CAMERA_NEAR - toRight - toTop);
bottomLeft.Normalize();
bottomLeft *= CAMERA_SCALE;
frustumCorners.SetRow (0, topLeft);
frustumCorners.SetRow (1, topRight);
frustumCorners.SetRow (2, bottomRight);
frustumCorners.SetRow (3, bottomLeft);
material.SetMatrix ("_FrustumCornersWS", frustumCorners);
material.SetVector ("_CameraWS", camera.transform.position);
material.SetFloat ("_Treshold", threshold * threshold);
Graphics.Blit (source, destination, material);
}
}
hader "Custom/TestShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Treshold ("Treshold", Float) = 0.2
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
sampler2D _CameraDepthNormalsTexture;
uniform sampler2D _CameraDepthTexture;
uniform float4 _MainTex_TexelSize;
uniform float _Treshold;
// for fast world space reconstruction
uniform float4x4 _FrustumCornersWS;
uniform float4 _CameraWS;
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
float2 uv_depth : TEXCOORD1;
float4 interpolatedRay : TEXCOORD2;
};
v2f vert( appdata_img v )
{
v2f o;
half index = v.vertex.z;
v.vertex.z = 0.1;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
o.uv_depth = v.texcoord.xy;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y = 1-o.uv.y;
#endif
if( v.vertex.x == 0 && v.vertex.y == 0 ) {
o.interpolatedRay = _FrustumCornersWS[3];
}else if( v.vertex.x == 1 && v.vertex.y == 0 ) {
o.interpolatedRay = _FrustumCornersWS[2];
}else if( v.vertex.x == 1 && v.vertex.y == 1 ) {
o.interpolatedRay = _FrustumCornersWS[1];
}else if( v.vertex.x == 0 && v.vertex.y == 1 ) {
o.interpolatedRay = _FrustumCornersWS[0];
}
//o.interpolatedRay = _FrustumCornersWS[(int)index];
o.interpolatedRay.w = index;
return o;
}
half4 frag (v2f i) : COLOR
{
//half4 original = tex2D(_MainTex, i.uv);
//return original;
half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv.xy);
float depth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv)));
float4 wsDir = depth * i.interpolatedRay;
float4 wsPos = _CameraWS + wsDir;
return float4( wsPos.xyz, 1 );
}
ENDCG
}
}
}
■
天地明察の4巻が出てたので買ってきた。自分もいつまでも中途半端な状態から抜けられないのでじわじわくる。光国伝も知らないうちに漫画化されてるらしい。原作と漫画のどっちを読むべきか
最寄りの本屋は大きくて本棚の数も多いんだけど、無機質で見て回るのがなんだかあまり楽しくない。冊数は少ないのに、引っ越し前によく言ってた小さなマンガ専門店のほうが欲しいと思える本が多かったように思う。引っ越してからあまり漫画を買わなくなった一因になってる気が
一時期見た事が無いものに触れて、新しいものを理解することが億劫に感じるようになってて、これはマズいと思ったので最近は意識して新しい漫画やゲームを買うようにしてる。日々を過ごすのに手一杯で好奇心が摩耗するのは怖い。そういえば最近は映画もあまり見に行ってない。行かねば。