Skip to content

Instantly share code, notes, and snippets.

@HarukaKajita
Created September 16, 2021 22:35
Show Gist options
  • Save HarukaKajita/ac0909450fff16eb05cb6ee18353bd7f to your computer and use it in GitHub Desktop.
Save HarukaKajita/ac0909450fff16eb05cb6ee18353bd7f to your computer and use it in GitHub Desktop.
P行列関係の詳しい内容を学びつつ座標変換後の座標の値域検証したシェーダー
Shader "Unlit/MatrixTest" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_X ("X", range(0,1)) = 0
_Y ("Y", range(0,1)) = 0
_Z ("Z", range(0,1)) = 0
_W ("W", range(0,1)) = 0
}
SubShader {
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;
float4 posCS : CLIPPOS;
float4 posOS : OBJECTPOS;
float4 posVS : VIEWPOS;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _X;
float _Y;
float _Z;
float _W;
float4 TransformClipToNDC(float4 posCS){
float4 ndc = posCS * 0.5f;
float4 ret;
ret.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
ret.zw = posCS.zw;
return ret;
}
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.posCS = UnityObjectToClipPos(v.vertex);//this is not SV_POSITION
o.posOS = v.vertex;
o.posVS = mul(UNITY_MATRIX_MV, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
float posterize(float v, int tone){
return floor(v * tone) / (float) tone;
}
/*
* In View Space, camera forward is -Z. (Both of DirectX and OpeGLCore are same.)
*/
fixed4 frag(v2f i) : SV_Target {
float viewZ = i.posVS.z;
float4 posCS = i.posCS;
float svPosViewz = (i.vertex.z * -viewZ - UNITY_MATRIX_P._m23) / UNITY_MATRIX_P._m22;
float clipPosViewz = (posCS.z * -viewZ - UNITY_MATRIX_P._m23) / UNITY_MATRIX_P._m22;
float4 recalSVPosZ = posterize(-float4(svPosViewz,svPosViewz,svPosViewz, 1), 5);
float4 recalClipPosZ = posterize(-float4(svPosViewz,svPosViewz,svPosViewz, 1), 5);
float4 rawZ = posterize(-float4(viewZ,viewZ,viewZ, 1), 5);
float2 xy = (posCS.xy / viewZ)*0.5+0.5;
if(xy.x < _X) return 1;
if(xy.x < _Y) return 1;
return float4(xy, 0, 1);
float4 ndcSV = TransformClipToNDC(i.vertex);
float2 wip = 0;
{
wip = ndcSV.xy - (float2)(-viewZ/2.0);
wip.y /= _ProjectionParams.x;
wip *= 2.0;
}
float4 ndcSVDecode = float4(wip / _ScreenParams.xy, 0, 1);;
if(ndcSVDecode.r < _X) return 1;
if(ndcSVDecode.g < _Y) return 1;
//return ndcSVDecode;
float4 ndcBeforeW = TransformClipToNDC(posCS);
wip = ndcBeforeW.xy - posCS.w/2;
wip.y /= _ProjectionParams.x;
wip *= 2;
//return float4(abs(wip - posCS.xy)*10000, 0, 1);
float4 posCSDivW = posCS / posCS.w;
float4 ndcAfterW = TransformClipToNDC(posCSDivW);
float zCheck = abs(ndcAfterW.z * -viewZ - posCS.z)*100;
float wCheck = ndcAfterW.w;
if(ndcAfterW.r < _X) return 1;
if(zCheck < _Y) return 1;
if(wCheck < _W) return 1;
//return float4(zCheck, 0,0, 1);
//return float4(wCheck,0, 0, 1);
}
/*
* VS : View Space
* CS : Clip Space
* NDC : Normalized Device Coordinate
*
* Note:View Space Z is minus.
*/
/*CS (: SV_POSITION)
* this is divided with w(=VS.z) automatically within vertex shader and fragment shader.
* At the same time, xy is scaled with screen resolution and adjusted difference of Graphics API
* x = 0 ~ screen width resolution
* x = 0 ~ screen height resolution
* z = ((VS.z * UNITY_MATRIX_P._m22) + UNITY_MATRIX_P._m23) / -VS.z
* w : -VS.z
*/
/*CS (NOT SV_POSITION)
* x : -VS.z ~ +VS.z (right to left)
* y : -VS.z ~ +VS.z (top to bottom)(when GLCore, top to bottom)
* z : VS.z * UNITY_MATRIX_P._m22 + UNITY_MATRIX_P._m23
* w : -VS.z
*/
/*NDC (when argument posCS is SV_POSITION)
* x : (0 ~ screen width resolution)/2 + -VS.z/2
* y : (0 ~ screen height resolution)/2 * _ProjectionParams.x + -VS.z/2
* z : CS.z (= ((VS.z * UNITY_MATRIX_P._m22) + UNITY_MATRIX_P._m23) / -VS.z)
* w : CS.w (= -VS.z)
*/
/*NDC (when argument posCS is not divided CS.w(=-VS.z))
* x : CS.x/2 + CS.w/2
* y : CS.y/2 * _ProjectionParams.x + CS.w/2
* z : CS.z (= VS.z * UNITY_MATRIX_P._m22 + UNITY_MATRIX_P._m23)
* w : CS.w (= -VS.z)
*/
/*NDC (when argument posCS is self-divided CS.w(=-VS.z))
* x : -1 ~ +1 (left to right)
* y : -1 ~ +1 (bottom to top)
* z : CS.z (= (VS.z * UNITY_MATRIX_P._m22 + UNITY_MATRIX_P._m23) / -VS.z)
* w : 1
*/
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment